Kubernetes 架构及核心概念
1. Kubernetes 是什么?
Kubernetes 是一个自动化的容器编排平台,它负责应用的部署、应用的弹性伸缩以及应用的管理。
2. Kubernetes 架构
Kubernetes 架构是一个比较典型的二层架构和 Server-Client 架构。Master 作为中央的管控节点,会去与 Node 进行一个连接。客户端(比如UI/CLI等)只会和 Master 进行连接,把希望的状态或者想执行的命令下发给 Master,Master 会把这些命令或者状态下发给相应的节点,进行最终的执行。
2.1 Master
Kubernetes 的 Master 包含四个主要的组件:kube-apiserver、kube-controller、kube-scheduler 以及 etcd,如下图所示。我们一般也称Master节点为控制面(Control Plane),控制面的这4个组件对集群做出全局决策(比如把Pod调度到某个合适的节点上),以及检测和响应集群事件。
各组件的作用简要概括如下:
-
kube-apiserver:顾名思义是用来处理 API 操作的,Kubernetes 中所有的组件都会和 API Server 进行连接,组件与组件之间一般不进行独立的连接,都依赖于 API Server 进行消息的传送;
-
kube-controller-manager:是控制器管理器,它用来完成对集群状态的管理。其中具体包括这几个控制器,如下所示:
- Node controller: Responsible for noticing and responding when nodes go down.
- Replication controller: Responsible for maintaining the correct number of pods for every replication controller object in the system.
- Endpoints controller: Populates the Endpoints object (that is, joins Services & Pods).
- Service Account & Token controllers: Create default accounts and API access tokens for new namespaces
-
kube-scheduler:是调度器,“调度器”顾名思义就是完成调度的操作,该组件监视那些新创建的 Pod,并选择符合调节的节点让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰等。
-
etcd:是一个分布式的一个存储系统,API Server 中所需要的这些原信息都被放置在 etcd 中,etcd 本身是一个高可用系统,通过 etcd 保证整个 Kubernetes 的 Master 组件的高可用性。
2.2 Node
Kubernetes 的 Node 是真正运行业务负载的,每个业务负载会以 Pod 的形式运行。一个 Pod 中运行一个或者多个容器,真正去运行这些 Pod 的组件的是叫做 kubelet,也就是 Node 上最为关键的组件,它通过 API Server 接收到所需要 Pod 运行的状态,然后提交到我们下面画的这个 Container Runtime 组件(简单的理解也就是平时我们所说的容器)中。
各组件的作用概括如下:
- kubelet:这是运行在每个工作节点上最重要的组件,kubelet 接收一组通过各类机制提供给它的 PodSpecs(也就是Pod的期望状态),确保这些 PodSpecs 中描述的容器处于运行状态且健康。
- kube-proxy:kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络与 Pod 进行网络通信。它是实现Kubernetes Service概念的重要组件。
- Container Runtime:容器运行时,指的是负责运行容器的软件,Kubernetes 支持多种容器运行时: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI 的容器。(初学者暂时可以把container runtime等同于Docker,或者平时所说的“容器”即可)
另外,上图中还有 Storage Plugin 和 Network Plugin,这些是 Kubernetes 的插件(addons),而不是 Kubernetes 本身就实现的,这些插件使用 Kubernetes 资源 (DaemonSet, Deployment等) 的形式实现集群功能。因为插件提供的功能是集群级别的,所以插件的命名空间资源属于 kube-system
命名空间,看起来就像 Kubeenetes 本身提供的原生功能一样。比如网络插件比较出名的就有 Calico 和 Flannel。
需要强调的是,Kubernetes 的 Node 并不会直接和用户进行交互,它的交互只会通过 Master,用户通过 Master 向节点下发信息。Kubernetes 每个 Node 上,都会运行刚才提到的这几个组件。
总结:
【拓展】
为了深入理解各个组件的交互过程,对「拉起一个Pod的具体过程」需要有非常细致的了解。
3. Kubernetes 核心概念
3.1 Pod
Pod 是 Kubernetes 的一个最小调度以及资源单元。用户可以通过 Kubernetes 的 Pod API 生产一个 Pod,让 Kubernetes 对这个 Pod 进行调度,也就是把它放在某一个 Kubernetes 管理的节点上运行起来。一个 Pod 简单来说是对一组容器的抽象,它里面会包含一个或多个容器。
比如像下面的这幅图里面,它包含了两个容器,每个容器可以指定它所需要资源大小。比如说,一个1 C, 1G,或者说 0.5 C, 0.5 G。
当然在这个 Pod 中也可以包含一些其他所需要的资源:比如说我们所看到的 Volume 卷这个存储资源;比如说我们需要 100 个 GB 的存储或者 20GB 的另外一个存储。
在 Pod 里面,我们也可以去定义容器所需要运行的方式。比如说运行容器的 Command,以及运行容器的环境变量等等。Pod 这个抽象给容器提供了一个共享的运行环境,它们会共享同一个网络环境,这些容器可以用 localhost 来进行直接的连接。而 Pod 与 Pod 之间,则是互相隔离的。
3.2 Volume
Volume 就是卷的概念,它是用来管理 Kubernetes 存储的,是用来声明在 Pod 中的容器可以访问文件目录的,一个卷可以被挂载在 Pod 中一个或者多个容器的指定路径下面。
而 Volume 本身是一个抽象的概念,一个 Volume 可以去支持多种的后端的存储。比如说 Kubernetes 的 Volume 就支持了很多存储插件,它可以支持本地的存储,可以支持分布式的存储,比如说像 ceph,GlusterFS ;它也可以支持云存储,比如说阿里云上的云盘、AWS 上的云盘、Google 上的云盘等等。
3.3 Deployment
Deployment 是在 Pod 这个抽象上更为上层的一个抽象,它可以定义一组 Pod 的副本数目、以及这个 Pod 的版本。一般用 Deployment 来做应用的真正的管理,而 Pod 是组成 Deployment 最小的单元。
Kubernetes 是通过 kube-controller去维护 Deployment 中 Pod 的数目,它也会去帮助 Deployment 自动恢复失败的 Pod。
比如说我可以定义一个 Deployment,这个 Deployment 里面需要两个 Pod,当一个 Pod 失败的时候,控制器就会监测到,它重新把 Deployment 中的 Pod 数目从一个恢复到两个,通过再去新生成一个 Pod。通过控制器,我们也会帮助完成发布的策略。比如说进行滚动升级,进行重新生成的升级,或者进行版本的回滚。
3.4 Service
Service 提供了一个或者多个 Pod 实例的稳定访问地址。
比如在上面的例子中,我们看到:一个 Deployment 可能有两个甚至更多个完全相同的 Pod。对于一个外部的用户来讲,访问哪个 Pod 其实都是一样的,所以它希望做一次负载均衡,在做负载均衡的同时,我只想访问某一个固定的 VIP,也就是 Virtual IP 地址,而不希望得知每一个具体的 Pod 的 IP 地址。
我们刚才提到,如果一个 Pod 失败了,可能会换成另外一个新的。对一个外部用户来讲,提供了多个具体的 Pod 地址,这个用户要不停地去更新 Pod 地址,当这个 Pod 再失败重启之后,我们希望有一个抽象,把所有 Pod 的访问能力抽象成一个第三方的一个 IP 地址,实现这个的 Kubernetes 的抽象就叫 Service。
实现 Service 有多种方式,Kubernetes 支持 Cluster IP,上面我们讲过的 kuber-proxy 的组网,它也支持 nodePort、 LoadBalancer 等其他的一些访问的能力。
3.5 Namespace
Namespace 是用来做一个集群内部的逻辑隔离的,它包括鉴权、资源管理等。Kubernetes 的每个资源,比如刚才讲的 Pod、Deployment、Service 都属于一个 Namespace,同一个 Namespace 中的资源需要命名的唯一性,不同的 Namespace 中的资源可以重名。
比如运行 kubernetes 本身需要的一些基础组件,也就上面提到的kube-apiserver,kube-proxy等,他们的 Namespace 就是 kube-system
。
➜ ~ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-tzbcz 1/1 Running 1 21h
coredns-66bff467f8-x6jml 1/1 Running 1 21h
etcd-minikube 1/1 Running 0 20h
kube-apiserver-minikube 1/1 Running 0 20h
kube-controller-manager-minikube 1/1 Running 1 21h
kube-proxy-77nj4 1/1 Running 1 21h
kube-scheduler-minikube 1/1 Running 1 21h
storage-provisioner 1/1 Running 3 21h
参考: