借用封面以感谢Aly Saleh & Murat Karslioglu
image.png

注:仅用于学习和交流,请勿转载/推广。

Kubernetes 基础设施和生产准备工作简介

随着越来越多的公司使用kubernetes作为他们的基础设施管理平台,kubernetes也逐步成为云上和本地管理和编排分布式应用的行业标准。所以无论你是独立完成公司内应用迁移的开发人员还是作为领导负责公司的云专项工作,你都应该学习kubernetes并了解他们落地过程中的挑战。
当你准备把kubernetes建设成为公司生产环境基础设施的过程中会遇到许多常见的问题,本书的核心宗旨就是指导你解决这些问题。在过去这些年里,我们在不同规模的kubernetes集群的建设和操作中非常多的成功和失败案例,我们这本书将会教会你如何避免这些错误,降低时间、经济成本的同时提高集群可靠性进而达到你的业务目标。
在本章节,我们讲述了如何在生产环境中部署kubernetes集群的最佳实践,同时也会说明书中剩余部分脉络,除此之外也会对于kubernertes的在设计和实施过程中的基础概念进行一个基本的介绍,而这些概念和设计原则也是我们进行生产基础设施建设的关键。最后,我们会明确读书的目标与我们保持一致(俗称,对齐)。
下面会详细介绍本书解决的核心问题,例如k8s生产挑战、准备生产环境的注意事项、云原生落地、基础架构设计以及管理原则。下面在本章中会介绍如下内容:

  • kubernetes基础设施的基础知识
  • 为什么使用kubernetes作为生产环境会具有挑战性
  • kubernetes生产环境准备事项
  • kubernetes生产最佳实践
  • 云原生之路

kubernetes基础设施之基本概念篇

如果你已经在阅读这本书,那么你已经决定把你的k8s基础设施提升到一个更好的水准,这也意味着已经不仅仅停留在技术评估的阶段。完成生产的基础设施建设对于整个团队仍然需要巨大的投入,这就需要我们足够理由来说服领导,在本篇中我们会尽量明确说明这个原因,并且阐明这个过程中可能遇到的挑战。
在过去几年里,全世界范围内Kubernetes使用者呈现爆炸式的增长,如International Data Corporation (IDC) 所预测的,在2021年的时候会有将近95%的微服务部署在容器中,目前大多数公司已经发现,容器和k8s能够优化成本,简化部署和操作流程,缩短上市时间,除此之外在混合云市场中也扮演着极为重要的策略。同样高德纳(咨询公司)也预测相比于2019年不足20%公司使用容器来部署应用,2021年会达到70%。
image.png
译文:k8s是用来自动化部署、扩缩容以及管理容器应用的开源系统。

为了更好的搭建一个高可用的kubernetes集群,我们会对他的组织架构进行讲解进而说明其中的挑战。kubernetes是一个标准的客户端-服务端架构的分布式系统,可以使用一个或者多个节点作为主节点(Master Node)来运行他的控制面系统组件,工作节点(下图中的Node)上会部署pod和负载均衡,单个集群最多能够管理5000个工作节点,详细的架构如下

image.png
上图展示了典型的高可用的K8S架构及其核心组件,目前对于K8S的集群架构有了基础了解,我们会在下一章节深入的介绍他们之前的通讯过程,详细创建和集群配置过程中的通信方式。

控制面组成

控制面是组成K8S集群Master 节点(Master Node)的核心部分,这些组件除了etcd之外都是属于K8S项目(etcd是独立的项目,KV存储),主节点的核心组件符合分布式架构的理念能够无状态的扩缩容来提高集群的性能的同时保障系统的可用性。

  • Kube-apiserver:系统的管理口,用于集群间通信以及处理和服务API的管理接口。
  • Etcd:分布式高可用的KV存储,用户保存系统的所有有状态数据。
  • Kube-controller-manager:集群的管理控制器,例如node控制器、replication控制器以及endpoint控制器用来管理平台对应的资源型为
  • Kube-scheduler:负责pod在集群中的跨界点调度,会根据调度算法、可用资源和配置来决定pod调度到哪个node上

    Node组成

    Node上运行这一组agent服务来维护运行中的pod,同时提供节点上pod的网络代理和基础运行环境。

  • Kubelet:运行在节点上的agent服务,会定期的拉取一组pod的yaml文件来确定是按照正确的配置运行,同时像master节点上报node的运行状态

  • Kube-porxy:运行在每个pod上的agent服务,用于创建、更新和删除node上的网络规则,目前是使用的linux自带的iptables实现(当然这是基础的实现,各个网络方案实现都有所不同),这些网络规则实现了集群内外容器之间的通讯。
  • container runtime:容器运行时,docker是目前用的比较多的运行时(docker底层也是调用containerd来实现,并且在新的版本被kubernetes抛弃),另外还支持CRI接口以及containerd来运行容器,使用kubervirt以及virtlet来运行虚拟机。

    生产环境Kubernetes带来的挑战

    Kubernetes是安装起来简单,但是维护和操作起来比较复杂。在生产环境中使用K8S会带来一些列的挑战,包括规模挑战、运行时间(这个uptime我其实没太懂)、安全性、弹性能力、可视化、资源有效利用以及成本的管理。K8S在容器的管理和编排的解决方案上非常成功,甚至对于计算服务总结出了统一的标准。然而在某些必要的服务上仍然没有完善的解决放哪,例如身份认证和管理、存储以及镜像注册?(这个暂时不太确定是对于镜像能力哪里的质疑)
    通常来说,即将把Kubernetes集群建设成为一个较大规模公司的基础设施时,他们已经建设了自己的数据库,IAM、轻量级目录访问协议(LDAP),消息队列,流处理等一些服务。这需要我们把k8s和这些已经存在的外部技术设施完成通信。上云项目中,我们希望k8s能够管理和集成本地的基础设施和服务,这也带来了更高的复杂度。
    除此之外的挑战是当一个团队使用K8S时已经天然的解决了应用的扩展以及运行问题,但是他们对于未来可能遇到的问题不会提前规划,这就会在安全性、扩展性、运行态、资源利用率、集群迁移、更新以及性能调优上产生灾难性后果。
    除了基础的挑战之外还会有管理上的挑战,特别是我们多个团队组成的引入k8s的时候,当我们组织架构并没有调整出合适的团队来运营和管理k8s的基础设施时,这会导致整个团队的标准化、最佳实践和交付工作流程调整难以落地。

Kubernetes生产环境准备事项

image.png
译文:能够把kubernetes投入生产使用的标志就是能够同时满足业务的增长以及客户的期望。(有点别扭?)
完成k8s的生产准备工作是我们本书需要实现的目标,但是对于这个流向词还没有一个明确的定义,这个词意味着集群可以给生产环境的负载和流量服务提供可靠且安全的环境。我们可以对这个定义进一步扩展,但是众多专家一致人为这是我们生产就绪集群需要满足的最低标准。下图是我们根据典型的K8S生产分层进行的收集和分类,我们也明白这些仍然每个组织有不同生产用例、业务增长以及业务目标,进而也会有不通的业务准备要求,然而我们仍然可以把下面的清单作为大多数主流场景的准备工作。
image.png

上图描述的kubernetes基础设施的典型的分层,一共分为六层包括:物理层的本地和云基础设施(自建机房、私有云和公有云)、基础设施服务层(数据、存储和vm等服务)、集群层(控制面和node)、集群服务层(认证、DNS等)、应用支撑层(包括负载均衡、证书等)及应用层(应用和负载均衡),后续深入学习书籍的过程中会展示如何设计Kubernetes生产架构并且无缝的结合起来。

生产准备checklist

我们已经对于生产准备清单进行分类并给对应到响应的基础设施的分层中,每个checklist项都代表我们生产准备工作中解决的设计和实施关注点,后面的数据中会对每个项目、设计方案和实施计划进行详细介绍。

  • 运行高可用的控制面:可以通过讲控制面运行在三个及以上的节点(三个及以上的master节点)上,另外推荐的最佳实践是把master节点和etcd分开部署,分开部署主要是为了简化etcd的操作,例如升级、备份并且减少控制面的故障半径。当然,对于大规模的kubernetes集群来说,我们需要把etcd运行在IO性能比较高的节点上。最后,避免混部(应用的pod调度到Master节点上)。
  • 运行高可用的工作组:这需要我们每个工作组运行三个及以上的实例来实现高可用,如果我们的工作组都使用一个公有云厂商,我们需要在不同可用区实现自动拓展的配置。另外一个必要条件是需要实现集群的弹性伸缩能力,这会根据节点的资源使用率实现水平的扩容和缩容。
  • 使用共享存储管理解决方案:你应该选择使用共享的存储来持久化的保存和管理有状态应用的数据,目前有非常多的选择,无论是开源的还是商用的,例如AWS的EBS、EFS以及Google Persistent Disk、Azure Disk Storage、Rook、Ceph以及 Portworx ,这些选择并无对错,只是看你的使用需求而已。
  • 部署可观测性基础设施(这里其实值得是监控、告警系统和日志系统):在集群收集节点、网络、存储和其他基础设施的日志和监控指标是至关重要的,特别在集群性能、可视化和故障排查中。你应该部署一个监控系统和告警系统,例如node exporter、prometheus、grafana以及日志收集的ELK。或者也可以考虑商业化解决方案例如Datadog、New Relic和AppDynamics 这些。

满足上面的要求可以保证生产的准备工作,在后面的书籍中,我们会详细的展示如何通过基础设施的设计、kubernetes的配置以及第三方工具来完成。

Cluster services

下面的checklist项需要在集群服务级别生产上线之前完成准备:

  • 控制集群访问:集群引入认证和授权选项来让集群管理员根据需求进行配置。在最佳实践中,你需要保证认证和授权配置已经到位,同时与第三方认证系统集来共同实现集群权限管理,例如LDAP、OIDC和AWS的IAM。对于集群管理人员,你需要配置集群以支持RBAC(角色空空盒子)、ABAC(属性控制)和webhooks。
  • 加固默认pod的安全策略:psp(pod安全策略)是一种kubernetes的一种资源来保证pod必须要满足特定的条件才能够被创建。作为最佳实践,我们建议限制kube-system空间内的所有特权pod,对于其他应用使用的namespace建议分配一个限制性的默认PSP
  • 执行自定义的策略和规则:无论是小租户集群还是多租户的大集群,规则和策略都是至关重要的,kubernetes引入了原生对象来实现这个能力,例如pod安全策略、网络策略、资源限制和配合。对于自定义的策略,你可以部署一个开放策略代理,例如OPA Gatekeeper,可以保证规则的强制执行,例如pod必须有资源限制,namespace必须有特定的label,镜像必须从固定的镜像仓库拉取等。
  • 部署并微调集群的DNS:对于kubernetes集群的域名解析和服务链接来说DNS至关重要,管理kubernetes需要提前部署DNS例如coreDNS,对于自己管理的集群,也需要部署coreDNS。在最佳实践中,你需要调整最小错误、故障率、优化性能、缓存策略以及解析时间。
  • 部署并限制网络策略:kubernetes集群默认允许单集群中所有pod之间的任意访问,这在多租户的集群中是不安全的。在最佳实践中,需要创建一个默认拒绝的网络策略来组织集群内pod间的所有流量,然后在创建较少限制的出入向规则的策略来保证特定pod之间的通信。
  • 启用安全检查和一致性测试:保证集群的安全是毋庸置疑的,我们需要启用和微调许多安全配置来保证集群的安全,这对于集群管理员来说非常痛苦,不过幸运的是我们有需要不同的工具可以扫描集群的配置来评估和确保集群能够满足最低的安全需求,而我们需要的是自动运行这些安全工具,例如kube-scan来扫描集群的安全配置,kube-bench来保证安全的基准测试和sonobuoy来保证集群标准的一致性测试。
  • 部署一个备份和恢复的解决方案:与其他任何系统一样,kubernetes也可能会出现问题,这需要有一个合适的备份和恢复过程,这就需要考虑使用北分工具来备份和快照集群的控制面数据或者是etcd的数据库。
  • 部署集群的监控系统:监控和中心日志对于kubernetes来说至关重要,你需要部署一个监控系统来收集集群的监控信息,例如node exporter、prometheus、grafana以及日志收集的ELK。

满足上面的需求才能够保证生产准备已经就绪,在后面的术中我们会详细的说明如何通过调整集群配置以及使用第三方工具来实现这个目标。

Apps and deployments

以下内容涵盖了应用程序和部署级别的生产准备要求:

  • 自动化执行镜像质量和漏洞扫描:一个低质量的应用或者是低质量代码的应用会应用集群的其他程序和集群自身的稳定性,对于安全漏洞来说也是如此,所以你需要运行一个通道来扫描集群中的镜像来保证他满足安全漏洞和质量标准的要求。
  • 部署ingress controller:默认我们可以使用load balance和 nodeport暴露kubernetes的service到公网,但是大多数的应用会有更多的路由需求,这就需要我们部署一个nginx的ingress controller来解决此类问题。
  • 管理证书和密钥:现在的应用通常用密钥和tls证书,kuberntetes带有一个内置的secrets来简化证书和密钥的创建和管理,你可以部署第三方的服务来拓展secret,例如Sealed Secrets 来加密secret,以及Cert-Manager来自动化的管理和提供证书Let’s Encrypt 和Vault。
  • 部署应用的可观测性堆栈:可以使用kubernetes内置的监控能力,例如自定义的readiness和liveness探活,除此之外,要给应用的pod部署一个中心的日志收集进程,部署一个黑盒的监控解决方案或者是使用托管服务来见监控应用的endpoints。最后,考虑使用应用程序监控解决方案,例如New Relic APM, Datadog APM, AppDynamics APM 等

满足以上的要求可以确保应用程序和部署生产环境的准备工作,在后面的章节中,我们更相信的展示如何使用kubernetes的配置和第三方工具来满足这些要求。

kubernetes 基础设施最佳实践

我们已经学习了kubernetes基础设施的基础知识并且对于kubernetes的生产准备工作有了更深的理解,现在我们需要准备好基础设施的最佳实践和设计原则。我们讲带领你搭建并操作你的生产集群。

基础设施设计和管理的12项原则

构建一个弹性且稳定的kubernetes基础设施需要我们不仅仅是使用配置工具启动和运行集群,坚实的基础设施设计是由一系列的架构决策和实施来组成,幸运的是许多组织和专家讲这些原则和架构决策投入到真实的测试中。
下面的列表总结基础设施设计的过程中决策者需要考虑的核心原则,通过这本书,你可以详细的学习并使用这些原则:

  1. 托管:尽管托管服务比自行管理要贵许多,但是还是更倾向于使用托管,几乎在任何的情况下,托管服务比自管理更加的高效、可靠,可以选择例如GKE、AKS和EKS等托管服务。而过管服务本身不属于任何一个技术设施,例如数据库、对象存储、缓存等,虽然托管服务在自定义能力上和价格优势上不如子管理服务,但是在其他的任何方面都更有优势。
  2. 简化:kubernetes不仅仅是个平台,也不仅仅是设置和操作,在云原生和微服务的场景下,大多数应用选择它用于解决服务数百万用户带来的互联网工作负载的复杂性。对于基础设施的创建和操作我们不需要在增加额外的层级,因为基础设施对于对产品应该是无缝且透明的,公司的关注点还是要集中在产品本身而非基础设施。对于简化的原则来说,我们不选择负责解决方案而是选择简单的解决方案,这要求我们在没有充分的用例证明的情况下要尽量减少操作的集群并且尽量避免多云环境。简化原则适用于我们的基础设施以及部署在集群中的应用,因为如果添加单个的服务组成一个功能丰富的集群非常具有吸引力,但是这会提高平台的复杂性并且降低它的稳定性。除此之外,我们还可以把这个原则用于技术栈和工具的选择上,即使是多种多样的工具会有一些非常好的特异性,但是事实证明统一的工具和技术栈会更有效。
  3. 一切即代码:对于现代的基础设施和devops团队来说这已经是一条共识,我们需要使用声明性的IaC和CaC工具和技术而不是命令行的方式来进行。(这块翻译的不太好,我理解就是CI平台的建立和实现)
  4. 不可变基础设施:当我们每次部署发布替换系统组件而不是直接的更新系统就是为了基础设施提供的不变性,当我们构建、测试和验证这些不便的系统并得到预期结果的时候,我们一直在使用镜像或者声明式的代码来创建不便的组件,就像docker的镜像和AWS的EC2 AMI一样。这个重要的原则让我们实现了kubernetes集群最重要的一个特性:将集群视为家畜而非宠物(这块翻译的不太好,我理解表达的意思是因为有个IaC,基础设施是代码,通过容器能够随时的构建一个新的服务并且投入生产,而且kubernetes的系统组件也是通过容器启动也具有销毁之后随时启动的特性)
  5. 自动化:我们本身是生活在一个软件自动化的时代,因为我们倾向于自动化一切,可以更高效和简单的实现管理和扩容,但是我们可以使用kubernetes把自动化提高到更高的水平,kubernetes实现了容器的生命周期自动化管理,这也带来了更先进的自动化概念,例如operator和GitOps,通过他们可以实现真正的自动化
  6. 标准化:拥有一些列标准能够帮助我们减少团队协调和合作中带来的困难,简化的流程能够提高整体的质量和生产力。而这对于计划在生产环境使用kubernetes的公司和团队至关重要,因为这涉及到不同基础设施的集成、本地环境到云上环境的迁移以及其他负责的问题。定义一套标准流程用来规范自动化运营脚本、执行脚本以及docker、kubernetes和夸团队工具集,这些工具应该距有这些特性:开源但是经过生产实战的验证,遵循全部原则例如基础设施即代码、与云供应商解耦(不依赖某个、几个云厂商)、易于使用以及最少的基础设施部署
  7. 单一数据源:具备单一数据源是现代基础设施管理和配置的基石和强有力的推动者,例如Git这种源代码控制系统是进行基础设施代码保存和版本管理的标准选择,拥有一个单一且专用的基础设施代码仓库是当前的最佳实践。
  8. 可用性设计:kubernetes是基础设施和应用层高可用设计的关键推动项,从第一天开始把高可用作为核心设计是获得kuberntetes全部能力的关键点,所以在每一层的设计中都应该考虑高可用,从云和IAAS层开始选择多可用区的架构设计,然后在kubernetes层使用多主节点,最后在应用层部署每个服务多副本部署。
  9. 云供应商解耦:实现云厂商解耦意味着能够在提供最基础能力上运行你的工作负载,你需要一直记住并且驳斥这个目标。docker和kubernetes是由社区创建和管理并不依赖于云厂商的平台,这个原则也同样适用于你的技术和工具的选择(想一想 Terraform 和CloudFormation )
  10. 业务连续性管理:具有弹性的公有云解决了阻碍业务连续性的问题,尤其是他能够及时拓展基础设施的能力,这让小公司也具备了大公司才有拥有的基础设施的能力。然而,日益增长的扩容需求以及实时性要求仍然是个巨大挑战,通过引入容器部署和运行应用让部署和扩容变大更加简单,但是这对于基础设施层和kubernetes带来了巨大的压力,为了保证业务的拓展和连续性,你需要对未来的拓展做出角色,例如是使用一个大集群还是多个小集群,如何管理基础设施的成本,节点的规格如何选择,有效的资源利用策略如何等等,这些问题都需要具体的答案和决策。
  11. 故障准备:许多分布式系统的特征都适用于kubernetes容器化的应用,特别是容错能力,我们能够接受系统组件的错误,当设计一个kubernetes集群时候要需要遵循高可用原则来容忍中断和错误。但是我们也要为故障做好准备,你可以通过使用混沌工程思想、故障应急预案、基础设施测试和基础设施的CICD来保障。
  12. 变更效率:公司通常会低估操作生产环境中容器所带来的工作量 — 第二天和后面日子里的影响,如何做好中断、集群升级、备份、性能调优、资源可视化和成本控制的准备,在这个阶段,公司需要弄清楚如何应对越来越多的生产和非生产环境的交付挑战,没有合适的最佳实践,这会达到瓶颈开始拖慢业务的增长,甚至是稳定性不能满足用户的需求,我们见证了太多kubernetes在生产上线但是最终因为运维团队和没有最佳实践导致的失败。

这12个原则被证明是大规模的云基础设施成功部署的常见模式,我们会在后面的章节依赖这些原则进行技术决策并且再次强调这些原则。

应用程序的定义和部署

通常来说,一个成功且高效的kubernetes集群也没办法拯救应用的糟糕设计和实现,当应用不遵守容器化最佳实践和高可用设计的时候,他可能也失去了kubernetes底层提供的云原生自身优势

  • 容器化:容器化是云工作负载的行业标准交付和部署模式,为了生产的稳定性,容器化最佳实践至关重要,你会在后面的章节中详细的学习这个原则,错误的最佳实践会导致生产不稳定或者是灾难性的中断,例如忽略容器的正常管理和进程的终止信号或者是不合理的重试机制。
  • 应用程序高可用:需要部署两个及以上的副本数,同时使用kubernetes的高级调度能力(节点选择,污点、亲和性和标签)来保证部署的副本能够调度到不通的节点和可用区,另外还要定义节点的中断策略。
  • 应用监控:通过定义readiness和liveness来实现不通的检查,部署APM并使用注明的监控方式来实现,例如监控速率,错误和持续时间、以及利用率、饱和度和错误率
  • 部署策略:kubernetes和云原生让部署变得更加简单,这些频繁的部署给企业带来好处,可以减少上市时间、加快用户需求上线并且全面提高产品质量。然而这也会存在一些问题,频繁的部署会影响产品的稳定性,如果你没有做好计划内核管理甚至会影响产品的运行,这些就需要我们定义好部署、回滚策略(滚动更新、重建、金丝雀、蓝绿发布或者是普通部署)。

考虑到这四点可以保证kubernetes集群中应用程序的顺利部署和操作,但是这还需要根据你的组织决策和kubernetes使用详情进行更详细的技术决策。

流程、团队和文化

云转型之路会对于组织文化、流程以及他们管理和操作基础设施和应用的方式上带来惊人的变化,devops很好的反应了采用云思维对于组织文化的深渊影响,他影响了开发和运维以及他们内部团队的组织方式。日复一日的工作中,开发和运维之间的界限愈发模糊,通过引入kubernetes和云原生方法,devops团队正在被重塑为SRE或者雇佣专门平台团队,这两种方式都是进行管理和操作kubernetes都是可行的。

云原生之旅

CNCF将运行在现代动态环境中的可拓展应用定义为云原生,这些应用使用了包括例如容器、微服务和声明式API等技术,kubernetes是CNCF的第一个项目也是全世界最流行的容器编排平台。云计算使用开源和现代商业化的第三方软件来实现构建、打包和部署微服务应用,容器和kubernetes为首的容器编排平台是云原生的核心要素,它们都实现云原生状态并且满足应用的12要素,这写技术要求包括资源可视化、分布式系统可靠性、可拓展行和可观察行等。
image.png
译文:12要素详见https://12factor.net/

CNCF介绍

2014年Google开源了kubernetes,是源自于他们数据中心内部用于编排容器和负载均衡的分布式系统Borg,Google联合Linux基金会创建CNCF并用go语言重写了Borg系统重命名为kubernetes,在这之后之后Google的竞争对内在内的微软和亚马孙也都加入到CNCF的研发中。CNCF的目的是为现代应用程序开发提供构建、管理的平台和解决方案,它监督并协调这些支持云原生软件开发的开源技术和项目的发展,当然这里面也有一些商业化的关键项目。

为什么我们关心云原生

image.png
译文:CNCF声明如下:即使是没有从事于软件行业的公司也开始意识到他们需要成为一家软件公司,例如Airbnb正在彻底改变酒店行业而其他的传统酒店还在努力竞争,云原生可以让IT和软件更加的循序,采用云原生的技术和实践可以让公司内部搭建软件,让业务人员和IT人员能够更加紧密的合作,跟上竞争对手并且为用户提供更好的服务,CNCF的技术能够实现云的可移植性并不依赖于供应商。
CNCF云原生建议和软件是建立最新版高质量kubernetes基础设施的基石,这也是我们打算交付和运维生产级别基础设施的核心部分,遵循CNCF的原则并且持续追踪他们的解决方案地图是kubernetes平台创建者和使用者最应该保持最佳实践。

云原生技术图谱和生态

image.png
转载自:书中没有包含cloud部分,附上图方便各位理解。https://www.cloudroads.com/blog/10-steps-to-navigate-your-cloud-native-journey
云原生技术图谱由CNCF和他的成员负责和支撑的开源和商业化软件的组合,CNCF根据云原生功能和基础设施的层级把这些项目分成了四个层级:

  • 供应商:这一层级有基础设施自动化和配置管理项目例如Ansible和Terraform,镜像仓库例如Quay和Harbor,安全设备例如Falco/TUF和Aqua,密钥管理例如Vault
  • 运行时:这一层级项目包括容器运行是例如containerd和CRI-O,云原生存储例如Rook和Ceph,以及云原生网络插件例如CNI、Calico和Cilium
  • 编排和管理:这一层级是我们最常见的kubernetes负责调度和编排的能力,当然也包括其他的核心项目例如CoreDNS、Istio、Envoy、gRPC和KrakenD
  • 应用定义和发布部署:这一层级主要是应用开发和他的生命周期管理,包括CICD工具,例如Jenkins和Spinnaker,构建和应用定义例如Helm和Packer,最后是分布式数据库、流媒体和消息队列。

CNCF生态包含了云原生和kubernetes的各个方面的需求,我们将来会使用CNCF这些项目来满足我们集群的各类需求。

云原生路线图

云原生路线图是CNCF推荐的云原生技术图谱,这个里程碑是为了云原生的转变,他跟我们的kubernetes生产化之路也是相交的,因为将kubernetes部署成为一个编排管理工具是我们的重要里程碑。我们不得不承认大多数kubernetes用户正在启动或者正在进行他们的云转型之旅,所以了解这个路线图的是完成kubernetes的规划和部署的基石。
CNCF建议任何云原生转型可以在云原生路线图上的不同项目中得到支持

  1. 容器化:容器是云原生应用的封装标准,也是应用上云要走的第一步,Docker容器已经证明了他的高效性、轻量级和可移植性
  2. 持续集成和持续交付(CICD):CICD是在应用容器化之后需要进行的下一步,当代码发生改动时,你可以自动化的构建镜像并且简单的进行测试、发布到开发、测试甚至是生产环境。
  3. 编排和应用定义:一旦你实现了应用容器的自动化部署,你会面临容器生命周期管理带来的挑战,你会创建许多自动化的脚本来处理容器的重启、扩容、日志管理、健康检查和调度,这个时候就需要提到我们的编排系统,例如kubernetes这种容器编排平台提供了开箱即用的管理能力,除此之外你还可以更多的容器生命周期管理,而且还有管理云底层以及它上层云原生和微服务的基础设施层。
  4. 可观测性和可分析性:监控和日志是云原生应用的组成之一,这些信息和metric可以让你更加的高效、可评估的、保证应用健康和SLO的情况下运维你的系统。
  5. 服务代理、服务发现和服务网格:在这个阶段,你的云原生应用和服务越发复杂,你会寻找提供服务发现、DNS解析、高级负载均衡和路由、ABtest、金丝雀测试和部署、限流以及访问控制
  6. 网络和策略:kubernetes和分布式的容器网络模型给你的基础设施带来的复杂度,这也是的你的网络需要向CNCF的CNI接口一样标准且灵活,因此,你需要部署像calico、cilium或者weave的方案来支持你的网络策略、数据过滤和其他网络需求
  7. 分布式数据库和存储:云原生应用模型是关于可扩展性的,传统 数据库是无法满足云原生的扩容需求的,这就是CNCF分布式数据填补的空白
  8. 流媒体和消息传递:CNCF推荐使用gprc或者Nats进行信息传递,他们俩比json-rest具有更高的性能,grpc是一个高性能开源rpc框架,nats是一个简单安全的信息传递系统,他可以运行在包含大型云服务、边缘网关和IOT设备在内的各种地方。
  9. 镜像仓库和运行时:镜像仓库是存储和管理容器镜像的地方,一个正确的镜像仓库需要能够有高性能、漏洞分析和访问控制功能。运行时是负责容器运行的软件层,通常来说,当你开始阶段会选择docker作为运行时,到那时最终更多会考虑选择CNCF支持的CRI-O和containerd作为运行时。
  10. 软件分发:The Update Framework 和Notary 是都是CNCF赞助的项目,他们提供了现代和云原生软件分发

把前面原生转型阶段作为推荐路线是比较明智的选择,公司通常不会严格遵守这一项目,但是这些是你开始云原生转型之旅的重要基础。

image.png
转载自:https://www.cloudroads.com/blog/10-steps-to-navigate-your-cloud-native-journey

总结

建设一个生产级别的稳定kubernetes基础设施和集群不仅仅是配置集群和部署应用,它是一个结合了基础设施、服务规划、设计、实施、CICD、运营和运维的持续绿城。每个挑战都有一套自己的技术决策、最佳实践和挑战。到目前为止,我们对于kubernetes基础设施基础、生产挑战和准备特性有了简要的了解,最后,我们了解了建设和管理kubernetes生产集群的行业最佳实践并且学习了云原生的方法。
下一个章节,我们会详细的去了解设计和构建一个成功的kubernetes集群和他的相关基础设施,与此同时会一同探索在部署集群期间技术和架构决策、选择和可替代方案。

构建生产级别kubernetes基础设施

在之前的章节中,我们学习了kubernetes组成、kubernetes基础设施相关基础知识以及在生产中使用kubernetes中的挑战,我们介绍了kubernetes生产准备事项,通过我们推荐的服务和配置的检查清单来保证你的集群能够达到要求。
我们通过构建生产级别云环境介绍了一组基础设施的设计原则,没当我们进行架构和设计决策的时候都会讲这些原则作为指导方针,我们强烈建议云基础设施团队在构建新的kubernetes基础设施和云平台的时候会考虑这些。
在本章节中,你讲了解在设计kubernetes基础设施期间需要解决的技术决策,我们讲探索每个决策的可替代方案和选择以及他们的优缺点。除此之外,还需要了解晕架构的注意事项,例如可拓展性、可用性、安全性和成本。我们不会帮助你做最终的决定仅仅会提供对应的指导,因为每个组织有不通的需求和使用场景。我们的定位是探索并指导进行决策,可能的情况下,我们会说明我么你的建议选项,我们会在本书中进行实践练习。
在本章节中,我们会介绍如下内容:

  • 了解kubernetes基础设施设计注意事项
  • 探索kubernetes部署策略的可替代方案
  • 设计一个Amazon EKS基础设施

了解kubernetes基础设施设计注意事项

Kubernetes基础设施设计方面,有一些重要的因素需要考虑,几乎每个云基础设施架构都有一组相同的考虑因素,我们会从kubernetes的角度来考虑这些因素并进行说明。
伸缩和弹性
像AWS、Azure和GCP这种公有云基础设施都具备前所未有的伸缩和弹性,kubernetes和容器化技术是在这个功能的基础上进一步的拓展它。当你设计一个kubernetes集群基础设施,你应该确保你的架构设计符合如下两个方面:

  • 可拓展的kubernetes基础设施
  • 可拓展的kubernetes集群上的工作负载

为了实现第一个要求,一部分是依赖于底层基础设施,无论是公有云还是本地,另一部分是依赖于kubernetes集群本身。当你选择例如EKS、AKS或者是GKE这种托管服务的时候通常是默认满足了第一个要求,因为云自身是迟滞基础设施的拓展进而是的kubernetes的控制面和NODE节点也是可以拓展的。
但是在某些场景下,你可能需要部署一个私有的kubernetes集群环境,无论是云环境还是本地环境,你部署的kubernetes集群都需要考虑到伸缩和弹性来能力。在公有云基础设施中,都有计算弹性组的概念,kubernees就是依此建立的,然而因为工作负载本身运行在kubernetes,扩缩容操作需要同步集群的调度报错,这也是kuberntetes集群的优势所在。
CAS是一个用来自动化扩缩容的插件,你可以选择性的部署在集群中,它可以根据根据你设置的条件和配置自动化的实现扩缩容,基本上可以在pod资源不足的情况下触发集群的扩容,在pod资源利用不足的情况下触发缩容,他们的节点能够调度到不通的node上。因为考虑到云供应商扩容新节点所需的事件,对对于时间敏感的应用需要启用CAS节点配置的过度配置。想了解更多关于CAS的信息,请跳转链接:https://github.com/ kubernetes/autoscaler/tree/master/cluster-autoscaler.
为了实现第二个拓展性需求,kubernetes提供了两个解决方案来实现节点的自动扩缩容:
HPA:这个的工作原理和云自动扩缩容策略很相似,是工作在pod的deployment层面,把pod想象为一个VM实例,HPA根据特定的指标扩容节点的数量,通常来说是CPU和内存使用率这种指标,也可以是其他的自定义指标,为了更好的了解HPA,请阅读:https://kubernetes.io/ docs/tasks/run-application/horizontal-pod-autoscale/.
VPA:会根据pod的资源使用情况垂直的增加他的CPU和MEM的limit值,可以联想做公有云场景下调整他的实例规格,VPA会影响到CAS并且触发扩容事件,所以同时使用的时候要准确调整CAS和VPA的配置来避免不可预测的扩缩容行为,为了更好的了解VPA的工作原理请阅读:http://rsm-ops.bytedance.net/resource/machine/list
我们强烈建议在生产环境使用HPAVPA(非生产不必须),在第八章节中『连续且稳定的应用部署』中给出例子如何使用它们部署生产级别的appservice的时候。

高可用和稳定性

运行时间(原文是uptime,这里我理解为是系统稳定运行无故障,后面统称运行时间)意味着可靠,也是基础设施团队衡量和提高的主要目标,运行时间驱动着SLOSLA,同时也代表着系统和SAAS的可靠性和稳定性。高可用是增加运行实现的核心,这对于kubernetes集群基础设施同样可用,这也是为什么高可用集群和工作负载是生产级别的kubernetes集群的关键。
你可以在不同的可用性级别上构建你的高可用kubernetes基础架构:

  • 单个公有云可用区部署单个集群:这跟其他的架构相比最简单的架构,但都是这会带来高可用风险,所以不推荐此方案。
  • 单个云大区下多可用区部署单个集群:这个集群很容易实现,他提供了更高的可用性也是kubernetes集群的通用架构,然而,当你的云供应商发生大区级别的中断是,集群仍然会出问题,尽管这个情况很少发现你还是要做好准备。
  • 同一个供应商下跨多个大区集群:在这种架构下,通常会运行多个联邦kubernetes集群来支撑我们的工作负载,这通常来说是推荐的高可用方案,不过部署和实施起来非常困难,尤其在网络条件差和有状态应用共享存储的场景下。因此对于大多数的SAAS产品来书,部署在一个大区下不通的可用区即可。然而,当你有高可用之外的其他需求,可以考虑使用集群联邦的方式部署在多个大区。
  • 多云环境下部署多个集群:因为存在云供应商之间的不兼容、集群间网络的复杂性高、更高的实施、运维和网络成本这些问题,这个架构目前仍然不做推荐,但是值得注意的是,越来越多的多云管理方案正在努力应对和解决这些挑战,所以不妨也考虑像GoogleAnthos这种多云解决方案,详情可以https://cloud.google.com/anthos

你可能注意到了,kubernetes在高可用建设上有同风格的架构,而这种不同的选择机会也让kubernetes适用于各种场景下,虽然第二种方案是当前最常用的方案,他在高可用、以及可实施和可维护性上做了平衡,但是我们还在充满希望的寻找使用第四种方案的可能,我们可以轻松的跨云部署k8s来实现高可用,同时不用承担繁重维护压力和成本。至于集群自身的可用性,毋庸置疑的k8s运行在高可用的架构之下,你可以让控制面运行在三个或者更多的节点上,或者是让云来进行托管例如EKSAKEGKE,至于工作节点,你可以在一个运行一个或多个弹性组、节点组或者pool
最后需要考虑的实现高可用的地方是你部署的pod和负载,虽然这对于本书来说有点超纲,但还是要提醒你需要使用高可用的模式来部署你的应用、服务或者对已有的服务进行改造,这样子才能够使用k8s基础设施带来的各种能力,不然的话,只能得到一个运行强大集群上运行的单体实例。

安全性和合规性

Kubernetes基础设施安全根植于集群的各个层级,从网络层开始OS层,上到集群服务和工作负载,kubernetes对于安全、加密和身份认证、授权提供了强大的支持,我们在第六章节kubernetes有效防护中详细的学习到这些。即便如此,我们还是要在集群基础设施的设计过程中注意安全相关决策,例如保护k8s apiendpoint、集群的网络设计、安全组、防火墙和控制面组件、node以及互联网之间的网络策略。除了这些你还需要提前计划对于基础设施组件与集群和身份认证服务的集成,这通常依赖于你的组织安全策略,也就是说要与安全和IT团队达成共识。
另外还需要考虑的就是审计和合规性,大多数组织都有云治理策略和合规性要求的,所以在你的应用在kubernetes上生产之前需要意识到这些。当你觉得使用多租户集群的时候,安全性讲更具有挑战,为不同的内部团队在集群租户之前设置清晰的边界最终会让我们部署一个服务网格、更坚固的网络策略以及更严格RBAC,在构建第一个集群的时候,这些都会影响你的决定。
Kubernetes社区热衷于合规和质量,所以提供了各种工具和测试用例来保证你的集群达到安全性和合规性要求,我们会在第六章中想写的学习。

成本管理和优化

云成本管理对于所有的使用云的用户来说都是一个重要因素,无论你是在上云的路上还是已经完成了上云,使用k8s作为云基础设施可以节省你的成本,容器化可以前所未有的的有效使用你的资源,有些组织在迁移到容器和k8s之后解决了将近90%的成本。然而,如果没有合适的成本控制的话,成本还是会提高并且最终得到一个大量浪费且不可控的k8s集群基础设施,有许多的工具和最佳实践可以考虑,但是我们主要关注的还是在基础设施设计期间需要考虑的技术决策和动作。我们相信有两个重要的方面需要考虑,这些决策会影响你的集群基础设施设计:

  • 运行单个或者多个多租户集群(每个租户一个集群)
  • 集群能力:无论是想运行少量的大规格节点还是大量的小规格节点都可以,混用也行

这些都没有明确的决定,但是我们会在下一小节中尝试着探索并做出决定。
在成本优化上还是有一些因素可以让我们更早的做出决定:

  • 使用spot或者抢占式实例:这可以节约巨大的成本,同时也伴随着巨大的风险,因为这会导致你的工作负载随时都可能会被中断进而影响生产的运行时间和可靠性,但是还是有一些场景下我们可以使用,例如像开发环境或者CICd这种非生产工作负载,以及像数据批处理进程这种随时可以中断的程序。因此,我们强烈建议对于生产的node使用spot 实例,你可以在节点组或者pool上运行这些可接受中断的程序。
  • Kubernetes成本可观测性:大多数的云平台提供所有云资源的成本可视化和分析能力,然而,在集群的部署和服务级别的成本可视化也是必不可少的,这一切都需要提前进行规划,这也需要你使用互相隔离的工作负载、团队、用户和环境,使用命名空间并且给他们分配quota,通过这些方式来确保使用成本分析工具能够为你提供与服务和集群操作相关的使用报告,这一切对于成本降低的关键决策至关重要。