上一期我们讲到,Kubernetes作为容器编排平台的事实标准,重新定义了容器网络的元素和接口标准,形成了以下共识:
1. Kubernetes的容器资源分配单位是pod,一个pod中可以有多个容器,但对pod之外呈现为一个整体(一个IP地址);
2. Kubernetes的容器运行载体是node,一个node可以运行多个Pod。node有自己的操作系统(一般为Linux)。
我们用图来表示:
这个图似曾相识——
没错,是你是你就是你——
在《局域网SDN技术硬核内幕 5 虚拟化网络的实现》中,我们给出的这张经典组网图里,可以看出,在每台宿主机上运行了一个vSwitch (在KVM中默认是OVS,在vsphere中默认是VDS),vSwitch连接了宿主机上所有的虚拟机。
我们可以类比虚拟化场景,将Node类比为宿主机,Pod类比为VM:
在Kubernetes中,还有另一个重要的概念——Service。
Service对外提供的是一个名称,通过这个名称,可以访问一组pod对内部或对外部提供的服务。
假设P站的某应用,通过容器化部署,那么其架构如下图:
图中,Pornhub-Web,Pornhub-APP和Pornhub-db是三个Service,只有Pornhub-web对外提供服务,另外两个service对内提供服务,类似于虚机实现的web-app-db三层架构。
当然,实际部署中,app很可能拆成多个微服务,这个问题我们后续再谈。
Service有三种类型:
Nodeport,Loadbalancer和Ingress。
其中,Nodeport访问非常麻烦,一般不使用,
LoadBalancer本质上是基于NAT的负载均衡,可以通过软件或硬件实现。
Ingress是基于HTTP反向代理的负载均衡,也可以通过软件或硬件实现。
但无论怎么样实现Service,都需要面临一个问题:同一组Pod之间如何跨宿主机互联互通呢?
我们联想到在《容器网络硬核技术内幕 (3) 批判的武器和武器的批判》中学习的,在docker中,不同宿主机上的容器可以通过VXLAN互通。
在K8S中可以吗?
让我们做个实验。
以下图为例:
两个node的IP分别为192.168.65.112和192.168.65.116,
分别运行命令:
# ovs-vsctl add-port br1 vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.65.116
# ovs-vsctl add-port br1 vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.65.112
就可以实现两个node通过VXLAN互通:
问题来了,对于100台主机构成的kubernetes集群,配置VXLAN互通的工作量将达到100*99=9900的天量!
如果考虑到VLAN划分,这个量级还要再乘以一个100-1000的数量。
当然,使用Ansible等自动化工具可以实现部分的自动化,但对于IT基础架构与运维人员而言,需要的一定是图形化,自动化的配置方式。
因此,Kubernetes提供了CNI(Container Network Interface)接口,来自五湖四海的开发者们,可以通过CNI接口实现自动化的网络编排,也就是CNI插件。五湖四海的爱好容器技术和世界和平的人们,也因此结成了深厚的友谊。
目前,主流的CNI插件有Flannel、Calico、Weave、H3C SNA、OpenShift SDN等。
在后面的专题中,我们也将分析各个插件的实现和利弊。
请看下期。