Docker网络详解

网友投稿 275 2022-10-18

Docker网络详解

文章目录

​​一、Docker网络间通信​​

​​`1.1.宿主机ping容器,可以正常通信`​​​​`1.2.容器ping宿主机,可以正常通信`​​​​`1.3.容器ping外网,可以正常通信(前提条件是宿主机能访问外网)`​​​​`1.4.容器ping另外一个容器`​​

​​二、Docker网络常用技术​​

​​`2.1.网络命名空间`​​

​​网络命名空间的操作​​

​​`2.2.Veth设备对`​​

​​创建veth设备对​​​​实现veth设备对之间的通信​​​​常用操作​​

​​`2.3.网桥`​​

​​把veth0连接到网桥docker1​​​​删除网桥​​

​​三、理解docker0​​

​​`3.1.iptables和Netfilter`​​​​`3.2.路由`​​

​​路由表的创建​​​​路由表的查看​​

​​四、Docker的网络实现​​

​​`4.1.Docker启动后`​​

​​NAT表​​​​filter表​​

​​`4.2.运行不映射端口的容器`​​​​`4.3.运行映射了端口(80:80)的容器`​​

​​NAT表​​​​filter表​​

一、Docker网络间通信

启动一个测试容器

docker run -d --name test busybox sleep 36000

查看容器的IP地址

docker exec -it test ip a s

​​1.1.宿主机ping容器,可以正常通信​​

​​1.2.容器ping宿主机,可以正常通信​​

​​1.3.容器ping外网,可以正常通信(前提条件是宿主机能访问外网)​​

​​1.4.容器ping另外一个容器​​

再启动一个容器test1

docker run -d --name test1 busybox sleep 36000

问题:那么它们之间是如何实现通信的呢?

二、Docker网络常用技术

查看Docker容器在哪个网络命名空间

​​2.1.网络命名空间​​

为了支持网络协议栈的多个实例,Linux在网络栈中引入了网络命名空间。处于不同命名空间中的网络栈是​​完全隔离​​的,彼此之间无法通信,就好像两个“平行宇宙”通过对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境

网络命名空间的操作

ip netns add ns1 #创建命名空间ns1ip netns list #列出命名空间ip netns exec ns1 ifconfig #在命名空间中执行命名,此时没有任何网络设备ip netns exec ns1 bash #进入到命名空间exit #退出到外面的命名空间ip link set br0 netns ns1 #把br0设备转移到ns1命名空间中ethtool -k br0 | grep netns #如果netns-local的值是on,说明不可以转移,否则可以转移ip netns del ns1 #删除网络命名空间

​​2.2.Veth设备对​​

通过Veth设备对可以直接将两个网络命名空间连接起来,实现不同网络命名空间之间的通信

创建veth设备对

ip link add veth0 type veth peer name veth1 #创建Veth设备对ip link show

ip netns add ns1 #创建命名空间ns1ip link set veth1 netns ns1 #把veth1转移到ns1命名空间中ip link show

ip netns exec ns1 ip link show #在ns1中查看网络设备

veth1已经移动到ns1网络命名空间了

14: veth1@if15解释

14表示设备的编号veth1表示设备名if15表示该设备的peer设备编号为15

注意:我们在Docker容器中看到的网络设备是eth0,这是因为Docker在将Veth设备放入容器后改名为eth0,简直以假乱真

实现veth设备对之间的通信

ip netns exec ns1 ip addr add 10.1.1.11/24 dev veth1ip netns exec ns1 ip link set dev veth1 upip addr add 10.1.1.10/24 dev veth0ip link set dev veth0 upping 10.1.1.11

常用操作

Veth设备查看对端

ip netns exec ns1 ethtool -S veth1

​​2.3.网桥​​

把veth0连接到网桥docker1

brctl addbr docker1 #新增网桥docker1brctl addif docker1 veth0 #将veth0连接到网桥docker1ifconfig veth0 0.0.0.0 #veth0工作在链路层,因此不再需要IP地址ifconfig docker1 10.1.1.1/24 #给网桥配置IP地址brctl show #查看网桥信息

bridge link #显示哪些设备连接到网桥中

删除网桥

ip link set dev docker1 downbrctl delbr docker1

三、理解docker0

每启动一个容器,就会分配一个IP地址

默认使用桥接(bridge)模式,通过​​Veth设备对​​技术来实现通信

​​3.1.iptables和Netfilter​​

​​Netfilter​​​负责在内核中执行各种挂接的规则,运行在​​内核模式​​中

而​​iptables​​​是在​​用户模式​​下运行的进程,负责协助和维护内核中Netfilter的各种规则表。

iptables 命令介绍

​​3.2.路由​​

路由表的创建

Linux的路由表至少包括两个表,一个是​​LOCAL表​​​,另一个是​​MAIN表​​。

LOCAL表包含所有本地设备地址,LOCAL路由表是在配置网络设备地址时自动创建的,用于供Linux协议栈识别本地地址,以及进行本地各个不同网络接口之间的数据转发

通过如下命令查看LOCAL表的内容:

ip route show table local type local

MAIN表用于各类网络IP地址的转发。

路由表的查看

ip route list

netstat -rn或route -n

四、Docker的网络实现

详细介绍Docker启动后、运行不映射端口的容器、运行映射了端口的容器时iptables的区别(使用​​iptables-save​​查看)

​​4.1.Docker启动后​​

NAT表

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

前两条匹配生效后,都会执行DOCKER链,而此时DOCKER链为空,所以前两条只是做了一个框架,并没有实际效果

若本地出发的数据包不是发往docker0的,则需要进行动态地址修改(MASQUERADE),将源地址从容器的地址(172段)修改为宿主机网卡的IP地址,之后就可以发送给外面的网络了,即SNAT

filter表

-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT-A FORWARD -o docker0 -j DOCKER-A FORWARD -i docker0 ! -o docker0 -j ACCEPT-A FORWARD -i docker0 -o docker0 -j ACCEPT

第1条:如果接收到的数据包属于以前已经建立好的连接,那么允许直接通过。这样接收到的数据表又走回docker0,并中转到相应的容器

第2条是框架,发往docker0的包都会走DOCKER链

第3条:来自docker0的包,如果Forward到非docker0的本地IP地址设备,是允许的。这样,docker0设备的包就可以根据路由规则中转到宿主机的网卡设备,​​从而访问外面的网络​​

第4条:docker0的包还可以被中转给docker0本身,即连接在docker0网桥上的​​不同容器之间的通信​​也是允许的

​​4.2.运行不映射端口的容器​​

iptable与Docker启动后一样

​​4.3.运行映射了端口(80:80)的容器​​

共增加了如下三条规则

NAT表

-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80

第1条:作用是将原地址和目标地址为容器IP 172.17.0.2/32, 且目标端口为80,MASQUERADE动态地转换为可用的宿主机IP地址—​​没搞懂为什么要这么做​​

第2条:其作用是将访问宿主机80端口请求的流量转发到容器172.17.0.2的80端口上,所以,外界访问Docker容器是通过iptables做DNAT实现的。

filter表

-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT

从非docker0发往docker0且目的地址为172.17.0.2/32,端口是tcp 8443的包是允许的

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringCloud网关(Zuul)如何给多个微服务之间传递共享参数
下一篇:k8s部署Istio1.5.8
相关文章

 发表评论

暂时没有评论,来抢沙发吧~