【云原生】云原生技术学习笔记(三)Kubernetes核心概念
Kubernetes,K→S有8个字母,所以又作K8S。
1. 什么是K8S?
kubernetes,希腊语,舵手,container除了拥有容器的含义,也有集装箱的含义。
Kubernetes 就像一个舵手开着轮船,载着一堆集装箱,把集装箱送到它们该去的地方。Kubernetes 也就一个“轮船”,来帮助我们管理这些集装箱,也就是管理这些容器。所以,Kubernetes就是一个管理容器的工具。
更具体一点,Kubernetes 是一个自动化的容器编排平台,负责:
- 应用的部署
- 应用的弹性
- 应用的管理,
这些都是基于容器的。
2. K8S的核心功能
- 服务发现
- 负载均衡
- 容器的自动装箱
- 我们也会把它叫做 scheduling,就是“调度”,把一个容器放到一个集群的某一个机器上,Kubernetes 会帮助我们去做存储的编排,让存储的声明周期与容器的生命周期能有一个连接;
- 自动化的容器恢复
- 在一个集群中,经常会出现宿主机的问题或者说是操作系统的问题,导致容器本身的不可用,Kubernetes 会自动地对这些不可用的容器进行恢复;
- 自动发布与回滚
- 应用的自动发布与应用的回滚,以及与应用相关的配置密文的管理;
- 批量执行
- 对于 job 类型任务,Kubernetes 可以去做批量的执行;
- 水平伸缩
- 为了让这个集群、这个应用更富有弹性,Kubernetes 也支持水平的伸缩。
2.1 调度
调度器
Kubernetes 可以把用户提交的容器放到 Kubernetes 管理的集群的某一台节点上去。Kubernetes 的调度器是执行这项能力的组件,它会观察正在被调度的这个容器的大小、规格。比如说它所需要的 CPU以及它所需要的 memory,然后在集群中找一台相对比较空闲的机器来进行一次 placement,也就是一次放置的操作。
2.2 自动修复
节点健康检查
Kubernetes 有一个节点健康检查的功能,它会监测这个集群中所有的宿主机,当宿主机本身出现故障,或者软件出现故障的时候,这个节点健康检查会自动对它进行发现。 Kubernetes 会把运行在这些失败节点上的容器进行自动迁移,迁移到一个正在健康运行的宿主机上,来完成集群内容器的一个自动恢复。
2.3 水平伸缩
业务负载检查
Kubernetes 有业务负载检查的能力,它会监测业务上所承担的负载,如果这个业务本身的 CPU 利用率过高,或者响应时间过长,它可以对这个业务进行一次扩容。之后它就可以通过负载均衡把原来达到的负载,平均分到扩容之后的负载上去,以此来提高响应的时间。
3. K8S的架构
Kubernetes 架构是一个比较典型的二层架构和 server-client 架构。Master 作为中央的管控节点,会去与 Node 进行一个连接。所有 UI 的、clients、这些 user 侧的组件,只会和 Master 进行连接,把希望的状态或者想执行的命令下发给 Master,Master 会把这些命令或者状态下发给相应的节点,进行最终的执行。
4.1 Master
Kubernetes 的 Master 包含四个主要的组件:API Server、Controller、Scheduler 以及 etcd。
- API Server:顾名思义是用来处理 API 操作的,Kubernetes 中所有的组件都会和 API Server 进行连接,组件与组件之间一般不进行独立的连接,都依赖于 API Server 进行消息的传送;
- Controller:是控制器,它用来完成对集群状态的一些管理。
- 比如自动对容器进行修复、自动进行水平扩张,都是由 Kubernetes 中的 Controller 来进行完成的;
- Scheduler:是调度器,完成调度的操作;
- 把一个用户提交的 Container,依据它对 CPU、对 memory 请求大小,找一台合适的节点,进行放置;
- etcd:是一个分布式的一个存储系统,API Server 中所需要的这些原信息都被放置在 etcd 中,etcd 本身是一个高可用系统,通过 etcd 保证整个 Kubernetes 的 Master 组件的高可用性。
API Server,它本身在部署结构上是一个可以水平扩展的一个部署组件;Controller 是一个可以进行热备的一个部署组件,它只有一个 active,它的调度器也是相应的,虽然只有一个 active,但是可以进行热备。
4.2 Node
-
Pod:Kubernetes 的 Node 是真正运行业务负载的,每个业务负载会以 Pod 的形式运行。
-
Kubelet:一个 Pod 中运行的一个或者多个容器,真正去运行这些 Pod 的组件的是叫做 kubelet,也就是 Node 上最为关键的组件,它通过 API Server 接收到所需要 Pod 运行的状态,然后提交 Container Runtime 组件中。
-
Storage Plugin:在 OS 上去创建容器所需要运行的环境,最终把容器或者 Pod 运行起来,也需要对存储跟网络进行管理。Kubernetes 不直接进行网络存储的操作,他们会靠 Storage Plugin 或者是网络的 Plugin 来进行操作。用户自己或者云厂商都会去写相应的 Storage Plugin 或者 Network Plugin,去完成存储操作或网络操作。
-
Kube-proxy:在 Kubernetes 自己的环境中,也会有 Kubernetes 的 Network,它是为了提供 Service network 来进行搭网、组网的。完成 service 组网的组件;利用了 iptable 的能力来进行组建 Kubernetes 的 Network,就是 cluster network,以上就是 Node 上面的四个组件
Kubernetes 每个 Node 上,都会运行上面几个组件。
4. K8S组件之间的交互
- 提交pod部署请求:用户可以通过 UI 或者 CLI 提交一个 Pod 给 Kubernetes 进行部署
- 请求至API Server:这个 Pod 请求首先会通过 CLI 或者 UI 提交给 Kubernetes API Server
- API Server写入etcd: API Server 会把这个信息写入到它的存储系统 etcd
- Scheduler一直在watch: Scheduler 会通过 API Server 的 watch 或者叫做 notification 机制得到这个信息:有一个 Pod 需要被调度。
- 使用过etcd的童鞋肯定能反应过来,这其实就是etcd的能力
- Scheduler调度: 这个时候 Scheduler 会根据它的内存状态进行一次调度决策,在完成这次调度之后,它会向 API Server报告:Pod需要被调度到某一个节点上。
- API Server写入etcd:
API Server
接收到这次操作之后,会把这次的结果再次写到 etcd 中,然后 API Server 会通知相应的节点进行这次 Pod 真正的执行启动 - Kubelet也一直在watch:相应节点的
kubelet
会得到这个通知 - Kubelet调Container runtime: kubelet 就会去调
Container runtime
来真正去启动配置这个容器和这个容器的运行环境:- 调度
Storage Plugin
来去配置存储 - 调度
network Plugin
去配置网络。
- 调度
以上就是这些组件之间相互沟通相互通信,协调来完成一次Pod的调度执行操作的。当然我们很容易可以看出,etcd几乎作为了整个k8s的通信中间件,无论是master中的各组件,还是master与node之间。
5. K8S的核心概念与API
5.1 Pod
Pod 是 Kubernetes 的一个最小调度以及资源单元。用户可以通过 Kubernetes
的 Pod API 生产一个 Pod,让 Kubernetes 对这个 Pod 进行调度,也就是把它放在某一个 Kubernetes 管理的节点上运行起来。
一个 Pod 简单来说是对一组容器的抽象,它里面会包含一个或多个容器。在 Pod 里面,我们也可以去定义容器所需要运行的方式。比如说运行容器 Command
,以及运行容器的环境变量等等。Pod 这个抽象也给这些容器提供了一个共享的运行环境,它们会共享同一个网络环境,这些容器可以用 localhost 来进行直接的连接。而 Pod 与 Pod 之间,是互相有隔离的。
5.2 Volume
Volume 就是卷的概念,它是用来管理 Kubernetes 存储的,是用来声明在 Pod 中的容器可以访问文件目录的,一个卷可以被挂载在 Pod 中一个或者多个容器的指定路径下面。而 Volume 本身是一个抽象的概念,一个 Volume 可以去支持多种的后端的存储。比如说 Kubernetes 的 Volume 就支持了很多存储插件:
- 它可以支持本地的存储
- 可以支持分布式的存储,比如说像 ceph,GlusterFS ;
- 它也可以支持云存储,比如说阿里云上的云盘、AWS 上的云盘、Google 上的云盘等等。
5.3 Deployment
Deployment
是在 Pod 这个抽象上更为上层的一个抽象,它可以定义一组 Pod 的副本数目、以及这个 Pod 的版本。 一般用 Deployment
这个抽象来做应用的真正的管理,而 Pod 是组成 Deployment
最小的单元。
Kubernetes 是通过控制器去维护 Deployment 中 Pod 的数目,它也会去帮助 Deployment 自动恢复失败的 Pod。
比如说我定义一个 Deployment,这个 Deployment 里面需要两个 Pod,当一个 Pod 失败的时候,控制器就会监测到,然后再去新生成一个 Pod,它重新把 Deployment 中的 Pod 数目恢复。
通过控制器以指定发布的策略以控制版本。比如说进行滚动升级,进行重新生成的升级,或者进行版本的回滚。
5.4 Service
Service 提供了一个或者多个 Pod 实例的稳定访问地址。
一个 Deployment 可能有两个甚至更多个完全相同的 Pod。
对于一个外部的用户来讲,访问哪个 Pod 其实都是一样的,所以会希望做一次负载均衡,在做负载均衡的同时,只想访问某一个固定的 VIP( Virtual IP), 虚拟IP,而不希望得知每一个具体的 Pod 的 IP 地址。这个 pod 本身可能终止,如果一个 Pod 失败了,可能会唤起另外一个新的。对一个外部用户来讲,提供了多个具体的 Pod 地址,这个用户要不停地去更新 Pod 地址,当这个 Pod 再失败重启之后,我们希望有一个抽象,把所有 Pod 的访问能力抽象成一个第三方的一个 IP 地址,实现这个的 Kubernetes 的抽象就叫 Service。
实现 Service 有多种方式:
- Kubernetes 支持 Cluster IP
- kuber-proxy 的组网
- nodePort
- LoadBalancer
5.5 Namespaces
Namespace 是用来做一个集群内部的逻辑隔离的,它包括鉴权、资源管理等。Kubernetes 的每个资源,比如 Pod、Deployment、Service 都属于一个 Namespace,同一个 Namespace 中的资源需要命名的唯一性,不同的 Namespace 中的资源可以重名。
所以以上结构大致应该是这样的:
- Namespaces:
- Deployment(Service)
- Pod1(Volume)
- container1
- container2
- container3
- Pod2(Volume)
- container1
- container2
- container3
- Pod1(Volume)
- Deployment(Service)
6. K8S的api
Kubernetes API 是由 HTTP+JSON 组成的:用户访问的方式是 HTTP,访问的 API 中的content是 JSON 格式的。Kubernetes 的 kubectl,Kubernetes UI,或者有时候用 curl,直接与 Kubernetes 进行沟通,都是使用 HTTP + JSON 这种形式。
如果我们去提交一个 Pod,它的 content 内容都是用 JSON 或者是 YAML 表达的:
- apiVersion: API 的 version
- Kind: 描述操作的哪个资源
- Metadata: 资源的名称,比如nginx,pod的名字
- lable: 标签
KeyValuePair
键值对,这些 label 是可以被 selector,也就是选择器所查询的。这个能力实际上跟我们的 sql 类型的 select 语句是非常相似的,这个可以实操时体会一下,通过 label,kubernetes 的 API 层就可以对这些资源进行一个筛选,那这些筛选也是 kubernetes 对资源的集合所表达默认的一种方式。例如:Deployment
可能是代表一组的 Pod,它是一组 Pod 的抽象,一组 Pod 就是通过 label selector 来表达的。Service
对应的一组 Pod,就是一个 service 要对应一个或者多个的 Pod,来对它们进行统一的访问,这个描述也是通过 label selector 来进行 select 选取的一组 Pod。- 所以可以看到 label 是一个非常核心的 kubernetes API 的概念。
annotation
: 对资源的额外的一些用户层次的描述
- lable: 标签
- Spec: 描述Pod预期的状态-
container
:pod内部需要有哪些 container 被运行image
:容器的镜像是什么port
:容器运行后暴露的端口是什么
当我们从 Kubernetes API
中去获取这个资源的时候,一般来讲在 Spec 下面会有一个项目叫 status,它表达了这个资源当前的状态;比如说一个 Pod 的状态可能是正在被调度、或者是已经 running、或者是已经被 terminates,就是被执行完毕了。
- 原文作者:Garfield
- 原文链接:http://www.randyfield.cn/post/2021-07-11-cloud-native-3-kubernetes/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。