宿主机下容器的网络访问解析

1.单机容器网络的实现

  • 同节点两个容器的互访
    为了说明容器间的访问,在consul-0所在宿主机上调度了一个web-1的应用。

    #进入consul-0容器
    kubectl exec consul-0 -it /bin/sh
    #在容器里执行
    / # ifconfig
    eth0      Link encap:Ethernet  HWaddr 6E:55:56:21:F3:9F
          inet addr:10.244.3.40  Bcast:10.244.3.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:13178957 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8061195 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1677907317 (1.5 GiB)  TX bytes:1085173944 (1.0 GiB)
    #看路由情况
    / # route
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    default         10.244.3.1      0.0.0.0         UG    0      0        0 eth0
    10.244.0.0      10.244.3.1      255.255.0.0     UG    0      0        0 eth0
    10.244.3.0      *               255.255.255.0   U     0      0        0 eth0
    

可以看到consul-0容器里面有eth0的网卡,怎么通过该网卡传输数据到指定web-0容器呢。这里涉及到Veth Pair的虚拟设备。Veth Pair的特点是它会以两张网卡的方式成对存在,并且从其中一张网卡发送数据包可以直接出现在对应的另一张网卡上,即使这两张网卡在不同的NetworkNamespace(对应容器namespace隔离技术中对应的网络隔离)上。

```
#宿主机上
[root@k8s-node3 ~]# ifconfig
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
    inet 10.244.3.1  netmask 255.255.255.0  broadcast 10.244.3.255
    inet6 fe80::242d:afff:fe7e:516  prefixlen 64  scopeid 0x20<link>
    ether 26:2d:af:7e:05:16  txqueuelen 1000  (Ethernet)
    RX packets 13784494  bytes 1697239447 (1.5 GiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 22202070  bytes 2850632066 (2.6 GiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
	
veth2e303920: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
    inet6 fe80::8c1d:cdff:fe31:6e6c  prefixlen 64  scopeid 0x20<link>
    ether 8e:1d:cd:31:6e:6c  txqueuelen 0  (Ethernet)
    RX packets 1  bytes 42 (42.0 B)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 280  bytes 16957 (16.5 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth6a98119e: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
    inet6 fe80::f45b:81ff:fee2:f031  prefixlen 64  scopeid 0x20<link>
    ether f6:5b:81:e2:f0:31  txqueuelen 0  (Ethernet)
    RX packets 13346497  bytes 1814710689 (1.6 GiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 21741625  bytes 2790447367 (2.5 GiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@k8s-node3 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
cni0            8000.262daf7e0516       no              veth2e303920
                                                        veth6a98119e
docker0         8000.0242aa302d4e       no
```

可以看到veth2e303920,veth6a98119e两张虚拟网卡被“插”到cni上,这里可以看到并没有走docker0,这是因为k8s的网络接管了容器原有的网络。这里怎么判断consul-0对应的veth pair是哪张虚拟网卡呢?

```
#宿主机上
[root@k8s-node3 ~]# ip link
21: veth2e303920@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default 
link/ether 8e:1d:cd:31:6e:6c brd ff:ff:ff:ff:ff:ff link-netnsid 3
44: veth6a98119e@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue 	master cni0 state UP mode DEFAULT group default 
link/ether f6:5b:81:e2:f0:31 brd ff:ff:ff:ff:ff:ff link-netnsid 0
#consul-0容器上
/ # cat /sys/class/net/eth0/iflink 
44
```

说明veth6a98119e对应consul-0的在veth pair的虚拟网卡,veth2e303920对应web-1,就不额外说明了。

```
#查看pod的ip信息
[root@k8s-master ~]# kubectl get pods  -o wide
NAME                                     READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE   READINESS GATES
consul-0                                 1/1     Running   0          6d23h   10.244.3.40    k8s-node3   <none>           <none>
web-1                                    1/1     Running   0          10d     10.244.3.17    k8s-node3   <none>           <none>
```

consul-0去访问web-1时通过ip地址10.244.3.17,前面route的时候看到10.244.3.0对应的Gateway是*,意味着是网络直连走二层网络,前面讲了veth2e303920,veth6a98119e插在cni0网络上,所以需要通过cni0找到10.244.3.17的mac地址,而veth2e303920对应的nginx-0的地址为10.244.3.17,cni0发广播到nginx-0的网络协议栈,就会把10.244.3.17的MAC地址回复给consul-0。所以consul-0可以访问到nginx-0.
宿主机不同容器网络的访问
结合下图整体说明同宿主机不同容器网络的访问情况。
在这里插入图片描述
- ARP广播
1. consul-0访问10.244.3.17,在路由上可以看到gateway为*,所以会走二层网络直达。
2. consul-0访问10.244.3.17,在路由上可以看到Use Iface为eth0,所以流量会通过eth0
3. 而eth0跟veth6a98119e是veth Pair,所以过eth0的流量会在veth6a98119e出现,此时veth6a98119e相当于一张虚拟网卡被插在cni网桥上。
4. consul-0访问10.244.3.17,第一次访问的时候不知道10.244.3.17对应的MAC地址,所以cni0会发ARP广播给整个二层网络。ARP广播通过veth2e303920到达web-1的eth0,web-1会把自身的MAC地址回复到consul-0容器。
- 发数据包
1. 同ARP广播流程,consul-0发数据包通过eth0到veth6a98119e,根据cni0缓存的CAM查询到端口为veth2e303920,数据包流量就进入到了web-1.

**宿主机访问容器**
```
[root@k8s-node3 ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway         0.0.0.0         UG    100    0        0 ens192
10.244.3.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
```
宿主机访问10.244.3.40,通过cni网关过veth pair到达consul-0的eth0。

**容器访问宿主机**
容器consul-0访问宿主机,数据包通过cni0网桥出现在宿主机上。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值