数据卷&&网络
8335 字
42 分钟
数据卷&&网络

数据卷&&网络
[TOC]
数据卷
1.让容器的"数据进行持久化",说白了,就是让容器的数据不丢失2.数据卷技术,本质上是把宿主机(Linux)的目录,挂载(映射)到容器内部3.容器之间也是可以进行数据共享4.可以指定一个宿主机的路径,也可以使用存储卷进行管理========================================1)镜像准备[root@Docker ~]# docker images | grep nginxnginx:latest 7f0adca1fc6c
2)ro映射[root@Docker ~]# ll /data/indexls: cannot access '/data/index': No such file or directory# 刚开始,宿主机也没有这个目录[root@Docker ~]# docker run -d --name web -p 81:80 -v /data/index:/usr/share/nginx/html/:ro --restart unless-stopped nginx--restart: # 为了能够让数据卷持久化挂载-v: # 前面是宿主机目录,后面是容器目录'都可以没有,会自动创建'✅️属于指定路径挂载!:ro # 以只读的方式进行挂载'默认给rw'[root@Docker ~]# ll /data/indextotal 0# 现在有了,会自动创建[root@Docker ~]# docker exec -it web /bin/bashroot@54cce6d13894:/# curl localhost<title>403 Forbidden</title># 403,这里是因为主页缺失!root@54cce6d13894:/# cd /usr/share/nginx/html/root@54cce6d13894:/usr/share/nginx/html# lsroot@54cce6d13894:/usr/share/nginx/html#'里面没有默认主页!'✅️覆盖行为原本是有默认主页的,只是被覆盖隐藏了取而代之的是宿主机目录下的内容'相当于是把宿主机的目录挂载到容器里面了'⚠️原文件并没有被删除,一旦你取消挂载,原文件就会重新出现🌿这里是指定的宿主机路径,如果是数据卷--->有一个初始化机制✅️# 会进行复制而并非覆盖!!!
root@54cce6d13894:/usr/share/nginx/html# echo "<h1>kpyun<h1/>" > index.htmlbash: index.html: Read-only file system# 想要手动给个主页,被警告权限拒绝!🌿因为这里实际上是宿主机的目录,我们是:ro只读,没有权限![root@Docker ~]# echo "<h1>kpyun<h1/>" > /data/index/index.html# 给个主页[root@Docker ~]# curl localhost:81<h1>kpyun<h1/>[root@Docker ~]# docker inspect web -f {{.Mounts}}[{bind /data/index /usr/share/nginx/html ro false rprivate}]# 但是总觉得怪怪的![root@Docker ~]# docker inspect web | grep -A 8 Mounts "Mounts": [ { "Type": "bind", "Source": "/data/index", "Destination": "/usr/share/nginx/html", "Mode": "ro", "RW": false, "Propagation": "rprivate" }✅️ 这样子显示出来就更加清晰了![root@Docker ~]# docker exec -it web /bin/bashroot@54cce6d13894:/# cat /usr/share/nginx/html/index.html<h1>kpyun<h1/># 一模一样[root@Docker ~]# docker rm -f web# 即使把这个容器删除了,我们宿主机的文件依旧保留[root@Docker ~]# cat /data/index/index.html<h1>kpyun<h1/>
3)rw映射[root@Docker ~]# docker run -d --name web02 -p 81:80 -v /data/index:/usr/share/nginx/html/:rw --restart unless-stopped nginx# 这次换了一个容器,但依旧是那个容器卷:rw权限[root@Docker ~]# curl localhost:81<h1>kpyun<h1/># 拉取页面直接就拉取成功了![root@Docker ~]# docker exec -it web02 /bin/bashroot@b3a1c588cd4d:/# cd /usr/share/nginx/html/root@b3a1c588cd4d:/usr/share/nginx/html# cat index.html<h1>kpyun<h1/>root@b3a1c588cd4d:/usr/share/nginx/html# echo oldboy > index.html'修改默认主页'root@b3a1c588cd4d:/usr/share/nginx/html# curl localhostoldboy✅️成功拉取到了 :rw ---> 可读写 "默认不写就是它"
4)多个数据卷[root@Docker ~]# docker run -d --name web03 -p 82:80 -v /data/index:/usr/share/nginx/html/:rw -v /oldboy:/kpyun --restart unless-stopped nginx'挂载多个容器卷'[root@Docker ~]# ll -d /oldboy/drwxr-xr-x 2 root root 6 Apr 21 08:30 /oldboy/# 凭空创建[root@Docker ~]# docker exec -it web03 /bin/bashroot@bf9cc775e720:/# ls -d -lh /kpyun/drwxr-xr-x 2 root root 6 Apr 21 00:30 /kpyun/# 也是自动创建root@bf9cc775e720:/# echo 111 >/kpyun/test.mdroot@bf9cc775e720:/# exitexit[root@Docker ~]# cat /oldboy/test.md111# 数据同步—volumes-from

[root@Docker ~]# docker run -d --name web04 -p 83:80 --volumes-from web03 --restart unless-stopped nginx'--volumes-from'# 覆盖了原本的文件[root@Docker ~]# curl localhost:83oldboy# 依旧拉取到它'此时,宿主机和父容器和子容器实现数据同步'[root@Docker ~]# docker rm -f web03web03'即使把父容器删除了,子容器依旧可以拉取到'[root@Docker ~]# curl localhost:83oldboy'本质上拉取的还是宿主机的文件'[root@Docker ~]# cat /data/index/index.htmloldboy[root@Docker ~]# docker exec -it web04 /bin/bashroot@9c8a77065d54:/# cd /usr/share/nginx/html/root@9c8a77065d54:/usr/share/nginx/html# cat index.htmloldboyroot@9c8a77065d54:/usr/share/nginx/html# echo hhhh > index.html# 修改页面后,成功拉取到root@9c8a77065d54:/usr/share/nginx/html# curl localhosthhhhroot@9c8a77065d54:/usr/share/nginx/html# exitexit# 退出容器后,宿主机里面的文件也被修改了[root@Docker ~]# cat /data/index/index.htmlhhhhdocker volume
[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal 0d47xxxxxlocal 3d03xxxxxlocal 9e9fxxxxx............[root@Docker ~]# cd /var/lib/docker/volumes/"默认的存储位置"# 把数据放在一个固定的目录[root@Docker volumes]# lldrwx-----x 3 root root 19 Apr 19 15:35 0d47xxxdrwx-----x 3 root root 19 Apr 19 14:41 3d03xxxdrwx-----x 3 root root 19 Apr 19 13:41 9e9fxxx...............[root@Docker ~]# docker rm -f $(docker ps -aq)'清除环境'[root@Docker ~]# docker volume --helpUsage: docker volume COMMANDCommands: create Create a volume # 创建数据卷 inspect Display detailed information ls List volumes # 列出 prune Remove unused local volumes # 删除未使用的 rm Remove one or more volumes # 删除[root@Docker ~]# docker volume prune -fDeleted Volumes:'清理数据卷'👆匿名卷好用,手动创建的数据卷---> 再加上-a选项,所有都删除docker volume prune -fa
1)创建数据卷[root@Docker ~]# docker volume create --helpUsage: docker volume create [OPTIONS] [VOLUME]Options: -d, --driver string 设备驱动(default "local")[root@Docker ~]# docker volume create# 后面什么都不跟674760xxx'创建了一个匿名的数据卷'[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal 674760xxx
2)设备驱动,不能乱写![root@Docker ~]# docker volume create -d xixi❌️plugin "xixi" not found--->🉐安装插件"默认是local设备"
3)指定数据卷名字'对应具名挂载'[root@Docker ~]# docker volume create -d local kpyun# -d 默认就是local,可以省略不写kpyun[root@Docker ~]# docker volume lslocal kpyun
4)删除数据卷[root@Docker ~]# docker volume rm kpyun 674760xxx# rm 指定删除[root@Docker ~]# docker volume prune -fa'全部未使用的数据卷'✅️更推荐这个-a选项手动创建的数据卷也适用
5)详细信息的查看[root@Docker ~]# docker volume create kpyunkpyun[root@Docker ~]# docker volume inspect kpyun[ { "CreatedAt": "2026-04-21T11:01:11+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/kpyun/_data", ✅️上面是挂载点,数据存放的位置 "Name": "kpyun", "Options": null, "Scope": "local" }][root@Docker ~]# cd /var/lib/docker/volumes/[root@Docker volumes]# tree kpyun/kpyun/└── _data[root@Docker volumes]# echo Hello World > kpyun/_data/index.html'数据卷里面不是空的,提前写了一个主页'
6)具名挂载'指定数据卷'[root@Docker ~]# docker run -d --name web -v kpyun:/usr/share/nginx/html nginx# 这次是我们提前创建的数据卷kpyun[root@Docker ~]# docker exec -it web /bin/bashroot@8e1728b6ebe1:/# curl localhostHello World'这里是提前写的主页'root@8e1728b6ebe1:/# echo aaaa > /usr/share/nginx/html/test.html# 创建测试文件root@8e1728b6ebe1:/# exitexit[root@Docker ~]# cd /var/lib/docker/volumes/[root@Docker volumes]# tree kpyun/kpyun/└── _data ├── index.html └── test.html[root@Docker volumes]# cat kpyun/_data/test.htmlaaaa
7)再次挂载'在挂载的同时创建数据卷'[root@Docker volumes]# docker volume ls | grep xixi | wc -l0# 并没有这个数据卷[root@Docker volumes]# docker run -d --name web02 -p 82:80 -v xixi:/usr/share/nginx/html nginx# 指定xixi数据卷[root@Docker volumes]# docker volume ls | grep xixi | wc -l1[root@Docker volumes]# docker volume ls | grep xixilocal xixi# 自动创建的xixi数据卷[root@Docker volumes]# tree /var/lib/docker/volumes/xixi/var/lib/docker/volumes/xixi└── _data ├── 50x.html └── index.html'它把,容器里对应路径下的文件“复制”一份到数据卷里'# 而不是覆盖为空![root@Docker volumes]# curl localhost:82<title>Welcome to nginx!</title>Docker 数据卷(Named Volume)有一个“初始化机制”
==核心原则是:==
如果数据卷是空的(刚创建,里面没东西)
Docker 会把容器镜像里对应路径下的文件==“复制”==一份到数据卷里
- ⚠️指定宿主机路径为==覆盖行为==
'上面是提前创建数据卷并给了一个主页'# 我们这次试试 新创建数据卷--->里面没东西[root@Docker ~]# docker volume create xin# 新创建的数据卷[root@Docker ~]# tree /var/lib/docker/volumes/xin//var/lib/docker/volumes/xin/└── _data👇0个文件-->里面是空的2 directories, 0 files[root@Docker ~]# docker run -d -p 84:80 --name web04 -v xin:/usr/share/nginx/html nginx# 手动指定我们刚创建的数据卷[root@Docker ~]# tree /var/lib/docker/volumes/xin//var/lib/docker/volumes/xin/└── _data ├── 50x.html └── index.html'现在里面有文件了'2 directories, 2 files[root@Docker ~]# curl localhost:84<title>Welcome to nginx!</title>'Nginx的默认主页'为什么会有这个机制?
为了把原本容器里自带的“初始数据”搬运到外部存储中,保证程序能正常启动
Note
- 卷空 -> 复制容器数据进去(保留文件)
- 卷有数据 -> 直接挂载(覆盖/隐藏容器文件)
我们可以把数据卷比作**“书包”**
| 操作 | 结果 | 原因 |
|---|---|---|
你没准备书包,直接去上学 docker run -v xixi:/path | 老师(Docker)看你没带书包,发了一个新书包,并把新课本(容器文件)帮你装进书包里 | 初始化机制:空卷会自动填充容器数据 |
你提前买了一个空书包 docker volume create (空) | 老师看你带了空书包,还是会把新课本(容器文件)帮你装进书包里 | 同上,只要书包是空的,就会填充 |
你提前准备了一个装有旧书的书包 docker volume create (有数据) | 老师看你书包里有书,就不会发新课本了 | ==挂载覆盖==:已有数据优先,不再初始化 |
8)匿名挂载-v /data# 只写一个路径✅️它是容器里面的路径那宿主机呢? 随机生成一个数据卷(长串字符)[root@Docker ~]# docker rm -f $(docker ps -qa)# 把容器都删除了[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal kpyunlocal xinlocal xixi'这是现在的容器卷!'[root@Docker ~]# docker run -d --name web -p 81:80 -v /data nginx# 跑一个容器, -v /data[root@Docker ~]# docker exec -it web /bin/bashroot@61b72b61452c:/# ls -d /data/data'证明: 是在容器里面创建出来的目录!'root@61b72b61452c:/# echo Hello > /data/test.mdroot@61b72b61452c:/# cat /data/test.mdHelloroot@61b72b61452c:/# exitexit[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal 931bbxxx....# 你会发现自己的数据卷多出来一个!如何确定,数据卷和容器的对应关系呢❓️docker inspect 容器名 -f {{.Mounts}}[root@Docker ~]# docker inspect web -f {{.Mounts}}[{volume 931bbfxx....'可以迅速确定它对应的数据卷'[root@Docker ~]# docker volume inspect 931bbfxx....# 查看数据卷的详细信息[ { "CreatedAt": "2026-04-21T13:09:51+08:00", "Driver": "local", "Labels": { "com.docker.volume.anonymous": "" }, "Mountpoint": "/var/lib/docker/volumes/931../_data", ✅️挂载点 "Name": "931bbfb...xxx", "Options": null, "Scope": "local" }][root@Docker ~]# tree /var/lib/docker/volumes/931../└── _data └── test.md# 这里面也有这个文件![root@Docker ~]# cat /var/lib/docker/volumes/931./_data/test.mdHello'内容一致!'docker rm -f -v✅️可以删除匿名挂载的数据卷❌️手动创建的删除不掉
"清理环境"[root@Docker ~]# docker rm -f $(docker ps -qa)[root@Docker ~]# docker volume prune -fa[root@Docker ~]# docker volume lsDRIVER VOLUME NAME# 里面是空的[root@Docker ~]# docker volume create kpyunkpyun[root@Docker ~]# docker run -d --name web -p 81:80 -v kpyun:/oldboy -v /data nginx🌰第一个指定数据卷-->具名挂载🌰第二个匿名挂载[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal 6d294xxx...local kpyun[root@Docker ~]# docker exec -it web /bin/bashroot@c4cb1b1483e2:/# ls -d /data/dataroot@c4cb1b1483e2:/# ls -d /oldboy/oldboy[root@Docker ~]# docker rm -f -v webweb[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal kpyun# 只剩下一个我们创建的数据卷[root@Docker ~]# docker ps -a# 没有容器占用数据卷[root@Docker ~]# docker volume prune -fTotal reclaimed space: 0B'只加 -f 还删除不了--->手动创建的数据卷'✅️ -a all所有的都删除,有它才能全部删除干净[root@Docker ~]# docker volume prune -faDeleted Volumes:kpyun[root@Docker ~]# docker volume lsDRIVER VOLUME NAME# 现在一个也没有了!🌐网络
docker0
[root@test ~]# ip a show docker04: docker0: xxx link/ether 02:42:3e:89:e1:a9 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✅️ docker 0的IP地址为 172.17.0.1[root@test ~]# docker rm -f $(docker ps -aq)'清理环境'
1)docker带来的网卡都是成对出现[root@test ~]# docker run -d -it --name v1 alpine:3.20.2[root@test ~]# docker exec v1 ip a show eth0'容器内部'7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever🌰前面有个7,过滤宿主机就过滤if7肯定没错![root@test ~]# ip a | grep -A 4 'if7'⚠️还要看vethxxx..@if7'前面的数字和字母串唯一''if8对应着vethxxx..@if7'--->成对出现8: veth37417ae@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether a2:ba:16:99:dd:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
2)互相ping'再跑一个容器'[root@test ~]# docker run -d -it --name v2 alpine:3.20.2[root@test ~]# docker exec v2 ip a show eth09: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 xxx...[root@test ~]# ip a | grep -A 4 'if9'10: veth0ec9eb6@if9: xxx...✅️依旧成对出现![root@test ~]# docker exec -it v2 sh/ # tail -1 /etc/hosts172.17.0.3 516ef652fd31/ # ping 172.17.0.2'v1容器的IP为172.xxx.2'PING 172.17.0.2 (172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.087 ms64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.080 ms
veth-pair技术
你可以把它通俗地理解为一根虚拟的网线
它的工作原理非常简单,核心特点如下:
- 成对出现:它总是由两个虚拟接口组成,就像一根网线的两个水晶头
- 💚容器内部: 7: eth0@if8
- ❤️宿主机中: 8: veth37417ae@if7
- 连接桥梁:它的主要作用是连接两个不同的网络环境
- 最常见的场景就是连接宿主机(Linux)和容器
容器通常有自己独立的网络空间,就像在一个封闭的房间里
- veth-pair 就像是在墙上打了个洞,穿了一根网线进去
- 一头插在容器里面, 另一头插在宿主机上
- 然后又连接到了
docker0中 docker0在这里扮演了一个虚拟交换机的角色
[root@test ~]# yum -y install bridge-utils[root@test ~]# brctl show docker0bridge name interfacesdocker0 veth0ec9eb6 veth37417ae# v1和v2宿主机上的网卡再次接到了docker0上veth0ec9eb6@if9 && veth37417ae@if7
它是如何连接宿主机(Linux)和容器的呢❓️✅️宿主机有docker0这张网卡 使用这张网卡的IP地址:172.17.0.1和容器进行通信[root@test ~]# ping 172.17.0.2'用宿主机ping 容器v1'PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.066 ms64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.102 ms'开另一个窗口抓包'[root@test ~]# tcpdump -nnvvi docker0 host 172.17.0.2tcpdump: listening on docker0 172.17.0.1 > 172.17.0.2: ICMP echo request, id 3589, seq 1, length 64 172.17.0.2 > 172.17.0.1: ICMP echo reply, id 3589, seq 1, length 64宿主机 Ping 容器的完整路径
当你在宿主机上执行 ping 172.17.0.2 时,数据包是这样走的:
- 起点:Ping 命令在宿主机发起,数据包的目标是容器的 IP
172.17.0.2 - 进入交换机:宿主机会发现这个 IP 属于
docker0网桥所在的网段(172.17.0.1是docker0的 IP),于是数据包被送到了docker0虚拟交换机上 - 查找端口:
docker0交换机根据 MAC 地址表,知道去往172.17.0.2的数据需要从连接着veth37417ae的端口转发出去 - 穿过网线:数据包进入
veth37417ae接口,通过这根“虚拟网线”,瞬间从容器内部的eth0@if7接口出来 - 抵达终点:数据包最终到达容器
v1,容器处理后,再以同样的路径返回一个 Echo Reply
- 整个通信流程就是:宿主机 -> docker0 -> veth-pair -> 容器
docker0是连接宿主机和所有容器的核心枢纽
容器如何上网
[root@test ~]# docker exec -it v1 sh/ # route -nDestination Gateway0.0.0.0 172.17.0.1'默认网关是docker0'/ # ping www.baidu.com'容器ping百度'PING www.baidu.com (39.156.70.239): 56 data bytes64 bytes from 39.156.70.239: seq=0 ttl=127 time=10.631 ms64 bytes from 39.156.70.239: seq=1 ttl=127 time=9.768 ms[root@test ~]# tcpdump -nnvvi vetha463a34 icmptcpdump: listening on vetha463a34 172.17.0.2 > 39.156.70.239: ICMP echo request, id 15, seq 0, length 64 39.156.70.239 > 172.17.0.2: ICMP echo reply, id 15, seq 0, length 64'👆vetha463a34 和 👇docker0抓包的内容是一样的!'[root@test ~]# tcpdump -nnvvi docker0 icmptcpdump: listening on docker0 172.17.0.2 > 39.156.70.239: ICMP echo request, id 13, seq 21, length 64 39.156.70.239 > 172.17.0.2: ICMP echo reply, id 13, seq 21, length 64
[root@test ~]# tcpdump -nnvvi eth0 icmptcpdump: listening on eth0 10.0.0.128 > 39.156.70.239: ICMP echo request, id 14, seq 0, length 64 39.156.70.239 > 10.0.0.128: ICMP echo reply, id 14, seq 0, length 64
[root@test ~]# sysctl -q net.ipv4.ip_forwardnet.ipv4.ip_forward = 1'这里内核转发默认是开启的'✅️允许数据包在不同网卡(docker0 -> eth0)之间流动[root@test ~]# sysctl -w net.ipv4.ip_forward=0net.ipv4.ip_forward = 0'关闭后'
'容器中再次ping'/ # ping www.baidu.comping: bad address 'www.baidu.com''这次就ping不通了'网络拓扑结构:
- 宿主机 (Host):
- 物理网卡 (
eth0):10.0.0.128 - Docker 网桥 (
docker0):172.17.0.1(通常默认网关) - Veth Pair (宿主机端):
vetha463a34(连接到 docker0)
- 物理网卡 (
- 容器 (Container v1):
- IP 地址:
172.17.0.2 - 默认网关:
172.17.0.1(指向宿主机的 docker0)
- IP 地址:
- 目标 (Target):
www.baidu.com(39.156.70.239)
数据包流向分析:
- 容器发出请求:
- 容器 (
172.17.0.2) 发送 ICMP 请求给百度 - 数据包到达容器的默认网关,即宿主机的
docker0网桥
- 容器 (
- 宿主机接收 (docker0/veth):
- 抓包证据:
tcpdump -i veth...和tcpdump -i docker0显示172.17.0.2 > 39.156.70.239 - 数据包成功到达了宿主机的内部网桥接口
- 抓包证据:
- 路由与转发 (关键步骤):
- 宿主机内核检查路由表,发现目标
39.156.70.239不在本地网段,需要通过eth0发往外部网关 - 内核检查
net.ipv4.ip_forward:- 此时值为 1 (开启)
- 内核允许将数据包从
docker0接口 转发 到eth0接口
- NAT (SNAT): Docker 的
iptables规则通常会将源 IP172.17.0.2伪装成宿主机的 IP10.0.0.128- 于是就成了--->宿主机的 IP
10.0.0.128访问baidu.com
- 于是就成了--->宿主机的 IP
- 宿主机内核检查路由表,发现目标
- 发往外部:
- 抓包证据:
tcpdump -i eth0显示10.0.0.128 > 39.156.70.239 - 数据包成功离开宿主机,到达百度服务器
- 抓包证据:
- 回程: 百度回复数据包给
10.0.0.128-> 宿主机收到 -> DNAT还原目标 IP 为172.17.0.2->转发回docker0-> 容器

- 涉及到 IPtables
端口转发
[root@test ~]# docker run -d -p 90:80 --name web nginx[root@test ~]# docker psd337385e7c7b nginx "/docker-entrypoint.…"[root@test ~]# iptables-save | grep 90:PREROUTING ACCEPT [8867:1493909]-A DOCKER ! -i docker0 -p tcp -m tcp --dport 90 -j DNAT --to-destination 172.17.0.4:80# 这条规则是 Docker 自动添加的,用于实现端口映射==========================================-A DOCKER # Append(追加)到 DOCKER 链! -i docker0 # 不是从 docker0 网卡进来的包-p tcp # 指定协议-m tcp # 加载 TCP 协议的扩展模块'访问90端口 --> DNAT --> 172.17.0.4:80'基本网络类型
| 类型\描述 | 描述 |
|---|---|
| bridge | 为容器创建一对虚拟网卡,默认类型 |
| none | 不为容器分配任何网卡设备,仅有一块lo本地回环网卡 |
| host | 不为容器创建虚拟网卡,而是使用宿主机的IP和端口 这种网络类型性能最高,但是要注意容器和宿主机端口冲突问题 |
| container | 和一个正在运行的容器共享IP、端口范围 |
'清理环境'[root@test ~]# docker rm -f $(docker ps -aq)
1)准备测试环境[root@test ~]# docker run -id --name c1-bridge --network bridge alpine:3.20.2⬆️默认类型,可以省略不写--network 可以写成 --net
[root@test ~]# docker run -id --name c2-none --network none alpine:3.20.2
[root@test ~]# docker run -id --name c3-host --network host alpine:3.20.2
[root@test ~]# docker run -id --name c4-container --network container:c1-bridge alpine:3.20.2⬆️:c1-bridge 冒号:后跟容器名# 和后面容器的网络保持一致
2)查看网卡🌰"bridge网桥"[root@test ~]# docker exec c1-bridge ip a1: lo: xxx link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo13: eth0@if14:xxx link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever[root@test ~]# ip a | grep -A 5 @if1314: vethbdbbeab@if13:xxx link/ether a6:a7:70:a9:5f:e3 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::a4a7:70ff:fea9:5fe3/64 scope link valid_lft forever preferred_lft forever
🌰"none"[root@test ~]# docker exec c2-none ip a👆只有回环网络1: lo: xxx link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo[root@test ~]# docker exec c2-none ping www.baidu.com -W2 -c2ping: bad address 'www.baidu.com'[root@test ~]# docker exec c2-none route -nKernel IP routing tableDestination Gateway'没有网关!没有路由'
🌰"host"[root@test ~]# docker exec c3-host ip a👆和宿主机中查看出来的网络信息一模一样✅️⚠️不要有端口冲突1: lo: <LOOPBACK,UP,LOWER_UP>2: eth0: xxx link/ether 00:0c:29:ec:ba:7b brd ff:ff:ff:ff:ff:ff inet 10.0.0.128/245: docker0:xxx link/ether 02:42:86:07:07:c6 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/1614: vethbdbbeab@if13:xxx[root@test ~]# docker exec c3-host netstat -lntup | wc -l27'监听的网络信息也一致'[root@test ~]# netstat -lntup | wc -l27[root@test ~]# docker exec c3-host route -n | wc -l8'路由信息也一致'[root@test ~]# route -n | wc -l8
🌰"container"[root@test ~]# docker exec c1-bridge ip a | wc -l10[root@test ~]# docker exec c4-container ip a | wc -l10'清理环境'[root@test ~]# docker rm -f $(docker ps -aq)
[root@test ~]# docker run -d -it --name v1 alpine:3.20.2[root@test ~]# docker attach v1/ # hostnamefc7e5245d29a'主机名太长了'/ # cat /etc/hosts | tail -1172.17.0.2 fc7e5245d29a/ # cat /etc/resolv.conf | grep nameservernameserver 223.6.6.6⬆️DNS服务器地址
🌰-h 指定主机名 && --dns 指定dns服务器[root@test ~]# docker run -d -it --name v1 -h kpyun --dns 114.114.114.114 alpine:3.20.2[root@test ~]# docker attach v1/ # hostnamekpyun/ # cat /etc/hosts | tail -1172.17.0.2 kpyun/ # cat /etc/resolv.conf | grep nameservernameserver 114.114.114.114/ # ping www.baidu.com -W2 -c2PING www.baidu.com (110.242.70.57): 56 data bytes64 bytes from 110.242.70.57: seq=0 ttl=127 time=10.369 ms64 bytes from 110.242.70.57: seq=1 ttl=127 time=9.509 ms自定义网络
-
可以自定义子网/掩码,网关,驱动等信息
- 内置DNS解析功能
-
如果不为网络指定驱动 ==-d==
- 则默认使用bridge网络类型驱动
'清理环境'[root@test ~]# docker rm -f $(docker ps -aq)
🌰网络驱动[root@test ~]# docker network lsNETWORK ID NAME DRIVER SCOPE14ec8fea0ee8 bridge bridge localb98e2e9c87db host host local51394abfec25 none null local'bridge、host 和 none 就是网络驱动(Driver)的名称'✅️后续创建网络可以-d指定
🌰创建网络[root@test ~]# docker network create --helpCreate a network -d, --driver # 网络设备(default "bridge") --gateway # 指定网关 --subnet # 指定子网/掩码[root@test ~]# docker network create -d bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 mynet[root@test ~]# docker network lsNETWORK ID NAME DRIVER SCOPE4df8f531278c mynet bridge local
🌰第一个容器[root@test ~]# docker run --name v1 -d -it --network mynet alpine:3.20.2✅️指定为自己刚创建的网络[root@test ~]# docker exec v1 ip a'容器内部网络地址'1: lo: xxx link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/834: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff inet 172.20.0.2/16 brd 172.20.255.255[root@test ~]# ip a | grep -A 4 @if34'宿主机对应的网络'35: vethaee52b3@if34:xxx link/ether 82:bd:a1:09:ba:d6 brd ff:ff:ff:ff:ff:ff'下面过滤的是网关'[root@test ~]# ip a | grep -C 2 172.20.0.1✅️ br-938e75f76ce7 等价于 docker0✅️33: br-938e75f76ce7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:48:4c:39:56 brd ff:ff:ff:ff:ff:ff inet 172.20.0.1/16 brd 172.20.255.255
🌰第二个容器[root@test ~]# docker run --name v2 -d -it --network mynet alpine:3.20.2[root@test ~]# docker exec v2 ip a1: lo: link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/836: eth0@if37: link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff inet 172.20.0.2/16 brd 172.20.255.255[root@test ~]# ip a | grep -A 4 @if3637: veth21ab5d4@if36: xxx link/ether e2:16:c6:17:32:92 brd ff:ff:ff:ff:ff:ff==========================================宿主机对应的网卡: veth21ab5d4@if36 vethaee52b3@if34他们都绑定在br-938e75f76ce7[root@test ~]# brctl show br-938e75f76ce7bridge name interfacesbr-938e75f76ce7 veth21ab5d4 vethaee52b3'等价docker0'
🌰通过inspect查看网络[root@test ~]# docker inspect v1 -f {{.NetworkSettings.Networks.mynet}}{.xxx. 172.20.0.1 172.20.0.2 16 .xxx.}"Gateway": "172.20.0.1","IPAddress": "172.20.0.2","IPPrefixLen": 16,
🌰内置DNS解析功能[root@test ~]# docker exec -it v1 sh/ # cat /etc/hosts127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopback....172.20.0.2 47efc57c32c4/ # cat /etc/resolv.conf | grep nameservernameserver 127.0.0.11/ # ping v2❤️即使本地hosts文件中没有 v2 ---> 172.20.0.3的映射关系 ✅️可以ping通✅️🦄容器重启后即使IP地址发生变化,可以通过容器名ping通PING v2 (172.20.0.3): 56 data bytes64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.089 ms64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.066 ms
🌰IP地址抢夺[root@test ~]# docker stop -t 0 v1'停止他'[root@test ~]# docker run --name v3 -d -it --network mynet alpine:3.20.2[root@test ~]# docker exec v3 ip a38: eth0@if39: ...xxx link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff inet 172.20.0.2/16 brd 172.20.255.255# 把ip地址抢回来了[root@test ~]# docker start v1[root@test ~]# docker exec v1 ip a40: eth0@if41: ...xxx link/ether 02:42:ac:14:00:04 brd ff:ff:ff:ff:ff:ff inet 172.20.0.4/16 brd 172.20.255.255[root@test ~]# docker exec v2 ip a36: eth0@if37: ...xxx link/ether 02:42:ac:14:00:03 brd ff:ff:ff:ff:ff:ff inet 172.20.0.3/16 brd 172.20.255.255[root@test ~]# docker exec v2 ping v3PING v3 (172.20.0.2): 56 data bytes64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.063 ms64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.075 ms[root@test ~]# docker exec v2 ping v1PING v1 (172.20.0.4): 56 data bytes64 bytes from 172.20.0.4: seq=0 ttl=64 time=0.113 ms64 bytes from 172.20.0.4: seq=1 ttl=64 time=0.067 ms'依旧可以ping通'⚠️容器在stop后,再启动,容器的IP可能会发生变化!✅️也没有太大的关系,我们用容器名,依旧可以ping通
🌰docker0 会发生类似的情况嘛❓️[root@test ~]# docker run -d -it --name test alpine:3.20.2# 默认就是docker0网络[root@test ~]# docker exec test ip a42: eth0@if43: ...xxx link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16[root@test ~]# docker run -d -it --name test-02 alpine:3.20.2[root@test ~]# docker exec test-02 ip a44: eth0@if45: ...xxx link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255[root@test ~]# docker stop -t 0 test'关闭第一个创建的容器'[root@test ~]# docker run -d -it --name test-03 alpine:3.20.2[root@test ~]# docker exec test-03 ip a46: eth0@if47: ...xxx link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255[root@test ~]# docker start test'再次启动!'[root@test ~]# docker exec test ip a48: eth0@if49: ...xxx link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff inet 172.17.0.4/16 brd 172.17.255.255✅️IP地址发生改变[root@test ~]# docker exec -it test-02 sh/ # cat /etc/hosts | tail -1172.17.0.3 a7a5e96a2b53/ # cat /etc/resolv.conf | grep nameservernameserver 223.6.6.6/ # ping testping: bad address 'test'/ # ping test-03ping: bad address 'test-03'/ # ping 172.17.0.4PING 172.17.0.4 (172.17.0.4): 56 data bytes64 bytes from 172.17.0.4: seq=0 ttl=64 time=0.120 ms64 bytes from 172.17.0.4: seq=1 ttl=64 time=0.073 ms/ # ping 172.17.0.2PING 172.17.0.2 (172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.076 ms64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.074 ms⚠️docker0 没有内置DNS解析功能✅️必须手动添加才行!/ # cat >> /etc/hosts <<EOF> 172.17.0.2 test-03> 172.17.0.4 test> EOF/ # ping testPING test (172.17.0.4): 56 data bytes64 bytes from 172.17.0.4: seq=0 ttl=64 time=0.098 ms64 bytes from 172.17.0.4: seq=1 ttl=64 time=0.072 ms/ # ping test-03PING test-03 (172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.077 ms64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.078 ms
🌰断开网路连接[root@test ~]# docker network --helpCommands: connect # 连接容器网络 create # 创建网络 disconnect # 断开容器网络 inspect # 展示网络详细信息 ls # 列出网络 prune # 移除没有使用的网络 rm # 手动删除指定网络[root@test ~]# docker network disconnect --helpdocker network disconnect [选项] 网络名 容器# 用法-f # 强制移除网络[root@test ~]# docker exec v1 ip a1: lo: ...xxx link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/840: eth0@if41: ...xxx link/ether 02:42:ac:14:00:04 brd ff:ff:ff:ff:ff:ff inet 172.20.0.4/16 brd 172.20.255.255'现在还是有网络的'[root@test ~]# docker network disconnect mynet v1[root@test ~]# docker exec v1 ip a1: lo: ...xxx link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8✅️现在只剩回环地址了[root@test ~]# docker network connect mynet v1'重新连接网络'[root@test ~]# docker exec v1 ip a1: lo: ...xxx link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo50: eth1@if51: ...xxx link/ether 02:42:ac:14:00:04 brd ff:ff:ff:ff:ff:ff inet 172.20.0.4/16 brd 172.20.255.255
'环境清理'[root@test ~]# docker rm -f $(docker ps -aq)[root@test ~]# docker network prune -f🌰不同网段无法ping通![root@test ~]# docker network create -d bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 mynet[root@test ~]# docker run --name v1 -d -it --network mynet alpine:3.20.2# 手动指定网络[root@test ~]# docker run --name v2 -d -it alpine:3.20.2# 这个是默认的docker0[root@test ~]# docker exec v1 cat /etc/hosts | tail -1172.20.0.2 093c532e53af[root@test ~]# docker exec v2 cat /etc/hosts | tail -1172.17.0.2 20e09a957076'一个是我们新建的网络,一个是docker0'[root@test ~]# docker exec v1 ping 172.17.0.2 -W2 -c2# v1: 172.20.0.2PING 172.17.0.2 (172.17.0.2): 56 data bytes0 packets received, 100% packet loss❌️❤️ping不通的!
🌰一个容器可以有多个IP如何才能ping通呢❓️[root@test ~]# docker network connect bridge v1'再给v1一个网络,bridge就是docker0网卡'[root@test ~]# docker exec v1 ip a1: lo: inet 127.0.0.1/853: eth0@if54: inet 172.20.0.2/16 brd 172.20.255.25557: eth1@if58: inet 172.17.0.3/16 brd 172.17.255.255'v1有两个不同网段的IP地址!'[root@test ~]# docker exec v1 ping 172.17.0.2 -W2 -c2PING 172.17.0.2 (172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.075 ms64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.083 ms'这样就能够ping通了'实战案例
部署WordPress
要求:
- 使用自定义网络
- MySQL不对外暴露端口
- 仅将WordPress数据进行暴露
- 发表测试文字,删除MySQL或者wordpress容器==数据不丢失==
'清理环境'[root@Docker ~]# docker rm -f $(docker ps -aq)[root@Docker ~]# docker network prune -f
1)网络的创建[root@Docker ~]# docker network create -d bridge --subnet 172.30.0.0/16 --gateway 172.30.0.1 mynet[root@Docker ~]# docker network ls | grep mynet1c94f7d15cac mynet bridge local
2)数据库创建[root@Docker ~]# docker run -d \ --network mynet \ --name db01 \ -v boke-db:/var/lib/mysql/ \ --restart unless-stopped \ -e MYSQL_ALLOW_EMPTY_PASSWORD="yes" \ -e MYSQL_DATABASE="wordpress" \ -e MYSQL_USER="jiu" \ -e MYSQL_PASSWORD="oldboy123.com" \ mysql:8.0.36 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci \ --default-authentication-plugin=mysql_native_password✅️自己创建的网络✅️"因为不暴露它的端口,这里没有做端口映射"✅️'为了数据持久化,给了一个数据卷'[root@Docker ~]# docker ps3926d1ddc721 mysql:8.0.36 "docker-entrypoint.s…" 15 seconds ago Up 15 seconds 3306/tcp, 33060/tcp db01🦄并没有暴露端口[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal boke-db[root@Docker ~]# docker volume inspect boke-db[ { "CreatedAt": "2026-04-22T15:03:05+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/boke-db/_data", "Name": "boke-db", "Options": null, "Scope": "local" }][root@Docker ~]# tree /var/lib/docker/volumes/boke-db/_data/ | wc -l189# 里面是有初始换数据的
3)wordpress创建[root@Docker ~]# docker run -d \ --name my-wordpress \ --network mynet \ --restart unless-stopped \ -v boke-wp:/var/www/html \ -p 8080:80 \ -e WORDPRESS_DB_HOST=db01 \ -e WORDPRESS_DB_USER=jiu \ -e WORDPRESS_DB_PASSWORD=oldboy123.com \ -e WORDPRESS_DB_NAME=wordpress \ -e WORDPRESS_TABLE_PREFIX=wp_ \ wordpress:6.7.1✅️-v # 挂载wp中的内容✅️--network # 指定网络✅️数据库DB_HOST=db01,"直接跟的容器名"[root@Docker ~]# docker ps42dc44d2c9f7 wordpress:6.7.1 "docker-entrypoint.s…" 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp my-wordpress✅️wordpress做了端口映射[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal boke-dblocal boke-wp[root@Docker ~]# tree /var/lib/docker/volumes/boke-wp/_data | wc -l3570
4)访问博客http://10.0.0.99:8080/
随手写几篇文章, 上传点图片
然后删除容器, 重复上面的操作
- 重新创建容器
再次访问测试
- 观察博客文章是否丢失

[root@Docker ~]# docker rm -f $(docker ps -aq)42dc44d2c9f73926d1ddc721'删除所有容器'[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal boke-dblocal boke-wp'数据卷是一直存在的!'✅️后面容器再次挂载时,因为数据卷里面是有东西的 ❤️会"覆盖隐藏"容器原来的内容!
🌰重新运行这两个容器[root@Docker ~]# docker run -d \ --network mynet \ --name db01 \ -v boke-db:/var/lib/mysql/ \ --restart unless-stopped \ -e MYSQL_ALLOW_EMPTY_PASSWORD="yes" \ -e MYSQL_DATABASE="wordpress" \ -e MYSQL_USER="jiu" \ -e MYSQL_PASSWORD="oldboy123.com" \ mysql:8.0.36 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci \ --default-authentication-plugin=mysql_native_password[root@Docker ~]# docker run -d \ --name my-wordpress \ --network mynet \ --restart unless-stopped \ -v boke-wp:/var/www/html \ -p 8080:80 \ -e WORDPRESS_DB_HOST=db01 \ -e WORDPRESS_DB_USER=jiu \ -e WORDPRESS_DB_PASSWORD=oldboy123.com \ -e WORDPRESS_DB_NAME=wordpress \ -e WORDPRESS_TABLE_PREFIX=wp_ \ wordpress:6.7.1
🌰再次测试访问http://10.0.0.99:8080/'原来发布的文章和图片都还在'✅️并且跳过了安装步骤部署Zabbix 7.0
-
- 容器安装 7.0 LTS
- 👆有详细的步骤
-
Zabbix 7.0 LTS 支持的数据库版本范围如下:
- 最低版本: MySQL 8.0.30
- 支持范围: MySQL 8.0.30 至 9.0.x
❤️主要用到四个容器(数据库、服务端、Web界面、Java网关) 共同构成了 Zabbix 的“监控中心”# 这里并没有Zabbix Agent⚠️我们需要手动在被'监控的目标机器'上,安装原生的 Zabbix Agent
1)拉取镜像[root@Docker ~]# docker pull docker.xuanyuan.run/zabbix/zabbix-java-gateway:alpine-7.2-latest✅️java网关[root@Docker ~]# docker pull docker.xuanyuan.run/zabbix/zabbix-server-mysql:alpine-7.2-latest✅️zabbix服务端[root@Docker ~]# docker pull docker.xuanyuan.run/zabbix/zabbix-web-nginx-mysql:alpine-7.2-latest✅️zabbix web页面'MySQL还用我们的8.0.36版本'# 我这里手动进行改个名tag# 要不然太长了!docker tag docker.xuanyuan.run/zabbix/zabbix-java-gateway:alpine-7.2-latest zabbix-java-gateway:alpine-7.2-latestdocker tag docker.xuanyuan.run/zabbix/zabbix-server-mysql:alpine-7.2-latest zabbix-server-mysql:alpine-7.2-latestdocker tag docker.xuanyuan.run/zabbix/zabbix-web-nginx-mysql:alpine-7.2-latest zabbix-web-nginx-mysql:alpine-7.2-latest# 再删除之前的冗余的镜像docker rmi docker.xuanyuan.run/zabbix/zabbix-java-gateway:alpine-7.2-latestdocker rmi docker.xuanyuan.run/zabbix/zabbix-server-mysql:alpine-7.2-latestdocker rmi docker.xuanyuan.run/zabbix/zabbix-web-nginx-mysql:alpine-7.2-latest[root@Docker ~]# docker images🎶mysql:8.0.36🎶zabbix-java-gateway:alpine-7.2-latest🎶zabbix-server-mysql:alpine-7.2-latest🎶zabbix-web-nginx-mysql:alpine-7.2-latest'需要提前准备4个镜像!'
2)清理环境[root@Docker ~]# docker rm -f $(docker ps -aq)[root@Docker ~]# docker network prune -fDeleted Networks:mynet[root@Docker ~]# docker volume prune -faDeleted Volumes:boke-wpboke-db
3)创建专属的网络[root@Docker ~]# docker network create -d bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 zabbix-net[root@Docker ~]# docker network ls | grep zabbix-net3d252d08d0a2 zabbix-net bridge local
4)运行数据库[root@Docker ~]# docker run -d \ --network zabbix-net \ --name mysql-server \ -v zabbix-db:/var/lib/mysql/ \ --restart unless-stopped \ -e MYSQL_ROOT_PASSWORD="root_pwd" \ -e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix" \ -e MYSQL_PASSWORD="oldboy123.com" \ mysql:8.0.36 \ --character-set-server=utf8 \ --collation-server=utf8_bin \ --default-authentication-plugin=mysql_native_password✅️自定义网络✅️数据卷挂载✅️没有暴露端口 mysql: 3306✅️数据库和用户为必须为zabbix⚠️⚠️root密码不能为空⚠️'否则zabbix-server导入数据失败'# zabbix的表结构和基本数据[root@Docker ~]# docker volume ls | grep zabbix-dblocal zabbix-db
5)部署java-gateway组件[root@Docker ~]# docker run -d \ --name zabbix-java-gateway \ --network zabbix-net \ --restart unless-stopped \ zabbix-java-gateway:alpine-7.2-latest✅️自定义网络
6)部署zabbix server[root@Docker ~]# docker run -d \ --name zabbix-server-mysql \ --network zabbix-net \ --restart unless-stopped \ -e DB_SERVER_HOST=mysql-server \ -e MYSQL_DATABASE=zabbix \ -e MYSQL_USER=zabbix \ -e MYSQL_PASSWORD=oldboy123.com \ -e MYSQL_ROOT_PASSWORD="root_pwd" \ -e ZBX_JAVAGATEWAY=zabbix-java-gateway \ zabbix-server-mysql:alpine-7.2-latest✅️自定义网络✅️没有暴露端口 server: 10051 agent: 10050⚠️root密码不能为空
7)部署zabbix的web页面[root@Docker ~]# docker run -d \ --name zabbix-web-nginx-mysql \ --network zabbix-net \ --restart unless-stopped \ -p 80:8080 \ -e ZBX_SERVER_HOST=zabbix-server-mysql \ -e DB_SERVER_HOST=mysql-server \ -e MYSQL_DATABASE=zabbix \ -e MYSQL_USER=zabbix \ -e MYSQL_PASSWORD=oldboy123.com \ -e MYSQL_ROOT_PASSWORD="root_pwd" \ zabbix-web-nginx-mysql:alpine-7.2-latest✅️自定义网络✅️映射端口80,用于浏览器访问✅️指定zabbix-server⚠️root密码不能为空
8)查看运行结果[root@Docker ~]# docker ps🌏zabbix-web-nginx-mysql Up 2 seconds (health: starting) 8443/tcp, 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp🌏zabbix-server-mysql Up 10 seconds 10051/tcp🌏zabbix-java-gateway Up 17 seconds 10052/tcp🌏mysql:8.0.36 Up 22 seconds 3306/tcp, 33060/tcp'只有web映射了端口!'
9)测试访问http://10.0.0.99/用户名: Admin密码: zabbix
部署JumpServer

- jumpserver/jms_all
- 上面⬆️网址
jumpserver/jms_all# 用最新的就行
1)拉取镜像[root@Docker ~]# docker pull docker.xuanyuan.run/jumpserver/jms_all[root@Docker ~]# docker tag docker.xuanyuan.run/jumpserver/jms_all:latest jumpserver/jms_all:latest[root@Docker ~]# docker rmi docker.xuanyuan.run/jumpserver/jms_all:latest[root@Docker ~]# docker imagesjumpserver/jms_all:latest
2)创建网络[root@Docker ~]# docker network create -d bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 jumpserver-net
3)创建容器[root@Docker ~]# docker run -d \ --name jms_all \ --network jumpserver-net \ -e SECRET_KEY="$SECRET_KEY" \ -e BOOTSTRAP_TOKEN="$BOOTSTRAP_TOKEN" \ -v jsdata:/opt/data \ -v pgdata:/var/lib/postgresql \ -p 2222:2222 \ -p 80:80 \ --restart unless-stopped \ jumpserver/jms_all:latest| 参数 | 值 | 含义 |
|---|---|---|
--network | jumpserver-net | 连接到自定义网络 |
-e | SECRET_KEY="$SECRET_KEY" | 加密密钥,用于数据加密和会话安全(需50位随机字符) |
-e | BOOTSTRAP_TOKEN="$BOOTSTRAP_TOKEN" | 认证令牌,用于组件间通信认证(需16位随机字符) |
-v | jsdata:/opt/data | 数据卷挂载,持久化 JumpServer 媒体文件和附件 |
-v | pgdata:/var/lib/postgresql | 数据卷挂载,持久化 PostgreSQL 数据库数据 |
[root@Docker ~]# docker psjumpserver/jms_all:latest Up About a minute 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:2222->2222/tcp, [::]:2222->2222/tcp jms_all
4)浏览页面
默认账号: admin默认密码: ChangeMe
部署Nginx负载
- 使用自定义网络部署3个容器,容器名称分别为: lb,web01,web02,要求如下:
- 修改web01和web02的首页内容,内容自定义即可
- 流量访问入口从lb访问,有lb代理流量到web01和web02,其中的比例为4:1
- 删除lb,web01,web02,要求数据不丢失
# 先去清理环境
1)创建网络[root@Docker ~]# docker network create -d bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 mynet
2)web创建[root@Docker ~]# docker run -d \ --name web01 \ --network mynet \ -v web01-html:/usr/share/nginx/html/ \ nginx✅️数据卷挂载✅️隐藏端口[root@Docker ~]# docker run -d \ --name web02 \ --network mynet \ -v web02-html:/usr/share/nginx/html/ \ nginx
3)修改默认主页[root@Docker ~]# docker exec -it web01 /bin/bashroot@46550e3ff026:/# echo web01... > /usr/share/nginx/html/index.htmlroot@46550e3ff026:/# curl localhostweb01...
[root@Docker ~]# docker exec -it web02 /bin/bashroot@fccfbcb1731d:/# echo web02... > /usr/share/nginx/html/index.htmlroot@fccfbcb1731d:/# curl localhostweb02...
4)lb负载[root@Docker ~]# docker run -d \ --name lb01 \ --network mynet \ -p 81:80 \ -v lb01-conf:/etc/nginx/conf.d/ \ nginx[root@Docker ~]# docker exec -it lb01 /bin/bashroot@e15291045302:/# cd /etc/nginx/conf.d/root@e15291045302:/etc/nginx/conf.d# cat > default.conf <<EOF upstream webs { server web01 weight=4; server web02;}server { listen 80 default_server; server_name _;
location / { proxy_pass http://webs; }}EOFroot@e15291045302:/etc/nginx/conf.d# nginx -tnginx: the configuration file ...xxx is oknginx: configuration file ...xxx is successfulroot@e15291045302:/etc/nginx/conf.d# exitexit[root@Docker ~]# docker restart lb01lb01# 通过重启容器--->重启nginx[root@Docker ~]# curl localhost:81web02...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web02...'比例 4:1'
5)数据卷验证[root@Docker ~]# docker volume lsDRIVER VOLUME NAMElocal lb01-conflocal web01-htmllocal web02-html[root@Docker ~]# tree /var/lib/docker/volumes//var/lib/docker/volumes/├── lb01-conf│ └── _data│ └── default.conf├── web01-html│ └── _data│ ├── 50x.html│ └── index.html└── web02-html └── _data ├── 50x.html └── index.html
6)删除容器&&重启运行[root@Docker ~]# docker rm -f $(docker ps -aq)[root@Docker ~]# docker run -d \ --name web01 \ --network mynet \ -v web01-html:/usr/share/nginx/html/ \ nginx[root@Docker ~]# docker run -d \ --name web02 \ --network mynet \ -v web02-html:/usr/share/nginx/html/ \ nginx[root@Docker ~]# docker run -d \ --name lb01 \ --network mynet \ -p 81:80 \ -v lb01-conf:/etc/nginx/conf.d/ \ nginx[root@Docker ~]# curl localhost:81web02...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web01...[root@Docker ~]# curl localhost:81web02...'成功负载均衡,比例 4:1'文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
Docker结课实践考核
Docker容器Docker容器技术结课实践考核,涵盖容器化部署、编排及运维实战
2
传统业务容器化
Docker容器以RuoYi-Vue为例演示Java项目全流程容器化,涵盖Maven打包、Vue前端与Compose多服务编排部署
3
单机编排&&私有镜像仓库
Docker容器详解Compose编排语法与私有仓库方案,实战WordPress/Zabbix部署及Harbor高可用配置
4
Dockerfile详解
Docker容器详解Dockerfile全部核心指令与ENTRYPOINT/CMD配合机制,实战多阶段构建与镜像优化
5
Linux底层特性&&初识Dockerfile
Docker容器手操chroot与OverlayFS分层结构,实践cgroup资源限制与namespace隔离,初识Dockerfile构建
随机文章随机推荐



