使用Kubernetes三年,我们从中学到了什么?

全文共3963字 , 预计学习时长10分钟
使用Kubernetes三年,我们从中学到了什么?文章插图
图源:unsplash
2017年.我们构建了第一个kubernetes集群 , 版本是1.9.4 。 有两个集群 , 一个用裸机RHEL VMs运行 , 另一个用的是AWS EC2 。 时至今日 , 我们的Kubernetes基础架构团队有超过400个虚拟机 , 遍布多个数据中心 。 这个平台有高度可用且关键的软件应用和系统 , 能管理运行近四百万个活跃机器的大型实时网络 。
虽然kubernetes使我们的生活更轻松了 , 但过程会蛮艰辛 , 要经过范式的改变 。 不仅要完全更迭我们的技能和工具 , 还有设计和思想 。 我们必须掌握许多新的科技 , 大幅扩充提升团队和基础设施 。
回首用kubernetes产出的这三年 , 我们得出以下关键经验 。
1.应用的奇怪案例
涉及到微服务和容器化 , 工程师们倾向于不使用Java , 主要是因为它糟糕的内存管理 。 然而Java已不同往日 , 它的容器适配性在几年里已有提高 。 毕竟大多数系统都用Java运行 , 如Apache Kafka和Elasticsearch 。
在2017-2018年 , 只有一些应用在Java8运行 。 这些应用通常很难适应Docker内存系统 , 并且很容易因为堆内存问题和异常的垃圾收集趋势而崩溃 。 这是由于Java虚拟机不能遵守Linux cgroup和namespace造成的 , 而他们是容器化技术的核心 。
然而甲骨文公司在这之后不断提升Java容器化的适配性 。 Java8的后续补丁也引入了实验性的Java虚拟机flag标示来解决这些问题:
· XX:+UnlockExperimentalVMOptions
· XX:+UseCGroupMemoryLimitForHeap
但Java仍名声不佳 , 对比同行的python和Go , Java占用内存且启动速度慢 。 主要是由Java虚拟机的内存管理及类加载器造成的 。
现在如果必须选择Java , 我们会确保版本为11及以上 , 并且我们的Kubernetes内存设定为Java虚拟机最大堆内存( -Xmx )之上的1GB , 以提供余量 。 也就是说 , 如果JVM使用8GB的堆内存 , 则该应用的Kubernetes资源限制就是9GB 。 有了它生活会更好 。
使用Kubernetes三年,我们从中学到了什么?文章插图
图源:unsplash
2.Kubernetes的生命周期升级
Kubernetes的生命周期管理很繁杂 , 比如它的升级和加强 , 特别体现在用裸机或者VM搭建的集群 。 在升级时 , 我们发现搭建新集群最简单的方式就是用最新的版本并将工作负载从旧版本转移到新版本 。 努力和计划在模型内进行升级是不值得的 。
Kubernetes有多个运行插件 , 需要与升级同步 。 Docker、Calico或Flannel之类的CNI插件都需要仔细地将它们组合在一起才能正常工作 。 虽然一些项目可以使它变得更容易运行 , 如Kubespray、Kubeone、Kops和Kubeaws , 但它们都有缺点 。
我们在RHEL VM上使用Kubespray搭建了集群 。 Kubespray有关于搭建、添加、删除新节点、版本升级的指导手册 , 基本覆盖了我们使用Kubernetes产出需要的所有内容 。 但升级手册包含了免责声明 , 提醒我们即使变更很小也不要忽略任何版本 , 也就是说要更新所有中间版本才能使用目标版本 。
诀窍就是 , 当你计划使用或已经使用了Kubernetes , 想想生命周期活动以及你的方案如何这些问题 。 相对来说用它来搭建和运行集群是比较简单的 , 但生命周期的维护仍是有着诸多活动部件的全新领域 。
3.构建和部署
使用Kubernetes三年,我们从中学到了什么?文章插图
图源:unsplash
要做好重新设计整个搭建和部署管道的准备 。 我们的搭建过程和部署必须经历Kubernetes的完全转型 , 不仅对Jenkins管道进行了大量的重组 , 还使用了Helm等新工具 , 策划了新的git流程和构建 , 标记了docker镜像 , 并对helm部署图表进行了版本控制 。
不仅需要维护代码 , 还需要策略来维护Kubernetes部署文件、Docker文件、Docker镜像和Helm图表 , 并设计一种将它们链接起来的方法 。
在几次迭代后我们有了如下设计:放置应用程序代码及其Helm图表于单独的git存储库中 , 这使我们可以分别对它们进行版本控制 。 (语义版本号)
然后 , 我们将图表版本的地图与应用程序版本一起保存 , 并使用它来跟踪发布 。 例如 , 将app-1.2.0与charts-1.1.0一起部署 。 如果仅更改Helm值文件 , 则仅更改图表的补丁程序版本(例如 , 从1.1.0到1.1.1) 。 所有这些版本均由每个存储库RELEASE.txt发行说明 。
Apache Kafka或Redis的代码之类的系统应用程序的工作方式有所不同 , 我们未构建或修改其代码 。 也就是说 , 由于Docker标签只是Helm chart版本控制的一部分 , 我们没有两个git存储库 。 如果我们曾经更改了docker标签进行升级 , 我们将在图表标签中增加主要版本 。