docker进阶!docker compose && consul
- docker compose
- docker compose容器编排
- docker compose配置常用字段
- docker compose常用命令
- compose部署
- 部署consul
- consul服务器上
- 容器服务自动加入consul集群
docker compose
- docker compose是一个定义及运行多个docker容器的工具
- 使用docker compose不再需要使用shell脚本来启动容器
- docker compose非常适合组合使用多个容器进行开发场景
docker compose容器编排
文件格式及编写注意事项
- 不支持制表符tab键缩进,需要使用空格缩进
- 通常开头缩进2个空格
- 字符后缩进1个空格,如冒号,逗号,横杆
- 用#注释
- 如果彪悍特殊字符用单引号引起来
- 布尔值必须用引号引起来
docker compose配置常用字段
字段 | 描述 |
command | 执行命令,覆盖默认命令 |
image | 指定镜像 |
environment | 添加环境变量 |
restart | 重启策略,默认no,always,no-failure,unless-stoped |
hostname | 容器主机名 |
deploy | 指定部署和运行服务相关配置,只能在Swarm模式使用 |
build dockerfile context | 指定Dockerfile文件名构建镜像上下文路径 |
networks | 加入网络 |
ports | 暴露容器端口,与-p相同,但端口不能低于60 |
volumes | 挂载宿主机路径或命令卷 |
container name | 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale |
docker compose常用命令
字段 | 描述 |
build | 重新构建服务 |
ps | 列出容器 |
up | 创建和启动容器 |
exec | 在容器里执行命令 |
scale | 指定一个服务容器启动数量 |
top | 显示容器进程 |
logs | 查看容器输出 |
down | 删除容器,网络,数据卷和镜像 |
stop/start/restart | 停止、启动、重启服务 |
compose部署
- 将compose包上传后,并给与权限
[root@node1 ~]# cp -p docker-compose /usr/local/bin/
[root@node1 ~]# chmod +x /usr/local/bin/docker-compose
- 创建模板脚本
[root@node1 compose_nginx]# vim docker-compose.yml
version: '3' //与docker版本相关
services:
nginx:
hostname: nginx //容器主机名
build:
context: ./nginx //指定构建镜像的路径
dockerfile: Dockerfile //Dockerfile文件
ports: //暴露容器端口
- 1216:80
- 1217:443
networks: //加入网络
- cluster
volumes: //挂载点
- ./wwwroot:/usr/local/nginx/html
networks:
cluster:
- 创建容器脚本
[root@node1 compose_nginx]# mkdir nginx
FROM centos:7
RUN yum install -y gcc pcre pcre-devel devel zlib-devel make &> /dev/null && yum clean all
ADD nginx-1.12.2.tar.gz /mnt
WORKDIR /mnt/nginx-1.12.2
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --prefix=/usr/local/nginx &> /dev/null
RUN make &> /dev/null
RUN make install &> /dev/null
RUN rm -rf /mnt/nginx-1.12.2
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
- 再创建一个站点,查看目录情况
[root@node1 compose_nginx]# tree
.
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx-1.12.2.tar.gz
└── wwwroot
└── index.html
- 创建和启动容器
[root@node1 compose_nginx]# docker-compose -f docker-compose.yml up -d
[root@node1 compose_nginx]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------------------------------------------
compose_nginx_nginx_1 /usr/local/nginx/sbin/ngin ... Up 0.0.0.0:1217->443/tcp,:::1217->443/tcp, 0.0.0.0:1216->80/tcp,:::1216->80/tcp
部署consul
consul的工作流程
- registrator去收集服务节点容器变化并注册到consul
- consul用web展示出来
- template模板用来以变量形式去展现,使自动获得新增的nginx或者http的ip和端口
- 然后服务进行重载
服务器:192.168.1.101 Docker-ce,compose 3 ,consul,consul-template
服务器:192.168.1.4 Docker-ce,registrator
consul服务器上
[root@server ~]# mkdir /root/consul
[root@server ~]# cp consul_0.9.2_linux_amd64.zip /root/consul
[root@server ~]# cd /root/consul/
[root@server consul]# ls
consul_0.9.2_linux_amd64.zip
[root@server consul]# unzip consul_0.9.2_linux_amd64.zip
Archive: consul_0.9.2_linux_amd64.zip
inflating: consul
[root@server consul]# mv consul /usr/bin/
[root@server consul]# consul agent \
> -server \ //server模式
> -bootstrap \ //前端框架
> -ui \ //可被访问的web界面
> -data-dir=/var/lib/consul-data \
> -bind=192.168.1.101 \
> -client=0.0.0.0 \
> -node=consul-server01 &> /var/log/consul.log &
- 查看集群信息
[root@server consul]# consul members
Node Address Status Type Build Protocol DC
consul-server01 192.168.1.101:8301 alive server 0.9.2 2 dc1
[root@server consul]# consul info | grep leader
leader = true
leader_addr = 192.168.1.101:8300
- 通过httpd api获取集群信息
[root@server consul]# curl 127.0.0.1:8500/v1/status/peers //查看集群server成员
["192.168.1.101:8300"]
[root@server consul]# curl 127.0.0.1:8500/v1/status/leader //集群Raf leader
"192.168.1.101:8300"
[root@server consul]# curl 127.0.0.1:8500/v1/catalog/services //注册的所有服务
{"consul":[]}
[root@server consul]# curl 127.0.0.1:8500/v1/catalog/nginx //查看nginx服务信息
[root@server consul]# curl 127.0.0.1:8500/v1/catalog/nodes //集群节点详细信息
[{"ID":"4c354aca-4b09-9ea0-9741-6d4e6298affc","Node":"consul-server01","Address":"192.168.1.101","Datacenter":"dc1","TaggedAddresses":{"lan":"192.168.1.101","wan":"192.168.1.101"},"Meta":{},"CreateIndex":5,"ModifyIndex":6}]
容器服务自动加入consul集群
在192.168.1.4上操作,先安装registrator
[root@apache ~]# docker run -d \
> --name=registrator \
> --net=host \
> -v /var/run/docker.sock:/tmp/docker.sock \
> gliderlabs/registrator:latest \
> -ip=192.168.1.4 \
> consul://192.168.1.101:8500
- 测试服务发现功能是否正常
[root@apache ~]# docker run -itd -p:83:80 --name test-01 -h test01 nginx
c1f71bfc180e2e785908853eee16f21724ff30c234414ed90131eb9355afa7ff
[root@apache ~]# docker run -itd -p:84:80 --name test-02 -h test02 nginx
fbb25e0d26941dbed3ee97a71936b8d4255b132c3b8d130cd8972ce20bd06e5c
[root@apache ~]# docker run -itd -p:88:80 --name test-03 -h test03 httpd
77fdb711e6064c675c746ef3ed23b3890505edd73441e94b8cad02f019806efc
[root@apache ~]# docker run -itd -p:89:80 --name test-04 -h test04 httpd
666d1c4405ba5af95c05f12d0aedfc64a1cf428a3e0a0214e686e07c32b998e3
[root@apache ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
666d1c4405ba httpd "httpd-foreground" 5 seconds ago Up 4 seconds 0.0.0.0:89->80/tcp, :::89->80/tcp test-04
77fdb711e606 httpd "httpd-foreground" 19 seconds ago Up 18 seconds 0.0.0.0:88->80/tcp, :::88->80/tcp test-03
fbb25e0d2694 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:84->80/tcp, :::84->80/tcp test-02
c1f71bfc180e nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:83->80/tcp, :::83->80/tcp test-01
- 在consul服务端上查看服务
[root@server consul]# curl 127.0.0.1:8500/v1/catalog/services
{"consul":[],"httpd":[],"nginx":[]}
- 安装template,在consul上操作,先准备template模板
upstream http_backend {
{{range service "nginx"}} //过滤nginx服务器
server {{.Address}}:{{.Port}}; //此处引用的变量会指向后端的地址和端口(动态变化)
{{end}}
}
server {
listen 83;
server_name localhost 192.168.1.101; //反向代理的IP地址(前端展示web的ip)
access_log /var/log/nginx/test.cn-access.log;
index index.html index.php;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr; //后端真实ip
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; //转发地址
proxy_pass http://http_backend;
}
}
- 手工编译安装nginx
[root@server ~]# yum install -y gcc pcre-devel zlib-devel
[root@server ~]# tar zxf nginx-1.12.2.tar.gz -C /opt/
[root@server ~]# cd /opt/nginx-1.12.2/
[root@server nginx-1.12.2]# ./configure --prefix=/usr/local/nginx
[root@server nginx-1.12.2]# make && make install
- 配置nginx
[root@server ~]# vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
include vhost/*.conf; //添加虚拟主机目录
default_type application/octet-stream;
- 创建虚拟主机目录和日志文件目录并启动服务
[root@server ~]# mkdir /usr/local/nginx/conf/vhost
[root@server ~]# mkdir /var/log/nginx
[root@server ~]# systemctl start nginx
- 配置并启动template
[root@server ~]# unzip consul-template_0.19.3_linux_amd64.zip
Archive: consul-template_0.19.3_linux_amd64.zip
inflating: consul-template
[root@server ~]# mv consul-template /usr/bin/
[root@server ~]# consul-template -consul-addr 192.168.1.101:8500 \
> -template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/test.conf:/usr/local/nginx/sbin/nginx -s reload" \
> --log-level=info
2021/09/11 10:04:41.326881 [INFO] consul-template v0.19.3 (ebf2d3d)
2021/09/11 10:04:41.326899 [INFO] (runner) creating new runner (dry: false, once: false)
2021/09/11 10:04:41.327148 [INFO] (runner) creating watcher
2021/09/11 10:04:41.327324 [INFO] (runner) starting
2021/09/11 10:04:41.327341 [INFO] (runner) initiating run
2021/09/11 10:04:41.329281 [INFO] (runner) initiating run
2021/09/11 10:04:41.330282 [INFO] (runner) rendered "/root/consul/nginx.ctmpl" => "/usr/local/nginx/conf/vhost/test.conf"
2021/09/11 10:04:41.330309 [INFO] (runner) executing command "/usr/local/nginx/sbin/nginx -s reload" from "/root/consul/nginx.ctmpl" => "/usr/local/nginx/conf/vhost/test.conf"
2021/09/11 10:04:41.330399 [INFO] (child) spawning: /usr/local/nginx/sbin/nginx -s reload
- 查看生成的配置文件
[root@server vhost]# cat /usr/local/nginx/conf/vhost/test.conf
upstream http_backend {
server 192.168.1.4:83;
server 192.168.1.4:84;
}
server {
listen 83;
server_name localhost 192.168.1.101;
access_log /var/log/nginx/test.cn-access.log;
index index.html index.php;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://http_backend;
}
}
- 在registrator上的服务器上增加一个nginx容器节点
[root@apache ~]# docker run -itd -p:85:80 --name test-05 -h test05 nginx
0d3041dd7cd9c99b06c536dbeea19d7d8bb108be6a06269a45d35cc5f5c104da
- 再看consul服务器上的变化
2021/09/11 10:08:43.298860 [INFO] (runner) initiating run
2021/09/11 10:08:43.300198 [INFO] (runner) rendered "/root/consul/nginx.ctmpl" => "/usr/local/nginx/conf/vhost/test.conf"
2021/09/11 10:08:43.300227 [INFO] (runner) executing command "/usr/local/nginx/sbin/nginx -s reload" from "/root/consul/nginx.ctmpl" => "/usr/local/nginx/conf/vhost/test.conf"
2021/09/11 10:08:43.300263 [INFO] (child) spawning: /usr/local/nginx/sbin/nginx -s reload
[root@server vhost]# cat /usr/local/nginx/conf/vhost/test.conf
upstream http_backend {
server 192.168.1.4:83;
server 192.168.1.4:84;
server 192.168.1.4:85;
}
server {
listen 83;
server_name localhost 192.168.1.101;
access_log /var/log/nginx/test.cn-access.log;
index index.html index.php;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://http_backend;
}
}
- 查看三台nginx容器日志,请求正常轮询到各个容器节点上
[root@apache ~]# docker logs -f test-01
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/09/11 17:23:03 [notice] 1#1: using the "epoll" event method
2021/09/11 17:23:03 [notice] 1#1: nginx/1.21.1
2021/09/11 17:23:03 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/11 17:23:03 [notice] 1#1: OS: Linux 3.10.0-957.el7.x86_64
2021/09/11 17:23:03 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/09/11 17:23:03 [notice] 1#1: start worker processes
2021/09/11 17:23:03 [notice] 1#1: start worker process 32
2021/09/11 17:23:03 [notice] 1#1: start worker process 33
2021/09/11 17:23:03 [notice] 1#1: start worker process 34
2021/09/11 17:23:03 [notice] 1#1: start worker process 35
[root@apache ~]# docker logs -f test-02
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/09/11 17:23:17 [notice] 1#1: using the "epoll" event method
2021/09/11 17:23:17 [notice] 1#1: nginx/1.21.1
2021/09/11 17:23:17 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/11 17:23:17 [notice] 1#1: OS: Linux 3.10.0-957.el7.x86_64
2021/09/11 17:23:17 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/09/11 17:23:17 [notice] 1#1: start worker processes
2021/09/11 17:23:17 [notice] 1#1: start worker process 32
2021/09/11 17:23:17 [notice] 1#1: start worker process 33
2021/09/11 17:23:17 [notice] 1#1: start worker process 34
2021/09/11 17:23:17 [notice] 1#1: start worker process 35
[root@apache ~]# docker logs -f test-05
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/09/11 18:08:43 [notice] 1#1: using the "epoll" event method
2021/09/11 18:08:43 [notice] 1#1: nginx/1.21.1
2021/09/11 18:08:43 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/11 18:08:43 [notice] 1#1: OS: Linux 3.10.0-957.el7.x86_64
2021/09/11 18:08:43 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/09/11 18:08:43 [notice] 1#1: start worker processes
2021/09/11 18:08:43 [notice] 1#1: start worker process 31
2021/09/11 18:08:43 [notice] 1#1: start worker process 32
2021/09/11 18:08:43 [notice] 1#1: start worker process 33
2021/09/11 18:08:43 [notice] 1#1: start worker process 34