likes
comments
collection
share

Kubernetes 系统化学习之 POD原理篇(二)

作者站长头像
站长
· 阅读数 25

Kubernetes 系统化学习之 基本概念篇(一) Kubernetes 系统化学习之 POD原理篇(二) Kubernetes 系统化学习之 资源清单篇(三) Kubernetes 系统化学习之 服务发现篇(四) Kubernetes 系统化学习之 持久存储篇(五) Kubernetes 系统化学习之 集群调度篇(六) Kubernetes 系统化学习之 集群安全篇(七)

1. Kubernets 概览回顾

Kubernetes 系统化学习之 POD原理篇(二)

Pod、Service、Volume 和 Namespace 是 Kubernetes 集群中四大基本对象,它们能够表示系统中部署的应用、工作负载、网络和磁盘资源,共同定义了集群的状态。Kubernetes 中很多其他的资源其实只对这些基本的对象进行了组合。

  • Pod -> 集群中的基本单元
  • Service -> 解决如何访问 Pod 里面服务的问题
  • Volume -> 集群中的存储卷
  • Namespace -> 命名空间为集群提供虚拟的隔离作用

Kubernetes 有许多的技术概念,同时对应很多 API 对象,其中最重要的也是最基础的是 Pod 对象。Pod 是在 Kubernetes 集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

2. POD 基础概念

  • 在 Kubernetes 中, Pods 是能够创建、调度、和管理的最小部署单元,是一组容器的集合,而不是单独的应用容器。
  • 同一个 Pod 里的容器共享同一个网络命名空间, IP 地址及端口空间。
  • 从生命周期来说, Pod 是短暂的而不是长久的应用。 Pods 被调度到节点,保持在这个节点上直到被销毁。

Kubernetes 系统化学习之 POD原理篇(二)

Pod 可简单地理解为是一组、一个或多个容器,具有共享存储/网络及如何运行容器的规范。 Pod 包含一个或多个相对紧密耦合的应用程序容器,处于同一个 Pod 中的容器共享同样的存储空间(Volume,卷或存储卷)、IP 地址和 Port 端口,容器之间使用 localhost:port 相互访问。

根据 Docker 的构造,Pod 可被建模为一组具有共享命令空间、卷、IP 地址和 Port 端口的 Docker 容器。 Pod 包含的容器最好是一个容器只运行一个进程。每个 Pod 包含一个 pause 容器,pause 容器是 Pod 的父容器,它主要负责僵尸进程的回收管理。 Kubernetes 为每个 Pod 都分配一个唯一的 IP 地址,这样就可以保证应用程序使用同一端口,避免了发生冲突的问题。

3. POD 内部原理

Pod 实际上也相当于是一个独立的容器(虚拟机),而这个 Pod 容器内部封装的是由 Docker 引擎所创建的容器,可以理解为 Pod 就是一个虚拟化分组,Pod 内存可以存储一个或者多个容器。

Pod 内部容器

Infrastructure Container(基础容器): 用户不可见,无需感知,维护整个Pod网络空间。

Containers(业务容器): 并行启动,启动成功后一直Running。

InitContainers(初始化容器): 一般用于服务等待处理以及注册 Pod 信息等;先于业务容器开始执行,顺序执行,执行成功退出( exit 0),全部执行成功后开始启动业务容器。

Kubernetes 系统化学习之 POD原理篇(二)

为什么 Kubernetes 会设计出一个全新的 Pod 概念,并且有这样特殊的结构?主要是因为,使用 Pause 容器作为 Pod 根容器,以它的状态代表整个容器组的状态;其次,Pod 里的多个业务容器共享 Pause 容器的 IP 地址,共享 Pause 容器挂接的 Volume 资源。

Pod 核心原理

Pod 底层核心原理 = 数据存储 + 网络通讯

Kubernetes 系统化学习之 POD原理篇(二)

共享存储资源

可以为一个 Pod 指定多个共享的 Volume 资源。Pod 中的所有容器都可以访问共享的 volume 资源。Volume 也可以用来持久化 Pod 中的存储资源,以防容器重启后文件丢失。

共享网络资源

每个 Pod 都会被分配一个唯一的 IP 地址。Pod 中的所有容器共享网络空间,包括 IP 地址和端口。Pod 内部的容器可以使用 localhost 互相通信。Pod 中的容器与外界通信时,必须分配共享网络资源,例如使用宿主机的端口映射。

Pod 的网络通信

Pod 是由多个 Docker 容器以 joined 容器方式构成的,多个容器共享由名为 pause 的容器创建的网络命名空间,容器内的进程彼此间通过环回接口实现数据通信。环回接口不依赖链路层和物理层协议,一旦传输层检测到目的端地址是环回接口地址,数据报文离开网络层时会被返回给本机的端口应用。这种模式传输效率较高,非常适用于容器间进程的频繁通信。

Kubernetes 系统化学习之 POD原理篇(二)

同节点的 Pod 间数据通信

每个 Pod 拥有唯一的 IP 和彼此隔离的网络命名空间,在 Linux 系统中,Pod 间跨网络命名空间的数据通信是通过 Veth 设备实现的。Veth 设备工作在链路层,总是成对出现,也被称为 Veth-pair 设备

Kubernetes 系统化学习之 POD原理篇(二)

在网络插件是 Flannel 的虚拟网络结构中,Flannel 在被 Kubernetes 触发、接收到相关 Pod 参数时,会为 Pod 创建 Veth 设备并分配 IP,Veth 设备一端是 Pod 的 eth0 接口,一端是 Node 节点中网络空间名为 default 的 Veth 虚拟接口。

跨主机的 Pod 间数据通信

由 CoreOS 使用 Go 语言开发的 Flannel 实现了一种基于 Vxlan(Virtual eXtensible Local Area Network)封装的覆盖网络(Overlay Network),将 TCP 数据封装在另一种网络包中进行路由转发和通信。

Kubernetes 系统化学习之 POD原理篇(二)

Vxlan 协议是一种隧道协议,基于 UDP 协议传输数据。Flannel 的 Vxlan 虚拟网络比较简单,在每个 Kubernetes 的 Node 上只有 1 个 VTEP(Vxlan Tunnel Endpoint)设备(默认为 flannel.1)。Kubernetes 集群中整个 Flannel 网络默认配置网段为 10.244.0.0/16,每个节点都分配了唯一的 24 位子网,Flannel 在 Kubernetes 集群中类似于传统网络中的一个三层交换设备,每个 Node 节点的桥接设备通过 VTEP 设备接口互联,使运行在不同 Node 节点中不同子网 IP 的容器实现跨 Node 互通。

4. POD 管理类型

Pod 存在多种不同的创建类型来满足不一样的用途。

ReplicationController(RC)

官方建议使用 RS 来代替 RC,完成部署服务的工作!

ReplicationController 简称为 RC,同时也是 kubectl 命令的快捷方式简写使用方式,是用来确保容器应用的副本数始终保持在用户定义的副本数。如果有容器异常退出的话,其会自动创建新的 Pod 来替代,而如果有异常多出来的容器也会被自动回收掉的。

当 pod 数量过多时,RC 会终止多余的 pod;当 pod 数量太少时,RC 将会启动新的 pod。与手动创建的 pod 不同之处在于,由 RC 创建的 pod 在失败、被删除或被终止时会被自动替换。例如,在中断性维护之后,创建的 pod 会在节点上会重新创建。因此,即使应用程序只需要一个 pod,也应该使用 RC 来创建 Pod。对应 RC 我们可以类似理解为进程管理器,但是 RC 不是监控单个节点上的单个进程,而是监控跨多个节点的多个 pod。

ReplicaSet(RS)

官方建议使用 RS 来代替 RC,完成部署服务的工作!

官方在新版本的 Kubernetes 中建议使用 RS 来取代 RC,而且 RS 跟 RC 的唯一区别是在选择器的支持上。其中 RS 支持集集合 (selector) 的选择器,其就意味着其支持通过标签进行 Pod 的选择,而 RC 仅支持基于相等选择器。

RS 确保任何时间都有指定数量的 Pod 副本在运行,而且大多数支持 RC 的 kubectl 命令也支持 RS,但是 rolling-update 这个命令是个例外。如果你需要使用滚动更新功能,请考虑使用 Deployment 来创建 Pod。

虽然 RS 可以独立的使用和创建, 然而 Deployment 是一个更高级的概念,它管理 RS 并向 Pod 提供声明式的更新以及许多其他有用的功能,用作协调 Pod 创建、删除和更新的机制。当你使用 Deployment 的时候,不必担心还要管理它们创建的 RS 控制器。因此,建议使用 Deployment 而不是直接使用 ReplicaSet,除非你需要自定义更新业务流程或根本不需要更新。

Deployment(推荐)

官方推荐的 Pod 部署方式,所以以后创建 Pod 的话,优先选择!

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义的方法,用来替代以前的 RC 来方便的管理应用。而定义方式分为,命令式(RS)和声明式(Deployment)两种,前者侧重于考虑如何实现,而后者侧重于定义想要什么。

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

Kubernetes 系统化学习之 POD原理篇(二)

DaemonSet

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

使用 DaemonSet 的典型场景就是,在每个节点运行日志收集、运行监控系统、运行集群存储等服务,只要新加进来的节点都需要运行该服务(Nginx 就很适合)。

一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

Kubernetes 系统化学习之 POD原理篇(二)

StatefulSet

StatefulSet 是用来管理有状态应用的工作负载 API 对象。

在 k8s 中,ReplicaSet 和 Deployment 主要是用于处理无状态的服务,无状态服务的需求往往非常简单并且轻量,每一个无状态节点存储的数据在重启之后就会被删除。但是如果我们需要保留,那该怎么办呢?所以为了满足有状态的服务这一特殊需求,StatefulSet 就是 Kubernetes 为了运行有状态服务引入的资源,例如 MySQL 等。

产生 StatefulSet 的用途主要是用于管理有状态应用的工作负载对象,与 ReplicaSet 和 Deployment 这两个对象不同,StatefulSet 不仅能管理 Pod 的对象,还它能够保证这些 Pod 的顺序性和唯一性。以及,其会为每个 Pod 设置一个单独的持久标识 ID 号,这些用于标识序列的标识符在发生调度时也不会丢失,即无论怎么调度,每个 Pod 都有一个永久不变的 ID。

Kubernetes 系统化学习之 POD原理篇(二)

StatefulSets 最为重要的功能就是稳定,稳定意味着 Pod 调度或重调度的整个过程是有持久性的。如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 Deployment 或者 ReplicaSet 可能更适用于您的无状态应用部署需要。

  • 稳定的、唯一的网络标识符
  • 稳定的、持久的存储
  • 有序的、优雅的部署和缩放
  • 有序的、自动的滚动更新

需要额外注意的是,删除或者收缩 StatefulSet 并不会删除它关联的存储卷,这样做是为了保证数据安全。而且,StatefulSet 当前需要无头服务来负责 Pod 的网络标识,所以需要事先创建好。

Job / Cront Job

Job 负责批处理任务,仅执行一次的任务,它保证批处理任务的一个或者多个 Pod 成功结束,才会返回成功。 Cront Job 管理是基于时间的 Job,即在给定时间点只运行一次,且周期行的在给定时间点运行特定任务。

Job 会创建一个或者多个 Pods,并确保指定数量的 Pods 成功终止。随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。当数量达到指定的成功个数阈值时,任务结束。删除 Job 的操作会清除所创建的全部 Pods。当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。

CronJob 对于创建周期性的、反复重复的任务很有用,例如执行数据备份或者发送邮件。CronJobs 也可以用来计划在指定时间来执行的独立任务,例如计划当集群看起来很空闲时 执行某个 Job。

Kubernetes 系统化学习之 基本概念篇(一) Kubernetes 系统化学习之 POD原理篇(二) Kubernetes 系统化学习之 资源清单篇(三) Kubernetes 系统化学习之 服务发现篇(四) Kubernetes 系统化学习之 持久存储篇(五) Kubernetes 系统化学习之 集群调度篇(六) Kubernetes 系统化学习之 集群安全篇(七)