Docker-compose容器编排入门
web:expose:- 90 #expose配置类似于python的类型声明,是文档式声明,只是给人看的 ports:- 80 :80 #若实际需要端口开放使用ports参数先创建一个管理卷,随后在yml文件中声明外部管理卷默认定义的数据卷是非外部卷,docker compose down会连同容器、数据卷、网络一并删除。若设置了外部卷声明,docker compose up会引用外部已经创建好
docker-compose官方文档
一、容器配置
1. ymal文件
# 文件名:docker-compose.yml
version: '3.8' #文件版本
services: #servers固定写法,一个项目可以有多个server(服务)
web: #自定义的服务名称
image: nginx:latest #指定构建的镜像
container_name: nginx_container #定义容器名称
labels: #设置容器的标签,便于搜索,不对程序起到实际作用
- "auther=hyy"
- "time=2026"
entrypoint: #启动容器,首先执行的入口命令
- tail
- -f
- /etc/os-release
env_files:
- .env1 #若环境变量较多,可以写入文本中,docker支持文件读取环境变量
- .env2
environment: #配置服务的环境变量
TEST_PWD: 123
2. 编排效果演示
小提示:
docker compose默认会以当前目录作为项目名称
- 我们进入到指定项目目录
docker compose up -d后台启动容器(自动检索docker-compose.yml文件)- 查看容器信息
- 进入容器查看是否创建了环境变量
# 1. 我们进入到指定项目目录
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# pwd
/root/docker_stu/docker_compose/p4_environment
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# ls -lh
total 4.0K
-rw-r--r-- 1 root root 175 Feb 19 17:30 docker-compose.yml
#2. `docker compose up -d `后台启动容器(自动检索docker-compose.yml文件)
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# docker compose up -d
WARN[0000] /root/docker_stu/docker_compose/p4_environment/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] Running 1/1
✔ Container p4_environment-web-1 Running 0.0s
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0a18f075dcd nginx:latest "tail -f /etc/os-rel…" 4 minutes ago Up 4 minutes 80/tcp p4_environment-web-1
d537af425b4f nginx:latest "/docker-entrypoint.…" 30 minutes ago Up 30 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp nginx_container
#3. 查看容器信息 可以看到entrypoint命令被修改 默认是"/docker-entrypoint.sh"
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0a18f075dcd nginx:latest "tail -f /etc/os-rel…" 4 minutes ago Up 4 minutes 80/tcp p4_environment-web-1
d537af425b4f nginx:latest "/docker-entrypoint.…" 30 minutes ago Up 30 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp nginx_container
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# docker container inspect --format '{{.Config.Entrypoint}}' p4_environment-web-1
[tail -f /etc/os-release]
# 4. 进入容器查看是否创建了环境变量 可以看到容器内自动设置了环境变量
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p4_environment# docker exec -it p4_environment-web-1
root@e0310a536f6a:/# env | grep TEST2
TEST2=123
二、定义端口声明和端口开放
1. ymal文件
version: '3.8'
services:
web:
image: nginx:latest
expose:
- 90 #expose配置类似于python的类型声明,是文档式声明,只是给人看的
ports:
- 80:80 #若实际需要端口开放使用ports参数
2. 编排效果演示
- 启动刚才的docker-compose.yml
- 查看容器状态
- 查看是否可以通过默认80端口curl通过
# 1. 启动刚才的docker-compose.yml
ls -lh
total 4.0K
-rw-r--r-- 1 root root 556 Feb 20 09:31 docker-compose.yml
docker compose up -d
WARN[0000] /root/docker_stu/docker_compose/p6_port/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] Running 3/3
✔ Network p6_port_mywebnet1 Created 0.2s
✔ Network p6_port_mywebnet2 Created 0.1s
✔ Container p6_port-web-1 Started
#2. 查看容器状态
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b5bae1ec993f nginx:latest "/docker-entrypoint.…" 45 seconds ago Up 45 seconds 90/tcp, 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp p6_port-web-1
3. 查看是否可以通过默认80端口curl通过
docker exec -it p6_port-web-1 curl 127.0.0.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
从上述表现看,expose并没有实际生效,实际端口生效仍然需要eports实现
三、定义数据卷
3.1 编排说明
3.1.2 创建管理卷,
- 先创建一个管理卷,随后在yml文件中声明外部管理卷
默认定义的数据卷是非外部卷,docker compose down会连同容器、数据卷、网络一并删除。
若设置了外部卷声明,docker compose up会引用外部已经创建好的卷,后续docker compose down不会删除该卷
3.1.3 创建绑定卷
- 创建绑定卷,
ro设置为false - 挂载传播模式为递归私有(linux使用mount不会影响容器正常读取)
3.3.4 创建临时卷
- 设置内存大小、访问模式
小提示:
访问模式含义具体请看连接文章的2.3最后一节内容
3.2 yml文件
# 文件名docker-compose.yml
services:
web:
image: nginx:latest
volumes:
- type: volume
source: nginx_logs
target: /var/log/nginx
read_only: false
volume:
nocopy: true
- type: bind
source: /root/docker_stu/docker_compose/target
target: /usr/share/nginx/html
read_only: false
bind:
propagation: rprivate # 定义子挂载模式
- type: tmpfs
target: /tmp/nginx
tmpfs:
size: 102400
mode: 1777
3.3 效果演示
3.3.1 创建管理卷+启动容器
docker volume create pre_created_nginx_logs
pre_created_nginx_logs
ls -lh
total 4.0K
-rw-r--r-- 1 root root 599 Feb 21 10:00 docker-compose.yml
docker compose up -d
[+] Running 1/1
✔ Container p11_blog-web-1 Started
3.3.2 查看管理卷绑定情况
# 查看当前宿主机管理卷路径内容(管理卷博人在/var/lib/docker/volumes路径下
cd /var/lib/docker/volumes/pre_created_nginx_logs/_data/
ls -lh
total 4.0K
-rw-r--r-- 1 root root 5 Feb 20 09:42 aa.txt
lrwxrwxrwx 1 root root 11 Nov 4 12:06 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Nov 4 12:06 error.log -> /dev/stderr
# 进入容器查看绑定路径内容是否一致
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
191ef3f0099e nginx:latest "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp p11_blog-web-1
docker exec -it p11_blog-web-1 bash
cd /var/log/nginx
ls -lh
total 4.0K
-rw-r--r-- 1 root root 5 Feb 20 01:42 aa.txt
lrwxrwxrwx 1 root root 11 Nov 4 04:06 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Nov 4 04:06 error.log -> /dev/stderr
3.3.3 查看绑定卷绑定情况
# 进入宿主机绑定卷路径
cd /root/docker_stu/docker_compose/target
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/target# ls -lh
total 4.0K
-rw-r--r-- 1 root root 16 Feb 21 08:55 resouce.txt
# 进入容器绑定卷路径
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/target# docker exec -it p11_blog-web-1 bash
root@191ef3f0099e:/# cd /usr/share/nginx/html
root@191ef3f0099e:/usr/share/nginx/html# ls -lh
total 4.0K
-rw-r--r-- 1 root root 16 Feb 21 00:55 resouce.txt
bind-propagation: rprivate的作用
用于定义宿主机目录mount命令重新挂载同目录及其子目录后,容器是否会收到影响
mount语法:
mount --bind 源路径 目标路径
把源路径的文件映射到目标路径,目标路径之前的内容
描述演示:
# 我们启动容器,根据上述的compose.yml文件
docker compose up -d
[+] Running 2/2
✔ Network p11_blog_default Created 0.1s
✔ Container p11_blog-web-1 Started
# 进入宿主机绑定卷路径
ls -lh /root/docker_stu/docker_compose/target
total 12K
-rw-r--r-- 1 root root 19 Feb 21 08:55 target.txt
-rw-r--r-- 1 root root 3 Feb 21 09:05 v1.txt
-rw-r--r-- 1 root root 3 Feb 21 09:04 v2.txt
#将该路径与/root/docker_stu/docker_compose/resource进行绑定
ls -lh /root/docker_stu/docker_compose/resource/
total 4.0K
-rw-r--r-- 1 root root 10 Feb 21 10:34 resource.txt
mount --bind /root/docker_stu/docker_compose/resource/ /root/docker_stu/docker_compose/target/
ls -lh /root/docker_stu/docker_compose/target/
total 4.0K
-rw-r--r-- 1 root root 10 Feb 21 10:34 resource.txt
ls -lh /root/docker_stu/docker_compose/resource/
total 4.0K
-rw-r--r-- 1 root root 10 Feb 21 10:34 resource.txt
#进入容器查看容器内绑定的路径是否收到刚才mount的影响
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dddf0a013931 nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp p11_blog-web-1
docker exec -it p11_blog-web-1 bash
ls -lh /usr/share/nginx/html
total 12K
-rw-r--r-- 1 root root 19 Feb 21 00:55 target.txt
-rw-r--r-- 1 root root 3 Feb 21 01:05 v1.txt
-rw-r--r-- 1 root root 3 Feb 21 01:04 v2.txt
小提示:
- 从上述操作中,我们发现设置了rprivate之后,子挂载(mount)不会影响内容容器的映射关系
- 注意rprivate只会在容器启动后的路径生效!
3.3.4 查看临时卷绑定情况
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dddf0a013931 nginx:latest "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 80/tcp p11_blog-web-1
docker container inspect p11_blog-web-1 | less -NS
...
"Mounts": [
109 {
110 "Type": "bind",
111 "Source": "/root/docker_stu/docker_compose/target",
112 "Target": "/usr/share/nginx/html",
113 "BindOptions": {
114 "Propagation": "rprivate"
115 }
116 },
117 {
118 "Type": "tmpfs",
119 "Target": "/tmp/nginx",
120 "TmpfsOptions": {
121 "SizeBytes": 102400,
122 "Mode": 1777
123 }
124 },
125 {
126 "Type": "volume",
127 "Source": "pre_created_nginx_logs",
128 "Target": "/var/log/nginx",
129 "VolumeOptions": {
130 "NoCopy": true
131 }
132 }
133 ]
...
可以看到临时卷已经生效了!
四、定义网络
Docker Compose 允许你为容器设置自定义网络配置,使得容器能够在不同的网络中相互通信。Docker Compose 的网络功能使得多个服务之间的连接更加灵活,可以配置服务之间的网络隔离、访问控制以及通信模式等。
4.1 bridge网络
4.1.1 编排说明
- 给nginx容器加入两个bridge网络
- bridge网络设置网段、网关
- 给bridge网络设置多个别名
4.1.2 yml文件
services:
web:
image: nginx:latest
networks:
mywebnet1:
ipv4_address: 177.177.0.4 #指定该网络下的ip地址(必须在配置的子网范围内,且不能是网关)
aliases: #设置两个别名
- name1
- name2
mywebnet2:
ipv4_address: 166.166.0.6
networks:
mywebnet1:
driver: bridge #网络类型设置 其他的有host\none\orverlay
ipam:
driver: default #这里的驱动指的是ip地址分配的驱动,默认是default,由docker自行管理
config:
- subnet: 177.177.0.0/16 #定义网段
gateway: 177.177.0.1 #定义网关
mywebnet2:
driver: bridge
ipam:
driver: default
config:
- subnet: 166.166.0.0/16
gateway: 166.166.0.1
4.1.3 效果演示
1、创建一个外部网络,类型为bridge:
docker network create --driver bridge my_external_net
a3a745bde2e9a51237880932076145ad6de0d3e49fb327dbbc55871cbdde363e
docker network ls
NETWORK ID NAME DRIVER SCOPE
4961851d7f3b bridge bridge local
a6be76bcbdde host host local
a3a745bde2e9 my_external_net bridge local
f446ebf2ce52 none null local
2、 启动容器:
docker compose up -d
[+] Running 3/3
✔ Network p5_network_mywebnet1 Created 0.1s
✔ Network p5_network_mywebnet2 Created 0.1s
✔ Container p5_network-web-1 Started
2、通过不同的别名,查看是否可以正常访问容器:
docker exec -it p5_network-web-1 curl name1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
3、查看网络列表:
docker network ls
NETWORK ID NAME DRIVER SCOPE
a3a745bde2e9 my_external_net bridge local
e3d692eac9c8 p5_network_mywebnet1 bridge local
2c62990cbe57 p5_network_mywebnet2 bridge local
容器中的三个网络都在。
4、停止容器,再次查看网络列表
docker compose down
[+] Running 3/3
✔ Container p5_network-web-1 Removed 0.4s
✔ Network p5_network_mywebnet1 Removed 0.4s
✔ Network p5_network_mywebnet2 Removed 0.2s
root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p5_network# docker network ls
NETWORK ID NAME DRIVER SCOPE
a3a745bde2e9 my_external_net bridge local
可以看到,停止后,只剩下外部引用的my_external_net
4.2 host网络
host网络配置(network_mode字段)和bridge网络(networks字段)是互斥的!
host网络下直接使用宿主机的网卡进行通信,继承所有网络端口。
4.2.1 yml文件
services:
web:
image: busybox:latest
network_mode: host
# 下面两个配置和-it一致
tty: true # 分配伪终端
stdin_open: true # 打开标准输入
4.2.2 效果演示
1、启动容器
docker compose up -d
[+] Running 1/1
✔ Container host_network-web-1 Started
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7b418c2dbbf busybox:latest "sh" 2 seconds ago Up 1 second host_network-web-1
2、 查看宿主机网卡:
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:16:3e:10:f7:cb brd ff:ff:ff:ff:ff:ff
altname enp0s3
altname ens3
inet 172.16.42.42/18 metric 100 brd 172.16.63.255 scope global dynamic eth0
valid_lft 1891381216sec preferred_lft 1891381216sec
inet6 fe80::216:3eff:fe10:f7cb/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether be:09:d4:9b:1f:1b brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::bc09:d4ff:fe9b:1f1b/64 scope link
valid_lft forever preferred_lft forever
3、查看容器内网卡:
docker exec -it host_network-web-1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
link/ether 00:16:3e:10:f7:cb brd ff:ff:ff:ff:ff:ff
inet 172.16.42.42/18 brd 172.16.63.255 scope global dynamic eth0
valid_lft 1891381182sec preferred_lft 1891381182sec
inet6 fe80::216:3eff:fe10:f7cb/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
link/ether be:09:d4:9b:1f:1b brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::bc09:d4ff:fe9b:1f1b/64 scope link
valid_lft forever preferred_lft forever
我们发现网卡信息和宿主机网卡信息保持一致,说明host网络下,容器共享宿主机网络。
4.3 container网络
container网络下,当前容器的网卡由依赖的容器提供,即共用同一套网卡。
4.3.1 编排说明
- 我们创建两个nginx容器,n1和n2
- n1设置bridge网络,容器内80端口映射宿主机8080端口
- n2设置container网络,依赖n1的虚拟网卡,n2容器内80端口映射宿主机9090端口
- 修改n2的默认界面信息,方便识别n1和n2的信息
4.3.2 yml文件
services:
n1:
image: nginx:latest
container_name: n1 # 设置容器名称
networks:
my_bridge:
aliases: #选项,设置容器的多个域名
- n1_name1
- n2_name2
ports: # 容器网络下,端口映射只能由提供虚拟网卡的容器设置!!
- 8080:80 # n1容器的端口
- 9090:8080 #n2容器的端口
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:80"] #健康检查 -f设置如果非正常状态码,返回非0
interval: 30s
timeout: 8s
retries: 5
start_period: 5s
restart: on-failure #不健康,则重启(可选)
n2:
image: nginx:latest
container_name: n2
network_mode: container:n1
command: /bin/bash -c "echo 'server { listen 8080; location / { return 200 \"n2 is healthy\\n\"; } }' > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" #设置n2的默认端口为8080,并且cur通后,返回healthy文字信息,最后后台启动nginx
depends_on: #设置依赖n1容器,因为需要n1的虚拟网卡
n1:
condition: service_healthy
# bridge网络配置
networks:
my_bridge:
driver: bridge
ipam:
config:
- subnet: 177.199.0.0/16
gateway: 177.199.0.1
4.3.3 效果演示
cd 回到项目目录
docker compose up -d
docker exec -it n1 curl 127.0.0.1 #查看n1容器
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
docker exec -it n1 curl 127.0.0.1:8080 #查看n2容器(通过n1网络)
n2 is healthy
4.5 none网络
这个最简单,network_mode: none即可
4.5.1 yml文件
services:
my_container:
image: busybox:latest #这个镜像有很多linux的命令可以直接用,方便看网卡信息
network_mode: none
#分配伪终端等价于-it 后续docker compose up -d容器才不会直接退出
std_in: true
tty: true
4.5.2 效果演示
none网络只有回环IP:
docker compose up -d
[+] Running 1/1
✔ Container none_network-my_container-1 Started 0.2s
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8082010044a4 busybox:latest "sh" 13 seconds ago Up 12 seconds none_network-my_container-1
docker exec none_network-my_container-1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
五、资源限制
我们可以通过docker-compose限制容器的cpu、内存资源
5.1 编排说明
- 启动容器,配置容器的cpu资源、内存资源
5.2 yml文件
下方配置,仅在单机环境下适用:
services:
my_container:
image: nginx:latest
container_name: my_container
memswap_limit: 166m #交换内存 = 实际内存 + 虚拟内存(在硬盘)
mem_limit: 128m #实际内存上限
mem_reservation: 64m # 至少分配64mb内存
cpus: '0.5' #cpu可用资源量
cpuset: '0,1'#可使用的cpu(硬件设备)
5.3 效果演示
通过docker inspect my_container我们可以查看容器的资源分配情况:

更多推荐
所有评论(0)