docker-compose是docker容器的单机编排工具,它是一个可以管理多容器的工具,比如可以解决多容器之间的依赖关系,比如启动nginx前端服务的时候会调用后端tomcat,这时候就需要先启动tomcat,但启动tomcat的时候需要依赖数据库,那就需要最先启动数据库,docker-compose就可以解决这样的依赖关系,其可以替代docker run来对容器进行管理。
docker-compose将所管理的容器分为3层,分别是project、service和container。
从github选择合适的docker-compose版本,下载其对应的二进制文件即可,并添加到linux命令搜索路径即可。https://github.com/docker/compose/releases
wget https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -O /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose
docker-compose -V #查看版本,验证是或否可用
docker-compose官方文档地址:https://docs.docker.com/compose/reference/
一些常用的参数和命令如下:
Usage: docker compose [OPTIONS] COMMAND
Docker Compose
Options:
-f, --file stringArray #指定docker-compose编排文件路径
Commands:
create #创建一个service,但创建之后容器会退出
down #停止并删除所有的容器、网络、镜像和卷等资源
exec #在指定的容器执行命令,类似docker exec
images #查看service使用的镜像
kill #强制停止一个service对应的容器
logs #查看容器日志
ls #查看运行的docker-compose项目
pause #暂停service的容器
ps #查看service对应的容器
pull #下载service使用的镜像
restart #重启service
rm #删除停止的service的容器
start #启动service
stop #停止service
top #显示容器内的进程
unpause #取消暂停状态的service的容器
up #创建并启动service
在使用docker-compose的时候最主要的就是编写docker-compose.yaml文件,文件中会定义所有用的resources,包括容器、卷和网络等。关于docker-compose.yaml的编写规范可以参考:https://docs.docker.com/compose/compose-file/
version: '3.6' #docker-compose.yaml的使用的版本
services: #定义services,一个service其实就是一个容器
nginx-server: #定义一个名为nginx-server的service
image: nginx #容器镜像
container_name: nginx_web1 #容器名称
expose: #容器要暴露的端口
- 80
- 443
ports: #容器的端口映射, host_port:container_port
- "1001:80"
- "443:443"
network_mode: bridge #让容器使用默认的docker0网络,而不是使用docker-compose创建的默认网络
networks: #自定义的docker网络
default: #引入默认的docker0网络
external: true
name: bridge
这个示例只定义了一个nginx容器,使用默认的docker0网络。
创建一个目录,将上面示例的内容保存到docker-compose.yaml,然后启动:
mkdir /opt/compose-example1/
docker-compose up -d
启动之后可以通过docker-compose ps查看,并通过宿主机1001端口访问nginx服务
version: '3.6'
services:
nginx-server:
image: habor.linux.io/cloud-native/nginx:v1.19.1
container_name: nginx_web1
expose:
- 80
- 443
ports:
- "1001:80"
- "443:443"
networks: #nginx使用front+backend两个网络,这样可以使用backend网络直接和tomcat通信
- front
- backend
tomcat-server1:
image: habor.linux.io/cloud-native/tomcat-app1:v1.0
container_name: tomcat-app1
expose:
- 8080
- 8443
ports:
- "1002:8080"
networks: #tomcat只使用backend网络即可
- backend
tomcat-server2:
image: habor.linux.io/cloud-native/tomcat-app2:v1.0
container_name: tomcat-app2
expose:
- 8080
- 8443
ports:
- "1003:8080"
networks:
- backend
networks: #自定义网络
front: #front网络
driver: bridge #网络driver使用bridge
backend: #backend网路
driver: bridge #网络driver使用bridge
这个示例定义了一个nginx容器+两个tomcat容器,nginx使用front和backend两个自定义网络,tomcat使用backend自定义网络。并且希望通过nginx实现动静分离。
创建一个目录,将上面示例的内容保存到docker-compose.yaml,然后启动:
mkdir /opt/compose-example2
docker-compose up -d
然后进入nginx容器中修改配置文件,实现动静分离:
$ docker-compose exec nginx-server bash
$ cat /usr/local/nginx/nginx.conf
user nginx;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
......
upstream web {
server 172.22.0.3:8080;
server 172.22.0.4:8080;
}
server {
......
location /myapp {
proxy_pass http://web;
}
}
}
$ nginx -s reload #修改完成后重新加载配置文件
但是这个示例还存在问题,如果容器重建了IP会改变,这样每次重建容器后都需要重新修改nginx配置文件,重启服务才可以,不方便。其实这可以通过links字段解决,在下面的示例3中会体现。
version: '3.6'
services:
haproxy-server: #定义haproxy容器
image: habor.linux.io/cloud-native/haproxy:2.2.11
container_name: haproxy
expose: #暴露的端口
- 80
- 443
- 9999
ports: #容器端口和宿主机端口的映射
- "1001:80"
- "1002:9999"
networks: #使用的自定义网络
- front
- backend
volumes: #定义卷,将主机上的haproxy配置文件挂载到容器里
- /apps/haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg
links: #links,定义之后可以直接通过service-name访问其它容器,可以避免因为容器地址改变导致需要修改配置文件
- nginx-server #这里就表示可以直接通过nging-server这个名字访问nginx容器
nginx-server:
image: habor.linux.io/cloud-native/nginx:v1.19.1
container_name: nginx_web1
networks:
- backend
volumes: #nginx的配置挂载
- /apps/nginx/nginx.conf:/usr/local/nginx/conf/nginx.conf
links: #nginx通过service-name直接访问两个tomcat
- tomcat-server1
- tomcat-server2
tomcat-server1:
image: habor.linux.io/cloud-native/tomcat-app1:v1.0
container_name: tomcat-app1
networks:
- backend
tomcat-server2:
image: habor.linux.io/cloud-native/tomcat-app2:v1.0
container_name: tomcat-app2
networks:
- backend
networks: #自定义网络
front:
driver: bridge
backend:
driver: bridge
haproxy.cfg内容如下:
global
chroot /usr/local/haproxy
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/run/haproxy.pid
log 127.0.0.1 local3 info
defaults
option http-keep-alive
option forwardfor
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
listen web_port
bind 0.0.0.0:80
mode http
log global
balance roundrobin
server web1 nginx-server:80 check inter 3000 fall 2 rise 5
nginx.conf内容如下:
user nginx;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
......
upstream web {
# 这里就不用写两个tomcat容器的IP,直接写tomcat容器的service-name就可以
server tomcat-server1:8080;
server tomcat-server2:8080;
}
server {
......
location /myapp {
proxy_pass http://web;
}
}
}
这个示例定义了一个小型web站点,haproxy+nginx+tomcat。
创建一个目录,将上面示例的内容保存到docker-compose.yaml,然后启动:
mkdir /opt/compose-example3
docker-compose up -d
更多使用方式可以参考docker-compose官方文档地址:https://docs.docker.com/compose/reference/