theboyaply

学,就硬学!

  • Home
  • Archives
  • Java
  • Maven
  • Docker
  • Kubernetes
  • JavaScript
  • ES6
  • Vue
  • 踩坑记录
  • noted

  • 搜索
element ui vue wsimport webservice npm mysql redis node nginx nfs ftp es6 开发工具 vscode 前端 javascript springboot 常见问题 tomcat oracle jenkins maven k8s Linux gitlab docker java

Pod、Pod 控制器及网络通讯

发表于 2020-03-17 | 分类于 Kubernetes | 0 | 阅读次数 429
  • Pod
  • Pod 控制器
    • ReplicationController
    • ReplicaSet
    • Deployment
    • HAP
    • StatefulSet
    • DaemonSet
    • Job
    • 服务发现
  • 网络通讯方式

Pod

  • 自主式 Pod

    即不被控制器管理的 Pod。因为不被控制器管理,所以这种 Pod 在停止后无法自动重启或者自动创建新的 Pod。

  • 控制器管理的 Pod

网络共享,只要定义了一个 Pod,那么该 Pod 会自带一个 pause 容器,pause 容器专门用来共享网络。也就是说,该 Pod 里面的所有容器都基于 pause 容器进行网络通讯。容器之间可以直接使用 localhost:端口号 来进行通信,因此同一个 Pod 里面的容器的端口号不能相同。

数据卷共享,Pod 里除了网络共享之外,所有的容器也共享一个数据卷。

pod共享网络及数据卷

Pod 控制器

ReplicationController

ReplicationController(RC) 用来确保容器的副本数始终维持在用户定义的副本数,也就是说,如果有容器异常退出,会自动创建新的 Pod 来替代。同理,如果容器多于期望的副本数,也会自动回收。

在新版本的的 k8s 中建议使用 ReplicaSet 来代替 ReplicationController。

ReplicaSet

ReplicaSet(RS) 与 ReplicationController 没有本质不同,只是名称不一样。但是 ReplicaSet 还支持集合式的 selector。

集合式的 selector:Pod 在被创建的时候,可以打上标签来标记该 Pod,RS 支持同时管理多个同一标签的 Pod。

虽然 RS 可以独立使用,但一般还是建议使用 Deployment 来自动管理 RS,这样就无需担心跟其它机制的不兼容问题(比如 RS 不支持 rolling-update ,但 Deployment 支持)。

Deployment

因为 Deployment 不支持 Pod 的创建,所以需要结合 RS 来创建 Pod。

Deployment 为 RS 和 Pod 提供了一个声明式定义(declarative)方法,用来替代以前的 RC 来方便管理应用。典型的应用场景包括:

  • 定义 Deployment 来创建 Pod 和 RS
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续 Deployment

滚动更新:

创建一个 Deployment ,Deployment 会创建一个 RS,让 RS 来创建 Pod,该 Pod 里运行的是 v1 版本的容器(假设运行了 2 个容器)。

现在进行版本更新,使用 Deployment 再创建一个 RS,同理让 RS 来创建 Pod,但是这次的 Pod 里面运行的是 v2 版本的容器。当 v2 版本的容器启动完成之后,再删除 v1 版本的容器。

需要注意是的, v2 版本的容器创建的时候,并不是一次创建两个。而是先创建一个 v2 版本的容器,该容器启动完成之后,删除一个 v1 版本的容器。然后再创建一个 v2 版本的容器,启动完成之后再删除一个 v1 版本的容器。即:创建一个 v2 删除一个 v1。

回滚:

如果更新完成之后,发现 v2 版本存在问题,可以进行回滚操作。

滚动更新成功之后,原本的 RS 并不会被删除,进行回滚的时候,会重新启动这个 RS,创建其中的容器,其原理和更新时一样,先创建一个 v1 版本的容器,再删除一个 v2 版本的容器。

deployment滚动更新

HAP

HAP(Horizontal Pod Autoscaling)仅适用于 Deployment 和 ReplicaSet,在 v1 版本中仅支持根据 Pod 的 CPU 利用率扩缩容,在 vlalpha 版本中,支持根据内存和用户自定义的 metric 扩缩容。

StatefulSet

StatefulSet 是为了解决有状态服务的问题(对应 Deployment 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:

  • 稳定的持久化存储,即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
  • 稳定的网络标志,即 Pod 冲i性能调度后其 PodName 和 HostName 不变,基于 Headless Service(即没有 Cluster IP 的 Service)来实现
  • 有序部署,有序扩展,即 Pod 是有顺寻的,在部署或者扩展的时候要依据定义的顺序一次进行(即从 0 到 N-1,在下一个 Pod 运行之前所有的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现
  • 有序收缩,有序删除(即从 N-1 到 0)

DaemonSet

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

DaemonSet 的一些典型用法:

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

Job

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

Cronjob 是基于时间管理的 Job,即:

  • 在给定时间运行一次
  • 周期性的在给定时间运行

服务发现

k8s 的 Pod 之间可以直接通过 IP 来互相通信。但是由于容器重启之后 IP 会变,所以使用 IP 直接通信的方式不常见。

这时可以使用 service(SVC) 来管理一组相同标签的 Pod。通过 serivce 对外开放的地址来访问到该 service 下的容器。

服务发现示例图

上图中的 php-fpm 使用 service-php-fpm 代理,squid 要访问到 php-fpm 只需要访问 service-php-fpm 提供的地址即可。

网络通讯方式

Kubernetes 的网络模型假定了所有 Pod 都在一个可以直接连通的扁平的网络空间中(即 Pod 间可以直接通过 IP 互相通信),这在 GCE(Google Compute Engine)里面是现成的网络模型,Kubernetes 假定这个网络己经存在。 而在私有云里搭建 Kubernetes 集群,就不能假定这个网络己经存在了。我们需要自己实现这个网络假设,将不同节点上的 Docker 容器之间的互相访问先打通,然后运行 Kubernetes。

  • 同一个 Pod 内部通讯

    同一个 Pod 共享同一个网络命名空间(pause容器),共享同一个 Linux 协议栈。

  • Pod1 至 Pod2(overlay network)

    • Pod1 与 Pod2 不在同一台主机

      Pod 的地址是与 docker0 在同一个网段的,但 docker0 网段与宿主机网卡是两个完 全不同的 IP 网段,并且不同 Node 之间的通信只能通过宿主机的物理网卡进行。将 Pod 的 IP 所在 Node 的 IP 关联起来,通过这个关联让 Pod 可以互相访问。

    • Pod1 与 Pod2 在同一台机器

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

  • Pod 至 Service 的网络

    默认使用 iptables 维护和转发。新版本中采用的是 lvs。

  • Pod 到外网

    Pod 向外网发送请求,査找路由表,转发数据包到宿主机的网卡,宿主网卡完成路由选择后,iptables 执行Masquerade,把源 IP 更改为宿主网卡的 IP,然后向外网服务器发送请求。

  • 外网访问 Pod

    直接访问 Pod 对应的 Service。

overlay network 实现方案 Flannel:

Flannel 是 CoreOS 团队针对 Kubernetes 设计的一个网络规划服务,简单来说,它的功能是 让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。而且它还能在这些 IP 地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内。

k8s-flannel转发数据包演示

上图中共有两台主机,同一主机内容器间通信只需要经过容器自己的网桥(Docker0)转发数据即可。

如果要跨主机通信,那么就需要将数据包封装,右边是数据包封装的格式,其中封装了两层地址信息,第一层是源主机地址及目的主机地址,第二层是源容器地址及目的容器地址。

-- end --

# k8s
k8s 基础组件
部署 k8s 集群
  • 文章目录
  • 站点概览
theboyaply

theboyaply

好记性不如烂笔头

184 日志
13 分类
27 标签
Github E-mail
Creative Commons
0%
© 2019 — 2023 theboyaply
由 Halo 强力驱动
|
主题 - NexT.Gemini
湘ICP备19009291号

湘公网安备 43312402001034号