【一】kubernetes学习笔记-Pod概念
阅读原文时间:2021年05月14日阅读:1

一、Pod 控制器类型

当一个 Pod 创建后,Pause 容器就会随着 Pod 启动,只要是有 Pod,Pause 容器就要被启动。
在同一个 Pod 里面的容器不能出现端口冲突,否则这个 Pod 可能会出现无法启动、无限重启。
一个 Pod 里面的容器数量是大于等于1。
Pod 里面的容器都是共享 Pause 的网络栈,在同一个 Pod 里即共享网络又共享存储卷。

Replication Controller 用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来代替;而如果异常多出来的容器也会自动回收。

在 K8s 新版本中,官方不再使用RC(Replication Controler),建议使用 RS(ReplicaSet)代替,因为RS支持集合式的 selector。

ReplicaSet 跟 Replication Controller 没有本质区别,只是名字不一样,并且 ReplicaSet 支持集合式的 selector。

支持集合式的 selector 作用:

在创建 Pod 的时候会为它打上标签(tag),也会为 Pod 里面的容器打上标签,当需要删除容器或者进行其他操作的时候,可以通过标签来进行相关操作。

RS 不支持滚动更新,但是 Deployment 支持滚动更新,RS 和 Deployment 建议一起使用的原因是 Deployment 不负责 Pod 创建,Deployment 需要创建 RS 来达到创建 Pod 的能力。

Deployment 结合 RS 使用,滚动更新:

Deployment 创建出来之后,它会去创建一个 RS,Deployment 再去负责创建对应 Pod;

当某一天需要版本更新,Deployment 会去新建一个RS-2版本,在RS-2下启动v2版本的第一个容器,则退出v1版本的第一个容器,以此类推…到达滚动更新状态。

回滚:

回滚的机制是因为 Deployment 在滚动更新之后,RS-1并没有删除,而是被停用状态,当执行回滚的时候,Deployment 就好启动旧版本的RS-1,到达一个回滚效果。

StatefulSet 是为了解决有状态服务的问题,有状态服务分为 MySQL、MongoDB 等,无状态服务分为 Nginx、Apache 等。

应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现;
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service 来实现;
  • 有序部署,有序扩展;
  • 有序收缩,有序删除。

DaemonSet 确保全部(或者一些)Node上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

使用 DaemonSet 的一些典型用法:

  • 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
  • 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
  • 在每个 Node 上运行监控 daemon,例如Prometheus Node Exporter。

Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。

Job 如果判断这个脚本不是正常退出,则重新执行一遍,直到正常退出为止,并且还可以设置正常退出次数,比如正常退出次数两次,才允许这个脚本执行成功。

二、服务发现

如果 Pod 之间没有相干性,是无法通过一个 Service 代理或者收集的。

Service收集的机制:

第一、比如是通一个 RC、RS、Deployment 创建的 Pod;

第二、或者拥有同一组标签,Service 通过标签来收集 Pod。

三、网络通信方式

同一个 Pod 共享同一个网络命名空间,共享同一个Linux协议栈,使用回环网卡(lo)通信。

Pod1 与 Pod2 不在同一台主机的情况:

Pod 的地址是与 docker0 在同一个网段的,但是 docker0 网段与宿主机网卡是两个完全不同的IP网段,并且不同 Node 之间的通信只能通过宿主机的物理网卡进行。

将 Pod 的 IP 和所在 Node 的IP关联起来,通过这个关联让 Pod 可以互相访问。

假设 Web APP2 需要访问 Backend:

源地址写自己的(10.1.15.2/24),目标地址写(10.1.20.3/24);

由于目标地址不是跟 Web app2 同一网段,所以发送数据包到网关(Docker0);

Docker0网关发送到 Flannel0,Flannel0 有一个路由表存储在 Etcd 中,根据路由表来进行转发;

Flannel0 将数据包转发到 Flanneld,因为 Flannel0 是 Flanneld 中的一个网桥;

到 Flanneld 之后,它会对该数据报文进行二次封装,请看上图右边数据封装结构;

此时数据包到了66.12这台机器上:

Flanneld 收到数据包后,解封数据包之后转发到 Flannel0 网桥中;

Flannel0 转发到 Docker0,Docker0 根据目标IP地址转发到 Backend 容器中;

因为 Docker0 只能看到第二层源IP地址和目标IP地址,第一层源IP地址和目标IP地址已经被砍掉了。

Pod1 与 Pod2 在同一台主机情况:

由 docker0 网桥直接转发请求到 Pod2,不需要经过 Flannel。

组件通讯示意图

节点网络:真实网络,就是节点主机的物理网卡;

Pod 网络:虚拟网络,所有的 Pod 之间通信都是通过该网络;

Service 网络:虚拟网络,通过 Service 网络访问后端Pod。

以上有不恰当或者讲得不对的地方,希望各位留言指正,谢谢!

站在巨人的肩膀上!