diff --git a/docs/tutorial/Vagrantfile b/docs/tutorial/Vagrantfile index 7728dc9db4..be1b65f0cf 100644 --- a/docs/tutorial/Vagrantfile +++ b/docs/tutorial/Vagrantfile @@ -26,7 +26,10 @@ echo "# Flocker-defined alternate temporary path to provide more temporary space echo "TMPDIR=/var/tmp" >> /etc/sysconfig/docker systemctl enable docker -systemctl start docker +# Enabling Docker allows it to be started by socket activation, but it may +# already be running. Restart it to ensure that it picks up the new tmpdir +# configuration. +systemctl restart docker systemctl enable geard systemctl start geard @@ -57,6 +60,13 @@ else fi fi +# XXX This is a hack to reduce the size of the mongodb image. It can be removed +# when we have created a smaller mongo image for use in this tutorial. See +# https://github.com/ClusterHQ/flocker/issues/383 +mkdir /var/tmp/dockerbuild +cd /var/tmp/dockerbuild +echo "FROM dockerfile/mongodb\nCMD mongod --dbpath=/data --noprealloc --smallfiles" > Dockerfile +docker build --tag mongodb-tutorial . SCRIPT Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| diff --git a/docs/tutorial/index.rst b/docs/tutorial/index.rst index 3d0fa35ab4..71810a9245 100644 --- a/docs/tutorial/index.rst +++ b/docs/tutorial/index.rst @@ -3,8 +3,8 @@ Flocker Tutorial The goal of this tutorial is to teach you to use Flocker's container, network, and volume orchestration functionality. By the time you reach the end of the tutorial you will know how to use Flocker to create an application. -You will know how to configure a persistent data volume for that application. You will also know how to expose that application to the network and how to move it from one host to another. +Finally you will know how to configure a persistent data volume for that application. This tutorial is based around the setup of a MongoDB service. Flocker is a generic container manager. @@ -17,3 +17,4 @@ Any application you can deploy into Docker you can manage with Flocker. vagrant-setup moving-applications exposing-ports + volumes diff --git a/docs/tutorial/minimal-application.yml b/docs/tutorial/minimal-application.yml index fb6068194b..a029608d10 100644 --- a/docs/tutorial/minimal-application.yml +++ b/docs/tutorial/minimal-application.yml @@ -1,4 +1,4 @@ "version": 1 "applications": "mongodb-example": - "image": "dockerfile/mongodb" + "image": "mongodb-tutorial" diff --git a/docs/tutorial/port-application.yml b/docs/tutorial/port-application.yml index bf1b93ea9e..bebde1edf4 100644 --- a/docs/tutorial/port-application.yml +++ b/docs/tutorial/port-application.yml @@ -1,7 +1,7 @@ "version": 1 "applications": "mongodb-port-example": - "image": "dockerfile/mongodb" + "image": "mongodb-tutorial" "ports": - "internal": 27017 "external": 27017 diff --git a/docs/tutorial/volume-application.yml b/docs/tutorial/volume-application.yml new file mode 100644 index 0000000000..42e350117d --- /dev/null +++ b/docs/tutorial/volume-application.yml @@ -0,0 +1,11 @@ +"version": 1 +"applications": + "mongodb-volume-example": + "image": "mongodb-tutorial" + "ports": + - "internal": 27017 + "external": 27017 + "volume": + # The location within the container where the data volume will be + # mounted: + "mountpoint": "/data" diff --git a/docs/tutorial/volume-deployment-moved.yml b/docs/tutorial/volume-deployment-moved.yml new file mode 100644 index 0000000000..63f35904f0 --- /dev/null +++ b/docs/tutorial/volume-deployment-moved.yml @@ -0,0 +1,4 @@ +"version": 1 +"nodes": + "172.16.255.250": [] + "172.16.255.251": ["mongodb-volume-example"] diff --git a/docs/tutorial/volume-deployment.yml b/docs/tutorial/volume-deployment.yml new file mode 100644 index 0000000000..549b528258 --- /dev/null +++ b/docs/tutorial/volume-deployment.yml @@ -0,0 +1,4 @@ +"version": 1 +"nodes": + "172.16.255.250": ["mongodb-volume-example"] + "172.16.255.251": [] diff --git a/docs/tutorial/volumes.rst b/docs/tutorial/volumes.rst new file mode 100644 index 0000000000..30919589f1 --- /dev/null +++ b/docs/tutorial/volumes.rst @@ -0,0 +1,110 @@ +============ +Data Volumes +============ + +The Problem +=========== + +By default moving an application from one node to another does not move its data along with it. +Before proceeding let's see in more detail what the problem is by continuing the example in :doc:`exposing-ports`. + +Recall that we inserted some data into the database. +Next we'll use a new configuration file that moves the application to a different node. + +:download:`port-deployment-moved.yml` + +.. literalinclude:: port-deployment-moved.yml + :language: yaml + +.. code-block:: console + + alice@mercury:~/flocker-tutorial$ flocker-deploy port-deployment-moved.yml port-application.yml + alice@mercury:~/flocker-tutorial$ ssh root@172.16.255.251 docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 4d117c7e653e dockerfile/mongodb:latest mongod 2 seconds ago Up 1 seconds 27017/tcp, 28017/tcp mongodb-port-example + alice@mercury:~/flocker-tutorial$ + +If we query the database the records we've previously inserted have disappeared! +The application has moved but the data has been left behind. + +.. code-block:: console + + alice@mercury:~/flocker-tutorial$ mongo 172.16.255.251 + MongoDB shell version: 2.4.9 + connecting to: 172.16.255.251/test + > use example; + switched to db example + > db.records.find({}) + > + +The Solution +============ + +Unlike many other Docker frameworks Flocker has a solution for this problem, a ZFS-based volume manager. +An application with a Flocker volume configured will move the data along with the application, transparently and with no additional intervention on your part. + +We'll create a new configuration for the cluster, this time adding a volume to the MongoDB container. + +:download:`volume-application.yml` + +.. literalinclude:: volume-application.yml + :language: yaml + +:download:`volume-deployment.yml` + +.. literalinclude:: volume-deployment.yml + :language: yaml + +Then we'll run these configuration files with ``flocker-deploy``: + +.. code-block:: console + + alice@mercury:~/flocker-tutorial$ flocker-deploy volume-deployment.yml volume-application.yml + alice@mercury:~/flocker-tutorial$ ssh root@172.16.255.250 docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 4d117c7e653e dockerfile/mongodb:latest mongod 2 seconds ago Up 1 seconds 27017/tcp, 28017/tcp mongodb-volume-example + alice@mercury:~/flocker-tutorial$ + +Once again we'll insert some data into the database: + +.. code-block:: console + + alice@mercury:~/flocker-tutorial$ $ mongo 172.16.255.250 + MongoDB shell version: 2.4.9 + connecting to: 172.16.255.250/test + > use example; + switched to db example + > db.records.insert({"the data": "it moves"}) + > db.records.find({}) + { "_id" : ObjectId("53d80b08a3ad4df94a2a72d6"), "the data" : "it moves" } + +Next we'll move the application to the other node. + +:download:`volume-deployment-moved.yml` + +.. literalinclude:: volume-deployment-moved.yml + :language: yaml + +.. code-block:: console + + alice@mercury:~/flocker-tutorial$ flocker-deploy volume-deployment-moved.yml volume-application.yml + alice@mercury:~/flocker-tutorial$ ssh root@172.16.255.251 docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 4d117c7e653e dockerfile/mongodb:latest mongod 2 seconds ago Up 1 seconds 27017/tcp, 28017/tcp mongodb-volume-example + alice@mercury:~/flocker-tutorial$ + +This time however the data has moved with the application: + +.. code-block:: console + + alice@mercury:~/flocker-tutorial$ mongo 172.16.255.251 + MongoDB shell version: 2.4.9 + connecting to: 172.16.255.251/test + > use example; + switched to db example + > db.records.find({}) + { "_id" : ObjectId("53d80b08a3ad4df94a2a72d6"), "the data" : "it moves" } + +At this point you have successfully deployed a MongoDB server and communicated with it. +You've also seen how Flocker allows you to move an application's data to different locations in cluster as the application is moved. +You now know how to run stateful applications in a Docker cluster using Flocker.