前言
Docker 容器和服务如此强大的原因之一是您可以将它们连接在一起,或者将它们连接到非 Docker 工作负载。本文主要介绍Docker的四种网络模式:Brideg模式、Host模式、Container模式、None模式。列出容器当前网络:
[root@sanxingtongxue ~]# docker network ls
NETWORK IDNAMEDRIVERSCOPE
e9f64abf8207bridgebridgelocal
e1e8a39e210fhosthostlocal
c8092bd3f577nonenulllocal
Bridge模式(自定义网络模式演示) docker 的默认?络模式为bridge模式,此模式会为每一个容器分配,设置IP等,并将容器连接到一个docker0 的虚拟网桥,通过docker0 网桥以及iptables nat 表配置与宿主机通信。示例图如下:
文章图片
桥接网络演示步骤如下:
1.创建alpine-net网络。您不需要该–driver bridge标志,因为它是默认标志。
docker network create --driver bridge alpine-net
2.创建两个容器。注意–network标志。执行命令时只能连接一个网络docker run。
docker run -dit --name alpine1 --network alpine-net alpine ash
docker run -dit --name alpine2 --network alpine-net alpine ash
3.ping命令验证容器之前是否互通。
ping -c 2 alpine2
操作演示如下:
[root@sanxingtongxue ~]#docker network create --driver bridge alpine-net
5cd703a37a83910502d6f4eff1d047c936434a0e77d27125865acfffba49a0e0
[root@sanxingtongxue ~]# docker network ls
NETWORK IDNAMEDRIVERSCOPE
5cd703a37a83alpine-netbridgelocal
e9f64abf8207bridgebridgelocal
e1e8a39e210fhosthostlocal
c8092bd3f577nonenulllocal
[root@sanxingtongxue ~]#docker network inspect alpine-net
[
{
"Name": "alpine-net",
"Id": "5cd703a37a83910502d6f4eff1d047c936434a0e77d27125865acfffba49a0e0",
"Created": "2022-08-10T10:58:28.892947982+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
[root@sanxingtongxue ~]# docker ps-a
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
203dcb1d64b9hello:v1"ash"21 seconds agoCreated8000/tcpalpine1
[root@sanxingtongxue ~]# docker rm -f $(docker ps -aq)#删除所有容器
203dcb1d64b9
[root@sanxingtongxue ~]#docker run -dit --name alpine1 --network alpine-net hello:v1 sh
6eee1dd7a27ac9823a8740f330ec2abfc55898e1c39ac5777180ddb6c1a68bee
[root@sanxingtongxue ~]#docker run -dit --name alpine2 --network alpine-net hello:v1 sh
de43dfe6ba727fede28837e7392b7cbb45615443f1ce8bf8041c43ddd5679ac8
[root@sanxingtongxue ~]# docker ps
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
de43dfe6ba72hello:v1"sh"2 minutes agoUp 2 minutes8000/tcpalpine2
6eee1dd7a27ahello:v1"sh"3 minutes agoUp 3 minutes8000/tcpalpine1
[root@sanxingtongxue ~]# docker container ls
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
de43dfe6ba72hello:v1"sh"2 minutes agoUp 2 minutes8000/tcpalpine2
6eee1dd7a27ahello:v1"sh"3 minutes agoUp 3 minutes8000/tcpalpine1
[root@sanxingtongxue ~]# docker exec -it alpine2 /bin/bash
root@de43dfe6ba72:/# ping -c 2 alpine2
bash: ping: command not found
root@de43dfe6ba72:/# apt-get update && apt-get install iputils-ping
root@de43dfe6ba72:/# ping -c 2 alpine1
PING alpine1 (172.18.0.2) 56(84) bytes of data.
64 bytes from alpine1.alpine-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from alpine1.alpine-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.061 ms--- alpine1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1015ms
rtt min/avg/max/mdev = 0.061/0.071/0.081/0.010 ms
[root@sanxingtongxue ~]# docker exec -it alpine1 /bin/bash
root@6eee1dd7a27a:/# ping -c 2 alpine2
PING alpine2 (172.18.0.3) 56(84) bytes of data.
64 bytes from alpine2.alpine-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.059 ms
64 bytes from alpine2.alpine-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.061 ms--- alpine2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1024ms
rtt min/avg/max/mdev = 0.059/0.060/0.061/0.001 ms
[root@sanxingtongxue ~]# docker network inspect alpine-net
[
{
"Name": "alpine-net",
"Id": "5cd703a37a83910502d6f4eff1d047c936434a0e77d27125865acfffba49a0e0",
"Created": "2022-08-10T10:58:28.892947982+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"6eee1dd7a27ac9823a8740f330ec2abfc55898e1c39ac5777180ddb6c1a68bee": {
"Name": "alpine1",
"EndpointID": "06f1c1f638f6d12a064d5738e45671cf613c6c38f3c5ae90c8c3480d9655be89",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"de43dfe6ba727fede28837e7392b7cbb45615443f1ce8bf8041c43ddd5679ac8": {
"Name": "alpine2",
"EndpointID": "be79f2f3d29870455b3faa40d8bf3b483bef0a6f0b32aaa43473f670e94ea5da",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
官网参考:https://docs.docker.com/network/network-tutorial-standalone/
Host模式 容器不会虚拟出自己的网卡,配置主机的IP等,而是使用宿主机的IP和端口。此时映射的端口可能会生产冲突,但是容器的其余部分(文件系统、进程等)依然是隔离的,此时容器与宿主机共享网络。示例图如下:
文章图片
演示步骤如下:
1.创建并启动容器作为分离的进程。该–rm选项意味着一旦容器退出/停止就将其移除。该-d标志意味着启动容器分离(在后台)。
docker run --rm -d --network host --name my_nginx nginx
2.通过浏览 http://localhost:80/访问 Nginx 。
3.使用以下命令检查您的网络堆栈:
检查所有网络接口并确认没有创建新的。
ip addr show
使用命令验证哪个进程绑定到端口 80 netstat。您需要使用sudo该进程,因为该进程归 Docker 守护程序用户所有,否则您将无法看到其名称或 PID。
sudo netstat -tulpn | grep :80
4.停止容器。它将在使用该–rm选项启动时自动删除。
docker container stop my_nginx
操作演示如下:
[root@sanxingtongxue ~]#docker run --rm -d --network host --name myhost_net hello:v1
7c1a1e03b12e30504fb3bd2f0f814209ac9d65cac525a2475eb40f36e34b97ef
[root@sanxingtongxue ~]# route -n
Kernel IP routing table
DestinationGatewayGenmaskFlags Metric RefUse Iface
0.0.0.0172.19.63.2530.0.0.0UG10000 eth0
10.88.0.00.0.0.0255.255.0.0U000 cni-podman0
172.17.0.00.0.0.0255.255.0.0U000 docker0
172.18.0.00.0.0.0255.255.0.0U000 br-5cd703a37a83
172.19.0.00.0.0.0255.255.192.0U10000 eth0
[root@sanxingtongxue ~]# docker ps
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
7c1a1e03b12ehello:v1"/bin/sh -c 'flask r…"About a minute agoUp About a minutemyhost_net
de43dfe6ba72hello:v1"sh"33 minutes agoUp 33 minutes8000/tcpalpine2
6eee1dd7a27ahello:v1"sh"35 minutes agoUp 22 minutes8000/tcpalpine1
[root@sanxingtongxue ~]# ip addr show
1: lo: 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: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:16:3e:02:b2:a8 brd ff:ff:ff:ff:ff:ff
inet 172.19.55.145/18 brd 172.19.63.255 scope global dynamic noprefixroute eth0
valid_lft 291075677sec preferred_lft 291075677sec
inet6 fe80::216:3eff:fe02:b2a8/64 scope link
valid_lft forever preferred_lft forever
3: cni-podman0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 4a:22:90:68:12:aa brd ff:ff:ff:ff:ff:ff
inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
valid_lft forever preferred_lft forever
inet6 fe80::4822:90ff:fe68:12aa/64 scope link
valid_lft forever preferred_lft forever
6: docker0: mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:f4:92:1b:07 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::42:f4ff:fe92:1b07/64 scope link
valid_lft forever preferred_lft forever
87: br-5cd703a37a83: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:32:ab:05:e0 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-5cd703a37a83
valid_lft forever preferred_lft forever
inet6 fe80::42:32ff:feab:5e0/64 scope link
valid_lft forever preferred_lft forever
93: vethf2c72a3@if92: mtu 1500 qdisc noqueue master br-5cd703a37a83 state UP group default
link/ether b2:ec:15:6d:d0:b5 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::b0ec:15ff:fe6d:d0b5/64 scope link
valid_lft forever preferred_lft forever
95: veth16a58ea@if94: mtu 1500 qdisc noqueue master br-5cd703a37a83 state UP group default
link/ether 7a:f3:e8:c2:ba:2b brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::78f3:e8ff:fec2:ba2b/64 scope link
valid_lft forever preferred_lft forever
[root@sanxingtongxue ~]# sudo netstat -tulpn | grep :80
tcp00 0.0.0.0:80000.0.0.0:*LISTEN552059/python3
tcp600 :::801:::*LISTEN513791/java
tcp600 127.0.0.1:8005:::*LISTEN513791/java
文章图片
Container模式 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP,端口范围。 kubernetes 中的pod就是多个容器共享一个 Network namespace。同样,两个容器除了?络??,其他的如?件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo ?卡设备通信。示例图如下:
文章图片
操作演示如下:
[root@sanxingtongxue ~]# docker run -tid --net=container:alpine1 --name docker_con hello:v1
0eb9f3fac30d6b979b5138816e633abaa80ee6301b1b12b8f1dde7fd583cf998
[root@sanxingtongxue ~]# docker exec -it docker_con /bin/bash
root@6eee1dd7a27a:/# apt-get update
root@6eee1dd7a27a:/# apt-get install net-tools
root@6eee1dd7a27a:/# ifconfig -a
eth0: flags=4163mtu 1500
inet 172.18.0.2netmask 255.255.0.0broadcast 172.18.255.255
ether 02:42:ac:12:00:02txqueuelen 0(Ethernet)
RX packets 2413bytes 4444758 (4.4 MB)
RX errors 0dropped 0overruns 0frame 0
TX packets 1924bytes 176355 (176.3 KB)
TX errors 0dropped 0 overruns 0carrier 0collisions 0lo: flags=73mtu 65536
inet 127.0.0.1netmask 255.0.0.0
looptxqueuelen 1000(Local Loopback)
RX packets 56bytes 5130 (5.1 KB)
RX errors 0dropped 0overruns 0frame 0
TX packets 56bytes 5130 (5.1 KB)
TX errors 0dropped 0 overruns 0carrier 0collisions 0root@6eee1dd7a27a:/# route -n
Kernel IP routing table
DestinationGatewayGenmaskFlags Metric RefUse Iface
0.0.0.0172.18.0.10.0.0.0UG000 eth0
172.18.0.00.0.0.0255.255.0.0U000 eth0
None模式 使用none模式,Docker 容器拥有自己的Network Namespace但不进行任何网络配置。
示例图如下:
文章图片
操作演示如下:
[root@sanxingtongxue ~]# docker run -tid --net=none --name docker_none hello:v1
b97b13864a0a8230a979b712e7676cd82a901105d54e390197f36413c9708f90
小拓展 Bridge
网桥是工作在 TCP/IP 二层协议 的虚拟网络设备,与现实世界中的交换机功能相似。与其他虚拟网络设备一样,可以配置 IP、MAC。Bridge 的主要功能是在多个接入 Bridge 的网络接口间转发数据包。如下图,Bridge (设备名 br0) 充当主设备,连接了四个从设备,分别是 tap1,tap2,veth1,eth0。
文章图片
虚拟网卡接口VETH
VETH (virtual Ethernet) 设备总是成对出现,彼此相连。 一个设备从协议栈读取数据后,会将数据发送到另一个设备上去。VETH 可以用于两个 namespace 间的网络通信。如果 VETH 设备对中有一个设备不可用,则整个链路也不可用。
【云原生|【云原生|Docker系列3】Docker网络模式详解】
文章图片
文章图片
落红不是无情物,化作春泥更护花。
推荐阅读
- 云原生|【云原生|Docker系列5】Docker Compose安装使用详解
- 编程语言|介绍 Docker 的多阶段构建功能
- 技术交流|【云原生】Docker 使用详解
- 云原生|【云原生丨Docker系列13】Docker 的多阶段构建详解
- prometheus|Prometheus监控(三)—— 钉钉和企业微信告警
- 政企组织为什么更需要私有化的IM即时通讯平台()
- 网络|Linux网络——DNS域名解析服务(正向解析实验)
- Linux|Linux网络 DNS域名解析服务
- 云原生|云原生周报 | Kubernetes 1.25 重要更新;2022 国际开源节即将开启