当前位置: 首页 > 科技观察

在生产中使用Kubernetes三年后我学到了什么

时间:2023-03-16 22:52:17 科技观察

>JessicaLewis在Unsplash上的照片我们于2017年开始构建我们的第一个Kubernetes集群,版本1.9.4。我们有两个集群,一个运行在裸机RHELVM上,另一个运行在AWSEC2上。今天,我们的Kubernetes基础架构团队由分布在多个数据中心的400多台虚拟机组成。该平台托管高度可用的关键任务软件应用程序和系统,以管理拥有近400万台活动设备的大型实时网络。Kubernetes终于让我们的生活变得更轻松了,但这个过程是艰难的,而且是一种范式转变。不仅我们的技能和工具发生了彻底的转变,我们的设计和思维也发生了彻底的转变。我们不得不采用多种新技术,并投入大量资金来提高我们的团队和基础设施的技能。回顾在生产环境中运行Kubernetes的三年,这是我们日记中的重要一课。1.Java应用的奇怪案例当谈到微服务和容器化时,工程师往往会避开Java,这主要是由于Java臭名昭著的内存管理。然而,现在情况发生了变化,多年来Java的容器兼容性得到了改善。毕竟,ApacheKafka和Elasticsearch等无处不在的系统都在Java上运行。早在2017-18年,我们就有一些应用程序在Java版本8上运行。这些应用程序经常难以理解Docker等容器环境,并且由于堆内存问题和异常的垃圾收集趋势而崩溃。我们了解到,这是由于JVM无法使用Linuxcgroups和命名空间造成的,而这些是容器化技术的核心。不过,从那以后,Oracle一直在不断提高Java在容器空间的兼容性。甚至Java8的后续补丁也引入了实验性JVM标志来解决这些问题,XX:+UnlockExperimentalVMOptions和XX:+UseCGroupMemoryLimitForHeap但是,尽管有所有改进,不可否认它与Python或Go等同行不相上下。但是,Java仍然有一个内存密集且启动缓慢的坏名声。这主要是JVM的内存管理和类加载器造成的。今天,如果我们必须选择Java,请确保它是11或更高版本。我们的Kubernetes内存限制设置为比JVM最大堆内存(-Xmx)高出1GB,以留出一些余量。也就是说,如果JVM使用8GB堆内存,我们对应用程序的Kubernetes资源限制为9GB。这样,生活会更好。2.Kubernetes生命周期升级Kubernetes生命周期管理(例如升级或增强)可能很繁琐,尤其是当您在裸机或虚拟机上构建自己的集群时。对于升级,我们已经意识到最简单的方法是使用最新版本构建一个新集群并将工作负载从旧版本过渡到新版本。就地节点升级的努力和计划是不值得的。Kubernetes有几个移动部件需要与升级保持一致。从Docker到CNI插件(如Calico或Flannel),您需要仔细地将它们拼凑在一起才能正常工作。虽然像Kubespray、Kubeone、Kops和Kubeaws这样的项目使它变得更容易,但它们都有缺点。我们在RHEL虚拟机上使用Kubespray构建了集群。Kubespray很棒,它有用于构建、添加和删除新节点、升级版本的剧本,以及我们在生产中运行Kubernetes所需的几乎所有内容。但是,升级手册附带免责声明,防止我们跳过次要版本。因此,必须通过所有中间版本才能达到目标版本。关键是,如果您计划使用Kubernetes或已经在使用Kubernetes,请考虑生命周期活动以及您的解决方案如何解决这个问题。构建和运行集群相对容易,但生命周期维护是一个全新的游戏,包含多个移动部分。3.构建和部署就绪重新设计整个构建和部署管道。我们的构建过程和部署必须在Kubernetes世界中经历彻底的转变。不仅在Jenkins管道中进行了大量重组,而且还使用了像Helm这样的新工具,制定了新的git流和构建策略,标记了docker图像,并对helm部署图表进行了版本控制。您不仅需要维护代码,还需要维护Kubernetes部署文件、Docker文件、Docker镜像、Helm图表的策略,并设计一种将所有这些链接在一起的方法。经过多次迭代,我们确定了以下设计。·应用程序代码及其Helm图表位于单独的git存储库中。这允许我们分别对它们进行版本控制。(语义版本控制)然后我们保留图表版本与应用程序版本的映射,并使用它来跟踪发布。因此,例如,app-1.2.0与Charts-1.1.0一起部署。如果只更改Helmvalues文件,则只更改Chart的补丁版本。(例如,从1.1.0到1.1.1)。所有这些版本都由每个存储库的RELEASE.txt中的发行说明规定。·像ApacheKafka或Redis这样的系统应用程序,我们没有构建或修改它们的代码,但它们的工作方式不同。也就是说,我们没有两个git存储库,因为Docker标签只是Helm图表版本控制的一部分。如果我们将docker标签更改为升级,则主要版本将在图表标签中递增。4.LivenessandReadinessProbes(双刃剑)Kuberneteslivenessandreadinessprobes是自动解决系统问题的优秀特性。他们可以在发生故障时重新启动容器,并从不健康的实例中转移流量。然而,在某些故障场景中,这些探针可能成为一把双刃剑,影响应用程序的启动和恢复,尤其是消息传递平台或数据库等消息传递应用程序。我们的Kafka系统就是这个的受害者。我们运行一个3Broker3Zookeeper状态集,ReplicationFactor为3,minInSyncReplica为2。当Kafka在意外系统故障或崩溃后启动时会出现此问题。这会导致它在启动期间运行额外的脚本来修复损坏的索引,这个过程可能需要10到30分钟,具体取决于严重程度。由于增加的时间,Liveness探测将继续失败,并向Kafka发出重新启动的信号。这可以防止Kafka修改索引并完全启动。唯一的解决方案是在实时探测设置中配置initialDelaySeconds以在容器启动后延迟探测评估。但是,当然,问题是很难解释这一点。有些恢复甚至需要一个小时,因此我们需要提供足够的空间来解决这个问题。但是,增加initialDelaySeconds越多,弹性就会越慢,因为Kubernetes在启动失败期间需要更长的时间来重新启动容器。所以中间的目的是评估initialDelaySeconds字段的值,使其介于您在Kubernetes中寻找的弹性和您的应用程序在所有故障场景(磁盘故障、网络故障)下成功启动所需的时间之间故障,系统崩溃等)为了更好的平衡)更新:如果您使用的是最新版本,Kubernetes引入了第三种探测类型,称为“启动探测”,以解决此问题。Alpha版本从1.16版本开始可用,Beta版本从1.18版本开始可用。启动探测器会禁用就绪和活动检查,直到容器启动,确保应用程序的启动不会中断。5.暴露外部IP我们了解到,暴露静态外部IP的服务会对内核的连接跟踪机制造成巨大的损失。除非它是周密计划的,否则它只会按比例分解。我们的集群在Calico上运行,用于CNI和BGP,基于Kubernetes中的路由协议以及与边缘路由器的对等体。对于Kubeproxy,我们使用IP表模式。我们在Kubernetes中托管了一项庞大的服务,该服务通过每天处理数百万个连接的外部IP公开。有了所有SNAT和来自软件定义网络的伪装,Kubernetes需要一种机制来跟踪所有这些逻辑流。为此,它使用内核的Conntrack和netfilter工具来管理这些与静态IP的外部连接,然后将这些连接转换为内部服务IP,然后再转换为您的podIP。这都是通过conntrack表和IP表完成的。然而,这个conntrack表有其局限性。一旦达到限制,您的Kubernetes集群(下面的操作系统内核)将无法再接受新连接。在RHEL上,你可以这样检查。$sysctlnet.netfilter.nf_conntrack_countnet.netfilter.nf_conntrack_maxnet.netfilter.nf_conntrack_count=167012net.netfilter.nf_conntrack_max=262144这个问题的一些解决方案是使用边缘路由器对等多个节点,以便将传入的流量分散到静态IP连接整个集群。所以如果你的集群中有大量的机器,累积起来,你可以有一个很大的conntrack表来处理大量的传入连接。早在2017年它刚成立时,我们就没有想到这一切,但最近,Calico在2019年以“为什么conntrack不再是你的朋友”为题对其进行了详细研究。你绝对需要Kubernetes吗?三年过去了,我们仍然每天都在继续发现和学习新事物。这是一个复杂的平台,有其自身的一系列挑战,尤其是构建和维护环境的开销。它将改变您的设计、思维、架构,并需要提高技能和扩大团队规模以适应转型。但是,如果您在云上并且能够将Kubernetes作为“服务”使用,则可以减轻平台维护的大部分开销,例如“我如何扩展我的内部网络CIDR?”。或“如何升级我的Kubernetes版本?”今天我们意识到,您需要问自己的第一个问题是“您绝对需要Kubernetes吗?”这可以帮助您评估您遇到的问题以及Kubernetes如何解决它的重要性。转换到Kubernetes并不便宜。您为此付出的代价必须真正证明“您的”用例及其利用平台的方式。如果可以,那么Kubernetes可以显着提高您的工作效率。请记住,为了技术而技术是没有意义的。本文翻译自KomalVenkateshGanesan的文章《3 Years of Kubernetes in Production–Here's What We Learned》