1. 简介

  我们可以使用docker runnerdctl run这样的命令来创建一个一个的容器, 那么我们在创建这些容器的时候,其实一个一个去创建的话整个的性能太低,而且假如说需要创建几十个或几百个容器的话,手动创建基本是不太现实的,所以说我们是需要一个更高层的编排工具。
  常见的编排工具有:kubernetes、红帽的openshift、twitter的mesos、docker的swarm等,不过目前来说kubernetes已经是一家独大而且基本是标准了。在k8s中不需要我们再去操作容器了,而是由k8s来帮我们管理容器,维持我们想要的容器状态。
  k8s本身并不提供容器创建的功能,它需要调用runtime,而runtime的类型还是挺多的比如说dockerpodmancontainerdrktcri-o等,对于k8s来说它有一个代理叫kubeletkubelet需要和各个runtime做关联。在k8s刚发布的时候基本上是docker一家独大,其他运行时基本不成气候,所以说kubelet内置了docker的代码来连接到docker,随着时间推移容器界百花争鸣像containerdrktpodman等项目说我也想成为你k8s的runtime,为了统一runtimek8s在kubelet上开放了一个CRI标准,你们开发的产品只要符合这个CRI标准那么我就可以使用你们产品作为runtime,然而docker并不支持CRI协议,一开始k8s是妥协的,就把docker-shim集成到kubelet中,直到1.24版本k8s把docker-shim从kubelet中剔除掉,docker又不支持CRI标准,要使用docker作为runtime则需要一个cri-docker作为转接口。所以作为k8s管理员,发布一个请求说我要创建一个容器,创建容器的时候是由kubelet调用后端的runtime最终创建出来的。

2. 理解pod

  我们使用nerdctl创建出来的都是一个一个的容器,而使用k8s进行管理的时候创建出来的都是一个一个的pod,那什么是pod?所谓pod就是包装好了的强化功能的的容器,一个pod中所有容器共享网络空间,在k8s里最小的调度单元就是pod.

3. k8s框架

  其实虚拟化和云平台的架构都是类似的,首选也需要有一个控制台,这个控制台我们称为master或称为control plane,其次还需要一个一个的工作节点我们称为worker node,它是专门用来运行容器的,所以需要在在每个node节点装上runtime ,然后需要一个client端可以是命令行也可以是图形界面,来连接到master节点的kube-apiserver组件(需要通过认证),再通过鉴权才可以创建出来pod,那么k8s如何知道pod创建到哪个node节点呢,那么就需要引出第二个组件kube-scheduler调度器这个组件他会根据自己的算法,根据node节点的cpu内存等资源进行打分,分值越高约优先进行调度。之后kube-apiserver就会通知kubelet进行容器创建,kubelet就会调用runtime通过pause这个镜像创建出需要的pod。看似一切都OK了,那么如何保证pod运行正常呢,那么就需要引出另一个master组件kube-controller-manager其中包括了namespace控制器、node控制器、deployment控制器等等。因此可知pod是不稳定的,当pod重建以后里面的容器IP就会发生变化,那么如何保证可以连接到pod呢,就需要引出另一个node节点组件kube-proxy,这个组件有两种模式iptablesipvs把流量转发到指定的pod,具体实现通过k8s自定义类型service简称svc,通过配置svc标签选择器来找到指定的pod的endpoint。我们知道宿主机之间有层网络,pod有层网络,service有层网络,那么如何保证pod层和service层网络可以跨主机通信呢,那么就需要通过隧道协议来打通各主机间虚拟网络,具体实现方式有BGPopenvswitchvxlan等技术.这太难了!!!,不用担心,有一些厂商或组织开发出符合CNI(容器网络接口规范)的产品他们已经把这些技术封装到产品里,我们只需要安装指定的产品配置即可使用,例如:calicoflannel等,这些产品我们统称为CNI网络插件。到目前为止,我们所有的配置都需要保存下来做持续化存储,k8s中用到的持久存储是etcd,存储了集群信息,包括cni网络插件信息也需要持久化到etcd中

4. k8s组件

  • kubectl:客户端命令行工具。
  • kube-apiserver:作为整个系统的控制入口,以REST API服务提供接口。
  • kube-controller-manager:用来执行整个系统中的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。
  • kube-scheduler: 接受来自kube-apiserver创建Pods任务,分配到某个节点。
  • etcd:存储集群信息的分布式存储。
  • kube-proxy: 运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。
  • kubelet:运行在每个计算节点上,作为agent,接受分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver。