今天我们给大家介绍一个简单的容器编排工具Docker Cpmpose.
1. 什么是Dock Compose
Docker compose是docker提供的一个命令行工具,实现对Docker容器集群的快速编排。
这个工具可以通过一个yml文件定义多容器的docker应用。
通过一条命令就可以根据yml文件的定义去创建或者管理这多个容器。
2.yml文件
1)简介:
一个service代表一个container(这个container可以从docker hub上拉取的image创建,也可以用本地Dockerfile build出来的image创建)。
service的启动类似docker run,我们可以给其指定network和volume
前提:我们本地需要有mysql和wordpress这两个镜像
version: '3'
services:
wordpress:
image: wordpress
ports:
- 8080:80 ##将容器的80端口映射到本地的8080 端口
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_PASSWORD: root
networks:
- my-bridge
mysql:
image: mysql
environment: #传递环境变量
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
volumes: #将容器里面的/var/lib/mysql的内容映射到本地的mysql-data
- mysql-data:/var/lib/mysql
networks:
- my-bridge
volumes:
mysql-data:
networks:
my-bridge:
driver: bridge
3. 安装docker-compose
##安装docker-compose
##1:从github上下载docker-compose二进制文件安装
curl -L https://github.com/docker/compose/releases/download/1.25./docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
##2:pip安装 注:需要安装python才有pip功能,Linux 自带python2.7,但没有pip
pip install docker-compos
查看Docker Compose 版本
[root@workernode1 ~]# docker-compose --version
docker-compose version 1.25.5, build unknown
[root@workernode1 ~]#
命令:docker-compose up
注意:docker-compose up启动要保证该目录下的yml文件名称为docker-compose.yml,若为其他 xxx.yml,启动命令则需要改成:
docker-compose -f xxx.yml up
实例1:我们使用docker compose 来搭建wordpress. 操作如下:
[root@workernode1 ~]# docker pull mysql
Using default tag: latest
Trying to pull repository docker.io/library/mysql ...
latest: Pulling from docker.io/library/mysql
afb6ec6fdc1c: Pull complete
0bdc5971ba40: Pull complete
97ae94a2c729: Pull complete
f777521d340e: Pull complete
1393ff7fc871: Pull complete
a499b89994d9: Pull complete
7ebe8eefbafe: Pull complete
597069368ef1: Pull complete
ce39a5501878: Pull complete
7d545bca14bf: Pull complete
0f5f78cccacb: Pull complete
623a5dae2b42: Pull complete
Digest: sha256:beba993cc5720da07129078d13441745c02560a2a0181071143e599ad9c497fa
Status: Downloaded newer image for docker.io/mysql:latest
[root@workernode1 ~]#
[root@workernode1 ~]# docker pull wordpress
Using default tag: latest
Trying to pull repository docker.io/library/wordpress ...
latest: Pulling from docker.io/library/wordpress
afb6ec6fdc1c: Already exists
3d895574014b: Pull complete
c309fdad6410: Pull complete
c201f6a5d6f9: Pull complete
e87f853892aa: Pull complete
998b2113b400: Pull complete
b3c0b4710d3b: Pull complete
c79fb2b38801: Pull complete
30aa6f0dd423: Pull complete
8af9a337c36d: Pull complete
64ec85e06910: Pull complete
606f88b4f608: Pull complete
845e768a44c5: Pull complete
232824f4bf64: Pull complete
c14e31cd46f2: Pull complete
df59d99840f5: Pull complete
0f3a9380af13: Pull complete
348bafbbcb22: Pull complete
d96f27aa3b63: Pull complete
58f35ab6fddc: Pull complete
0c1a0d01788e: Pull complete
Digest: sha256:1c4b01a38f37fee0e3aee5266bef13cbb3bb2ff705803377a35687fc441f6da8
Status: Downloaded newer image for docker.io/wordpress:latest
[root@workernode1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/mysql latest 94dff5fab37f 19 hours ago 541 MB
docker.io/wordpress latest 675af3ca3193 22 hours ago 540 MB
[root@workernode1 ~]# vim docker-compose.yml
##docker compose 启动容器
[root@workernode1 ~]# docker-compose up -d ##-d 代表后台运行
Creating network "root_my-bridge" with driver "bridge"
Creating volume "root_mysql-data" with default driver
Creating root_wordpress_1 ... done
Creating root_mysql_1 ... done
[root@workernode1 ~]#
##使用docker-compose 查看运行状态
[root@workernode1 ~]# docker-compose ps
##使用docker-compose stop 停止正在运行的容器
测试:wordpress 是否搭建成功。
显然我们的word press 就搭建成功了。
5.docker-compose.yml 配置文件详解
文件配置
一份标准配置文件应该包含 version、services、networks 三大部分,其中最关键的就是 services 和 networks 两个部分。
.yml
或 .yaml
作为文件扩展名
${VARIABLE}
语法在配置值中使用环境变量。示例1.
#定义一个service, 创建一个db 容器,来自于从镜像仓库中拉取的镜像。 镜像名字为postgres:9.4。
#同时设置了将容器内的 /var/lib/postgresql/data数据同步到本地的db-data目录(卷映射)。
#并且指定了网络为back-tier, 此网络会之后被定义。
services:
db:
image: postgres:9.4
volumes:
- "db-data:/var/lib/postgresql/data"
networks:
- back-tier
示例2.
#定义一个service, 创建一个worker容器,镜像来自于本地./worker目录下面的dockerfile定义的镜像。
#设置links将此容器和db,redis容器link 到一起。
#并且指定了网络为back-tier, 此网络会之后被定义。
services:
worker:
build: ./worker
links:
- db
- redis
networks:
- back-tier
6.Docker compose多容器架构实现网页负载均衡
#1. 准备haproxy 和 nginx 镜像
[root@workernode1 ~]# docker pull nginx
[root@workernode1 ~]# docker pull haproxy
#2. 准备docker-compose.yml 文件
[root@workernode1 ~]# mkdir compose
[root@workernode1 ~]# cd compose/
[root@workernode1 compose]# cat docker-compose.yml
version: '3'
services:
web1:
image: nginx
expose:
-
volumes:
- ./web1:/usr/share/nginx/html
web2:
image: nginx
expose:
-
volumes:
- ./web2:/usr/share/nginx/html
haproxy:
image: haproxy:latest
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- web1
- web2
ports:
- "80:80"
expose:
- "80"
[root@workernode1 compose]#
#3. 编写web测试页面
[root@workernode1 compose]# mkdir web1
[root@workernode1 compose]# mkdir web2
[root@workernode1 compose]# vim web1/index.html
<h1>web1</h1>
[root@workernode1 compose]# vim web2/index.html
<h1>web2</h1>
#4. 负载均衡haproxy配置
[root@workernode1 compose]# cd haproxy
[root@workernode1 haproxy]# ls
haproxy.cfg
[root@workernode1 haproxy]# cd haproxy.cfg/
[root@workernode1 haproxy.cfg]# ls
[root@workernode1 haproxy.cfg]# vim haproxy.cfg
[root@workernode1 haproxy.cfg]# pwd
/root/compose/haproxy/haproxy.cfg
[root@workernode1 haproxy.cfg]# cat haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option httplog
option dontlognull
timeout connect ms
timeout client ms
timeout server ms
stats uri /status
frontend balancer
bind 0.0.0.0:
default_backend web_backends
backend web_backends
balance roundrobin
server weba web1: check
server webb web2: check
[root@workernode1 haproxy.cfg]#
#5. 关闭httpd服务,关闭80端口
[root@workernode1 compose]# systemctl stop httpd
#6. 启动
[root@workernode1 compose]# docker-compose up -d
Starting compose_web2_1 ... done
Starting compose_web1_1 ... done
Starting compose_haproxy_1 ... done
Attaching to compose_web1_1, compose_web2_1, compose_haproxy_1
haproxy_1 | [NOTICE] / () : New worker #1 (6) forked
#使用docker-compose ps 查看容器运行状态。 全部为up代表正常运行。
[root@workernode1 compose]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------
compose_haproxy_1 /docker-entrypoint.sh hapr ... Up 0.0.0.0:->/tcp
compose_web1_1 nginx -g daemon off; Up /tcp
compose_web2_1 nginx -g daemon off; Up /tcp
#7. 负载均衡测试。 第一次访问为web1, 第二次访问为web2, 依次轮询,代表负载均衡策略生效。
[root@workernode1 compose]# curl http://localhost:80
<h1>web1</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web1</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web1</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
#也可以通过shell 命令 测试访问结果。
[root@workernode1 compose]# while [ TRUE ]; do curl http://localhost:80; done
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
<h1>web1</h1>
<h1>web2</h1>
可以访问haproxy 网页来查看负载的详细信息:
下面我们来模拟web1 停止, 查看状态:
[root@workernode1 compose]# docker-compose up -d
Starting compose_web1_1 ... done
Starting compose_web2_1 ... done
Starting compose_haproxy_1 ... done
[root@workernode1 compose]# docker stop compose_web1_1
compose_web1_1
[root@workernode1 compose]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc9ff460e haproxy:latest "/docker-entrypoin..." minutes ago Up seconds 0.0.0.0:->/tcp compose_haproxy_1
d68e685b18 nginx "nginx -g 'daemon ..." minutes ago Up seconds /tcp compose_web2_1
#compose_web1_1 停止, 每次都访问web2.
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]#
#我们来启动web1. 看是否回复正常
[root@workernode1 compose]# docker start compose_web1_1
compose_web1_1
[root@workernode1 compose]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc9ff460e haproxy:latest "/docker-entrypoin..." minutes ago Up minutes 0.0.0.0:->/tcp compose_haproxy_1
f50517b0e72e nginx "nginx -g 'daemon ..." minutes ago Up seconds /tcp compose_web1_1
d68e685b18 nginx "nginx -g 'daemon ..." minutes ago Up minutes /tcp compose_web2_1
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web1</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web2</h1>
[root@workernode1 compose]# curl http://localhost:80
<h1>web1</h1>
[root@workernode1 compose]#
#轮询访问, 可见服务恢复正常
今天我们就介绍到这里。以后会继续分享docker的内容。