在《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
Google
是全世界最大的搜索引擎,拥有数量庞大的服务器集群,为了提高资源利用率和部署运维效率,它专门开发了一个集群应用管理系统,名字叫 Borg
,在底层支持整个公司的运转
2014 年,Google
内部系统要“升级换代”,从原来的 Borg
切换到 Omega
,趁着 Docker
的东风,把 C++
开发的 Borg
系统用 Go
语言重写并开源,于是 Kubernetes
就这样诞生了
Kubernetes
这个名字来源于希腊语,意思是舵手或飞行员。K8s
作为一个缩写,是通过计算“K”和“s”之间的八个字母得出的
你可能想问,K8s
到底有什么用?
Kubernetes
就是一个生产级别的容器编排平台和集群管理系统,不仅能够创建、调度容器,还能够监控、管理服务器,它凝聚了 Google 等大公司和开源社区的集体智慧,从而让中小型公司也可以具备轻松运维海量计算节点——提供云计算能力
刚开始学习容器技术的时候,特别是还没有学Docker
的时候,时常不清楚K8s
和Docker
的区别。但看着两者的标志,一个是在海上漂浮的鲸鱼,另外一个是航海的掌舵,两者似乎存在的某种联系
不过两者不能放在一个维度上讨论,Docker 是当前流行的 Linux 容器解决方案,利用 Namespaces
、Cgroups
以及联合文件系统UnionFS和chroot
实现了同一主机上容器进程间的相互隔离
NameSpaces
:隔离进程,让进程只能访问到本命名空间里的挂载目录、PID、NetWork 等资源Cgroups
: 限制进程能使用的计算机系统各项资源的上限,包括 CPU、内存、磁盘、网络带宽等等联合文件系统UnionFS和chroot
: 保存一个操作系统的所有文件和目录,在它基础之上添加应用运行依赖的文件。创建容器进程的时候给进程指定Mount Namespace
把镜像文件挂载到容器里,用 chroot
把进程的 Root目录切换到挂载的目录里,从而让容器进程各自拥有独立的操作系统目录K8s
是容器编排平台和集群管理系统,可以按照应用的定义调度各个运行着应用组件 Docker
容器,但它没有限定 container-runtime
(容器运行时) 必须是 Docker
,K8s
的 容器运行时支持对接多种容器,完全可以替换成任何符合标准的其他容器运行时,例如 containerd
、CRI-O
等等
前面我们提到docker-compose
是单机环境下的容器编排工具,那你可能想问,Docker
有没有容器集群管理方案呢,其实是有的,叫Docker Swarm
,但由于使用起来体验很差,另外Docker公司没有像Google
那种大规模集群管理经验,几乎没有人使用
现在K8s
在市场上已经成为霸主地位,想学 K8s
不一定非得会 Docker
,但如果我们想要自己开发的服务在K8s
上运行,若在调度容器时使用Docker
,我们还是需要先去了解Dockerfile
文件编写、打包上传镜像的等Docker命令
,所以建议还是先学习Docker
的基本用法后,再来学习K8s
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
就无法启动,而插件为一些附加功能,不安装不会影响正常运行,下面先介绍一下 Master
和 Work
节点里面的组件
Master
节点里有4个组件,分别是 apiserver
、etcd
、scheduler
、controller-manager
apiserver
,是 Master 节点和整个 Kubernetes 系统的唯一入口,它对外公开了一系列的 RESTful API,并且加上了验证、授权等功能,所有其他组件都只能和它直接通信etcd
是一个高可用的分布式 Key-Value 数据库,用来持久化存储系统里的各种资源对象和状态,etcd
只与apiserver
有直接联系,要想拿到etcd
里面的数据必须经过apiserver
scheduler
负责容器的编排工作,检查节点的资源状态,把 Pod
(可以理解成穿了马甲的容器,后续介绍)调度到最适合的节点上运行。因为节点状态和 Pod
信息都存储在 etcd
里,所以 scheduler
必须通过 apiserver
才能获得controller-manager
负责维护容器和节点等资源的状态,实现故障检测、服务迁移、应用伸缩等功能,相当于监控运维人员。同样地,它也必须通过 apiserver
获得存储在 etcd
里的信息,才能够实现对资源的各种操作Node
里有 3 个组件,分别是 kubelet
、kube-proxy
、container-runtime
。Master 里的 apiserver、scheduler 等组件需要获取节点的各种信息才能够作出管理决策,也需要依赖这3个组件
kubelet
是 Node
的代理,负责管理 Node (work Node)
相关的绝大部分操作,Node
上只有它能够与 apiserver
通信,实现状态报告、命令下发、启停容器等功能,相当于是 Node
上的一个“小管家”kube-proxy
的作用有点特别,它是 Node
的网络代理,只负责管理容器的网络通信,简单来说就是为 Pod 转发 TCP/UDP 数据包,相当于是专职的“小邮差”container-runtime
我们就比较熟悉了,它是容器和镜像的实际使用者,在 kubelet
的指挥下创建容器,管理 Pod
的生命周期,是真正干活的“苦力”因为 Kubernetes
的定位是容器编排平台,所以它没有限定 container-runtime
必须是 Docker,完全可以替换成任何符合标准的其他容器运行时,例如 containerd
、CRI-O
等等,只不过在这里我们使用的是 Docker
现在,我们再把 Node
里的组件和 Master
里的组件放在一起来看,就能够明白 Kubernetes
的大致工作流程了
Node
上的 kubelet
会定期向 apiserver
上报节点状态,apiserver
再存到 etcd
里Node
上的 kube-proxy
实现了 TCP/UDP
反向代理,让容器对外提供稳定的服务scheduler
通过 apiserver
得到当前的节点状态,调度 Pod
,然后 apiserver
下发命令给某个 Node
的 kubelet
,kubelet
调用 container-runtime
启动容器controller-manager
也通过 apiserver
得到实时的节点状态,监控可能的异常情况,再使用相应的手段去调节恢复K8s
里面内部架构和工作机制刚开始接触起来比较复杂,但可以看出它的功能非常完善,通过K8s
里的组件,把原先繁琐低效的人力工作搬进了高效的计算机里,就能够随时发现集群里的变化和异常,再互相协作,维护集群的健康状态
这篇文章当中出现了很多新的术语,比如K8s里面核心概念Pod
,以后再做介绍
Kubernetes
一般都运行在大规模的计算集群上,刚开始学习K8s
,免不了要进行搭建K8s
练手,这时可以选择使用kind
和 minikube
,它们都可以在本机上运行完整的 Kubernetes
环境,在官网(https://kubernetes.io/zh/docs/tasks/tools/)可以查看详细说明,下篇文章也会介绍minikube
搭建教程
如果你觉得这篇文章对你有帮助的话,麻烦点一下【赞】和【在看】