k8s学习笔记二:pod基础概念和k8s网络通讯方式

252 阅读4分钟

pod 概念

一. pod 的分类:

自主式pod:没有控制器管理的pod。挂掉不会重启。

控制器pod:受控制器管理的pod。

二. pod内网络通讯方式

pod内一定有一个容器 pause。一个pod的多个容器会共用pause的网络栈和存储卷。

因此容器之间可以用localhost互相访问,端口不能冲突。

image.png (图片:php-fpm容器和nginx容器在同个pod内共享pause的网络栈和存储卷)

三. 控制器的类别

3.1. ReplicatonController & ReplicaSet & Deployment

3.1.1.区别

image.png

3.1.2. Deployment实现 rolling-upadte滚动更新的机制

(1)v1版本:deployment创建RS(ReplicaSet),由RS来创建管理pod

image.png

(2)滚动更新到v2版本:deployment创建一个新的RS。新的RS创建一个新的v2版本的pod后,旧的RS删除一个v1版本的pod。以此类推,直到所有pod都升级。

image.png

(3)回滚:更新完成后,旧的RS不会消失,而是被停用。如果回滚,该RS会重新启用,上面的过程会反过来执行一次。

3.2. HPA (HorizontalPodAutoScale)

image.png

3.3.StatefullSet (为了解决有状态服务的问题)

image.png

3.4. DaemonSet

image.png

之所以说是一些node上运行pod副本,是因为我们可以在node上打污点,这样就不会在其上运行pod副本。

3.5. Job & Cron Job

image.png

相比于linux自带的cron功能,可以做到:1.pod是可以重复利用的;2.linux自带的cron,在脚本异常退出时不会再次执行,而Job可以。

四. 服务发现

image.png

通过Service来访问其下的pod。这样的好处之一是,pod重启时,ip、端口改变也没有关系。因为都是Service与其交互的。

一个例子如下:

image.png

(1)mysql通过statefullSet控制,可以有稳定的hostName

(2)php-fpm的3个pod,可以由一个deployment管理,维持固定的副本数量

(3)缓冲服务 Squid通过Service来与php-fpm交互

(4)外部服务通过Service访问Squid。图里的nodeport代表其暴露方式

k8s的网络通讯方式

一. k8s 的网络模型

image.png

如果我们要搭建k8s集群,就需要先实现扁平的网络空间,所以的pod都可以直接通过ip到达其他的pod。目前很多三方组件可以帮助我们实现这个,比如Flannel。

二. Flannel

image.png

要实现一个扁平化的网络:

  1. 容器之间ip不能冲突 这点可以通过docker的配置解决,修改docker0网桥的分配网段,可以避免ip冲突

  2. 容器之间必须要能够扁平化地通信:可以借助Flannel实现

image.png 如图是一个Flannel实现的网络解决方案,具体如下: (1)共两台机器,192.168.66.11 和192.168.66.12

(2)共4个pod:Webapps1,Webapps2,Webapps1、3,Backend

(3)Flanneld是一个守护进程,用于转发、接收数据包。这个进程启动之后,会开启一个网桥Flannel0,这个网桥会接收、转发Docker0网桥的数据报文。可以理解为一个钩子函数,会强行获取数据报文。

(4)Docker0会分配ip给对应的pod上。

(5)同一台机器上的pod进行访问:通过Docker0的网桥进行转发,实现访问的。

(6)难点在于:跨主机、根据ip就能实现通信:例如(source)10.1.15.2想和(dest)10.1.20.3通信,过程如下:

第一步:数据包传到Docker0,(source)10.1.15.2而(dest)10.1.20.3

第二步:会有一个钩子函数,将其转到Flannel0。Flanneld进程察觉到数据包,会从etcd中查找路由表,发现(dest)10.1.20.3在主机192.168.66.12 上。

第三步:Flanneld进行数据包转发,封装信息如图右上角所示:outerIp写了真实主机的source ip和dest ip(图中的dest ip应该为192.168.66.12)。而innerIp则写的是pod的source ip和dest ip。转发时,端口正是192.168.66.12主机上Flanneld进程监听的端口。

第四步:数据包传递到192.168.66.12主机后,由Flaaneld拆封,传递给Flannel0,再传给Docker0,再传给对应的pod。注意Docker0是看不到OuterIp这一层的信息的,它只能看到InnerIp层的信息。

三. Flannel与etcd

image.png 其中的pod节点路由表,可以将pod和物理主机ip对应起来。

四.k8s通信模式总结:

1.同个pod的多个容器,共享pause容器的网络栈,因此可以通过localhost进行互相访问。

2.pod1 到 pod2:

image.png

3.pod和servcie之间的通讯,除了通过各节点的iptables规则实现,还支持通过lvs的机制进行转发(洗效率更高)。

4.pod到外网

image.png

5.外网访问pod:通过service访问pod,方式必须是nodeport