Container orchestrators and persistent volumes: part 2: Kubernetes
In my previous post, I presented how external persistent volumes were handled by DC/OS on AWS and how persistent services would recover from a node failure. Now let's review how Kubernetes deals with similar situations, but on Google Cloud.
Kubernetes on GCP in 10 mins
I used this tutorial from Kubernetes documentation to generate a small cluster in GCP. TL;DR If you basically run the following command on your cloud shell, you should have a running cluster in about 5 minutes: [code language="bash"] gabocic@kubernetes-196513:~$ curl -sS https://get.k8s.io | bash [/code] I then installed the latest version of kubectl by downloading it from storage.googleapis.com directly. You can use this link for more details about installing Kubernetes CLI.A quick recap
In Part 1, I created a persistent service on DC/OS (i.e., a MySQL instance) using external persistent volumes. This means that the data was not actually stored on the node where the container was running, but on an AWS EBS volume. We also saw that upon failure, the volume would be moved and mounted transparently on the new node where the service is running. Let’s run a similar test on Kubernetes and see how it reacts.Deploying a MySQL service
I chose to use the web GUI to interact with the cluster, so I first launched kubectl proxy from Google cloud shell and used the web preview feature to make the GUI available from my laptop. Additional details about how to do this can be found here. For those new to Kubernetes, the Create button on the upper right corner will allow you to create any Kubernetes resource by providing the correspondent YAML code. To create the MySQL service, I used this example YAML:![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/Untitled.png?width=649&height=439&name=Untitled.png)
--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim spec: accessModes: - ReadWriteOnce resources: requests: storage: 20GiFrom the snippet above, you can infer that we are requesting a persistent, 20Gib volume through a claim named mysql-pv-claim. Further down the YAML text, we can see that the resultant persistent volume should be mounted on /var/lib/mysql:
volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claimAfter uploading the YAML objects description, you can now see we have our Deployment, Persistent Volume Claims and Services created and healthy.
![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/kube_deploy.png?width=1573&height=146&name=kube_deploy.png)
![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/kube_pv.png?width=1570&height=148&name=kube_pv.png)
![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/kube_services.png?width=1571&height=213&name=kube_services.png)
![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/kube_pods.png?width=1568&height=143&name=kube_pods.png)
![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/kube_migrated_service.png?width=1567&height=143&name=kube_migrated_service.png)
![](https://www.pythian.com/hs-fs/hubfs/Imported_Blog_Media/kube_disks-1.png?width=1248&height=126&name=kube_disks-1.png)
Storage provisioner
When we queried the container mount metadata on DC/OS, we observed that it was using the REXRay driver. Doing the same for Kubernetes will show us that the volume was made available through a "bind" mount, pointing to a path in the local filesystem. How did our GCE volume make it to the node and how was it presented to the container? If we check our volume on the "Persistent volumes" section, you will find that there is a storage class associated with it ( Standard in this case). Going to the "Storage classes" menu in Kubernetes GUI, we can see the properties of our Standard class. In this case, it is using the kubernetes.io/gce-pd provisioner, which basically allows Kubernetes to manage GCE volumes. When creating a persistent volume, you can specify the class using storageClassName. If not provided, it will default to the "default" class, which is Standard in this case (you can check if a class is the default by checking its YAML configuration). Before a container is started on a node, the kubelet volume manager locally mounts all the volumes specified in the PodSpec under a directory for that pod on the host system. Once all the volumes are successfully mounted, it constructs the list of volume mounts to pass to the container runtime.Conclusions
Kubernetes also provides the necessary mechanisms to transparently provision and handle external persistent volumes (GCE disks for this lab). Kubernetes will make sure that volumes associated with a service are mounted on the host and presented to the container when it is started. Unlike DC/OS, Kubernetes uses bind mounts and relies on a GCE-specific provisioner to create the volumes. Finally, it is the kubelet agent which is the one in charge of mounting the external volumes into the appropriate host.Share this
Previous story
← Log buffer #546: a carnival of the vanities for DBAs
Next story
Backup strategies in Cassandra →
You May Also Like
These Related Stories
MySQL Can't Use Index With Uncorrelated IN Subquery
MySQL Can't Use Index With Uncorrelated IN Subquery
Jan 9, 2007
1
min read
The value of Pythian’s internship program
The value of Pythian’s internship program
Feb 19, 2016
2
min read
Ansible dependencies for docker containers
Ansible dependencies for docker containers
Sep 9, 2016
3
min read
No Comments Yet
Let us know what you think