6、docker容器网络互联
docker容器互联
本章要点:docker容器互联,端口映射
参考来源汇总: Docker容器互联1,Docker网络管理2,容器与外部连接
端口映射
除了通过网络访问外,Docker还提供了两个方便功能来满足服务访问的基本需求:
- 允许映射容器内应用的服务端口到本地宿主主机;
- 互联机制实现多个容器间通过容器名来快速访问;
端口映射访问容器
-
从外部访问容器应用:
# -P 随机映射端口 (容器中EXPOSE出的端口) ]# docker run -itd -P --name n1 nginx Status: Downloaded newer image for nginx:latest 0a461db48626c065cb39f3c4eb53e7a25c43e2cb632a28b56d74ba1cba269ae7 ~ ]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a461db48626 nginx "/docker-entrypoint.…" 8 seconds ago Up 8 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp n1 -
映射所有接口地址
~ ]# docker run -itd -p 12888:80 --name n2 nginx 6c88c535528d1a2c3791c85a348763eb68e781d04d872f5905f2d6502504be15 ~ ]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6c88c535528d nginx "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:12888->80/tcp, :::12888->80/tcp n2 -
指定地址
]# docker run -itd -p 127.0.0.1:12889:80 --name n3 nginx d5c6c68e873185abe7171b92df67306bfd463251189fbc62ffb68bd88efff442 ~ ]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d5c6c68e8731 nginx "/docker-entrypoint.…" 2 seconds ago Up Less than a second 127.0.0.1:12889->80/tcp n3 # 如果不写端口就是随机 ]# docker run -itd -p 127.0.0.1::80 --name n4 nginx 87158d011b0b377054c735b0f448f037f124559cf1552b8b1b0b87bc2021cfc7 ~ ]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 87158d011b0b nginx "/docker-entrypoint.…" 2 seconds ago Up 1 second 127.0.0.1:49154->80/tcp n4 -
指定协议
]# docker run -itd -p 127.0.0.1::80/udp --name n5 nginx 8361c6b3a3697c128b6387530296be50e7c0bd629a6ef792d0d9636ba1df148e ~ ]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8361c6b3a369 nginx "/docker-entrypoint.…" 1 second ago Up 1 second 80/tcp, 127.0.0.1:49153->80/udp n5 -
查看绑定端口
]# docker port n4 80/tcp -> 127.0.0.1:49154
容器间互联
同一台宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来通信,也可以通过宿主机的ip加上容器暴露出的端口来通信,前者会导致ip址址的硬编码,不方便迁移,并且容器重启后ip地址会改变,除非使用固定的ip,后都的通信方式比较单一,只能依靠监听在暴露出的端口的进程来进来有限通信。通信docker的link机制可以通过一个name来和另一个容器通信,link机制方便了容器去发现其它的容器并且可以安全的传递一些连接信息给其它的容器。
-
语法
docker run --link=[容器名]:别名 [镜像] [命令] -
示例 - 默认网络
# 运行两个容器 docker run -d -P --name tomcatn1 -v share1:/usr/local/tomcat/webapps/ edf8233555ae docker run -d -P --name tomcatn2 -v share1:/usr/local/tomcat/webapps/ edf8233555ae docker inspect -f '{{ .NetworkSettings.Networks.bridge.IPAddress }}' tomcatn1 172.17.0.2 docker inspect -f '{{ .NetworkSettings.Networks.bridge.IPAddress }}' tomcatn2 172.17.0.3 docker inspect -f '{{ .NetworkSettings.EndpointID }}' tomcatn2 3b8493a98b7f8866055e07338.... # 当我们重启容器之后,容器的id会产生变化, 容器的ip地址是一个不可靠的连接,它会随着容器的改变而改变,如果某些服务使用的ip跟端口是固定的,那么后续使用会产生异常 -
示例 - 容器互联-link
# 创建两个容器,一个假设是数据库,另一个为web ]# docker run -itd --name db nginx # 将db链接到web中, 这些就可以避免外部直接访问数据库 ]# docker run -itd --name web --link db:link-db nginx ]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ccb226d24865 nginx "/docker-entrypoint.…" 2 seconds ago 80/tcp web 0cb1c854cec2 nginx "/docker-entrypoint.…" 40 seconds ago 80/tcp db ]# docker inspect -f "{{ .HostConfig.Links }}" web [/db:/web/link-db] # --rm在执行完最后一条任务之后会直接删除容器 ]# docker run --rm --name w2 --link db:link-db nginx env LINK_DB_PORT_80_TCP=tcp://172.17.0.2:80 LINK_DB_ENV_PKG_RELEASE=1~buster HOSTNAME=5e1e40f85c3b LINK_DB_ENV_NGINX_VERSION=1.19.10 .... LINK_DB_NAME=/w2/link-db LINK_DB_PORT_80_TCP_ADDR=172.17.0.2 LINK_DB_PORT_80_TCP_PORT=80 LINK_DB_PORT_80_TCP_PROTO=tcp PWD=/ ]# docker run --rm -it --name w2 --link db:link-db nginx cat /etc/hosts 127.0.0.1 localhost .... 172.17.0.2 link-db 0cb1c854cec2 db # 1、别名, 2、容器ID, 3、容器名称 172.17.0.4 41dbe70b10ea -
示例 - 拒绝所有容器间互联
守护进程添加启动选项: --icc=false /usr/bin/docker -icc=false -
示例- 允许特定容间器连接
守护进程添加启动选项: docker利用了iptables阻止了容器间访问,并利用link选项 --icc=false --iptables=true --link /usr/bin/docker -icc=false
网络虚拟化
Docker中的网络接口默认都是虚拟接口,虚拟接口最大优势就是转发效率极高,这是因为Linux通过在内核中进行数据复制来实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据包将被直接复制到接收接口的接收缓存中,而无需通过外部物理网络设备进行交换,Docker容器网络很好的利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并让它们互相连通(这一对接口叫做veth pair)

网络容器接口
一般情况下,Docker创建一个容器的时候,会有如下过程。
-
创建一对虚拟接口,分别放到本地主机和新容器的命名空间中。
-
本地主机一段的虚拟接口连接到默认的docker0网桥或者指定的网桥上,并具有一个veth开头的唯一名字,如veth1234。
]# yum install bridge-utils ]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02427de30f27 no veth4e48afe -
容器一端的虚拟接口将放到新创建的容器中,并修改名称作为eth0,这个接口只在容器的命名空间可见。
-
Docker 在启动时会创建一个虚拟网桥 docker0, 容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址。
-
从网桥可用地址段中获取一个空闲地址分配给容器的eth0(例如172.17.0.2/16),并配置默认路由网关为docker0网卡的内部接口docker0的ip地址(例如:172.17.42.1/16)。
~]# ip a 5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:f9:e2:05:8f 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
容器与外部网络的连接
配置容器以访问外部网络及允许外部访问容器。通过设置ip_forward参数和使用iptables规则实现容器网络连接
转发理论
先给结论:使用 iptables -t [表名] -S 或 iptables -t [表名] -L [链名] 命令,指定 Docker 相关链(如 DOCKER、DOCKER-USER)即可查看,需关注 nat 表和 filter 表。
-
数据转发说明
- 当数据以本地为目的地时, 数据–> perrouting --> input --> 本机服务 --> output --> postrouting
- 数据发送时路径: 本机发出–> output --> postrouting
- 转发路径: 数据不是本机时先到forward链,在进行一个转发
-
filter表中包含的链
-
INPUT
-
FORWARD

-
OUTPUT
-
-
查看 Docker 链的关键命令
命令格式 作用 示例 iptables -t nat -S查看 nat 表中所有链(含 Docker 相关链)的规则 iptables -t nat -S可显示 DOCKER 链的规则iptables -t filter -S查看 filter 表中所有链(含 Docker 相关链)的规则 iptables -t filter -S可显示 DOCKER 和 DOCKER-USER 链iptables -t filter -L DOCKER-USER单独查看 filter 表中 DOCKER-USER 链的详细规则 iptables -t filter -L DOCKER-USER --line-number(带编号) -
核心步骤与注意事项
- 确定目标表:Docker 网络规则主要在 nat 表(地址转换)和 filter 表(数据包过滤)中。
- 查看所有 Docker 链
- 执行
iptables -t nat -S查看 nat 表的 DOCKER 链(如端口映射规则)。 - 执行
iptables -t filter -S查看 filter 表的 DOCKER(容器间通信)和 DOCKER-USER(用户自定义规则)链。
- 执行
- 单独查看特定链:若需修改用户规则,可单独查看 DOCKER-USER 链:
iptables -t filter -L DOCKER-USER -n(-n 以数字显示 IP/端口)。 - 权限要求:所有 iptables 命令需 root 权限(前缀加
sudo)
-
转发示例
-
容器要想访问外部网络,需要本地系统的转发支持
cat /etc/sysctl.conf net.ipv4.ip_forward = 1 启动Docker服务的时候设定 --ip-forward=true,Docker就会自动设置系统的ip_forward值为1 -
示例
# 配置前,先清掉iptables策略用于查看 ~]# iptables -L -n # 运行容器并映射端口 ~]# docker run -d -P -v share1:/usr/local/tomcat/webapps edf8233555ae # 两个表 nat 映射端口, ~]# iptables -t nat -L DOCKER -n Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1030 to:172.17.0.2:8080 # 转发过滤端口 ~]# iptables -t filter -L DOCKER -n Chain DOCKER (0 references) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 172.17.0.2 tcp dpt:8080 ``
-
更多推荐


所有评论(0)