什么是容器编排

《Docker 进阶指南(下)- 使用Docker Compose编排多个容器》文章当中,我提到了docker-compose,对于docker-compose单机环境下的容器编排工具,而Kubernetes(K8s)是一个生产级别的容器编排平台和集群管理系统,能够创建、调度容器,监控、管理服务器

对于简易任务的应用场景,我们可以直接使用docker-compose,而对于集群下的容器编排,使得集群中的多种容器同时调度,这时候就要用到更加强大的Kubernetes作为容器编排平台,它的用途非常广泛,可以用于大型企业的上线平台应用部署以及要想搭建和生产环境一致的测试环境

在正式介绍Kubernetes之前,我们再来回顾一下什么是容器编排

容器技术的流行,让我们进入了云原生时代,容器技术可以让进程之间实现隔离不受互相影响,实际情况下我们需要在集群里面部署几百个甚至上千个容器,还需要解决它们之间互相通信、互相协作的超级问题,困难程度可以说是指数级别的上升

这些容器之上的管理、调度工作,我们统称为容器编排(Container Orchestration)

容器编排这个词听起来好像挺高大上,但如果理解了之后就会发现其实也并不神秘。像我们在上篇使用 docker-compose 部署 Python Web服务的时候,把 Python环境和存放项目代码、Redis 这两个容器,理清次序、配好 IP以及端口去运行,就是最初级的一种“容器编排”,只不过这是纯手工操作

面对单机上的几个容器,使用docker-compose 来"纯人工"编排调度还可以应付,但如果规模上到几百台服务器、成千上万的容器,处理它们之间的复杂联系就必须要依靠计算机了,而目前计算机用来调度管理的“标准”,就是Kubernetes

什么是Kubernetes

Google 是全世界最大的搜索引擎,拥有数量庞大的服务器集群,为了提高资源利用率和部署运维效率,它专门开发了一个集群应用管理系统,名字叫 Borg,在底层支持整个公司的运转

2014 年,Google 内部系统要“升级换代”,从原来的 Borg 切换到 Omega,趁着 Docker的东风,把 C++ 开发的 Borg 系统用 Go 语言重写并开源,于是 Kubernetes 就这样诞生了

Kubernetes 这个名字来源于希腊语,意思是舵手或飞行员。K8s 作为一个缩写,是通过计算“K”和“s”之间的八个字母得出的

你可能想问,K8s到底有什么用?

Kubernetes 就是一个生产级别的容器编排平台和集群管理系统,不仅能够创建、调度容器,还能够监控、管理服务器,它凝聚了 Google 等大公司和开源社区的集体智慧,从而让中小型公司也可以具备轻松运维海量计算节点——提供云计算能力

K8s 和 Docker 之间的关系

刚开始学习容器技术的时候,特别是还没有学Docker的时候,时常不清楚K8sDocker的区别。但看着两者的标志,一个是在海上漂浮的鲸鱼,另外一个是航海的掌舵,两者似乎存在的某种联系
请添加图片描述
不过两者不能放在一个维度上讨论,Docker 是当前流行的 Linux 容器解决方案,利用 NamespacesCgroups 以及联合文件系统UnionFS和chroot 实现了同一主机上容器进程间的相互隔离

在这里插入图片描述

  • NameSpaces:隔离进程,让进程只能访问到本命名空间里的挂载目录、PID、NetWork 等资源
  • Cgroups: 限制进程能使用的计算机系统各项资源的上限,包括 CPU、内存、磁盘、网络带宽等等
  • 联合文件系统UnionFS和chroot : 保存一个操作系统的所有文件和目录,在它基础之上添加应用运行依赖的文件。创建容器进程的时候给进程指定Mount Namespace 把镜像文件挂载到容器里,用 chroot 把进程的 Root目录切换到挂载的目录里,从而让容器进程各自拥有独立的操作系统目录

K8s 是容器编排平台和集群管理系统,可以按照应用的定义调度各个运行着应用组件 Docker 容器,但它没有限定 container-runtime(容器运行时) 必须是 DockerK8s 的 容器运行时支持对接多种容器,完全可以替换成任何符合标准的其他容器运行时,例如 containerdCRI-O 等等
请添加图片描述

前面我们提到docker-compose是单机环境下的容器编排工具,那你可能想问,Docker有没有容器集群管理方案呢,其实是有的,叫Docker Swarm,但由于使用起来体验很差,另外Docker公司没有像Google那种大规模集群管理经验,几乎没有人使用

现在K8s在市场上已经成为霸主地位,想学 K8s 不一定非得会 Docker,但如果我们想要自己开发的服务在K8s上运行,若在调度容器时使用Docker,我们还是需要先去了解Dockerfile 文件编写、打包上传镜像的等Docker命令,所以建议还是先学习Docker的基本用法后,再来学习K8s

Kubernetes的整体架构

Kubernetes 是一个生产级别的容器编排平台和集群管理系统,能够创建、调度容器,监控、管理服务器,容器可以理解成软件、应用或者进程。服务器则是硬件,是 CPU、内存、硬盘、网卡。既可以管理软件,也可以管理硬件,那不就跟操作系统一样了

确实,在某种角度来上来看,Kubernetes 可以说是一个集群级别的操作系统,主要功能就是资源管理和作业调度

对比Linux 操作系统,使用Linux 操作系统的用户有开发(Dev)和运维(Ops),而使用Kubernetes的角色叫DevOps

所以在 Kubernetes 这里,开发和运维的界限变得不那么清晰了。由于云原生的兴起,开发人员从一开始就必须考虑后续的部署运维工作,而运维人员也需要在早期介入开发,才能做好应用的运维监控工作

用一张图来看一下K8s的整体架构

在这里插入图片描述

Kubernetes 采用了控制面 / 数据面(Control Plane / Data Plane)架构,集群里的计算机被称为节点(Node),少量的节点用作控制面来执行集群的管理维护工作,其他的大部分节点都被划归数据面,用来跑业务应用

  • 控制面的节点:在 Kubernetes 里叫做 Master Node,一般简称为 Master,它是整个集群里最重要的部分,可以说是 Kubernetes 的大脑和心脏

  • 数据面的节点:叫做 Worker Node,一般就简称为 Worker 或者 Node,相当于 Kubernetes 的手和脚,在 Master 的指挥下干活

我们还可以看到有一个 kubectl,它就是 Kubernetes 的客户端工具,用来操作 Kubernetes,但它位于集群之外,理论上不属于集群,kubectl的相关命令在下一篇文章当中为大家介绍

不管是Master节点还是Worker节点, 每个节点内部有很多模块组成,这些模块可以分成组件(Component)插件(Addon)两类

组件不存在Kubernetes就无法启动,而插件为一些附加功能,不安装不会影响正常运行,下面先介绍一下 MasterWork 节点里面的组件

Master 里的组件构成

Master 节点里有4个组件,分别是 apiserveretcdschedulercontroller-manager
在这里插入图片描述

  • apiserver,是 Master 节点和整个 Kubernetes 系统的唯一入口,它对外公开了一系列的 RESTful API,并且加上了验证、授权等功能,所有其他组件都只能和它直接通信
  • etcd 是一个高可用的分布式 Key-Value 数据库,用来持久化存储系统里的各种资源对象和状态,etcd 只与apiserver有直接联系,要想拿到etcd里面的数据必须经过apiserver
  • scheduler 负责容器的编排工作,检查节点的资源状态,把 Pod (可以理解成穿了马甲的容器,后续介绍)调度到最适合的节点上运行。因为节点状态和 Pod 信息都存储在 etcd 里,所以 scheduler 必须通过 apiserver 才能获得
  • controller-manager 负责维护容器和节点等资源的状态,实现故障检测、服务迁移、应用伸缩等功能,相当于监控运维人员。同样地,它也必须通过 apiserver 获得存储在 etcd 里的信息,才能够实现对资源的各种操作

Work Node 里的组件构成

Node 里有 3 个组件,分别是 kubeletkube-proxycontainer-runtime。Master 里的 apiserver、scheduler 等组件需要获取节点的各种信息才能够作出管理决策,也需要依赖这3个组件
在这里插入图片描述

  • kubeletNode 的代理,负责管理 Node (work Node)相关的绝大部分操作,Node 上只有它能够与 apiserver 通信,实现状态报告、命令下发、启停容器等功能,相当于是 Node 上的一个“小管家”
  • kube-proxy 的作用有点特别,它是 Node 的网络代理,只负责管理容器的网络通信,简单来说就是为 Pod 转发 TCP/UDP 数据包,相当于是专职的“小邮差”
  • 第三个组件 container-runtime 我们就比较熟悉了,它是容器和镜像的实际使用者,在 kubelet 的指挥下创建容器,管理 Pod 的生命周期,是真正干活的“苦力”

因为 Kubernetes 的定位是容器编排平台,所以它没有限定 container-runtime 必须是 Docker,完全可以替换成任何符合标准的其他容器运行时,例如 containerdCRI-O 等等,只不过在这里我们使用的是 Docker

总结K8s 组件工作流程

现在,我们再把 Node 里的组件和 Master 里的组件放在一起来看,就能够明白 Kubernetes 的大致工作流程了

  • 每个 Node 上的 kubelet 会定期向 apiserver 上报节点状态,apiserver 再存到 etcd
  • 每个 Node 上的 kube-proxy 实现了 TCP/UDP 反向代理,让容器对外提供稳定的服务
  • scheduler 通过 apiserver 得到当前的节点状态,调度 Pod,然后 apiserver 下发命令给某个 Nodekubeletkubelet 调用 container-runtime 启动容器
    controller-manager 也通过 apiserver 得到实时的节点状态,监控可能的异常情况,再使用相应的手段去调节恢复

结束语

K8s里面内部架构和工作机制刚开始接触起来比较复杂,但可以看出它的功能非常完善,通过K8s里的组件,把原先繁琐低效的人力工作搬进了高效的计算机里,就能够随时发现集群里的变化和异常,再互相协作,维护集群的健康状态

这篇文章当中出现了很多新的术语,比如K8s里面核心概念Pod,以后再做介绍

Kubernetes 一般都运行在大规模的计算集群上,刚开始学习K8s,免不了要进行搭建K8s练手,这时可以选择使用kindminikube,它们都可以在本机上运行完整的 Kubernetes 环境,在官网(https://kubernetes.io/zh/docs/tasks/tools/)可以查看详细说明,下篇文章也会介绍minikube搭建教程

如果你觉得这篇文章对你有帮助的话,麻烦点一下【赞】和【在看】

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐