首页 » 云自动化 » k8s » 正文

K8S架构自动化深层解析

提到K8S这离不开三件事情即微服务,容器和 DevOps。关于微服务和容器这两个部分在这里就不多做解释。我重点介绍一下 DevOps。DevOps 是 2007 年比利时的一个 IT 咨询师提出来的。当时他在给比利时的一个国企做一个大型数据中心迁移的项目。他白天支持开发人员做敏捷开发,晚上他接着支持运维团队把白天迭代出来的产品进行上线。

那时开发和运维之间存在很大差异。比如白天与开发人员未沟通清楚 Issue,在晚上运维人员就不知如何操作,如此产生很多弊端,导致工作效率低下。但是,这个 IT 咨询师有很强的抽象能力,在他不断的实践思考之后,提出了 DevOps 这个理念。DevOps 讲的就是是否存在更好的组织架构、流程来节约交付时间,是否存在更自动化的方式提高交付速度,更好地验证交付质量。这就是 DevOps 的一个核心诉求,它关心的是时间和质量两个问题。

但是从 DevOps 最开始产生到现在,它从未明确定义应该利用什么工具、方式以及流程。DevOps 一直都是一个概念,一种文化,这也是自 2007 年到现在 DevOps 才真正被大家认可,被更多企业接受的原因。因为它是一个无形的东西,它不像 Docker,可以实际进行容器化交付。

什么是 DevOps?

DevOps 不存在一个能够被大家借鉴和认可的范式一样的流程。在以前,大部分企业可能是采用一个非常大型的单体化架构设计,使用瀑布流的方式进行开发,这样会导致组织结构变得异常复杂。信息流在不同的部门之间流转很慢。因为这是一个很大型的单体应用,很难保证每一个 Feature 上线的质量。这就是 DevOps 难以在很短的时间落地,被大家认可的原因。

为什么最近 DevOps 被人们认同且有很大的影响力?

首先,这个可能要归功于微服务的这个概念。微服务这个概念是 2014 年提出来的。微服务简单来说是一种分而治之的思想。它把一个大型的单体系统切分成很多自包含的,有自己生命周期的子系统。每个子系统都有一个自己的服务边界,通过独立的负责人员,进行更快交付、更快迭代,产生更小代价来验证自己的质量。

所以从这个角度来讲,微服务的提出,以及企业对微服务的实现,无形中帮助了 DevOps。当你去切分这样一个微服务的一个场景,你会发现你的每一个模块都会有独立的负责人。原本大兵团作战的场景,逐渐演进成向小团队快速迭代的方式。

第二,当微服务以一个非常小的 Scope 进行连续迭代时,迭代的速度以及验证的速度都会很快,如此 DevOps 原本关注的时间部分就被很好的解决了。所以微服务从架构、流程和质量上解决了 DevOps 的一些缺陷。但微服务并不是万能的,当你把一个大型的单体系统切分成十个或二十个子系统时,对于微服务的管理实际上是一个很大的挑战。而且微服务是对于不同场景,不同模块,选择一个合适的框架或语言来构建的。

但是这并不适用于所有情况。举个例子,在一个团队中,原本大家都是用 Java 去写 Code,每个成员都可以总结出很多公共的类库,大家可以一起统一代码风格。但如果这个事情变成了很多语言,不同的框架去完成这样一个大型系统时,你会发现很多公共的部分是不能使用的。这种公共部分在交付的时候就会变成一个没有标准的场景。发生这种情况应该如何解决?诸如此类情况就可以由 Docker 来解。

但是不论是 Java 的应用,还是 NodeJs 的应用,或是 Golang 的应用,最终都会变成一个 Docker image。你可以用同样的方式去生成一个中间构建的产物,而这个交付的产物可以用同样的命令进行运行。比如说不论你是 Java 应用,还是 NodeJs 应用,都可以用 Docker 去执行它。Docker 通过标准化的方式去协助提升微服务实现。

为什么 Kubernetes 逐渐被大家默认为是容器编排标准的制定者?

从我自己的理解来看,Swarm 是这几个容器编排里最简单、最友好,开发者学习成本最低的。但 Kubernetes 它不仅仅定义了编排系统怎么做,还说明了开发者如何与社区进行结合。就比如在 Kubernetes 中,它并不关注容器网络如何做,而是关注开发者定义了一个什么样的标准,是否符合开发者的某个标准开源组件,是否可以与开发者的 Kubernetes 进行结合。

在 Kubernetes 中可以使用 Flannel,可以使用 Calico,可以使用各种各样的网络方案。这些都符合 Kubernetes 定义的 CNI 标准。所以 Kubernetes 相比 Swarm,定义了一个标准、一个平台。而 Swarm 更多的是通过一个 lib 的方式去执行。

从物理节点上看,Kubernetes 分为 Master 节点和 Worker 节点。在 Master 节点上面会部署 kube-apiserver,API Server 是 API 的一个提供者。etcd 是作为数据存储的部分。kube-scheduler 用来负责 Pod 调度的部分。cloud-contoller-manager 是和 IaaS层沟通的组件。最下面的 kube-contoller-manager,是对于很多资源对象的一个管理组件。右侧是每一个 Worker 节点运行的组件,包括 Kubelet 和 kube-proxy。Kubelet 用来执行一些具体任务、具体命令。而 kube-proxy 主要是解决一些网络问题。

我们通过一个具体的 Pod 生命周期,来了解这些组件之间是如何进行通信以及协作运转。

这是一个 Pod 的生命周期。举个例子,我在 Kubernetes 里边创建了一个 Pod,它的执行流程是什么?首先我下达一个 Pod 的 yaml,API Server 是整个 Kubernetes 的驱动机,接收到 Pod 的 yaml。

Kubernetes 的 API Server 是把一些相应的配置透传下去,然后提供一些接口,能够让别人获得这个数据。当你创造一个 Pod 时,API Server 只是把相应的一个文件透传下去,然后回写给 etcd。而 etcd 会去 watch API Server 的一个接口。

当 Pod 有变化时,kube-scheduler 会计算整个 Kubernetes 集群里 Worker 节点的资源利用率,相应的调度会约束选择一个节点给这个 Pod。但它并不是直接以命令的方式执行创建 Pod,而是把相应的这个 Worker 节点的信息传到 yaml 上,在 yaml 上增加一条配置,指定这个 Pod 在那个节点上执行。接下来,真正去执行这个 Pod 创建的动作是 Kubelet 调用的 Docker。

当 Kubelet 发现 Pod 配置的变化,并且分配节点的 Node 是自己,那么 Kubelet 会把这个 yaml 拿下来,调用 Docker 去真正执行这个 Pod 创建动作。当这个 Pod 创建有任何问题时,它会更新 yaml 的 Status 字段,然后再回写给 etcd。这就是一个 Pod 的生命周期。

这种设计和传统的设计有什么区别?如果是 Swarm,它又会怎么做?Swarm 是命令式设计,Swarm Master 拿到一个 yaml 会直接把这个透传到底下的 Docker 再去创建。这是命令式的创建。而 Kubernetes 是基于状态机的创建。这是 Swarm 和 Kubernetes 在原理上一个比较大的差异。

K8S 集群中节点级别的弹性伸缩如何实现?

答:在 Kubernetes 社区里有一个组件叫 Autoscaler,它是用来做节点级别的弹性伸缩。在 Kubernetes 中弹性伸缩分为三种:

HPA,基于容器的水平的伸缩;

资源的垂直伸缩,相当于一个 Pod 的动态资源调增的伸缩;

弹性伸缩,是基于 Node 的开源组件 Autoscaler。

Kubernetes 本身与 IaaS 并不相关。但是 Kubernetes 里边有一个专门对接云平台的组件 Cloud Provider,它与 IaaS 层有密切的联系,所以用户可以通过 Autoscaler 组件去监听 Node 的负载变化,然后动态地来弹性伸缩这个集群节点的数目。

在 Kubernetes 里设置好用户需要的资源申请值和限制值。不论是 HPA,还是 Autoscaler,它都是基于调度来计算的。就比如 Autoscaler 和传统的弹性伸缩是有区别的。传统的伸缩是基于阈值水位去实现的。

比如 CPU 到了 80%,就可以开始扩容。但是在 Kubernetes 里的伸缩是基于调度的。也就是用户把这个 request 设置好,当 Kubernetes 发现这个 request 值不能满足调度时,它会弹性伸缩这个节点。所以用户经常在 Kubernetes 里能看到资源利用率可能还没到达顶峰,但是对于 Kubernetes 来说,request 已经达到这个阈值了,而不能去调度,此时就会产生弹性节点。

赞 (1)

发表评论