Kubernetes-基于Flannel的网络原理

Kubernetes(k8s)底层网络原理刨析 1 典型的数据传输流程图 • 一个外部的business-manager请求,首先进入集群的入口(ingress),ingress反向代理后负载到business-manager的service。Service层再负载到某个node下的具体的business-manager pod • Business-manager pod再将请求发往data-pro... 阅读详情

目录

一、容器与容器之间的通信

二、POD与POD之间的通信

1、同一个Node上的pod之间的通信

2、不同Node上的pod之间的通信

3、使用 tcpdump和wireshark进行分析

三、Pod与Service之间的通信

1、Service的类型

2、ClusterIP类型的service需要的iptables规则

3、NodePort类型的Service需要的iptables规则

4、更近一步,直接使用服务的名字访问

四、k8s集群外部到k8s集群内部的访问


一、容器与容器之间的通信

查看pod mysql-demo-e81sy中容器的网络模式:

[root@k8s-master ~]# kubectl --namespace=hyjx--hyjx-group3 get pods -o wide
NAME                READY     STATUS    RESTARTS   AGE       IP            NODE
mysql-demo-e81sy    1/1       Running   0          21h       10.20.92.11   k8s-node2
wp-frontend-0rlk4   1/1       Running   0          1d        10.20.92.3    k8s-node2
wp-mysql-t5w0m      1/1       Running   0          1d        10.20.37.5    k8s-node1

[root@k8s-node2 ~]# docker ps |grep mysql-demo-e81sy
772d26fcf3e4        192.168.138.225:5000/mysql:5.7.15                               "docker-entrypoint.sh"   21 hours ago        Up 21 hours                             k8s_mysql-demo.1a1add3a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_d1b1e4aa
2e429e000a9f        192.168.138.225:5000/rhel7/pod-infrastructure:latest            "/pod"                   21 hours ago        Up 21 hours                             k8s_POD.5da6097a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_e3c27577

注意:pod mysql-demo-e81sy中有两个容器:id分别是772d26fcf3e4,2e429e000a9f。名字以k8s_POD开头的容器是kubelet自动加上的,只提供基础的网络栈,其他的容器都是直接共用这个容器的网络栈(网络命名空间)。


[root@k8s-node2 ~]# docker inspect `docker ps |grep mysql-demo-e81sy |awk '{print $1}'` |jq '.[] | {ContainerID: .Id, ContainerName: .Name, NetworkMode: .HostConfig.NetworkMode}'

{
    "ContainerID": "772d26fcf3e4e13aedff04b9b4c3131fa177a301745dba3062141102fba19574",
    "ContainerName": "/k8s_mysql-demo.1a1add3a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_d1b1e4aa",
    "NetworkMode": "container:2e429e000a9fdf1bdc56aa8fc5f3a57cf4a61d250b3e8252191d06d553fef07a"
}

{
    "ContainerID": "2e429e000a9fdf1bdc56aa8fc5f3a57cf4a61d250b3e8252191d06d553fef07a",
    "ContainerName": "/k8s_POD.5da6097a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_e3c27577",
    "NetworkMode": "default"
}

用户的容器(k8s_mysql-demo.1a1add3a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_d1b1e4aa)的网络模式是container模式:可以从输出看到,网络基础设施容器(k8s_POD.5da6097a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_e3c27577)是default的网络模式(bridge模式);

container:2e429e000a9fdf1bdc56aa8fc5f3a57cf4a61d250b3e8252191d06d553fef07a

说明容器(k8s_mysql-demo.1a1add3a_mysql-demo-e81sy_hyjx--hyjx-group3_1ae92c77-babb-11e6-9055-5254005c2a8d_d1b1e4aa)共用网络基础设施容器的网络栈:


[root@k8s-node2 ~]# docker ps |grep mysql-demo-e81sy |awk '{print $1}' |xargs docker inspect |jq '.[] |.State.Pid' |xargs -i nsenter -t {} -p -n ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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

77: eth0@if78: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP
    link/ether 02:42:0a:14:5c:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.20.92.11/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe14:5c0b/64 scope link tentative dadfailed
       valid_lft forever preferred_lft forever

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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

77: eth0@if78: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP
    link/ether 02:42:0a:14:5c:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.20.92.11/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe14:5c0b/64 scope link tentative dadfailed
       valid_lft forever preferred_lft forever

[root@k8s-node2 ~]# docker ps |grep mysql-demo-e81sy |awk '{print $1}' |xargs docker inspect |jq '.[] |.State.Pid' |xargs -i nsenter -t {} -p -n ip route
default via 10.20.92.1 dev eth0
10.20.92.0/24 dev eth0  proto kernel  scope link  src 10.20.92.11
default via 10.20.92.1 dev eth0
10.20.92.0/24 dev eth0  proto kernel  scope link  src 10.20.92.11


[root@k8s-node2 ~]# docker ps |grep mysql-demo-e81sy |awk '{print $1}' |xargs docker inspect |jq '.[] |.State.Pid' |xargs -i nsenter -t {} -p -n netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::3306                 :::*                    LISTEN      12587/mysqld
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::3306                 :::*                    LISTEN      12587/mysqld

既然都是共用同一个网络命名空间,直接使用localhost或127.0.0.1加上端口访问就好了。可以看到这两个容器的ip地址,路由表,以及暴露的端口号等都是一样的,因为他们使用的是同一个网络命名空间,同一个网络栈


[root@k8s-node2 ~]# docker ps |grep mysql-demo-e81sy |awk '{print $1}' |xargs -i docker exec {} ps -ef

UID        PID  PPID  C STIME TTY          TIME CMD
mysql        1     0  0 Dec05 ?        00:05:28 mysqld
root       299     0  0 Dec09 ?        00:00:00 bash
root       334     0  0 05:27 ?        00:00:00 ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Dec05 ?        00:00:02 /pod
root        59     0 11 00:27 ?        00:00:00 ps -ef

【注意】:他们只是共用网络命名空间(network namespace),但是进程命名空间(PID namespace)、用户命名空间(user namespace)等其他的命名空间是相互隔离的。

二、POD与POD之间的通信

1、同一个Node上的pod之间的通信

每个pod都有唯一一个ip(属于docker0网桥上的网段),每个pod的网络基础设施容器都是通过veth设备对直接连在docker0网桥上的:

20

研究这两个pod:

[root@k8s-master ~]# kubectl --namespace=hyjx--hyjx-group3 get pods -o wide
NAME                READY     STATUS    RESTARTS   AGE       IP            NODE
mysql-demo-e81sy    1/1       Running   0          23h       10.20.92.11   k8s-node2
wp-frontend-0rlk4   1/1       Running   0          1d        10.20.92.3    k8s-node2

分别查看pod内的路由表:

[root@k8s-node2 ~]# docker exec -it `docker ps |grep -v POD |grep mysql-demo-e81sy |awk '{print $1}'` ip route list
default via 10.20.92.1 dev eth0
10.20.92.0/24 dev eth0  proto kernel  scope link  src 10.20.92.11

[root@k8s-node2 ~]# docker exec -it `docker ps |grep -v POD |grep wp-frontend-0rlk4 |awk '{print $1}'` ip route list
default via 10.20.92.1 dev eth0
10.20.92.0/24 dev eth0  proto kernel  scope link  src 10.20.92.3

两个pod中匹配的路由表是:

10.20.92.0/24 dev eth0  proto kernel  scope link  src 10.20.92.3

而目的地址为 10.20.92.0/24(本机docker0网桥的地址)的数据包都会通过容器内的eth0(veth设备)直接转给Kernel,路由的范围是link(与本设备直接连接),因为veth设备都是成对存在的,另一端连在docker0网桥上,所以会由Kernel直接转发给docker0网桥上的另一个veth设备。

宿主机上的路由表:

[root@k8s-node2 ~]# ip route list
default via 192.168.128.1 dev eth0  proto static  metric 100
10.20.0.0/16 dev flannel0  proto kernel  scope link  src 10.20.92.0
10.20.92.0/24 dev docker0  proto kernel  scope link  src 10.20.92.1
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1
192.168.128.0/20 dev eth0  proto kernel  scope link  src 192.168.138.222  metric 100

[root@k8s-node2 ~]# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.128.1   0.0.0.0         UG        0 0          0 eth0
10.20.0.0       0.0.0.0         255.255.0.0     U         0 0          0 flannel0
10.20.92.0      0.0.0.0         255.255.255.0   U         0 0          0 docker0
192.168.122.0   0.0.0.0         255.255.255.0   U         0 0          0 virbr0
192.168.128.0   0.0.0.0         255.255.240.0   U         0 0          0 eth0

同样的,宿主机上匹配的路由表是:

10.20.92.0/24 dev docker0  proto kernel  scope link  src 10.20.92.1

宿主机将数据包通过docker0发给Kernel,最终docker0网桥会将数据包转发给目的pod。

2、不同Node上的pod之间的通信

要支持不同Node节点上的pod通信需要满足的要求:

1)、整个kubernetes集群中对每个POD分配一个唯一的IP:在部署Kubernetes时,对每个Node节点的docker0网桥的网段重新划分,用户设定一个大的网段(eg:10.20.0.0/16),存在etcd中,每个节点的flanneld会去etcd中查找这个值,然后,flanneld随机生成一个属于大网段的,且不冲突的子网(eg: 10.20.37.0/24; 10.20.92.0/24; 10.20.0.53/24)并将该值写回etcd中,这样就保证了每个pod的IP都会在10.20.0.0/16这个网段内;

2)、Node节点之间需要架设一个overlay网络(一般通过flannel实现),保证pod可以互相访问。

以下面两个pod为例:


[root@k8s-master ~]# kubectl --namespace=hyjx--hyjx-group3 get pods -o wide
NAME                READY     STATUS    RESTARTS   AGE       IP            NODE
wp-mysql-t5w0m      1/1       Running   0          2d        10.20.37.5    k8s-node1
mysql-demo-e81sy    1/1       Running   0          1d        10.20.92.11   k8s-node2

如果,k8s-node1(192.168.138.221/20)上的pod(src=10.20.37.5/24)要发送目的地址为dest=10.20.92.11/24的数据包。

根据node1的路由表:

[root@k8s-node1 ~]# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.128.1   0.0.0.0         UG        0 0          0 eth0
10.20.0.0       0.0.0.0         255.255.0.0     U         0 0          0 flannel0
10.20.37.0      0.0.0.0         255.255.255.0   U         0 0          0 docker0
192.168.122.0   0.0.0.0         255.255.255.0   U         0 0          0 virbr0
192.168.128.0   0.0.0.0         255.255.240.0   U         0 0          0 eth0

dest=10.20.92.11/24匹配第二条路由表,目的地址为10.20.0.0/16的数据包要交给flannel0网桥处理,flanneld会到etcd中查找10.20.92.11/24所在的node节点的IP(192.168.139.222/20):


[root@k8s-master ~]# etcdctl get /awcloud.com/network/config
{"NetWork":"10.20.0.0/16"}
[root@k8s-master ~]# etcdctl ls /awcloud.com/network/subnets
/awcloud.com/network/subnets/10.20.92.0-24
/awcloud.com/network/subnets/10.20.100.0-24
/awcloud.com/network/subnets/10.20.53.0-24
/awcloud.com/network/subnets/10.20.37.0-24

[root@k8s-master ~]# etcdctl get /awcloud.com/network/subnets/10.20.92.0-24
{"PublicIP":"192.168.138.222"}

在目的Node节点,flanneld收到数据包后,去除flanneld加上的头部,将原始的数据包发送到宿主机的网络栈里面,这时的数据包src=10.20.37.5/24,dest=10.20.92.11/24;根据本机路由表:
然后flanneld在原来的数据包的基础上,重新封装成UDP数据包,加上UDP的头部(src=192.168.138.221/20:8285, dest=192.168.138.222/20:8285,flannel 默认使用 8285 端口作为 UDP 封装报文的端口,VxLan 的话使用 8472 端口)直接发送给192.168.138.222:8285(8285是flanneld监听的端口)。

[root@k8s-node2 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.128.1   0.0.0.0         UG    100    0        0 eth0
10.20.0.0       0.0.0.0         255.255.0.0     U     0      0        0 flannel0
10.20.92.0      0.0.0.0         255.255.255.0   U     0      0        0 docker0
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
192.168.128.0   0.0.0.0         255.255.240.0   U     100    0        0 eth0

dest=10.20.92.11/24优先匹配第三条路由规则,将数据包转发给docker0网桥上,docker0网桥再将数据包转给IP为10.20.92.11/24的POD中,响应数据包反之。

3、使用 tcpdump和wireshark进行分析

1)、在192.168.138.221上进入pod wp-mysql-t5w0m中(IP为10.20.37.5/24)登录10.20.92.11中的mysql-server(在192.168.138.222):

[root@k8s-node1 ~]# docker exec -it `docker ps |grep -v POD |grep wp-mysql-t5w0m |awk '{print $1}'` bash
root@wp-mysql-t5w0m:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default
    link/ether 02:42:0a:14:25:05 brd ff:ff:ff:ff:ff:ff
    inet 10.20.37.5/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe14:2505/64 scope link tentative dadfailed
       valid_lft forever preferred_lft forever

root@wp-mysql-t5w0m:/# mysql -h 10.20.92.11 -P 3306 -uroot -pr00tme
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 5.7.15 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>


2)在192.168.138.222上使用tcpdump抓取eth0进入的数据包(被flannel封装成UDP数据包):


[root@k8s-node2 ~]# tcpdump -i eth0 -nn -X src host 192.168.138.221 and port 8285 -w eth0.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
^C6 packets captured
6 packets received by filter
0 packets dropped by kernel

使用wireshark分析:

3)在192.168.138.222上使用tcpdump抓取由flanneld转发到flannel0网桥上的数据包:

[root@k8s-node2 ~]# tcpdump -i flannel0 -X -nn dst host 10.20.92.11 and port 3306 -w flannel0.pcap
tcpdump: listening on flannel0, link-type RAW (Raw IP), capture size 65535 bytes
^C6 packets captured
6 packets received by filter
0 packets dropped by kernel

使用wireshark分析:

 

4)在192.168.138.222上使用tcpdump抓取最终进入docker0的原始数据包:


[root@k8s-node2 ~]# tcpdump -i docker0 -X -nn dst host 10.20.92.11 and port 3306 -w docker0.pcap
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 65535 bytes
^C6 packets captured
6 packets received by filter
0 packets dropped by kernel

使用wireshark分析:

验证目的MAC地址02:42:0a:14:5c:0b为POD的MAC地址:


[root@k8s-node2 ~]# docker inspect `docker ps |grep POD |grep mysql-demo-e81sy |awk '{print $1}'` |jq '.[] | .NetworkSettings.MacAddress'

"02:42:0a:14:5c:0b"

验证源MAC地址02:42:b6:2f:9d:03为docker0网桥地址:


[root@k8s-node2 ~]# ifconfig docker0 |grep ether |awk '{print $2}'

02:42:b6:2f:9d:03


三、Pod与Service之间的通信

为了支持水平扩展和高可用,实际使用中并不会直接使用POD的IP来访问POD中的服务,而是定义service来访问一组POD中的服务。service是对一组POD的抽象,会根据访问策略(负载均衡)来访问这组POD。

Kubernetes会在创建service时随机分配一个ClusterIP,这是一个虚IP(VIP),不能与docker0网桥的网段冲突,比如:10.10.0.0/16这个网段(在 kube-apiserver的--service-cluster-ip-range=10.10.0.0/16配置项中指定)。

访问POD中服务是只需要访问这个VIP就好了,而service会将请求经过负载均衡之后转发到后端POD中,这些工作都是运行在每个Node节点的kube-proxy进程管理的,它的核心功能是:将对某个Service的访问经过负载均衡(Round Robin算法)之后转发到某一个后端POD:

1、Service的类型

1、ClusterIP:默认类型,自动分配一个仅cluster内部可以访问的虚拟IP;
2、NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort来访问改服务;
3、LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到<NodeIP>:NodePort

wKiom1aJ50SDyB-vAAO8DyIMPig832.gif

无论是ClusterIP+TargetPort的方式,还是NodeIP+NodePort的方式访问服务,都会被节点的iptables规则重定向到kube-proxy监听Service的服务代理端口,kube-proxy接受到Service请求之后,会使用Round-Robin负载均衡算法按照Service维护的Endpoint对象中选择一个endpoint(其实就是POD)。

以下面这个svc及其对应的pod为例:

[root@k8s-master ~]# kubectl --namespace=hyjx--hyjx-group3 get pods -o wide |grep mysql-demo-e81sy
mysql-demo-e81sy    1/1       Running   0          1d        10.20.92.11   k8s-node2

[root@k8s-master ~]# kubectl --namespace=hyjx--hyjx-group3 get svc -o wide -l name=mysql-demo
NAME         CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE       SELECTOR
mysql-demo   10.10.147.26   <none>        13306/TCP   1d        name=mysql-demo

[root@k8s-master ~]# kubectl --namespace=hyjx--hyjx-group3 get ep -o wide -l name=mysql-demo
NAME         ENDPOINTS          AGE
mysql-demo   10.20.92.11:3306   1d

service mysql-demo对象维护着一个endpoint对象,指向当前这个service服务的底层podIP:containerPort。endpoint对象会随着pod的改变而自动修改。

2、ClusterIP类型的service需要的iptables规则

任何数据包进入宿主机后,首先进入PREROUTING链:

-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
通过服务访问POD时,进入KUBE-SERVICES链,-m comment --comment "kubernetes service portals" 表示匹配规则使用iptables的显示扩展的注释功能(使用额外的匹配机制)

kube-proxy进程在启动时或者监听到Service和Endpoint发生变化之后,会为每个endpoint修改本机Iptables的NAT表中的4条规则链:


[root@k8s-node1 ~]# iptables-save |grep -v mysql-demo2 |grep mysql-demo
-A KUBE-SEP-6XCC4VJACKOMSYVV -s 10.20.92.11/32 -m comment --comment "hyjx--hyjx-group3/mysql-demo:mysqld-demo" -j KUBE-MARK-MASQ
-A KUBE-SEP-6XCC4VJACKOMSYVV -p tcp -m comment --comment "hyjx--hyjx-group3/mysql-demo:mysqld-demo" -m tcp -j DNAT --to-destination 10.20.92.11:3306
-A KUBE-SERVICES -d 10.10.147.26/32 -p tcp -m comment --comment "hyjx--hyjx-group3/mysql-demo:mysqld-demo cluster IP" -m tcp --dport 13306 -j KUBE-SVC-DM5EMDBLORDRGWLL
-A KUBE-SVC-DM5EMDBLORDRGWLL -m comment --comment "hyjx--hyjx-group3/mysql-demo:mysqld-demo" -j KUBE-SEP-6XCC4VJACKOMSYVV

1)、在KUBE-SERVICES链中匹配到第三条规则,目的地址是 10.10.147.26/32 (就是service的VIP),目的端口为13306(service监听的端口),协议为TCP,则转到KUBE-SVC-DM5EMDBLORDRGWLL规则进行处理;

2)、第四条规则就是KUBE-SVC-DM5EMDBLORDRGWLL,直接转到规则KUBE-SEP-6XCC4VJACKOMSYVV;

3)、第一条规则就是KUBE-SEP-6XCC4VJACKOMSYVV,如果源地址为10.20.92.11/32(就是POD自己),直接使用KUBE-MARK-MASQ规则。在dockerd的启动配置项中,默认设置"--ip-masq=true",则“Enable IP masquerading for bridge's IP range.”,启用IP伪装功能(IP Masquerade),具体介绍移步维基百科。

[root@k8s-node1 ~]# iptables-save |grep :KUBE-MARK-MASQ

:KUBE-MARK-MASQ - [0:0]

4)、第二条规则也是KUBE-SEP-6XCC4VJACKOMSYVV,直接就使用DNAT(目的地址转换),将目的地址:端口 10.10.147.26:13306 直接转换成 10.20.92.11:3306。

5)、使用tcpdump工具进行抓包分析,首先找到POD的eth0另一端的veth设备:

[root@k8s-node1 ~]# docker exec -it `docker ps |grep -v POD |grep wp-mysql-t5w0m |awk '{print $1}'` ip addr |grep eth0@
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default

[root@k8s-node1 ~]# docker exec -it `docker ps |grep -v POD |grep wp-mysql-t5w0m |awk '{print $1}'` ip addr |grep eth0@ |awk -F ': <' '{print $1}'
45: eth0@if46

[root@k8s-node1 ~]# docker exec -it `docker ps |grep -v POD |grep wp-mysql-t5w0m |awk '{print $1}'` ip addr |grep eth0@ |awk -F ': <' '{print $1}' |awk -F '@if' '{print $2}'
46

wp-mysql-t5w0m这个pod的veth设备的另一端的id为46,在宿主机上,查找:


[root@k8s-node1 ~]# ip addr |grep ^46 |awk -F '@if' '{print $1}'

46: veth529894a

设备的名字为veth529894a,现在在POD中使用service mysql-demo的VIP(10.10.147.26)登录10.20.92.11中的mysql-server:

root@wp-mysql-t5w0m:/# mysql -h 10.10.147.26 -P 13306 -uroot -pr00tme
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.7.15 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>


同时,使用tcpdump抓取设备veth529894a上的最原始的数据包:

同时,使用tcpdump抓取设备docker0上的数据包:

其实,将目的IP和端口改成POD的IP和服务的端口,不仅Iptables起作用;kube-proxy也会根据负载均衡,配合Iptables选择其中一个POD的IP,因为一个Service对应的Endpoint可能有很多个(RC中的replica以及Service的selector共同控制后端Endpoint),官方图:

同时,使用tcpdump抓取设备flannel0上的数据包:

同时,使用tcpdump抓取设备eth0上的数据包:

从docker0网桥上出来以后,就直接使用目的POD的IP和端口了,就和之前分析的一样了。

3、NodePort类型的Service需要的iptables规则

[root@k8s-node1 ~]# iptables-save |grep mysql-demo2
-A KUBE-NODEPORTS -p tcp -m comment --comment "hyjx--hyjx-group3/mysql-demo2:mysqld-demo2" -m tcp --dport 30016 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "hyjx--hyjx-group3/mysql-demo2:mysqld-demo2" -m tcp --dport 30016 -j KUBE-SVC-NVNGTMQMPFTQA6YS
-A KUBE-SEP-7MWHP37XXE3W6QI4 -s 10.20.92.11/32 -m comment --comment "hyjx--hyjx-group3/mysql-demo2:mysqld-demo2" -j KUBE-MARK-MASQ
-A KUBE-SEP-7MWHP37XXE3W6QI4 -p tcp -m comment --comment "hyjx--hyjx-group3/mysql-demo2:mysqld-demo2" -m tcp -j DNAT --to-destination 10.20.92.11:3306
-A KUBE-SERVICES -d 10.10.95.1/32 -p tcp -m comment --comment "hyjx--hyjx-group3/mysql-demo2:mysqld-demo2 cluster IP" -m tcp --dport 23306 -j KUBE-SVC-NVNGTMQMPFTQA6YS
-A KUBE-SVC-NVNGTMQMPFTQA6YS -m comment --comment "hyjx--hyjx-group3/mysql-demo2:mysqld-demo2" -j KUBE-SEP-7MWHP37XXE3W6QI4

NodePort类型的Service比ClusterIP类型就多了两条规则KUBE-NODEPORTS,剩下的4条规则是用来处理使用ClusterIP的方式访问服务的请求,因为NodePort类型的服务,同样可以使用ClusterIP的方式访问。

1)、第一条规则,实现了IP Masquerade功能,不太懂这条规则的意义。。。;

2)、第二条规则,如果是使用NodeIP+NodePort的方式,目的端口为30016,处理方法和直接使用ClusterIP类型的服务访问一样。

4、更近一步,直接使用服务的名字访问

使用服务的VIP的方式还是不太友好,因为只有创建好Service之后,系统才会随机分配一个VIP,运行在容器中的应用无法提前知道这个VIP,动态修改镜像是不现实的。最终的解决方案是直接使用服务的名称来访问服务。而,服务的名称到服务的VIP的解析是由kube-dns来完成的。


[root@k8s-node2 ~]# docker exec -it `docker ps |grep -v POD |grep mysql-demo-e81sy |awk '{print $1}'` cat /etc/resolv.conf
search hyjx--hyjx-group3.svc.k8s.weike.me svc.k8s.weike.me k8s.weike.me
nameserver 192.168.138.224
options ndots:5

kubelet在启动容器的时候,会修改容器的/etc/resolv.conf,设置容器的DNS服务器为kube-dns(k8s-master节点IP),每个服务都有唯一一个域名:

[root@k8s-node2 ~]# docker exec -it `docker ps |grep -v POD |grep mysql-demo-e81sy |awk '{print $1}'` ping mysql-demo
PING mysql-demo.hyjx--hyjx-group3.svc.k8s.weike.me (10.10.147.26): 56 data bytes
^C--- mysql-demo.hyjx--hyjx-group3.svc.k8s.weike.me ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

[root@k8s-node2 ~]# docker exec -it `docker ps |grep -v POD |grep mysql-demo-e81sy |awk '{print $1}'` ping mysql-demo2
PING mysql-demo2.hyjx--hyjx-group3.svc.k8s.weike.me (10.10.95.1): 56 data bytes
^C--- mysql-demo2.hyjx--hyjx-group3.svc.k8s.weike.me ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

在容器中无法ping通服务mysql-demo的VIP,但是使用服务的名称,kube-dns可以正确地返回服务对应的VIP(10.10.147.26)。

四、k8s集群外部到k8s集群内部的访问

上面已经介绍过了,设置service的类型为NodePort,并为服务指定一个不冲突的端口(30000-32767)就行了,访问时直接使用任意一个Node节点的IP加上这个NodePort就好了。

K8S网络与插件整理 POD的通信:1.同一Pod中容器间通信,共享同一网络命名空间,使用locahost地址+容器端口进行通信2.同一Node中Pod间通信,让veth对的一端链接到root网络命名空间(宿主机的),另一端链接到Pod的网络命名空间,使用同一docker0网桥,使用docker0分配的ip+端口进行通信3.不同Node中 Pod间通信,使用第三方插件如Flannel,Calico进行通信。docker0/cni是虚拟网桥,作用于同一物理子网中,查询通过转发表(mac表)mac地址进行通信,是二层网络设备,如二层 阅读详情

相关推荐

Kubernetes网络原理剖析

如果说Kubernetes这座房子是由一个个Pod堆积而成,那Kubernetes的网络就是给这座房子注入了灵魂,通过它可以驱动这座房子里的所有Pod,让其保持强大的灵活性,从而保证Kubernetes这座房子不会倒下,为了方便描述,下面统一叫k8s。我们知道Pod是k8s的最小调度单位,而容器就是k8s里一个一个的进程,而这些进程之间又免不了要进行通信,这就是k8s网络要解决的问题。多数情况下,我们讲到k8s的网络都不自觉会把容器考虑进来,这是因为到目前为止k8s主要还是以Docker为主的容器来管理进程

程序员班吉 484

理解flannel的三种容器网络方案原理

本文主要介绍flannel在k8s网络中作为网络插件通过UDP、VXLAN、HOST-GATEWAY三种模式来解决容器跨主机网络通信的,并通过手动实现这三种模式深入理解其原理。在Flannel的UDP模式中,每个节点都会启动一个UDP服务器,用于监听来自其他节点的数据包。当一个容器向另一个容器发送数据包时,它会将数据包发送到目标容器的IP地址和端口号。Flannel会将该数据包封装在一个UDP数据包中,并将其发送到目标节点的UDP服务器。目标节点的UDP服务器会解析该数据包,并将其传递给目标容器。

Crazy博客 2441

kubernetes(k8s)二进制部署——flannel网络

flannel前言一、Flannel简介二、Flannel原理三、Flannel的作用四、模拟实验4.1 master配置4.2 node节点操作 前言 此文接着上篇博客kubernetes(k8s)二进制部署——etcd部署继续学习k8s 当一个k8s集群创建好后一般会存在三种IP,分别是:Pod IP、Node IP、Cluster IP 这些IP可以理解为简单的套娃关系,即其中一个Cluster IP之下包含多个Node IP,而一个Node IP之下又包含多个Pod IP,同一个Pod包含多个容器(

weixin_51613313的博客 1124

Kubernetes容器网络(一):Flannel网络原理

前言 本文主要分享Flannel如何解决跨主机容器之间通信问题的,如果你对主机内容器之间通信流程还不了解,建议先看下这篇文章:Docker网络原理 1、前置网络知识 1)、tun/tap设备 tun/tap设备在虚拟机的组网过程中起到作用。tun表示虚拟的是点对点设备,tap表示虚拟的是以太网设备,这两种设备针对网络包实施不同的封装 tun/tap设备到底是什么?从Linux文件系统的角度看,它是用户可以用文件句柄操作的字符设备;从网络虚拟化角度看,它是虚拟网卡,一端连着网络协议栈,另一端连着用户态程序 t

hxt的博客 8209

wireshark支持flannel报文解析

wireshark支持flannel报文,支持8285端口解析。支持的wireshark版本为1.12.13 兼容https://download.youkuaiyun.com/download/xxb249/10512541

三极管NPN与PNP的工作原理及快速识别技巧

本文深入浅出地解析了三极管NPN与PNP的核心工作原理。通过“水龙头”比喻,阐明其以小电流控制大电流的放大与开关本质。文章重点对比了NPN与PNP在电流方向、电位关系和控制逻辑上的根本区别,并提供了快速识别技巧与实用的选型、应用指南,帮助电子爱好者与工程师快速掌握这两种基础元件的关键知识。

neovim7hacker的博客 454

k8s与flannel网络原理

我们这里假设flannel使用VXLAN协议。每台主机都安装有flannel。k8s定义的flannel网络为10.0.0.0/16,各主机的flannel从这个网络申请一个子网。pod1所在的主机的flannel子网为10.0.14.1/24,pod2所在主机的flannel子网为10.0.5.1/24。每台主机有cni0和flannel.1虚拟网卡。cni0为在同一主机pod共用的网桥,当ku...

newbei5862的博客 1330

Python量化投资入门教程:从零构建你的第一个交易策略

量化投资教程以数学模型和计算机程序实现超额收益,选用Python工具链完成数据获取、策略构建及回测。通过移动平均线交叉策略示例,展示数据预处理、信号生成、收益计算及可视化全流程,结合收益率、最大回撤和夏普比率评估策略,并建议参数优化与策略融合提升稳健性。

ylmx5201314的博客 2456

深入 K8s 网络原理(一)- Flannel VXLAN 模式分析

Pod-to-Pod通信(同节点 or 跨节点),以 Flannel VXLAN 模式为例;通信,以 iptables 实现为例;Ingress原理,以 NGINX Ingress Controller 实现为例;其他:(到时候看心情)Flannel host-gw 模式,Calico,……今天先介绍下 Flannel 实现 Pod 跨节点通信的原理。在 minikube 环境中,Flannel 会被默认部署到 kube-flannel namespace 下。},

sdgfafg_25的博客 1345

大津法(OTSU)点云强度信息分割

大津法(OTSU)是一种灰度图像自适应的阈值分割方法,大津法根据图像的灰度分布,将图像分成背景和前景两部分,前景就是需要按照阈值分割出来的部分。由于点云的强度信息的特性,也可以利用此方法进行分类,但需要保证信息干扰较少,例如道路标线分割等场景较为适用。

qq_48694523的博客 965

基于STM32设计的智能门锁(微信小程序+手机APP等多种方式开锁)(188)

当前智能门锁项目是基于STM32微控制器、ESP8266-WIFI模块、OLED显示屏、指纹模块、蓝牙模块、门禁刷卡模块、烟雾检测模块、火光检测模块、温湿度检测模块等硬件设备开发的一种智能门锁系统

1万+

12、Kubernetes中KubeProxy实现之iptables和ipvs

iptables和ipvs其实都是依赖的一个共同的Linux内核模块:Netfilter。Netfilter是Linux 2.4.x引入的一个子系统,它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪成为了可能。Netfilter的架构就是在整个网络流程的若干位置放置了一些检测点(HOOK),而在每个检测点上登记了一些处理函数进行处理。

weixiaohuai的博客 2072

RK3568平台开发系列讲解(DMA篇)DMA engine使用

DMA传输属于异步传输,在启动传输之前,slave driver需要将此次传输的一些信息(例如src/dst的buffer、传输的方向等)提交给dma engine(本质上是dma controller driver),dma engine确认okay后,返回一个描述符(由struct dma_async_tx_descriptor抽象)。DMA_PREP_PQ_DISABLE_P、DMA_PREP_PQ_DISABLE_Q、DMA_PREP_CONTINUE,PQ有关的操作,TODO。

内核笔记 1723

带你玩转kubernetes-k8s(第48篇:深入分析k8s网络原理[开源的网络组件Flannel])

Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平网络空间中。这在GCE里面是现成的网络模型,Kubernetes假定这个网络也存在。而在私有云里搭建Kubernetes集群,就不能假定这种网络已经存在了。我们需要自己实现这个网络假设,将不同节点上的Docker容器之间的相互访问先打通,然后运行Kubernetes。 目前已经有多个开源组件支持容器网络模...

坚持的道路注定孤独 1525

[Python图像处理] 十九.图像分割之基于K-Means聚类的区域分割

前面的文章讲解了图像锐化和边缘提取技术,该篇文章将开始围绕图像分割进行讲解。图像分割就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。 本篇文章主要讲解基于理论的图像分割方法,通过K-Means聚类算法实现图像分割或颜色分层处理。基础性文章,希望对你有所帮助。 1.K-Means原理 2.K-Means聚类分割灰度图像 3.K-Means聚类对比分割彩色图像

杨秀璋的专栏 4万+

微信小程序 - [wxapplib]] backgroundfetch privacy fail {“errno”:101,“errMsg”:“private_getBackgroundFetchDa

微信小程序报错之backgroundfetch privacy fail,微信小程序报错WAServiceMainContext.js:1 [wxapplib]] backgroundfetch privacy fail {“errno“:101,怎么解决?问题出现:调用wx.chooseMessageFile报错(开发者工具中正常)用户隐私协议中未声明小程序使用此功能,安卓真机调试报错:backgroundfetch privacy fail ,怎么解决?微信小程序[wxapplib]] backgrou

🏆 前端领域优质创作者 1万+

k8s网络插件之——flannel 和 calico的网络原理

原文出处:无限飞翔 » 白话 flannel 和 calico 网络原理 概括 容器虚拟化网络方案,总体分为2种截然不同的发展路线: 基于隧道 基于路由 下面分别说一下这两种思路的原理,以及和flannel、calico的关系。 一 标题基于隧道 隧道方案最具普适性,在任何网络环境下都可以正常工作,这与它的原理密不可分。 最常见的隧道方案是flannel vxlan模式,以及calico的ip...

aspu O_O的博客 1775

YOLOv13涨点改进| CVPR 2026 |独家创新首发、主干改进篇 |利用RIS-PiDiNet主干让YOLOv13更加强大!适合遥感目标检测、小目标检测、旋转目标检测,变化检测,图像分割涨点

🔥本文提出了一种改进的RIS-PiDiNet主干网络,通过引入几何先验构建几何一致性检测器,显著提升了模型在任意方向、结构规则目标场景下的检测性能。包含两个核心模块:S-PDC利用极谐变换的谐波核建模目标结构对称性,RIS-PDC通过SO(2)群平均实现旋转不变性。网络采用基于RIS-block的主干结构并融合轻量级LBP特征,增强了细粒度结构表达能力。实验表明,该方法特别适用于遥感和复杂几何分布场景,能有效提升目标检测的鲁棒性和精度。文章还详细介绍了如何将RIS-PiDiNet集成到YOLOv13框架

Ai缝合怪、助力小伙伴高效发论文 90

docker和k8s网络模型复盘

Docker K8S网络模型复盘网络模式简介常见网络模型docker网络模式默认模式Bridge详解Kubernetes网络通信原理Flannel NetWork原理: 网络模式简介 Docker和k8s跟着老师学了一遍,容器化技术及其编排如此强大,最近让我想不通的是docker及k8s的网络通信是如何实现的,无论是虚拟机还是物理机都有自己的ip,网卡,虚拟网卡等等,然而容器也有自己的ip地址,到...

sinat_38247294的博客 602

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

需求导向的K8S网络原理分析:Kube-proxy、Flannel、Calico的地位和作用

一文讲清K8S网络原理

weixin_43466027的博客 1650

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Kubernetes 的网络原理 (七)---开源的网络组件flannel及calico

一 Flannel组件 1.1 flannel介绍 Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平网络空间中。若需要实现这个网络假设,需要实现不同节点上的Docker容器之间的互相访问,然后运行Kubernetes。目前已经有多个开源组件支持容器网络模型。如Flannel、Open vSwitch、直接路由和Calico。 Flannel之所以可以搭建Kubernetes依赖的底层网络,是因为它能实现以下两点。 它能协助Kubernetes,给每一个Node上的Doc

会哭的雨@的博客 1295

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Flannel:简化 Kubernetes 网络的高效解决方案

Flannel 是一个简单、稳定的 CNI 插件,适合中小规模的 Kubernetes 集群,特别是在网络性能要求不高且团队中网络相关维护人员较少的情况下。Flannel 以低维护成本和易用性著称,是一个非常适合中小企业和初学者的网络解决方案。

weixin_44867889的博客 1386

k8s集群网络(1)-简介

在以前系列文章中我们以学习为目的介绍了二进制手动安装k8s集群,这里也是一个系列文章,同样以学习为目的,我们介绍k8s集群网络。对于网络基本涉及两个方面,一是到各个服务的网络间负载均衡,...

weixin_46073333的博客 221

k8s-flannel容器集群网络

k8s-flannel容器集群网络一、Flannel容器集群网络原理二、flannel容器集群网络配置 一、Flannel容器集群网络原理 Overlay Network:覆盖网络,在基础网络上叠加的一种虚拟网络技术模式,该网络中的主机通过虚拟链路连接起来 VXLAN:将源数据包封装到UDP中,并使用基础网络的IP/MAC作外层报文头进行封装,然后再以太网上传输,到达目的地后由隧道端点解封并将数据转发到目标地址 Flannel:是Overlay网络的一种,也是将源数据包封装在另一种网络包里进行路由转发和通

weixin_50355475的博客 481
上一篇: Kubernetes-在Kubernetes中部署Tensorflow集群
下一篇: Kubernetes-使用kubeadmin安装部署
Aaron.com
博客等级 码龄17年 25粉丝 39原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值