需求
2个不同的容器,启动后查询到的ip是同一个。2个容器可以直接访问对方的网络。
实际情况
一个服务启动后就须要链接redis,而redis地址又是代码写死的127.0.0.1:6379。所以先启动一个redis,再让服务使用redis网络就可以实现2个服务访问127.0.0.1都是一个网络。
验证实现
docker里面 直接使用 --net=container:xxx 命令
启动一个busybox,暴露端口80。
docker run -itd --name busybox -p80:80 busybox sleep 3600
再启动一个nginx,使用busybox的网络。不直接对外暴露端口。
docker run -d --name nginx --net=container:busybox nginx:1.17.8-alpine
查看容器情况
[root@cloud /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80c7eb469682 nginx:1.17.8-alpine "nginx -g 'daemon of…" 1 second ago Up 1 second nginx
283d4cb8b34f busybox "sleep 36000" 53 seconds ago Up 53 seconds 0.0.0.0:80->80/tcp busybox
查看2个容器的ip,可以看出2个容器使用的是一个ip。
[root@cloud /]# docker exec -it busybox ip a s eth0
31: eth0@if32: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.20.0.2/24 brd 172.20.0.255 scope global eth0
valid_lft forever preferred_lft forever
[root@cloud /]# docker exec -it nginx ip a s eth0
31: eth0@if32: <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/24 brd 172.20.0.255 scope global eth0
valid_lft forever preferred_lft forever
物理机访问主机80端口。看到返回了nginx状态。
[root@cloud /]# curl-I 127.0.0.1:80
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Fri, 31 Mar 2023 03:39:05 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Jan 2020 14:39:00 GMT
Connection: keep-alive
ETag: "5e270d04-264"
Accept-Ranges: bytes
可能会报错
docker: Error response from daemon: can’t join IPC of container 85970c2e34fef8be83897c5f2f7ff64c8bd6ee37f16bd9c2b9337a25dd4e46d4: non-shareable IPC (hint: use IpcMode:shareable for the donor container).
问题原因:由于ipc的模式被默认设置为private导致的
解决方法:修改/etc/docker/daemon.json文件,添加字段
{
"default-ipc-mode": "shareable"
}
完成后,重启docker进程
sudo systemctl daemon-reload
sudo systemctl restart docker
扩展
容器里有 IPC、NET、PID。
IPC:容器的内存共享
NET:容器的网络共享
PID:容器的进程共享
如果想要让busybox里面直接能看到nginx的进程就可以使用 --pid=container:busybox
如果让2个容器共享内存可以使用 --ipc=container:busybox
docker run -d --name pause -p80:80 registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1
docker run -d --name nginx --net=container:pause --ipc=container:pause --pid=container:pause nginx:1.17.8-alpine
docker run -itd --name busybox --net=container:pause --ipc=container:pause --pid=container:pause busybox sleep 3600
[root@cloud /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
54fb3b9ab2b8 busybox "sleep 3600" 10 seconds ago Up 10 seconds busybox
5dea7e3861d0 nginx:1.17.8-alpine "nginx -g 'daemon of…" 55 seconds ago Up 55 seconds nginx
e34bc78f6fe5 registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1 "/pause" 56 seconds ago Up 55 seconds 0.0.0.0:80->80/tcp pause
[root@cloud /]# docker exec -it busybox ps -ef
PID USER TIME COMMAND
1 root 0:00 /pause
6 root 0:00 nginx: master process nginx -g daemon off;
11 101 0:00 nginx: worker process
12 101 0:00 nginx: worker process
18 root 0:00 sleep 3600
23 root 0:00 ps -ef
在docker-compose里面启动
docker-compose.yaml
version: '3'
services:
busybox:
image: busybox
command: sh -c "sleep 3600"
ports:
- "80:80"
nginx:
image: nginx:1.17.8-alpine
network_mode: "service:busybox"
pid: "service:busybox"
ipc: "service:busybox"
depends_on: # 启动busybox后再启动nginx
- busybox
[root@cloud /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1967a5aed8fc nginx:1.17.8-alpine "nginx -g 'daemon of…" 3 minutes ago Up 3 minutes docker-compos_nginx_1
c0c40f5051d0 busybox "sh -c 'sleep 3600'" 3 minutes ago Up 3 minutes 0.0.0.0:80->80/tcp docker-compos_busybox_1
[root@cloud /]# docker exec -it c0c40f5051d0 ps -ef
PID USER TIME COMMAND
1 root 0:00 sleep 3600
6 root 0:00 nginx: master process nginx -g daemon off;
11 101 0:00 nginx: worker process
12 101 0:00 nginx: worker process
18 root 0:00 ps -ef
这里还可以借助一个pause容器。
docker run -d --name pause registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1
如果须要对外提供端口访问,就须要在启动pause容器时就创建。
docker run -d --name pause -p80:80 registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1
参考文章:
关于pause容器