Kubernetes 3年生产中我们所学到的东西

Kubernetes 3年生产中我们所学到的东西

作者:祝祥 2020-09-22 08:09:13

云计算 我们于2017年开始构建第一个基于1.9.4版本的Kubernetes集群。至今,我们已经有两个集群,一个集群在裸机RHEL VM上运行,另一个集群在公有云AWS EC2上运行。

[[343163]]

本文转载自微信公众号「新钛云服」,作者祝祥 。转载本文请联系新钛云服公众号。  

我们于2017年开始构建第一个基于1.9.4版本的Kubernetes集群。至今,我们已经有两个集群,一个集群在裸机RHEL VM上运行,另一个集群在公有云AWS EC2上运行。

今天,我们的Kubernetes集群由分布在多个数据中心的400多个虚拟机组成。该平台承载着高度可用的核心应用程序和系统,管理拥有近400万个活跃用户的的大型实时系统。

Kubernetes最终使我们的运维变得更轻松,但是这一过程是艰辛的,是范式的转变。不仅仅是我们的技能和工具有了彻底的转变,而且我们的设计和思维也得到了彻底的转变。我们必须采用多种新技术,并进行大量的投入,以提高团队和基础设施的档次和技能。

回顾三年来,Kubernetes在我们的生产中运行了三年,这也是本文将会将的重点内容。

1. 基于Java的APP容器化问题

当涉及微服务和容器化时,很多人都倾向于避免使用Java,这主要是由Java不太友好的内存管理造成的。但是,现在情况发生了变化,并且Java的容器兼容性在过去几年中得到了很大的改善。毕竟,当前大部分的系统都有使用Java程序的 Apache Kafka作为中间件,另外Elasticsearch通常也是在Java程序上运行。

回顾2017-2018年度,我们有一些应用程序在Java 8上运行。它们常常难以理解像Docker这样的容器环境,并且由于堆内存问题和异常的垃圾收集而崩溃。我们了解到,这是由于JVM无法支持Linux cgroups和namespaces,后者是容器化技术的核心。

但是,从那时起,Oracle一直在不断提高Java在容器领域的兼容性。甚至Java 8的后续补丁都引入了实验性JVM标志来解决这些问题:XX:+UnlockExperimentalVMOptions和XX:+UseCGroupMemoryLimitForHeap。

但是,尽管有了这些改进,但不可否认的是,与Python或Go等同类产品相比,Java仍因占用内存和启动时间慢而名声不佳。主要是由JVM的内存管理引起的。

今天,如果我们必须选择Java,我们会确保它的版本是11或更高。我们的Kubernetes内存限制会在比JVM最大堆内存(-Xmx)多1GB,以获得足够的空间。也就是说,如果JVM使用8GB作为堆内存,我们对应用程序的Kubernetes资源限制将是9GB。这样,应用将会更加健康。

2. Kubernetes升级

Kubernetes生命周期管理(如升级或补丁修复)非常麻烦,尤其是在裸机或虚拟机上构建了自己的集群时。对于升级,我们已经意识到最简单的方法是用最新版本重新构建一个集群,并将工作负载从旧的集群迁移到新的集群。进行节点的升级相对而言会更复杂,且结果无法预料。Kubernetes有多个与其一起协调工作的组件需要与Kubernetes升级保持一致。从Docker到像Calico或Flannel这样的CNI插件,你需要小心地把它们拼凑在一起才能工作。尽管像Kubespray、Kubeone、Kops和Kubeaws这样的项目使它更容易维护,但它们都有各自的缺点,且不太通用。

我们在RHEL VM上使用Kubespray构建了集群。Kubespray非常不错,它有基于ansible的构建、添加和删除新节点、升级版本的playbooks,以及我们在生产中操作Kubernetes所需的几乎所有内容。但是,升级的playbook带了一个免责声明,可防止我们跳过次要版本。因此,必须经过所有中间版本才能达到目标版本。简而言之,Kubespray不支持跨版本升级。

以上可得出的结论是,如果您打算使用Kubernetes或已经在使用Kubernetes,请考虑生命周期管理。构建和运行集群相对容易一些,但是Kubernetes的生命周期管理则相对复杂,涉及内容较多。

3.构建和部署

准备重新设计整个构建和部署的pipelines。我们的构建过程和部署必须经历一个基于Kubernete的完整转型。不仅在Jenkins pipelines中进行了大量的重组,还使用了诸如Helm这样的新工具,制定新的git流和构建策略,docker 镜像的tag标签,以及版本化Helm chart。

您不仅需要维护代码,还需要维护Kubernetes部署文件,Docker文件,Docker镜像,Helm Chart的策略,并设计一种将所有这些链接在一起的方法。

经过几次迭代,我们决定采用以下设计。

应用程序代码及其helm chart位于单独的git存储库中。这使我们可以分别对它们进行版本控制。

然后,我们将helm chart版本与应用程序版本一起保存,并使用它来跟踪发布。因此,例如,使用进行app-1.2.0部署charts-1.1.0。如果仅更改Helm values文件,则仅更改chart的补丁程序版本。(例如,从1.1.0到1.1.1)。所有这些版本均由每个存储库中的发行说明规定RELEASE.txt。

我们与构建或修改其代码的Apache Kafka或Redis之类的系统应用程序的工作方式有所不同。也就是说,我们没有两个git存储库,因为Docker tag只是Helm chart版本控制的一部分。如果我们曾经更改了docker tag进行升级,我们将在chart标签中增加主要版本号。

4.Liveliness和Readiness探针(双刃剑)

Kubernetes的liveliness和readiness探测是自动解决系统问题的的优秀特性。他们可以在发生故障时重新启动容器,并将流量从不正常的实例中转移出去。但在某些故障情况下,这些探测可能成为一把双刃剑,影响应用程序的启动和恢复,尤其是消息中间件或数据库等有状态应用程序。

我们的kafka系统就是受害者。我们运行了一个3 broker 3 zookeeper的状态集群,replicationFactor 为3,minInSyncReplica为2。当Kafka在意外系统故障或崩溃后启动时,就会发生问题。这导致它在启动期间运行其他脚本来修复损坏的索引,根据严重程度,该过程可能需要10到30分钟。由于增加了时间,Liveliness将不断失败,从而向Kafka发出终止信号以重新启动。这阻止了Kafka修改索引并完全启动。

唯一的解决方案是配置initialDelaySeconds liveliness探针设置,以在容器启动后延迟探测。但是,当然,问题在于很难对此加以说明。有些恢复甚至需要一个小时,因此我们需要提供足够的空间来解决这一问题。但是增加的越多initialDelaySeconds,恢复速度就越慢,因为在启动失败期间,Kubernetes需要更长的时间来重新启动容器。

因此,择优的方法是评估initialDelaySeconds字段的值,以便更好地平衡您在Kubernetes中寻求的弹性和应用程序在所有故障情况下(磁盘故障、网络故障、系统崩溃等)成功启动所需的时间

更新*:如果您使用的是最新版本,Kubernetes引入了第三种探针类型,称为“启动探针”,以解决此问题*](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)*。在1.16的alpha版本和1.18的beta版本后是可用的。

在容器启动之前,启动探针将禁用readiness与liveliness检查,以确保应用程序的启动不会中断。

5.对外的External的IP

我们了解到,使用external IP暴露服务会对内核的连接跟踪机制造成巨大负荷。除非规划详细,考虑周全,否则一旦规模上去,那么它只会崩溃。

我们的集群运行在基于Calico CNI和BGP上,作为我们在Kubernetes内部的路由协议,也可以与边缘路由器对接。对于Kubeproxy,我们使用IP Tables模式。我们在Kubernetes中托管着庞大的服务,该服务通过external IP对外暴露,每天处理数百万个连接。由于使用来自软件定义网络的SNAT和masquerading,Kubernetes需要一种机制来跟踪所有这些逻辑流。为此,它使用内核的Conntrack 与 netfilter工具来管理静态IP的这些外部连接,然后将其转换为内部服务IP,最后转换为您的pod IP。转发过程全部通过conntrack表和IP表完成。

然而,这个conntrack表有其局限性。一旦达到这个限制,Kubernetes集群(底层的操作系统内核)将无法再接受新的连接。在RHEL上,你可以这样检查。

  1. $ sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_maxnet.netfilter.nf_conntrack_count = 167012 
  2. net.netfilter.nf_conntrack_max = 262144 

解决这一问题的一些方法是使用边缘路由器连接多个节点,这样您的静态IP的传入连接遍及整个群集。因此,如果您的集群有大量的机器,那么累积起来就可以有一个大的conntrack表来处理大量传入的连接。

早在2017年成立之初,这一切就让我们望而却步,但最近,Calico在2019年对此进行了详细研究(https://www.projectcalico.org/when-linux-conntrack-is-no-longer-your-friend/)。

6.您真的需要Kubernetes吗?

三年过去了,我们仍然每天都在不断地发现和学习新的东西。kubernetns是一个复杂的平台,有其自身的一系列挑战,特别是构建和维护环境方面的。它将改变你的设计、思维、架构,并将需要提高你的团队能力以满足架构转型。

然而,如果你在云端并且能够将Kubernetes用作“service”,它可以减轻平台维护带来的大部分开销,例如“如何扩展内部网络CIDR?”。或“如何升级我的Kubernetes版本?”

今天,我们意识到你需要问自己的第一个问题是“你真的需要Kubernetes吗?”。这可以帮助您评估您所遇到的问题以及Kubernetes解决该问题的重要性。

Kubernetes转型并没有想象中的那么简单,那么廉价。您为此付出的代价必须真正证明“您的”应用及其如何利用该平台。如果满足这些条件,那么Kubernetes可以极大地提高您的生产力。

记住,为了技术而技术是没有意义的。

原文:https://medium.com/better-programming/3-years-of-kubernetes-in-production-heres-what-we-learned-44e77e1749c8

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/262509.html<

(0)
运维的头像运维
上一篇2025-05-04 03:24
下一篇 2025-05-04 03:25

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注