Persistent Volume Claims

A process requires compute, memory, network, and storage. In the Guestbook sample, we saw how Kubernetes helps us abstract the compute, memory, and network. The same yaml files work across all cloud providers, including a cloud-specific setup of public-facing Load Balancers. The WordPress example shows how the last and the most important piece namely storage is abstracted from the underlying cloud provider.

In this case, the WordPress helm chart depends on the Maria DB helm chart (https://github.com/helm/charts/tree/master/stable/mariadb) for its database install. Describing the helm format would take another book; it is easier to look at the output and see what was done. Unlike stateless applications, such as our frontends, Maria DB requires careful handling of storage. We inform of this Kubernetes by defining the Maria DB deployment as StatefulSet. StatefulSet (https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) is like Deployment with the additional capability of ordering, and uniqueness of the pods. The previous statement is from the documentation, so what does it really mean. It means that Kubernetes will try really hard  and we mean really, really hard  to ensure that the pod and its storage are kept together. One way to help us is also the naming. The pods are named <pod-name>-#, where # starts from 0 for the first pod (you know it's a programmer thing).

You can see from the following code that mariadb has a predictable number attached to it, whereas the WordPress Deployment has a random number attached to the end. The numbering reinforces the ephemeral nature of the Deployment pods versus the StatefulSet pods.

ab443838-9b3e-4811-b287-74e417a9@Azure:~$ kc get pod
NAME READY STATUS RESTARTS AGE
handsonaks-wp-mariadb-0 1/1 Running 1 17h
handsonaks-wp-wordpress-6ddcfd5c89-fv6l2 1/1 Running 2 16h

Another difference is how pod deletion is handled. When a Deployment Pod is deleted, Kubernetes will launch it again anywhere it can, whereas when a StatefulSet Pod is deleted, Kubernetes will relaunch it only on the node it was running. It will relocate the pod only if the node is removed from Kubernetes cluster.

Another requirement for StatefulSet is dynamically-provisioned persistent volume. Volume can be backed up by many mechanisms (including blocks, such as Azure Blob, EBS, and iSCSI, and network filesystems, such as AFS, NFS, and GlusterFS), please see https://Kubernetes .io/docs/concepts/storage/volumes/#persistentvolumeclaim for more information. StatefulSets require dynamically-provisioned volumes handled by PVC. PVC provides an abstraction over the underlying storage mechanism, whether it is backed by block storage or a host directory (not recommended for production use, but works pretty well for local development). Let's look at what the Maria DB helm chart did for us by running the following:

kubectl get statefulsets
NAME DESIRED CURRENT AGE
handsonaks-wp-mariadb 1 1 17h

kubectl get -o yaml statefulsets/handsonaks-wp-mariadb &gt; mariadb_statefulset.yaml
code mariadb_statefulset.yaml # open it in the editor

For our install, we got the following command:

  1 apiVersion: apps/v1
2 kind: StatefulSet
3 metadata:
4 creationTimestamp: 2018-12-27T10:08:51Z
5 generation: 1
6 labels:
7 app: mariadb
8 chart: mariadb-5.2.5
9 component: master
10 heritage: Tiller
11 release: handsonaks-wp
12 name: handsonaks-wp-mariadb
13 namespace: default
14 resourceVersion: "182595"
15 selfLink: /apis/apps/v1/namespaces/default/statefulsets/handsonaks-wp-mariadb
16 uid: 68a51584-09bf-11e9-9914-82000ff4ac53
17 spec:
18 podManagementPolicy: OrderedReady
19 replicas: 1
20 revisionHistoryLimit: 10
21 selector:
22 matchLabels:
23 app: mariadb
24 component: master
25 release: handsonaks-wp
26 serviceName: handsonaks-wp-mariadb
27 template:
28 metadata:
29 creationTimestamp: null
30 labels:
31 app: mariadb
32 chart: mariadb-5.2.5
33 component: master
34 release: handsonaks-wp
35 spec:
36 affinity:
37 podAntiAffinity:
38 preferredDuringSchedulingIgnoredDuringExecution:
39 - podAffinityTerm:
40 labelSelector:
41 matchLabels:
42 app: mariadb
43 release: handsonaks-wp
44 topologyKey: Kubernetes .io/hostname
45 weight: 1
46 containers:
47 - env:
48 - name: MARIADB_ROOT_PASSWORD
49 valueFrom:
50 secretKeyRef:
51 key: mariadb-root-password
52 name: handsonaks-wp-mariadb
53 - name: MARIADB_USER
54 value: bn_wordpress
55 - name: MARIADB_PASSWORD
56 valueFrom:
57 secretKeyRef:
58 key: mariadb-password
59 name: handsonaks-wp-mariadb
60 - name: MARIADB_DATABASE
61 value: bitnami_wordpress
62 image: docker.io/bitnami/mariadb:10.1.37
63 imagePullPolicy: IfNotPresent
64 livenessProbe:
65 exec:
66 command:
67 - sh
68 - -c
69 - exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD
70 failureThreshold: 3
71 initialDelaySeconds: 120
72 periodSeconds: 10
73 successThreshold: 1
74 timeoutSeconds: 1
75 name: mariadb
76 ports:
77 - containerPort: 3306
78 name: mysql
79 protocol: TCP
80 readinessProbe:
81 exec:
82 command:
83 - sh
84 - -c
85 - exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD
86 failureThreshold: 3
87 initialDelaySeconds: 30
88 periodSeconds: 10
89 successThreshold: 1
90 timeoutSeconds: 1
91 resources: {}
92 terminationMessagePath: /dev/termination-log
93 terminationMessagePolicy: File
94 volumeMounts:
95 - mountPath: /bitnami/mariadb
96 name: data
97 - mountPath: /opt/bitnami/mariadb/conf/my.cnf
98 name: config
99 subPath: my.cnf
100 dnsPolicy: ClusterFirst
101 restartPolicy: Always
102 schedulerName: default-scheduler
103 securityContext:
104 fsGroup: 1001
105 runAsUser: 1001
106 terminationGracePeriodSeconds: 30
107 volumes:
108 - configMap:
109 defaultMode: 420
110 name: handsonaks-wp-mariadb
111 name: config
112 updateStrategy:
113 type: RollingUpdate
114 volumeClaimTemplates:
115 - metadata:
116 creationTimestamp: null
117 labels:
118 app: mariadb
119 component: master
120 heritage: Tiller
121 release: handsonaks-wp
122 name: data
123 spec:
124 accessModes:
125 - ReadWriteOnce
126 resources:
127 requests:
128 storage: 8Gi
129 status:
130 phase: Pending
131 status:
132 collisionCount: 0
133 currentReplicas: 1
134 currentRevision: handsonaks-wp-mariadb-544cbd7968
135 observedGeneration: 1
136 readyReplicas: 1
137 replicas: 1
138 updateRevision: handsonaks-wp-mariadb-544cbd7968
139 updatedReplicas: 1

Those are lots of lines, and if you read them carefully, you will see it is mostly the same information that we provided for Deployment. In the following block, we will highlight the key differences, to take a look at just the PVC:

  1 apiVersion: apps/v1
2 kind: StatefulSet
...

19 replicas: 1
...

94 volumeMounts:
95 - mountPath: /bitnami/mariadb
96 name: data
...

114 volumeClaimTemplates:
115 - metadata:
117 labels:
118 app: mariadb
119 component: master
120 heritage: Tiller
121 release: handsonaks-wp
122 name: data
123 spec:
124 accessModes:
125 - ReadWriteOnce
126 resources:
127 requests:
128 storage: 8Gi
Persistent Volume Claims (PVC) can be used by any Pod, not just StatefulSet Pods.

The following lines will give a detailed explanation of the preceding code:

  • Line 2: StatefulSet declaration
  • Line 19: As a Maria/MySQL DB, they don't support running active/inactive multiple instances (unlike Hadoop, for example)
  • Line 94-96: Mount the volume defined as data and mount it under the /bitnami/mariadb path
  • Line 114-122: Declare the metadata from the volume claim with the data ID
  • Line 128: The size requested for the database storage is 8 Gigabytes

Based on the preceding information, Kubernetes dynamically requests and binds 8Gi volume to this pod. In this case, the default dynamic-storage provisioner backed by Azure Disk is used. The dynamic provisioner is set up by Azure when we created the cluster as shown in the following command and the obtained output:

ab443838-9b3e-4811-b287-74e417a9@Azure:~$ kc get storageclass
NAME PROVISIONER AGE
default (default) Kubernetes .io/azure-disk 8h
managed-premium Kubernetes .io/azure-disk 2d

We get more details about the PVC by running the following:

ab443838-9b3e-4811-b287-74e417a9@Azure:~$ kc get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-handsonaks-wp-mariadb-0 Bound pvc-68aa2ba4-09bf-11e9-9914-82000ff4ac53 8Gi RWO default 19h

When we asked for storage in the StatefulSet description (Line 114-128), Kubernetes performed Azure-Disk-specific operations to get the Azure Disk with 8GiB storage:

The helm chart keeps the deployment cloud provider agnostic through the use of abstractions, such as PVC. This script would work the same on AWS or GCP. On AWS, it will be backed by EBS, and on GCP it would be Persistent Disk.

Also note that PVC can be deployed without using Helm.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset