java怎么拦截某个对象
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~