docker in production - stateful services

28
Running Docker in Production Lauri Nevala, Founder Stateful Services

Upload: kontena-inc

Post on 12-Jan-2017

598 views

Category:

Internet


2 download

TRANSCRIPT

Page 1: Docker in Production - Stateful Services

Running Docker in Production

Lauri Nevala, Founder

Stateful Services

Page 2: Docker in Production - Stateful Services

© 2015 Kontena, Inc.

Page 3: Docker in Production - Stateful Services

Containers Do Not Persist the Data!

© 2015 Kontena, Inc.

Page 4: Docker in Production - Stateful Services

Apps with Persistent Data

• Databases • File storages •  Image registries • Version Control Systems • etc

© 2015 Kontena, Inc.

Page 5: Docker in Production - Stateful Services

© 2015 Kontena, Inc.

Page 6: Docker in Production - Stateful Services

How to solve the problem

• Mounting a host directory as a data volume • Creating and mounting a data volume container • Using Docker volume drivers (>= 1.9)

© 2015 Kontena, Inc.

Page 7: Docker in Production - Stateful Services

Mounting a host directory as a data volume • $ docker run -d -P --name web -v /src/webapp:/opt/webapp

training/webapp python app.py • Cons:

•  Not recommended on production •  Problems with file permissions •  How to keep track what directories are in use?

© 2015 Kontena, Inc.

Page 8: Docker in Production - Stateful Services

Creating and mounting a data volume container • $ docker create -v /dbdata --name dbdata training/postgres /bin/

true • $ docker run -d --volumes-from dbdata --name db1 training/

postgres

© 2015 Kontena, Inc.

Page 9: Docker in Production - Stateful Services

Using Docker volume drivers (>= 1.9)

• $ docker volume create --name my_mongo_volume • $ docker run -d -v my_mongo_volume:/data –name mongo

mongo:3.0

© 2015 Kontena, Inc.

Page 10: Docker in Production - Stateful Services

Stateful Services

Page 11: Docker in Production - Stateful Services

How?

• Creating services with persistent data with Kontena is easy

© 2015 Kontena, Inc.

# kontena.yml mysql: image: mariadb:5.5 stateful: true

$ kontena service create –stateful mongo mongo:3.0

Page 12: Docker in Production - Stateful Services

Under the Hood

• Kontena creates data volume container for stateful service instances automatically

• The running container will use volumes from the created data volume container

• The same data volume container is used for future containers as well and the data won’t be lost

© 2015 Kontena, Inc.

Page 13: Docker in Production - Stateful Services

Some Words of Caution

• Stateful services can not be moved to another node automatically

•  User have to migrate data manually • Data is not shared between service instances

•  Each stateful service instance will have an own data volume container

© 2015 Kontena, Inc.

Page 14: Docker in Production - Stateful Services

Examples

Page 15: Docker in Production - Stateful Services

MongoDB cluster – Pure Docker Way

• https://medium.com/@gargar454/deploy-a-mongodb-cluster-in-steps-9-using-docker-49205e231319#.urb900wm8

• Step 1: Get the IP address of all three servers and export the following IP addresses variables on all servers by running the following commands on all servers (replace the IP addresses).

•  Ideally you would not have and the IPs can be resolved via DNS. Since this is a test setup, this is easier.

© 2015 Kontena, Inc.

root@node*:/# export node1=10.11.32.174 root@node*:/# export node2=10.11.33.37 root@node*:/# export node3=10.11.31.176

Page 16: Docker in Production - Stateful Services

• Step 2: On node1, start the following mongodb container.

© 2015 Kontena, Inc.

root@node1:/# docker run --name mongo \ -v /home/core/mongo-files/data:/data/db \ --hostname="node1.example.com" \ -p 27017:27017 \ -d mongo:2.6.5 –smallfiles --replSet "rs0"

Page 17: Docker in Production - Stateful Services

• Step 3: Connect to the replica set and configure it. This is still on node1. We will start another interactive shell into the mongo container and start a mongo shell and initiate the replica set.

© 2015 Kontena, Inc.

root@node1:/# docker exec -it mongo /bin/bash root@node1:/# mongo MongoDB shell version: 2.6.5 > rs.initiate() { "info2" : "no configuration explicitly specified -- making one", "me" : "node1.example.com:27017", "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 }

Page 18: Docker in Production - Stateful Services

• Step 4: Start Mongo on the other 2 nodes

© 2015 Kontena, Inc.

root@node2:/# docker run \ --name mongo \ -v /home/core/mongo-files/data:/data/db \ -v /home/core/mongo-files:/opt/keyfile \ --hostname="node2.example.com" \ --add-host node1.example.com:${node1} \ --add-host node2.example.com:${node2} \ --add-host node3.example.com:${node3} \ -p 27017:27017 -d mongo:2.6.5 \ --smallfiles \ --replSet "rs0"

root@node3:/# docker run \ --name mongo \ -v /home/core/mongo-files/data:/data/db \ -v /home/core/mongo-files:/opt/keyfile \ --hostname="node3.example.com" \ --add-host node1.example.com:${node1} \ --add-host node2.example.com:${node2} \ --add-host node3.example.com:${node3} \ -p 27017:27017 -d mongo:2.6.5 \ --smallfiles \ --replSet "rs0"

Page 19: Docker in Production - Stateful Services

• Step 5: Add the other 2 nodes into the replica set •  Back to node1 where we are in the mongo shell. If you hit enter a few

times here, your prompt should have changed to “rs0:PRIMARY”. This is because this is the primary node now for replica set “rs0".

© 2015 Kontena, Inc.

rs0:PRIMARY> rs.add("node2.example.com") rs0:PRIMARY> rs.add("node3.example.com")

Page 20: Docker in Production - Stateful Services

Let’s try it out

Page 21: Docker in Production - Stateful Services

© 2015 Kontena, Inc.

Page 22: Docker in Production - Stateful Services

MongoDB cluster – The Kontena Way

• Step 1: Create / copy kontena.yml • https://github.com/kontena/examples/tree/master/mongodb-

cluster

© 2015 Kontena, Inc.

Page 23: Docker in Production - Stateful Services

© 2015 Kontena, Inc.

peer: image: mongo:3.0 stateful: true command: --replSet kontena --smallfiles instances: 3 hooks: post_start: - cmd: sleep 10 name: sleep instances: 1 oneshot: true - cmd: mongo --eval "printjson(rs.initiate());" name: rs_initiate instances: 1 oneshot: true - cmd: mongo --eval "printjson(rs.add('%{project}-peer-2'))" name: rs_add2 instances: 1 oneshot: true - cmd: mongo --eval "printjson(rs.add('%{project}-peer-3'))" name: rs_add3 instances: 1 oneshot: true

Page 24: Docker in Production - Stateful Services

• Step 2: Deploy the stack

© 2015 Kontena, Inc.

~/mongo-db-cluster$ kontena app deploy

Page 25: Docker in Production - Stateful Services

MariaDB Galera Cluster

• https://github.com/kontena/examples/tree/master/mariadb-galera

• Step 1: Write secrets to Kontena Vault

• Step 2: Create / copy kontena.yml

© 2015 Kontena, Inc.

$ kontena vault write GALERA_XTRABACKUP_PASSWORD "top_secret" $ kontena vault write GALERA_MYSQL_ROOT_PASSWORD "top_secret"

Page 26: Docker in Production - Stateful Services

© 2015 Kontena, Inc.

seed: image: jakolehm/galera-mariadb-10.0-xtrabackup:latest stateful: true command: seed secrets: - secret: GALERA_XTRABACKUP_PASSWORD name: XTRABACKUP_PASSWORD type: env - secret: GALERA_MYSQL_ROOT_PASSWORD name: MYSQL_ROOT_PASSWORD type: env node: image: jakolehm/galera-mariadb-10.0-xtrabackup:latest stateful: true instances: 3 command: "node %{project}-seed.kontena.local,%{project}-node.kontena.local" secrets: - secret: GALERA_XTRABACKUP_PASSWORD name: XTRABACKUP_PASSWORD type: env environment: - KONTENA_LB_MODE=tcp - KONTENA_LB_BALANCE=leastconn - KONTENA_LB_INTERNAL_PORT=3306 - KONTENA_LB_EXTERNAL_PORT=3306 links: - lb lb: image: kontena/lb:latest instances: 2

Page 27: Docker in Production - Stateful Services

© 2015 Kontena, Inc.

• Step 3: Deploy the stack

• Step 4: Remove seed node

$ kontena app deploy

$ kontena app scale seed 0

Page 28: Docker in Production - Stateful Services

Thank You! www.kontena.io