Kubernetes 容器平台架构之道|社区征文

社区征文Kubernetes
1.Kubernetes 容器平台架构之道

a34bdb5819e6b1e6ae9ceb001cdbdb2d.png

Kubernetes 是一个开源容器编排平台,管理大规模分布式容器化软件应用,是云计算发展演进的一次彻底革命性的突破。Kubernetes 是谷歌的第三代容器管理系统,是 Borg 独特的控制器和 Omega 灵活的调度器的组合。Kubernetes 中的应用被打包成与环境完全分离的容器镜像,并且自动配置应用并维护跟踪资源分配。

****Kubernetes 是以应用为中心的技术架构与思想理念,向下屏蔽基础设施差异,实现底层基础资源统一调度及编排;向上通过容器镜像标准化应用,实现应用负载自动化部署;中间通过 Kubernetes 通用的编排能力,开放 API 以及自定义 CRD 扩展能力,打造云原生操作系统能力,形成云计算新界面;助力研发团队快速构建标准化、弹性高可靠、松耦合、易管理维护的应用系统,提升交付效率,降低运维复杂度。Kubernetes 在技术架构方面具备三个能力:

敏捷的弹性伸缩能力:不同于虚拟机分钟级的弹性伸缩响应,容器应用可实现秒级甚至毫秒级的弹性伸缩响应;

智能的服务故障自愈能力:容器应用具有极强的自愈能力,可实现应用故障的自动摘除与重构;

大规模的复制分发能力:容器应用标准化的交付制品,可实现跨平台、跨区域,云边一体规模化复制分发部署能力。

1.1.Kubernetes 整体架构

f7c5403df0c605a8fe9444ec38c1d794.png

****Kubernetes 是典型的主从分布式架构,由集中式管理节点(Master Node),分布式的工作节点(Worker Node)组成以及辅助工具组成。

集中式管理节点,对集群进行调度管理,有四大核心组件:

API Server: 承担集群的网关,实现统一认证鉴权对外服务 同时也是管理 Node/Pod 资源代理通道;

Scheduler: 资源调度器 除了 Kubernetes 默认的调度器,也支持自定义调度器;

ETCD: 集群状态统一存储 与 Zookeeper 类似的 key-value 存储;

Controller Manger: 控制管理器实现自愈、扩容、应用生命周期管理、服务发现、路由、服务绑定等能力;Kubernetes 默认提供 Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller 等控制器。

分布式的工作节点,工作节点运行业务应用容器;默认会运行三大核心组件:

Kubelet: 与管理节点通信并触发指令执行,管理驱动网络,存储及容器运行时;

Kube Proxy: 通过 DNS 实现服务发现,借助 iptables 规则引导访问至服务 IP,并将重定向至正确的后端应用,实现高可用负载均衡能力;

Container Runtime: 容器运行时 为了扩展 Kubernetes 平台适配能力,同时也标准化整个生态,通过 CNI 与 CSI 标准规范网络及存储的扩展;通过 CRI 与 OCI 标准规范容器镜像及容器运行时的扩展;目前 CRI 支持的容器运行时有 docker、rkt、cri-o、frankti、kata-containers 和 clear-containers 等。

辅助工具,主要是辅助集群管理及网络扩展:

kubectl:: 通过 API Server 进行交互,实现集群管理的命令行工具;

Dashboard: 是 Kubernetes 的 web 用户管理监控界面;

Core DNS: 是可扩展的 DNS 服务器,实现集群服务发现能力。

1.2.Kubernetes 核心理念

1.2.1.POD 容器组,Kubernetes 最小调度单元

Pod 是 Kubernetes 的最小调度及资源分配单元**,Pod 之间相互隔离,通常情况一个 Pod 只建议运行一个容器,当某些容器之间关系非常紧密(Tightly coupled),可以运行在同一 Pod 运行多个容器方便一起调度管理。一个 Pod 就是一个应用运行实例,通过同时运行多个 Pod 来实现应用横向扩展能力。Pod 本身没有自恢复能力,当调度或运行失败时,需要管理节点的 Controller 根绝配置触发实现 Pod 重启、重建或迁移等操作。

9f26ca0799372182c6932edfca14745f.png

从 Pod 启动过程来看,Pod 容器主要是 Pause Container,Init Container 以及 App Container 三种类型容器组成:

Pause Container: 又叫 Infra Container,Pod 通过 Pause Container 实现 Pod 多个容器网络共享,Pause Container 最先启动并绑定 Pod 唯一 IP 地址与各种网络资源,其他容器通过加入 Pause Container 的 Network namespace 来实现网络共享。Pause 是 C 语言实现,镜像非常小只有 700KB 左右,并且永远处于 Pause(暂停)状态;官方镜像是 gcr.io/google_containers/pause-amd64:3.0,同时也支持自定义。

Init Container: Pod 中可以自定义一个或者多个 Init Container,按照顺序依次启动, 在应用 Container 之前启动并执行一些辅助任务,比如执行脚本、拷贝文件到共享目录、日志收集、应用监控等。将辅助功能与主业务容器解耦,实现独立发布和能力重用。 除了不支持 Readiness Probe,其他与特性与普通容器保持一致。

App Container: Pod 中真正承接业务的 Container,一般情况会独立运行,如果是有微服务治理等需求会搭配 Sidecar Container 一起运行。在 Init Container 启动完成之后,App Container 会并行启动,但是需要等待所有 App Container 处于就绪状态,整个 Pod 才算启动成功。

ec98afd14d1f7ebfe23811e511a82762.png

从 POD 的资源隔离来看,Pod 容器主要由 Linux 提供的 Namespace 和 Cgroup 能力实现的,Namespace 实现进程间隔离,Cgroup 实现进程资源控制;其中 Namespace 由 ipc 、uts 、net 、mnt 、pid 各种资源空间联合组成。

CRI 是 Kubernetes v1.5 引入的,将 Kubelet 与容器运行时解耦;CRI 中定义了容器镜像的服务的接口,因为容器运行时与镜像的生命周期是彼此隔离的,所以定义了 RuntimeServiceImageService 两个服务,其中 RuntimeService 主要包含 Sandbox 和 Container 两种容器的管理 gRPC 接口,Sandbox 就是上面 Pod 启动过程中提到的 Pause 容器。目前支持 CRI 的后端有 cri-o,cri-containerd,rkt,frakti,docker 等,cri-o 是由 redhat 发起并开源且由社区驱动的 container-runtime,轻量化专为 kubernetes 而生,主要目的就是替代 docker 作为 kubernetes 集群的容器运行时。

1.2.2.Volume 存储卷,Kubernetes 复杂的存储架构

8c4ae650f82a48fdf177a126fcbcbc9e.png

**存储非常重要关键,同时也是生态与技术都比较复杂的领域,就 linux、window 两个生态支持的文件系统就多达 20+。对于 Kubernete 存储架构设计一直在持续演进完善,为了尽可能多地兼容各种存储平台,Kubernetes 以 in-tree plugin 的形式默认对接很多不同类型的存储系统;同时也支持基于 FlexVolume 和 CSI 插件以 out-of-tree plugin 来实现自定义存储服务。

对 Kubernetes 存储,主要有应用的基本配置文件读取、密码密钥管理**;应用的存储状态、数据存取不同应用间数据共享等三大使用场景。目前 Kubernetes 支持的 Volume Plugins 如下表:

6763b16d156ffd41237e6e7132e80485.png

Empty Dir:生命周期与 Pod 保持一致,当 Pod 删除后 emptyDir 中的数据也会被自动清除。当前 emptyDir 支持的类型有内存、大页内存、Node 节点上 Pod 所在的文件系统。

ConfigMap: 主要是承担配置中心,用于存储应用的配置数据,比如 Springboot 应用 properties 配置文件数据,但是空间大小限制在 1MB 内。

Secret: 功能与 ConfigMap 类似,用于存储应用的敏感数据,比如数据密码、token、证书等,可以与 ConfigMap 联合使用,同样空间大小限制在 1MB 内。

HostPath: 将 Node 节点本地文件系统路径映射到 pod 容器中使用。与 emptyDir 不同之处就是 Pod 删除后,HostPath 中的数据 Kubernetes 根据用户的配置,可以不被清除。

In-tree 网络存储:网络存储跟随 Pod 的生命周期,通过存储插件对接不同类型存储;其中 FlexVolume 虽然允许自定义开发驱动来挂载卷到集群 Node 节点上供 Pod 使用,但生命周期与 pod 同步。

PersistentVolumeClaim 网络存储: 具有独立的生命周期,可以通过存储的 out-tree 插件对接不同类型存储。当前支持的存储插件类型有 FlexVolume 与 CSI。

9229935a8c2b6569675ddeebfc8a290a.png

****引入 PV、PVC、StorageClass 之后,资源管控更加灵活,团队职责更加明确,研发人员只需考虑存储需求(IO、容量、访问模式等),不需要关注底层存储细节;底层复杂的细节都由专业的集群管理与存储管理员来完成。

CSI 是 Kubernetes 1.9 版本开始引入,建立一套标准的存储管理接口,通过该接口为容器提供存储服务。从而实现 Kubernetes 平台与存储服务驱动完全解耦。CSI 主要包含 CSI Controller ServerCSI Node Server 两个部分,Controller Server 主要实现创建、删除、挂载、卸载等控制功能;Node Server 主要实现的是 Node 节点上的 mount、unmount 的操作。

e420065e07b18ef799a133e50e214f58.png

CSI Controller Server 和 External CSI SideCar 是通过 Unix Socket 来进行通信的,CSI Node Server 和 Kubelet 也是通过 Unix Socket 来通信。CSI 实现类也日趋完善,比如 ExpandCSIVolumes 可以实现文件系统扩容;VolumeSnapshotDataSource 可以实现数据卷的快照;VolumePVCDataSource 实现自定义定 PVC 数据源;CSIInlineVolume 在 Volume 中定义一些 CSI 的驱动。阿里云也开源了阿里云盘、NAS、CPFS、OSS、LVM** 等 CSI 存储插件。

1.2.3.Ingress 与 Service,百花齐放的 Kubernetes 网络

**Kubernetes 容器网络非常复杂,涉及的概念也比较多,比如 Pod 网络,Service 网络,Cluster IP,NodePort,LoadBalancer 和 Ingress 等,为此将 Kubernetes 的网络参考 TCP/IP 协议栈抽象为四层:

fe83d930a25263efa2e9b30e2f537d4c.png

第 0 层: Node 节点网络比较简单,就是保证 Kubernetes 节点(物理或虚拟机)之间能够正常 IP 寻址和互通的网络,一般由底层(公有云或数据中心)网络基础设施支持

第 1 层: Pod 是 Kubernetes 的最小调度单元,Pod 网络就是确保 Kubernetes 集群中所有 Pod(包括同一节点及不同节点上的 Pod),逻辑上在同一个平面网络内,能够相互 IP 寻址和通信的网络。是容器网络最复杂部分,通过各种容器网络插件满足不同网络需求,通过 CNI 标准化及开放网络自定义能力。

第 3 层: 虽然单个 Pod 都有 IP,但是与 Pod 生命周期一致,为了解决一组相同 Pod 统一稳定的访问地址,并且将请求均衡的分发到后端 Pod 应用服务中。Kubernetes 引入了 Service 网络,以此实现服务发现(Service Discovery)和负载均衡(Load Balancing)能力,底层是通过 Kube-Proxy + iptables 转发实现,对应用无侵入且不穿透代理,没有额外性能损耗。

第 4 层: Kubernetes Service 网络是集群内部网络,集群外部是无法访问,需要将内部服务暴露外部才能访问。Kubernetes 通过 NodePort,LoadBalancer 和 Ingress 多个方式构建外部网络接入能力。

7491b8a4532c558cc95ad338e19aa38d.png

CNI 最早是由 CoreOS 发起的容器网络规范,是 Kubernetes 网络插件的基础。Container Runtime 在创建容器时,先创建好 network namespace,再调用 CNI 插件为 network namespace 配置网络,最后启动容器内进程。CNI 插件包括 CNI Plugin 与 IPAM Plugin 两部分:

CNI Plugin: 负责配置管理容器网络,包括两个基本的接口:

网络配置: AddNetwork(net NetworkConfig, rt RuntimeConf) (types.Result, error)

清理网络: DelNetwork(net NetworkConfig, rt RuntimeConf) error

IPAM Plugin: 负责容器 IP 地址分配,实现包括 host-local 和 dhcp。

44b123d7b424c757c269a8273aeda599.png

**容器网络技术也在持续演进发展,社区开源的网络组件众多,比如 Flannel、Calico、Cilium、OVN 等,每个组件都有各自的优点及适应的场景,难以形成大一统的组件及解决方案。

1.2.4.Workload 工作负载,Kubernetes 应用中心理念

132757840dfc40bfadee40377158df2a.png

Kubernetes 通过工作负载 Workload** 实现应用管理部署与发布,践行 Kubernetes 以应用为中心的理念。Kubernetes 支持多种类型的工作负载,包含 Deployment、StatefulSet、ReplicaSet、Job、CronJob、DaemonSet,以满足不同场景的需求。

Deployment 与 ReplicaSet: 替换原来的 ReplicationController 对象,管理部署无状态应用,Deployment 管理不同版本的 ReplicaSet,ReplicaSet 管理相同版本的 Pod,通过 Deployment 调整 ReplicaSet 的终态副本数,控制器会维持实际运行的 Pod 数量与期望的数量一致,Pod 出故障时会自动重启或恢复。

StatefulSet: 管理部署有状态应用,创建的 Pod 拥有根据规范创建的持久型标识符。Pod 迁移或销毁重启后,标识符仍会保留。如每个 Pod 有序号,可以按序号创建更新或删除;Pod 有唯一网络标志(hostname)或独享的存储 PV,支持灰度发布等。

DaemonSet: 管理部署每个节点运行的守护任务,如监控、日志收集等。新加入的节点也运行,移出节点是需要删除。也可以通过标签的指定运行节点。

Job 与 Cronjob: Job 是一次性任务,可创建一个或多个 Pod,监控 Pod 是否成功运行或终止;根据 Pod 状态设置重复次数、并发度、重启策略。Cronjob 是定时调度的 Job,可以指定运行时间、等待时间、是否并行运行、运行次数限制。

****在 Kubernetes 生态中,还有一些提供额外操作的第三方工作负载。同时也可以通过使用 CRD 自定义工作负载。还有就是 Device Plugin 驱动的硬件工作负载,会在后续章节详细讲解。

1.2.5.Controller 控制器,Kubernetes 集控管理中心

Controller Manager 作为 Kubernetes 集控管理中心,负责集群的 Node、Pod 副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的资源管理,并通过 API Server 接口实时监控集群的每个资源对象的状态,一旦发生故障导致系统状态发生变化,就会立即尝试修复到“期望状态”。

c129e4541a606c79b83be6d7370bd76e.png

Replication Controller: 保证集群中一个 RC 所关联的 Pod 副本数始终保持预设值。

ResourceQuota Controller: 确保 Kubernetes 中的资源对象在任何时候都不会超量占用系统物理资源。有容器,Pod 以及 Namespace 三个级别。

Namespace Controller: 通过 API Server 定时读取 Namespace 信息。如果 Namespace 被 API 标记为优雅删除(即设置删除期限,DeletionTimestamp),则将该 Namespace 状态设置为“Terminating”,并保存到 etcd 中。同时删除该 Namespace 下的 ServiceAccount、RC、Pod 等资源对象。

Endpoint Controller: Endpoints 是 Service 对应所有 Pod 副本的访问地址,Endpoint Controller 主要负责监听 Service 和对应的 Pod 副本的变化,从而生成和维护 Endpoints 对象控制器。

2fb38e2f278e7c3d90e3b121d040eb31.png

Deployment Controller: Deployment 通过控制 ReplicaSet,ReplicaSet 再控制 Pod,最终由 Deployment Controller 驱动达到期望状态,Deployment Controller 会监听 DeploymentInformer、ReplicaSetInformer、PodInformer 三种资源。

另外,在 Kubernetes v1.6 引入了云控制管理器 Cloud Controller Manager(CCM)** ,提供与阿里公有云基础产品对接的支持,后续也会详细讲解。

1.3.总结

b4e8f62c6053711ddf0371dd8ea1c02a.png

总结一下,Kubernetes 不仅是一个强大的容器编排系统本身,而且促进了一个庞大的工具和服务的生态系统,云原生时代的操作系统,形成云计算新界面。

从设计理念方面, Kubernetes 是以应用为中心的构理念,向下屏蔽基础设施差异,实现底层基础资源统一调度及编排;向上通过容器镜像标准化应用,实现应用负载自动化部署;中间通过 Kubernetes 通用的编排能力,开放 API 以及自定义 CRD 扩展能力;

从技术架构方面, Kubernetes 是典型的分布式主从架构,由 Master 控制节点与可以水平扩展的 Worker 工作节点组成,Master 实现集中式控制管理,Worker 实现分布式运行;与 Openstack 的架构还有基于 SpringCloud 研发的分微服业务应用没有太大区别。

从设计模式方面, Kubernetes 通过定义大量的模型(原语、资源对象、配置、常用的 CRD),通过配置管理模型实现集群资源的控制;虽然模型多切复杂,可以分层(核心层,隔离与服务访问层,调度层,资源层)逐步理解。

从平台扩展方面, Kubernetes 是一个开放可扩展平台,不仅有开发的 API,开放标准(CNI,CSI,CRI 等)以及 CRD,不仅是一个单纯运行时平台,同时面向运维的开发平台。

文章来源:Kubernetes容器平台架构之道 - InfoQ 写作平台

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论