Safeguard and scale containers

Herding Containers

Pods and More

Pods [11] are the smallest unit of deployment and are containers that share a single fate. Kubernetes generates them on the same node: They share an IP address, share access to the filesystem, and die together when a container in the pod breathes its last breath. A YAML file describes a pod; Listing 1 defines one for a simple Nginx server.

Listing 1


01 apiVersion: v1
02 kind: Pod
03 metadata:
04   name: nginx
05 spec:
06   containers:
07   - name: nginx
08     image: nginx
09     ports:
10     - containerPort: 80

A replication controller [12], however, guarantees that a certain number of pods are always running. Listing 2 shows what this looks like in YAML format. Typing kubectl scale lets you change the number of active instances retroactively; you can use kubectl autoscale to define an autoscaler as a function of the system load. The autoscaler boots up instances at set intervals as the load on the system increases, and if it drops, it sends the instances back to sleep.

Listing 2


01 apiVersion: v1
02 kind: ReplicationController
03 metadata:
04   name: nginx
05 spec:
06   replicas: 3
07   selector:
08     app: nginx
09   template:
10     metadata:
11       name: nginx
12       labels:
13         app: nginx
14     spec:
15       containers:
16       - name: nginx
17         image: nginx
18         ports:
19         - containerPort: 80

Services (Figure 2) [13] (e.g., an Nginx service [14]) create a unit out of a logical set of pods that offer the same function. They decouple ongoing pods and services by spanning a transparent network across all the hosts. Each node can retrieve services, even if no pod is running on the node.

Figure 2: Containers, Pods, Nodes, and a Service, which groups various pods for the load balancer.

Pets vs. Cattle

To populate the Kubernetes architecture meaningfully, you need to bear some fundamental things in mind, including distinguishing between cattle and pets [15], which has played a role in the DevOps area for quite a long time. While you lovingly tend your pets, you eat the cattle for dinner. The cattle are all stateless processes, whereas the pets are the data in the databases.

The pod approach only helps you deal with pets. Without any further action, containers do not persist; thus, you will want to design pods as stateless processes, but databases and all persistent data need a storage back end (Figure 3) to stored the data so that they persist beyond the lifespan of the pod.

Figure 3: Multi-tier architecture of web applications. Only the bottom layer should contain persistent data.

Persistent Data

Therefore, how should you best handle the data? The simplest solution might be to rely on the cloud provider; that is, use the storage or database services provided. However, this does involve the risk of provider lock-in, which you need to weigh against the expense you save.

You can install databases on existing storage with a ReplicationController and a replicas: 1. In this case, the data resides on the storage back end. If the container restarts on a different host, it can still access the existing data. This requires a cross-host storage provider. In the simplest case, NFS is used; GlusterFS and Ceph are also suitable. Kubernetes supports a variety of providers.

If you want to work with your own hardware, you can even set up local disks. With the help of labels, you can uniquely assign pods to nodes. Replication of databases proves to be the drawback of this approach. The existing SQL and NoSQL, but also messaging systems, require separate solutions.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus