一.简介

我们都知道pod是k8s的最小单元,但pod有IP吗?pod中的所有容器都有IP吗?同一节点node的pod之间如何通信?不同节点node的pod之间如何通信?pod与service之间怎么通信?外部网络访问服务是如何与pod中的容器通信的?

什么是overlay技术?基于的overylay的vxlan又是什么?

vlan只有2^12=4096个,vxlan有2^24=16777216个
underlay是底层网络,完成互联互通。
overlay是一种大二层技术,在underlay的基础之上,使用隧道技术穿越底层的三层网络,
实现了二层网络在三层范围内的扩展。
vxlan是overlay的一种技术实现,通过Mac In UDP封装实现虚拟二层网络的方法。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

kubernetes网络基础_网络

实验基础环境

#版本查看,版本1.23.17
kubectl version
#节点查看,一个管理节点master三个node节点
kubectl get nodes -o wide
  • 1.
  • 2.
  • 3.
  • 4.

kubernetes网络基础_kubernetes_02

二.k8s如何通信

0.网络基础命令

#网卡查看,安装了docker环境的会看到docker0网卡,veth虚拟以太网卡,
ip add
#或
ip link
#路由查看,安装了docker环境的会看到,一台走docker0的路由,一条走服务器以太网卡eth的路由
ip route
#查看网桥信息,安装了docker环境和运行容器后,会看到连接到docker0的veth虚拟以太网卡都有哪些
brctl show
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

1.容器之间的通信

每个pod都有一个IP,同一pod中,无论有多少个容器,仅有一个容器有IP,这个容器是pause容器,也叫根容器,pod的IP与根容器的IP相同,其他容器都共享这个IP的,容器之间是通过localhost+port访问的。其实pod就可以当做一台服务器,容器当做服务,这样服务没有IP也很好理解。

#如容器1上访问容器2的web服务
curl http://localhost:80
#如容器1上访问容器3的mysql服务
telnet localhost 3306
  • 1.
  • 2.
  • 3.
  • 4.

2.pod之间的通信

在k8s集群中,pod之间可以互相访问,无论是否在同一个node节点。这样的话,同一个node节点内pod怎么分配IP的,在不同node节点上的pod又是怎么分配IP?无论是否在不在一个node节点上,IP肯定是不能一样的。

同一node节点中,不同的pod都拥有一个全局的IP地址,pod直接通过IP访问,实际上不同pod的veth都通过cni0网桥连接起来,通过cni0实现访问。

#通过deployment运行7个nginx副本
kubectl create deployment nginx  --image=nginx:1.17.1 --replicas=7
#查看每个pod的IP
kubectl get pods -o wide
#在有三个副本的主机上查看网桥,会看到三个虚拟以太网卡veth都指向cni0
brctl show
#查看路由
ip route
#查看IP
ip a
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

在初始化master节点时指定了--pod-network-cidr=10.100.0.0/16,通过以上命令,可以看到

不同node上的pod从10.100.0.0/16的分出3个子网
子网分别为10.100.1.0/24 10.100.2.0/24 10.100.2.0/24
网关分别为10.100.1.1 10.100.2.1 10.100.3.1
  • 1.
  • 2.
  • 3.

kubernetes网络基础_kubernetes_03

kubernetes网络基础_网络_04

不同node节点中,pod之间的访问,通过flanneld将其流量封装在UDP数据包中,路由到目的地,查看节点上的路由,到达不同node节点通过flannel.1转发。

kubernetes网络基础_kubernetes_05

整个流程为:容器中的应用将数据包通过pod的eth0的发送出去,然后数据包发送到容器对应的虚拟以太网接口veth,veth通过cni0相连接的(同一节点pod通信直接通过cni0通信了),数据包通过cni0发送到flannel.1,flannel的路由信息存在etcd中,flannel的代理服务flanned查找路由后,通过node节点的eth0发送出去,到达目的node节点后,在传输层交给flanned守护进程处理,数据被解封装后,发送给flannel.1,然后在发送给cni0,然后发送给对应的虚拟以太网接口veth,最后达到对应的pod。

kubernetes网络基础_网络_06

vxlan报文封装:

kubernetes网络基础_网络_07

3.pod和service之间的通信

在初始化master节点时指定了--service-cidr=10.200.0.0/16,通过以下命令可以看到ClusterIP,nginx服务名和端口。在任意node节点上都可以访问curl 10.200.204.237:80

#查看svc,看不到nginx服务
kubectl get svc -o wide
#创建一个服务service,类型为ClusterIP
kubectl expose deployment nginx --port=80 --type=ClusterIP
#再次查看svc
kubectl get svc -o wide
#任何node节点查看路由
iptables-save
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

kubernetes网络基础_kubernetes_08

kubernetes网络基础_kubernetes_09

ClusterIP是一个虚拟IP,其作用是将访问该服务的流程转发到与其绑定的endport(ip+port)上,pod与服务之间的通信是通过iptables的规则实现的。

4.外部网络访问服务是如何与pod中的容器通信

在初始化master节点时指定了--service-cidr=10.200.0.0/16,通过以下命令可以看到ClusterIP,nginx服务名和随机分配了一个NodePort端口号31356。在任意node节点上都可以访问curl nodeip:31356,或通过浏览器访问任意node节点的31356端口。

#删除nginx的service
kubectl delete service nginx
#创建一个服务service,类型为NodePort
kubectl expose deployment nginx --port=80 --type=NodePort
#查看svc
kubectl get svc -o wide
#任何node节点查看路由
iptables-save
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

kubernetes网络基础_kubernetes_10

kubernetes网络基础_网络_11

kubernetes网络基础_kubernetes_12

ClusterIP是一个虚拟IP,其作用是将访问该服务的流程转发到与其绑定的endport(ip+port)上,pod与服务之间的通信是通过iptables的规则实现的。