向 Kubernetes 迁移的经验

向 Kubernetes 迁移的经验

Kubernetes 是当下的热门话题,所有主流的云服务供应商都采用 Kubernetes 作为部署 cloud native app 的解决方案。几周前,AWS 在 reInvent 大会上发布的 EKS(亚马逊 Elastic 容器服务),可以充分地管理 Kubernetes 集群。
这是 AWS 迈出的巨大一步,因为 AWS 是最大的公有云服务提供商,并且部署了最多的 Kubernetes 应用。官方提供了工具 kop,用于部署和管理 Kubernetes 集群,kop 可以很好地在生产环境使用。随着 Kubernetes 的流行,越来越多的公司也在极力拥抱 Kubernetes,因为 Kubernetes 可以解决许多常见问题。
是否真的应该向 Kubernetes 迁移? 如何做才是拥抱 Kubernetes 的正确姿势?我将在本文中分享我的经验,并尽力回答这个问题。


问题

向 Kubernetes 迁移的经验


今年早些时候,我们开始容器化 Sematext Cloud 和 Sematext Enterprise 的一些部署,这看起来确实有些直截了当。需要做的就是容器化应用,为应用所需要的资源如部署、服务等创建一些 Kubernetes 配置,以为已经准备好可以大干一场了,但事情并非这么简单。
主要的问题是所有用于管理发布的东西都不适合 cloud native 范式。应用不是 cloud native 的,应用可能没有使用 CI 或 CD 部署,健康检查或使用监控工具进行日志,指标和警报的监控也有问题。应用可能是静态的并且部署也很复杂。向 Kubernetes 迁移过程中,这种复杂性无济于事,也不会神奇地消失,只会让事情变得更糟。cloud native 意味着将操作系统从应用程序中解耦,这也是容器正在做的事情。
在软件行业的发展中,首先出现的是瀑布模型,然后是 Agile,而现在是 DevOps。这是一个非常重要的难题,也没有前人的经验可以借鉴。每个团队都使用最适合自己的方案,如果你想保持现状也是可以的。 你只需要确保你的程序能适用于 cloud native app,这意味着你可能需要改变一些东西。让整个团队接受 DevOps 原则并不容易,所以这可能需要一些时间,要为此做好准备。
如果想了解我对于 DevOps 的看法,可以阅读 什么是 DevOps?[1]
解决方案

向 Kubernetes 迁移的经验


这个解决方案无需盲目遵循,这里只给出想法,并解释过程中可能遇到的问题。这个话题比较广泛,我不会详细解释我所提到的所有东西。
首先,废弃所有未使用过的组件,并做好清理工作。软件开发持续几年后,就会变得非常复杂,因为总是有更重要的事情要做,新功能、新的修复等等。
其次,对 Kubernetes 的 readiness 和 liveness probes 进行健康检查,这部分不难。需要花费主要的经历来管理配置,这部分比较困难。我建议使用 config map 和秘钥,避免使用环境变量。可以使用一些环境变量,但不要完全使用环境变量来管理配置。你的应用程序应该充分利用 Kubernetes 的潜力。 
Kubernetes 应用间使用服务互相通信。Kubernetes 中有不同类型的服务,可以将这些服务视为负载平衡。你定义的服务名称即是 endpoint(http://service_name:port)。如果你正在使用的是有状态应用程序,则可能需要使用可以访问特定的 Pod 的 headless service。如你所料,Kubernetes 中的服务以某种方式也解决了服务发现的问题。如果你早已用过诸如 Consul 来做服务发现,恭喜你!你可以继续使用,只需将其部署在 Kubernetes 上即可——根据 Consul Helm Chart 便可轻松部署。
从 Kubernetes 的角度来看,无状态应用程序应该非常容易扩展。 你需要将“部署”作为资源,因为此类服务还可以管理简单的升级——滚动更新。当然,应用程序需要在处理扩容时不出问题,这可能需要更改一些代码才能实现。
主要问题集中在有状态应用如数据库上,Kubernetes 为这类应用程序提供了 StatefulSet 资源,但在添加新节点或发生故障时 Kubernetes 不清楚某些特定的应用程序应该作何反应,这是Ops 人员的日常工作。幸运的是,通过编写Kubernetes Operator来完成这些并不难。
简而言之,Operator 是 Kubernetes 的自定义资源,或 CRD。可以自己写也可以用现有的。我们正在使用 Elasticsearch Operator,我们很高兴可以为这个项目做出贡献。我已经提交了一些 pull request。
你可能开始着手整合资源了,但不要忽略计算资源,而且要限制容器的计算资源。有两种类型的计算资源:请求,它指定一个节点上的最小可用资源量,用于 Kubernetes 调度程序运行特定 Pod;限制,一个 Pod 可以使用的最大计算资源量。这一点非常重要,特别是对于 Java 应用程序。请注意,对于 Java 应用程序,你还需要根据堆内存要求调整这些限制。我的建议是使用 Java 版本 8u131 或更新版本,这是 Docker-aware 对 Docker CPU 和内存的限制。
标签化应用程序,这会对你监视容器和应用程序有所帮助。一般来说,元数据信息就是通过选择器连接不同的资源的方式。例如,部署和服务。
当你开始编写 Kubernetes 配置文件时,你会对觉得还不错,维护它们也不是什么大不了的事儿。但当你试图实现一个部署的 pipeline 时,你会意识到只使用一堆配置文件会非常糟糕。所以就要提到 Helm 了。 Helm 是用于打包 Kubernetes 应用程序的工具,我强烈建议将其用于部署。像多环境支持,依赖关系,版本控制,回滚以及各种 hook(像数据库迁移)等功能就足以证明 Helm 有多棒了。但你还需要学习另一个工具,但是我向你保证会学有所值。
无需多个群集来支持不同的环境。只需使用不同的 Kubernetes 命名空间。例如,为了创建一个新环境,只需创建一个单独的命名空间,完成测试后删除它就行,这样就节省了大量的时间和金钱。但是,不要忽略安全问题。Kubectl 类似集群的的 root 用户,不要给每个人都分配访问 kubectl 的权限。有时候,虽然创建一个全新的集群比较复杂,但可能比管理 RBAC[2] 要好。不过,还是强烈建议使用 RBAC。 
那么如何版本化容器镜像呢? 可以使用 Helm 打包, 当然,这取决于你。最常用的方法是使用 commit ID 标记镜像,随后使用release 标签。你需要将 Docker 镜像存储在私有或公共的 registry 中。我建议使用 DockerHub,因为 DockerHub 可能是性价比最高的。如果上述都搞定了,那么你需要创建一个部署的 pipline, 可以使用 Jenkins 来部署所有内容,并作为 DevOps 的主要工具之一。


总结

向 Kubernetes 迁移的经验


最近,我们的重点要放在 cloud native 上,而不仅仅是 Kubernetes 本身,Kubernetes 只是一个工具。我们向 Kubernetes 迁移 Sematext Cloud 和 Sematext Enterprise 的工作仍在进行中,这需要一个过程,而不是一次性的工作。
我希望这篇文章能够让你了解到向 cloud native 和 Kubernetes 迁移的一个过程以及预期达到的效果。虽然过程艰难费时,但对于你的的公司文化及软件都很有好处。扩展将不再是问题,基础架构上将只会是代码和软件问题。拥抱 Kubernetes,但也要准备好面对挑战,其中一些挑战,本文也有所提及。 
相关链接:
  1. https://akomljen.com/what-is-devops/

  2. https://kubernetes.io/docs/admin/authorization/rbac/


原文链接:https://dzone.com/articles/embracing-kubernetes-successfully


Kubernetes 实战培训

向 Kubernetes 迁移的经验


本次培训内容包括:Docker容器的原理与基本操作;容器网络与存储解析;Kubernetes的架构与设计理念详解;Kubernetes的资源对象使用说明;Kubernetes 中的开放接口CRI、CNI、CSI解析;Kubernetes监控、网络、日志管理;容器应用的开发流程详解等,点击识别下方二维码加微信好友了解具体培训内容

向 Kubernetes 迁移的经验


3月23日开始上课,点击阅读原文链接即可报名。