Kubernetes应用最佳实践

小白debug 2023-09-22 08:15

概述

本文从应用开发人员的角度,总结一下 Kubernetes 的业务开发中的最佳实践,本文不会展示任何相关的 kubelet 命令以及 yaml 格式文件,通过尽可能精简篇幅来提高读者阅读体验和效率。

面向开发人员的 Kubernetes 资源结构图

Namespace

Kubernetes 通过 Namespace 将资源进行逻辑上的隔离,默认情况下集群中有三个命名空间:default、kube-public 和 kube-system, 通常情况下,有一个非生产的 Kubernetes 集群用于特定环境 (开发、测试、集成),如果出于成本和业务服务独立性考虑,将生产和非生产环境混合到一个集群中, 则应该建立新的 Namespace 来进行业务服务区分与隔离,例如常见的 Namespace 是 testprod

此外,建立新的 Namespace 之后,应该为不同的 Namespace 来配置不同的资源配额和资源限制。例如给测试环境分配较少的资源额度,给生产环境分配较多的资源额度, 这样即使在测试环境对某个服务进行压测,也不会影响到生产环境。

阿里云 Kubernetes 集群命名空间与配额

使用 RBAC 进行访问控制

Kubernetes 中支持使用 RBAC 为集群中的用户和组定义细粒度的访问控制规则,例如可以将无状态应用、有状态应用、路由管理的功能开放给开发人员,将命名空间、资源配额与限制的功能开放给运维人员。

Pod

将 Pod 视为独立的机器,并将单个应用或者多个紧密耦合的应用放入单个 Pod 中。

对于多层应用,应该分散放到多个 Pod 中,典型的如 Web 应用,应该将前端页面、后端接口、缓存、数据库分别放入不同的 Pod 中。此外,不要将应用部署到单独的 Pod 中,在保持应用可以水平扩展的前提下:

  • 使用 Deployment 部署无状态应用
  • 使用 StatefulSet 部署有状态应用

如何判定单个 Pod 中是否应该放入多个容器?这里给出几个判断条件:

  • 多个应用需要一起运行还是相互独立运行?
  • 多个应用表示的是一个整体应用还是相互独立的组件?
  • 多个应用是否可以一起扩容还是需要独立进行?(例如多个生产者,单个消费者的应用场景)

组合大于继承

这条软件设计原则针对 Pod 依然适用,大多数情况下,单个应用容器都是最佳实践,对于某些多应用容器场景,可以通过将辅助容器中的应用使用子进程的方式运行,这样就可以将多个容器应用集成到一个容器应用中。


容器

每个容器中的应用都应该遵循单一职责,只负责一个功能或执行一项任务。如果应用内部发生不可恢复的错误,应该让它崩溃并自动退出,Kubernetes 会自动重启该容器。

避免以 root 身份运行

容器共享主机的内核,因此隔离程度无法到达虚拟机级别,安全的策略就是禁止使用 root 身份运行应用。

镜像优化

应该尽可能缩小镜像体积,因为当集群自动扩容添加新节点时,新节点必须下载容器镜像。容器的镜像体积越小,节点下载速度越快,应用的启动速度也就越快。

如果 CRI 容器使用的是 Docker,可以参考之前的 Docker 最佳实践[1]

镜像仓库

如果所在企业没有自己的基础设施团队,建议镜像仓库和云服务器的提供商保持一致,这样保证镜像仓库高可用的同时,可以节省带宽费用并提升镜像拉取速度 (因为走的是内网)。

镜像标签和拉取策略

网上大多数文章会提到 不要使用 latest 作为镜像标签,笔者不是特别认同,还是需要具体情况具体分析,笔者的建议是:

  1. 首先保证镜像仓库的高可用和访问速度,这是重中之重,如果这一点做到了,那么可以使用 latest 标签并将镜像拉取策略 imagePullPolicy 设置为 Always
  2. 对于测试环境,直接使用 latest 标签并将 imagePullPolicy 设置为 Always, 配置 CI 构建脚本在打包应用镜像时,除了 latest 标签镜像外,再额外打包一个以 git commit 哈希值作为标签的镜像 (回滚时专用镜像)
  3. 对于生产环境,使用应用迭代版本号作为镜像的标签

使用多维度而不是单维度的标签

维度名称
发布版本release"stable", "canary"
发布环境environment"dev", "qa", "production"
应用类型tier"frontend", "backend", "cache"

Deployment

对于无状态应用,直接使用 Deployment 部署。

阿里云 Kubernetes Deployment 滚动升级策略

下面主要说下几个重要的参数。

replicas

Pod 的副本数量。

maxUnavailable

指定滚动更新过程中不可用的 Pod 数量上限,数值可以是绝对数字,也可以是百分比 (最终会转换成数字),例如 Pod 数量为 10, maxUnavailable 值的 30%, 那么在滚动升级过程中,始终保证可用的 Pod 数量为 7 。

maxSurge

指定可以创建超出 replicas 的 Pod 数量,数值可以是绝对数字,也可以是百分比 (最终会转换成数字),例如 Pod 数量为 10, maxSurge 值为 30%, 那么在滚动升级过程中,始终 Pod 最大数量不超过 13 。

在滚动升级期间设置合理的 maxUnavailable 和 maxSurge 值,在资源消耗和保证服务可用性之间取得平衡。

minReadySeconds

指定新创建的 Pod 的最小就绪时间,只有超过这个时间 Pod 才会被认为可用,使用该参数更好掌握升级部署过程,避免 Pod 中的进程启动后立即接受流量导致错误,同时减缓滚动升级的速率。

通常情况下需要根据业务场景计算出应用的初始化时间上限,同时还要考虑到应用的就绪时间条件,通过两者的综合考量,将 minReadySeconds 值设置地尽量高一些。

progressDeadlineSeconds

默认情况下, 10 分钟内无法完成滚动升级将被判定为失败,对于大多数无状态应用来说这个时间太长了,可以更新 spec.progressDeadlineSeconds 来自定义超时时间。

Recreate 策略

Deployment 的默认策略是 RollingUpdate, 也就是滚动升级。

此外还可以将策略设置为 Recreate, Recreate 策略首先终止当前版本中的所有 Pod,然后创建并启动新 Pod, 两个过程之间会有一定的服务不可用空窗期, 该策略的应用场景是: 无法接受应用在滚动升级策略中同时存在的两个版本,并且可以接受一定的服务不可用空窗期 (例如金融相关业务),可以在业务低峰期采用这种策略,并在用户界面给出对应的维护公告。

DaemonSet

将所有由 systemd 管理的进程使用 DaemonSet 管理

ConfigMap

针对不同的环境单独配置 ConfigMap, 可以将多个小的配置文件合并到一个大的配置文件中,参考 这个示例[2]

配置热更新

热更新 ConfigMap 会导致应用重新加载新的配置,但不会触发应用程序重启。

  1. 创建一个 ConfigMap 对象,包含应用的配置数据
  2. 在 Pod 配置中,将 ConfigMap 挂载为一个卷(Volume), 应用可以直接从卷中读取配置数据
  3. 当配置数据需要更新时,修改 ConfigMap
  4. 修改 ConfigMap 后,Kubernetes 会自动触发相关的事件,通知 Pod 更新其挂载的卷
  5. Pod 接收到更新事件,重新加载卷中的配置文件,从而实现配置热更新

图片来源: https://www.manning.com/books/kubernetes-in-action-second-edition

Secret

确保采用 Secret 的方式存储敏感数据,禁止使用环境变量、自定义加密方式等毫无意义的奇技淫巧。同时限制特定容器集合才能访问 Secret, 读取 Secret 之后保持只读状态,避免以明文存储 Secret 数据或将 Secret 传输给第三方。

注意: Secrets 默认情况下采用 base64 编码存储非加密的形式存储在 etcd 中,需要配置为静态加密方式


Job

正常情况下,Job 会在 Pod 中运行直到完成,但是,如果节点发生故障,或者当 Pod 在运行时被驱逐出节点时,调度器会将 Job 放在一个新的节点上重新运行。所以 Job 要保证幂等性 (例如创建数据表时的 IF NOT EXISTS 判断语句),并且在状态为失败时自动停止,不再重新启动 (将 Restart Policy 配置为 Never)。对于涉及到网络请求的 Job, 笔者的建议是 将请求重试等策略放在应用代码中,而不是通过配置 Job 的 Restart Policy 来完成

比较重要的两个声明字段:

  • spec.completions: 指定 Job 需要运行的次数
  • spec.parallelism: 指定 Job 并行数量

CronJob

将周期性的自动化任务通过 CronJob 来执行,例如数据备份、回归测试、日志分析、运营数据邮件、已有 Cron 任务的迁移等。

注意: 因为工作节点本身受到资源使用和调度的限制,所以可能发生 Job 运行时间延时的情况 (和在应用层使用的定时任务组件延时情况类似),如果 Job 本身有较高的时间敏感度, 可以通过指定 startingDeadlineSeconds 字段来指定 Job 运行截止日期,这样的话,如果 Job 运行时会检测,如果运行时间大于截止日期,Job 将不再运行并且直接标记状态为失败。

此外,不应该将 Job 的运行时间作为业务时间序列属性,对于多副本运行的 Job 要保证幂等性

不管是传统的 Linux Cron 任务,还是通过守护进程 + 定时器组件模式,亦或是 Kubernetes 中的 Job, 这些都只是具体的运行时载体,最重要的是保证业务代码的健壮性。

日志

将 Pod 内应用日志输出到文件或标准输出,然后通过日志采集组件,最后将日志数据发送到自建日志仓库或云服务商提供的日志聚合服务。

防火墙和网络策略

大多数情况下,使用云服务商提供的默认配置就可以满足需求,如果需要自定义网络策略,可以参考 官方文档[3]

监控集群

监控 Kubernetes 集群对于确保应用程序的运行状况和性能至关重要,使用 Prometheus、Grafana 等工具或云服务商提供的原生监控解决方案,来收集和分析集群中的指标, 例如 CPU 使用率、内存使用率和网络流量等,同时设置警报和主动通知方式,保证集群出现任何问题时收到通知。

集群伸缩

集群伸缩可以自动添加或者删除工作节点,需要主要的是: 如果遇到业务在某个时刻流量突增的场景,则最好提前手动添加节点,毕竟新节点从启动到加入到集群并开始接收流量也需要时间,提前增加节点可以避免突增的流量造成负载过大甚至宕机。

升级到稳定的新版本

新的版本除了引入新功能之外,还包括漏洞和安全修复,可以定期升级到最新的稳定版本,享受官方升级带来的红利。担心已有组件和新版本不兼容?主流云服务商都有兼容性自动检测功能,直接使用即可。

小结

随着微服务架构的普及,实现一个简单的服务都需要对云原生中涉及到的分布式技术栈和容器编排基础知识有较深入的理解。因此,开发人员必须精通现代编程语言来实现业务功能,并且同时精通云原生技术来解决非功能性需求。

评论
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 58浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 60浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 63浏览
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 157浏览
  • 国产光耦合器因其在电子系统中的重要作用而受到认可,可提供可靠的电气隔离并保护敏感电路免受高压干扰。然而,随着行业向5G和高频数据传输等高速应用迈进,对其性能和寿命的担忧已成为焦点。本文深入探讨了国产光耦合器在高频环境中面临的挑战,并探索了克服这些限制的创新方法。高频性能:一个持续关注的问题信号传输中的挑战国产光耦合器传统上利用LED和光电晶体管进行信号隔离。虽然这些组件对于标准应用有效,但在高频下面临挑战。随着工作频率的增加,信号延迟和数据保真度降低很常见,限制了它们在电信和高速计算等领域的有效
    腾恩科技-彭工 2024-11-29 16:11 106浏览
  • 在电子技术快速发展的今天,KLV15002光耦固态继电器以高性能和强可靠性完美解决行业需求。该光继电器旨在提供无与伦比的电气隔离和无缝切换,是现代系统的终极选择。无论是在电信、工业自动化还是测试环境中,KLV15002光耦合器固态继电器都完美融合了效率和耐用性,可满足当今苛刻的应用需求。为什么选择KLV15002光耦合器固态继电器?不妥协的电压隔离从本质上讲,KLV15002优先考虑安全性。输入到输出隔离达到3750Vrms(后缀为V的型号为5000Vrms),确保即使在高压情况下,敏感的低功耗
    克里雅半导体科技 2024-11-29 16:15 119浏览
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 159浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 57浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 71浏览
  • 光耦合器作为关键技术组件,在确保安全性、可靠性和效率方面发挥着不可或缺的作用。无论是混合动力和电动汽车(HEV),还是军事和航空航天系统,它们都以卓越的性能支持高要求的应用环境,成为现代复杂系统中的隐形功臣。在迈向更环保技术和先进系统的过程中,光耦合器的重要性愈加凸显。1.混合动力和电动汽车中的光耦合器电池管理:保护动力源在电动汽车中,电池管理系统(BMS)是最佳充电、放电和性能监控背后的大脑。光耦合器在这里充当守门人,将高压电池组与敏感的低压电路隔离开来。这不仅可以防止潜在的损坏,还可以提高乘
    腾恩科技-彭工 2024-11-29 16:12 117浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 88浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦