这篇文章讲了Docker-machine,Docker-compose,Docker-swarm的一些基础知识。
这里是基于docker1.12之前的版本
1 Docker Machine
1.1 简介
Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台
上快速安装 Docker 环境。
现在支持很多驱动,通过-d参数即可,比如:
1.2 安装
Linux下:
$curl -L https://github.com/docker/machine/releases/download/v0.10.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine
or mac环境下:
$brew install docker-machine
1.3 运行
v0.10.0有一个比较大的change,如官网所说:
There is one small breaking change in this release. The default driver for docker-machine create has been changed from none to virtualbox. virtualbox was far more common than none, so this change allows you to quickly create VirtualBox machines like so:
$ docker-machine create manager
...
$ docker-machine create worker
...
boot2docker:
如果上述中出现问题,可以手工安装boot2docker:
https://github.com/boot2docker/boot2docker/releases
$curl -Lo ~/.docker/machine/cache/boot2docker.iso https://github.com/boot2docker/boot2docker/releases/download/v1.13.1/boot2docker.iso
现在一个大的问题就是,github使用的amazon的云被墙了,所以都不行。
2 Docker-compose
2.1 简介
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速在集
群中部署分布式应用。
- 定义和运行多个Docker容器的工具
- 一个文件 – docker-compose.yml
- 一条命令 – docker-compose up
2.2 安装
$curl -L https://github.com/docker/compose/releases/download/1.11.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
2.3 例子
docker-compose.yml
weba:
build: ./web
expose:
- 80
webb:
build: ./web
expose:
- 80
webc:
build: ./web
expose:
- 80
haproxy:
image: haproxy:latest
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- weba
- webb
- webc
ports:
- "80:80"
- "70:70"
expose:
- "80"
- "70"
子文件夹结构如下:
haproxy目录下:haproxy.cfg是配置文件。
web目录下:python web启动的dockerfile及index.py和html这两个后端和前端文件。
dockerfile如下所示:
FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py
最后使用docker-compose up 即可启动。
2.4 Docker-compose命令集
- 管理镜像 – build/pull
- 管理服务 – up/start/stop/kill/rm/scale
- 服务状态 – ps/logs/port
- 一次性命令 - run
2.5 Docker Compose工作原理
- 工程(project)/服务(service)/容器(container)
- 调用docker-py库与远程Docker Daemon/Swarm API -Server通信
- 按依赖性排序/调度
3 Docker Swarm
3.1 简介
Docker Swarm 是 Docker 官方编排(Orchestration)项目之一,负责对 Docker 集
群进行管理。
- Docker集群管理工具
- 多个Docker主机抽象成一个单一的虚拟主机
- 支持标准Docker API
Docker Swarm 是 Docker公司官方在 2014 年 12月初发布的一套管理 Docker 集群 的工具。它将一群 Docker 宿主机变成一个单一的,虚拟的主机。
Swarm 使用标准的 Docker API 接口作为其前端访问入口,换言之,各种形式的 Docker 工具比如 Dokku,Compose,Krane,Deis,docker-py,Docker 本身等都 可以很容易的与 Swarm 进行集成。
工作原理如下:
下面我使用2个方向来介绍Docker Swarm的使用:
- 使用Docker-machine来创建swarm集群
- 使用原生Swarm命令来创建Swarm集群
3.2 使用Docker-machine来创建swarm集群
Docker 集群管理需要使用服务发现(Discovery service backend)功能,Swarm支持 以下的几种方式:DockerHub 提供的服务发现功能,本地的文件,etcd,consul, zookeeper 和 IP 列表,本节会详细讲解前三种方式,其他的用法都是大同小异 的。
3.2.1 使用Dockerhub提供的服务发现功能
Step1: 创建Token
swarm create - 从Docker Hub发现服务申请一个唯一标识此集群的token
$docker run swarm create
b7625e5a7a2dc7f8c4faacf2b510078e
Step2:创建Swarm管理节点及工作节点
管理节点swarm-master:
docker-machine create \
-d virtualbox \
--engine-registry-mirror http://db8ff3fd.m.daocloud.io\
--swarm \
--swarm-master \
--swarm-discovery token://b7625e5a7a2dc7f8c4faacf2b510078e \
swarm-master
docker@swarm-master:~$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c4773d7ca84f1547580aa43ec38250651fb8ec9a005062d2dc4fbf130490771 microbox/etcd:latest "/bin/etcd -addr 10.0.2.15:4001 -peer-addr 10.0.2.15:7001" 14 hours ago Up 14 hours 0.0.0.0:4001->4001/tcp, 0.0.0.0:7001->7001/tcp shipyard-discovery
3d4493eb0934ac1aba15c503cea4f9512a0e3c50d4d0c61ca9674ea95e23cf36 russmckendrick/nginx-php "supervisord" 18 hours ago Up 18 hours 0.0.0.0:80->80/tcp, 443/tcp kickass_aryabhata
3e81e904465f9a162a7b6e8059d9bb46d237795ded58db7f50f038f6a500b775 swarm:latest "/swarm join --advertise 192.168.99.101:2376 etcd://192.168.99.100:4001" 18 hours ago Up 18 hours 2375/tcp swarm-agent
0ecc90458128926e56cbcc28f02bab3fc759ceba92cb3e3d167136442180d912 swarm:latest "/swarm manage --tlsverify --tlscacert=/var/lib/boot2docker/ca.pem --tlscert=/var/lib/boot2docker/server.pem --tlskey=/var/lib/boot2docker/server-key.pem -H tcp://0.0.0.0:3376 --strategy spread --advertise 192.168.99.101:3376 etcd://192.168.99.100:4001" 18 hours ago Up 18 hours 2375/tcp, 0.0.0.0:3376->3376/tcp swarm-agent-master
swarm manage – 启动swarm manage进程
工作节点swarm-node-00:
docker-machine create \
-d openstack \
--engine-registry-mirror http://db8ff3fd.m.daocloud.io\
--swarm \
--swarm-discovery token://b7625e5a7a2dc7f8c4faacf2b510078e \
swarm-node-00
docker@swarm-node-00:~$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f9fe781e0e34fa73921d7fc741a9e7648f982a99a79f612535727275635b8166 russmckendrick/nginx-php "supervisord" 3 weeks ago Up 3 weeks 0.0.0.0:80->80/tcp, 443/tcp brave_heyrovsky
0914302f17258775f95aab4c61c725735dd004fba6df8b2a9b582d8e6e883d64 mysql "docker-entrypoint.sh mysqld" 3 weeks ago Up 3 weeks 3306/tcp mysql
759617d53f392279f3c927f3b6583b0eec17eed4d1ccb95b1d70e55090a69654 swarm:latest "/swarm join --advertise 192.168.99.102:2376 etcd://192.168.99.100:4001" 3 weeks ago Up 3 weeks 2375/tcp swarm-agent
这样我们就创造了一个名字为swarm-master的管理节点,及swarm-node-00和swarm-node-01的集群。
Step3: 显示集群信息
eval $(docker-machine env --swarm swarm-master)
XiaoleideMacBook-Pro:nss professor$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
localtest * virtualbox Running tcp://192.168.99.100:2376 v1.13.1
swarm-master - virtualbox Running tcp://192.168.99.101:2376 swarm-master (master) v1.13.1
swarm-node-00 - virtualbox Running tcp://192.168.99.102:2376 swarm-master v1.13.1
swarm-node-01 - virtualbox Running tcp://192.168.99.103:2376 swarm-master v1.13.1
XiaoleideMacBook-Pro:nss professor$ eval $(docker-machine env --swarm swarm-master)
XiaoleideMacBook-Pro:nss professor$ docker info
Containers: 11
Running: 7
Paused: 0
Stopped: 4
Images: 6
Server Version: swarm/1.2.6
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint, whitelist
Nodes: 3
swarm-master: 192.168.99.101:2376
└ ID: RIRL:X5TL:EQQP:LSON:ANTV:TT4F:ZCVN:QPHN:2EX7:ID5C:VK5A:LZ3X
└ Status: Healthy
└ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: kernelversion=4.4.47-boot2docker, operatingsystem=Boot2Docker 1.13.1 (TCL 7.2); HEAD : b7f6033 - Wed Feb 8 20:31:48 UTC 2017, provider=virtualbox, storagedriver=aufs
└ UpdatedAt: 2017-03-28T07:25:40Z
└ ServerVersion: 1.13.1
swarm-node-00: 192.168.99.102:2376
└ ID: GJIW:ABWA:6OP5:ZHYU:2GWG:NV32:QJJE:5H7Y:ISTD:62AL:VEWL:47Y3
└ Status: Healthy
└ Containers: 6 (3 Running, 0 Paused, 3 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: kernelversion=4.4.47-boot2docker, operatingsystem=Boot2Docker 1.13.1 (TCL 7.2); HEAD : b7f6033 - Wed Feb 8 20:31:48 UTC 2017, provider=virtualbox, storagedriver=aufs
└ UpdatedAt: 2017-03-28T07:25:40Z
└ ServerVersion: 1.13.1
swarm-node-01: 192.168.99.103:2376
└ ID: LOW7:5ZSC:7XQR:KLRU:CIHB:IF34:6DEZ:EGBB:W3BS:D54H:TPA5:MF3D
└ Status: Healthy
└ Containers: 3 (2 Running, 0 Paused, 1 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: kernelversion=4.4.47-boot2docker, operatingsystem=Boot2Docker 1.13.1 (TCL 7.2); HEAD : b7f6033 - Wed Feb 8 20:31:48 UTC 2017, provider=virtualbox, storagedriver=aufs
└ UpdatedAt: 2017-03-28T07:25:40Z
└ ServerVersion: 1.13.1
通过docker-machine env swarm-master,可以直接操控swarm-master,进一步来控制整个集群。
其中:eval $(docker-machine env --swarm swarm-master)
,可以理解为直接控制了这个docker管理节点。
比如:
XiaoleideMacBook-Pro:nss professor$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7310e34db6b5 russmckendrick/nginx-php "supervisord" 3 weeks ago Up 3 weeks 192.168.99.103:80->80/tcp, 443/tcp swarm-node-01/elated_joliot
f9fe781e0e34 russmckendrick/nginx-php "supervisord" 3 weeks ago Up 3 weeks 192.168.99.102:80->80/tcp, 443/tcp swarm-node-00/brave_heyrovsky
0914302f1725 mysql "docker-entrypoint..." 3 weeks ago Up 3 weeks 3306/tcp swarm-node-00/mysql
tips: --engine-registry-mirror http://db8ff3fd.m.daocloud.io
生成machine之前加入这个参数可以使用daocloud的加速器,国外太慢。
step4:创建容器
例子1 :创建2个容器
$docker -H 192.168.99.101:2376 pull redis
$docker -H 192.168.99.102:2376 pull mysql
docker run -d --name mysql -e affinity:image==mysql -e MYSQL_ROOT_PASSWORD=root mysql
docker run -d --name redis1 -e affinity:image==redis redis
eval $(docker-machine env --swarm swarm-master)
XiaoleideMacBook-Pro:compose-haproxy-web professor$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
72896f932fae mysql "docker-entrypoint..." 4 seconds ago Up 3 seconds 3306/tcp swarm-node-00/mysql
68a7c531ec08 redis "docker-entrypoint..." 3 minutes ago Up 3 minutes 6379/tcp swarm-master/redis1
可以看出来,使用-H的话,可以两个镜像分别在两个node中
例子2:创建3个容器
$docker -H 192.168.99.101:2376 pull russmckendrick/nginx-php
$docker -H 192.168.99.102:2376 pull russmckendrick/nginx-php
$docker -H 192.168.99.103:2376 pull russmckendrick/nginx-php
运行3次,启动3个容器。
docker run -d -p 80:80 russmckendrick/nginx-php
虽然端口一样。但是swarm将其分到两个节点上。
XiaoleideMacBook-Pro:nss professor$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d4493eb0934 russmckendrick/nginx-php "supervisord" 2 seconds ago Up 2 seconds 192.168.99.101:80->80/tcp, 443/tcp swarm-master/kickass_aryabhata
7310e34db6b5 russmckendrick/nginx-php "supervisord" 3 weeks ago Up 3 weeks 192.168.99.103:80->80/tcp, 443/tcp swarm-node-01/elated_joliot
f9fe781e0e34 russmckendrick/nginx-php "supervisord" 3 weeks ago Up 3 weeks 192.168.99.102:80->80/tcp, 443/tcp swarm-node-00/brave_heyrovsky
0914302f1725 mysql "docker-entrypoint..." 3 weeks ago Up 3 weeks 3306/tcp swarm-node-00/mysql
3.2.2 使用etcd提供的服务发现功能
这里不做赘述,只把如何配置etcd服务,及如何修改docker-machine的命令列一下:
启动etcd服务:
$docker-machine create \
--engine-registry-mirror http://db8ff3fd.m.daocloud.io\
localtest
$eval $(docker-machine env localtest)
$docker run -ti -d -p 4001:4001 -v /etc/ssl/certs/:/etc/ssl/certs/ docker.io/microbox/etcd --name discovery
这里可以看出,使用docker-machine启动了一个docker环境 localtest,ssh进去后,创建一个etcd的镜像,并暴露4001端口。
启动swarm管理及工作节点:
$docker-machine create \
-d virtualbox \
--engine-registry-mirror http://db8ff3fd.m.daocloud.io\
--swarm \
--swarm-master \
--swarm-discovery etcd://192.168.99.100:4001 \
swarm-master
$docker-machine create \
-d openstack \
--engine-registry-mirror http://db8ff3fd.m.daocloud.io\
--swarm \
--swarm-discovery etcd://192.168.99.100:4001 \
swarm-node-00
$docker-machine create \
-d virtualbox \
--engine-registry-mirror http://db8ff3fd.m.daocloud.io\
--swarm \
--swarm-discovery etcd://192.168.99.100:4001 \
swarm-node-01
$ docker run swarm list etcd://192.168.99.100:4001
time="2017-03-28T07:32:45Z" level=info msg="Initializing discovery without TLS"
192.168.99.101:2376
192.168.99.102:2376
192.168.99.103:2376
可以看出和上面github提供的token相比,--swarm-discovery使用的是etcd
后面就一样了。
3.3 使用原生命令启动swarm集群
根据官网的介绍。
In Docker 1.12 and higher, Swarm mode is integrated with Docker Engine.
所以,对于Docker1.12版本之前可以参阅此文档中使用docker-machine的办法来创建swarm集群。
对于Docker1.12版本之后,可以用新的姿势来创造swarm集群。具体参阅另外一篇文章
3.4 docker-swarm工作原理
3.4.1 服务发现 –swarm-discovery
总共有以下几种方式:
- Docker Hub (token://<token>)
- etcd (etcd://<etcd服务器ip:端口>)
- consul (consul://<consul服务器ip:端口>)
- zookeeper (zk://<zookeeper服务器ip:端口>)
- 静态文件(file://文件路径)
- 节点发现(nodes://<工作节点ip:端口>)
3.4.2 调度机制
swarm支持多种调度策略来选择节点。每次在swarm启动container的时候,swarm 会根据选择的调度策略来选择节点运行container。目前支持的有: spread,binpack和 random。
在执行 swarm manage 命令启动 swarm 集群的时候可以通过 --strategy 参数 来指定,默认的是spread。
spread和binpack策略会根据每台节点的可用CPU,内存以及正在运行的containers 的数量来给各个节点分级,而random策略,顾名思义,他不会做任何的计算,只是 单纯的随机选择一个节点来启动container。这种策略一般只做调试用。
使用spread策略,swarm会选择一个正在运行的container的数量最少的那个节点来 运行container。这种情况会导致启动的container会尽可能的分布在不同的机器上运行,这样的好处就是如果有节点坏掉的时候不会损失太多的container。
binpack 则相反,这种情况下,swarm会尽可能的把所有的容器放在一台节点上面 运行。这种策略会避免容器碎片化,因为他会把未使用的机器分配给更大的容器, 带来的好处就是swarm会使用最少的节点运行最多的容器。
3.4.3 过滤器
swarm 的调度器(scheduler)在选择节点运行容器的时候支持几种过滤器 (filter):
可以在执行 swarm manage 命令的时候通过 --filter 选项来设置。
- Constraint
- Affinity: 通过使用 Affinity Filter,可以让一个容器紧挨着另一个容器启动,也就是说让两个 容器在同一个节点上面启动。
- Port:Port 也会被认为是一个唯一的资源
- Dependency,
- Health
具体可以参阅官方文档。
4 others
Docker镜像蜂巢加速:
http://support.c.163.com/md.html#!容器服务/镜像仓库/使用技巧/DockerHub 镜像加速.md
Ubuntu | Debian | Centos
$ sudo echo "DOCKER_OPTS=\"--insecure-registry registry.hz.netease.com -H 0.0.0.0:2375 -H unix:///var/run/docker.sock\"" >> /etc/default/docker
$ service docker restart