本文主要介绍Kubernetes 的核心组件、架构、服务编排,以及在集群规模、网络&隔离、SideCar、高可用上的一些使用建议,尤其是在CICD中落地,什么是 GitOps. 通过此文可彻底了解 k8s 的整体核心技术以及如何应用在 DevOps 实践中。
荣辛是我的同事,阿里云过来的一位大佬,我也把他邀请到了我们「研发效能DevOps」群中。Kubernetes 在现在的云原生体系基础设施中的地位太重要了,无论是做 Dev 还是 Ops 都要了解一些,欢迎大家一起来讨论。本文内容大纲如下
云原生(Cloud Native)是一种构建和运行应用程序的方法,是一套技术体系和方法论。
CNCF(Cloud Native Computing Foundation,云原生计算基金会)在定义中给出了云原生的关键技术,容器、服务网格、微服务、不可变基础设施和声明式API,是目前云原生应用的最佳实践。
微服务架构向开发人员提出新的挑战。应用向微服务演进的过程遇到新的问题?
云原生就是面向云环境的,从设计层面支持自动伸缩容,资源控制和支持统一服务注册/发现的应用 。
容器的兴起
容器的本质是一个特别的线程
但是容器和容器之间的关系如何维护?如何编排容器?
实际上,过去很多的集群管理项目(比如 Yarn、Mesos,以及 Swarm)所擅长的,都是把一个容器,按照某种规则,放置在某个最佳节点上运行起来。这种功能,我们称为“调度”。
而 Kubernetes 项目所擅长的,是按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系。这种功能,就是我们经常听到的一个概念:编排。
所以说,Kubernetes 项目的本质,是为用户提供一个具有普遍意义的容器编排工具。不过,更重要的是,Kubernetes 项目为用户提供的不仅限于一个工具。它真正的价值,乃在于提供了一套基于容器构建分布式系统的基础依赖。
Pod,是 Kubernetes 项目中最小的 API 对象。Kubernetes 项目的原子调度单位。
容器本质是线程,那么K8s管理容器就对应着操作系统,在OS中管理线程是以线程组的形式存在,因此通过Pod的对象将进程组的概念映射到容器的世界里。
可是对于容器来说,一个容器永远只能管理一个进程。更确切地说,一个容器,就是一个进程。这是容器技术的“天性”,不可能被修改。所以,将一个原本运行在虚拟机里的应用,“无缝迁移”到容器中的想法,实际上跟容器的本质是相悖的。
工作负载/控制器类型
此外:
服务编排通俗地说就是将一个服务在合适的时间放在一个合适的地方,让其按照规划的方式运行。
首先,通过 APIServer 的 LIST API“获取”所有最新版本的 API 对象;
然后,再通过 WATCH API 来“监听”所有这些 API 对象的变化。
Informer 就可以实时地更新本地缓存,并且调用这些事件对应的 EventHandler 了。
List&Watch关键设计:
性能瓶颈
API资源对象在ETCD里面是以JSON格式来存储的,而K8S的API对象是以protobuf格式存储,在资源对象数量多的时候JSON的序列化和反序列化性能会成为瓶颈。
单集群(可用区)规模(NC数量):
- 自建网关 适合多集群,多可用区场景
- Ingress 适合单集群场景
Kubernetes 这种声明式配置尤其适合 CI/CD 流程,况且现在还有如 Helm、Draft、Spinnaker、Skaffold 等开源工具可以帮助我们发布 Kuberentes 应用。
技术选项:
Kubernetes :: Pipeline :: DevOps Steps Kubernetes CLI Plugin Kubernetes plugin Kubernetes Credentials Plugin
GitLab Plugin Generic Webhook Trigger Plugin
实战范例参考
https://juejin.cn/post/6963466680613896206
GitOps 是一套使用 Git 来管理基础设施和应用配置的实践。对于 Kubernetes 来说,这意味着任何 GitOps 操作者都需要依次自动完成以下步骤:
在 Kubernetes中发布应用时,需要注意的内容总结概括为以下8条 :