This blog is written by Liping Xue who is a software engineer in Cloud Native Applications Storage team. She focuses on vSphere Docker Volume Service.
As described in this blog, we can see that users have strong demands to run data intensive workloads in containers. Although Docker has good support for running stateless applications which dominate the micro services era, it lacks enough support to enable users to run stateful applications effortlessly.
Starting 0.12 release, Docker has introduced swarm mode which is a great tool to setup a clustered Docker environment to run applications quickly and efficiently. In Docker swarm mode, users can deploy an application image as a service easily.
Swarm manager accepts the service definition as the desired state of the service, and tries to maintain the desired state of the service automatically. For example, if a user deploys a “Nginx” service to the swarm cluster and specifies the number of replicas of the service to 1, swarm manager will figure out which node to run this task on and starts this task by creating a container on the selected node automatically. If the node running the task is down for whatever reason, swarm manager will automatically create another container on one of the remaining nodes. No user intervention is needed. Sounds great! Unfortunately, it only works well if the service is a stateless service.
When a user deploys a stateful service like PostGreSQL, swarm manager will start the container on a node and attach the container to a local volume created by Docker. In case of a node failure, swarm will create another container on another node but leaving data behind which is not good. Long lived stateful service like database need persistent storage which should exist outside the container because it has a life span longer than the container which uses it. With vSphere Docker Volume Service (vDVS), a user can create highly available Docker Volumes by using either vSAN, NFS or VMFS as the underlying storage. Here is the introduction about this. vDVS provides a real persistent layer to run stateful containers with the benefit of all the enterprise capabilities.
In this post, we’d like to show you how to deploy a stateful service like PostgreSQL with Docker swarm mode and vDVS.
Configuration
VM name | Role |
swarm01 | manager |
swarm02 | worker1 |
swarm03 | worker2 |
Deploy PostGreSQL service using “docker stack” command
We run “docker stack deploy” command from the swarm manager(“swarm01”) to deploy a stack with the following yaml file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
version: "3" services: postgres: image: postgres ports: - "5432:5432" volumes: - postgres_vol:/var/lib/data environment: - "POSTGRES_PASSWORD=secretpass" - "PGDATA=/var/lib/data/db" deploy: restart_policy: condition: on-failure placement: constraints: - node.role == worker volumes: postgres_vol: driver: "vsphere" driver_opts: size: "1GB" vsan-policy-name : "goldPolicy" fstype : "ext4" |
The following shows the command to deploy the service and check the status of the service after deploy .In the above YAML file, we define the service needed to mount a volume “postgres_vol” which maps to “/var/lib/data” to store the database file. That volume is created by vDVS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
root@swarm01:—# docker stack ls NAME SERVICES root@swarm01:—# root@swarm01:—# docker stack deploy -c postgres-stack-vmdk.yml postgres Creating network postgres_default Creating service postgres_postgres root@swarm01:~# docker volume ls DRIVER VOLUME NAME vsphere mariadb_db_data@vsanDatastore vsphere mariadb_db_data_vol@vsanDatastore vsphere postgres_db_data_vol@vsanDatastore vsphere postgres_postgres_vol@vsanDatastore vsphere testvol@vsanDatastore root@swarm01:—# docker service ps postgres_postgres ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS b7jcjlur114p postgres_postgres.1 postgres:latest swarm02 Running Running 1 second ago |
We can see that, after deploy, a volume “postgres_postgres_vol” is created on the “vsanDatastore”, and a container starts running on node worker1(“swarm02”) with the volume attached, which is shown in the following diagram.
Then we run “docker inspect” command to inspect the service. In the “Mounts” section of the output shown below, we can see that the source of the mounts is “postgres_postgres_vol”, which was created by vDVS. We can also see the driver specific options in the “DriverConfig” section when the volume was created.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
root@swarm01:~# docker inspect postgres_postgres [ { "ID": "7r6k76hz3cxx8n0jwhuuecndm", "Version": { "Index": 187 }, "CreatedAt": "2017-03-21T22:52:33.012723999Z", "UpdatedAt": "2017-03-21T22:52:33.017837833Z", "Spec": { "Name": "postgres_postgres", "Labels": { "com.docker.stack.namespace": "postgres" }, "TaskTemplate": { "ContainerSpec": { "Image": "postgres:latest@sha256:d865bf05c382a2b54c8436a80f0257010587afc01830907899b66a9e615bbbbf", "Labels": { "com.docker.stack.namespace": "postgres" }, "Env": [ "PGDATA=/var/lib/data/db", "POSTGRES_PASSWORD=secretpass" ], "Mounts": [ { "Type": "volume", "Source": "postgres_postgres_vol", "Target": "/var/lib/data", "VolumeOptions": { "Labels": { "com.docker.stack.namespace": "postgres" }, "DriverConfig": { "Name": "vsphere", "Options": { "fstype": "ext4", "size": "1GB", "vsan-policy-name": "goldPolicy" } } } } ] }, |
Connect to PostGreSQL service
Then we try to connect to the service through PostgreSQL client. We connect to swarm manger’s IP 10.161.20.17 at port 5432, then create a table “user” with two columns “name” and “department”.
We then insert the following three rows into table “user”.
DB table is persistent after node failover
We shutdown node worker1(“swarm02”). After node shutdown, swarm manager restarts the container on another worker node worker2(“swarm03”) with the same volume attached, which is shown in the following diagram.
Then we try connect to swarm manger’s IP 10.161.20.17 at port 5432 again, and check the content in table “user”. The content in table “user” keeps unchanged as expected.
As you can see, vDVS implements a persistent storage layer for Docker Swarm mode which enables users to run stateful applications as a service easily.
We would love to hear your feedback! We will be at DockerCon. Please drop by at booth G9 to learn more about what we have to offer.
If you are interested in contributing code or have any questions or feedback, you can reach us at