用了就会更好吗?小心 Kubernetes 陷阱

阅读数:5140 2019 年 8 月 22 日 10:13

用了就会更好吗?小心Kubernetes陷阱

在公司,你不可能没有听到过有关 Kubernetes 的信息,来自谷歌的 red hot 容器编排技术通常是大家茶余饭后的聊天话题。

很少有一种技术可以让从 DevOps 实习生到首席技术官 (CTO) 都能轻松的理解,Kubernetes 也不例外,阅读有关 Kubernets 的文章反而会让你比以前更困惑,无法理解这些文章到底在讲些什么。当然,也有许多人认为 Kubernetes 是神级存在,但如果你想很好的使用 Kubernetes 并充分发挥它的作用,这取决于很多因素,我打算解释其中一些关键因素。

在本文中我还将为你提供一种渐进式评估 Kubernetes 并将其引入公司的方法。Kubernetes 是一项伟大的技术,如果使用得当,它将带来巨大的好处。

1. 从一个到一群

曾几何时,服务器被系统管理员亲切地命名并贴上便利贴。而现在,我们真的不知道运行我们工作任务的服务器是什么类型的,因为那些位于冷服务器室和数据中心的灰色机架上的盒子已经让位于由 Amazon、Microsoft 和谷歌运行的公共云。系统管理员也会继续给运行在公共云上的虚拟机命名,就像给他们的宠物命名一样。过去,如果需要服务器,可能需要几周的时间,通过电话或电子邮件与销售人员沟通,才能最终获得我们所需的服务。但是随着高性能虚拟化和公共云的出现,出现了 API。一个简单的 API 调用可以在几秒钟内启动一台机器。而在过去,需要花上几周的时间跟销售人员沟通。因为这样,很快,聪明的技术人员意识到,公共云不仅可以提供对计算的快速访问,还有通过简单易用的 RESTful API 提供自动化的潜力。这是相当有含金量的事情。

2. 作为代码和 DevOps 的基础设施

之后我们看到了像 Chef、Puppet、Ansible 和 SaltStack 这样的技术。有了这些,开发和运维之间的界限开始变得模糊。虽然系统管理员很少会冒险修改 shell 脚本,但是像 Chef、Puppet 和 Ansible 这样的系统都是成熟的系统编排框架。Puppet 使用领域特定的语言或 DSL 来让系统管理员定义基础设施设置的最终状态,而 Chef 使用基于 Ruby 语言的 DSL,该 DSL 充分利用 Ruby 的表现力来定义基础设施的最终状态。这些技术使我们完全进入了声明式和命令式基础设施的时代,在这个时代,可以使用文件中的代码定义服务器基础设施的最终状态,然后可以像常规源代码一样对其进行版本控制。这与系统管理员手动设置服务器,然后登录到服务器上设置各种软件服务和硬件资源(如存储或网络)非常不同。虽然他们所能做的仅仅是运行 shell 脚本,但是 Chef 和 Puppet 提供了对系统配置的集中管理,以及非常强大的 API 接口,使管理大量服务器变得不那么麻烦。

3.Docker 的崛起

随后,另一项强大的技术将使用 Linux 原语组合和管理容器变得非常容易:Docker。并不像通常被认为的那样,Docker 并不是一种容器技术。Linux 容器是使用 Linux 的操作系统原语(CGroups 或 Control group 和 Namespaces)构建的。Docker 使构建和管理容器变得很容易。Docker 有一篇介绍自己的文章 / 视频,但那是之后的事了。使用 Docker,可以很容易地打包应用程序及其所有依赖项,并对其进行容器化。就像一个真正的集装箱一样,“运输”变得非常容易。然后,这个容器可以在任何 Linux 机器上运行,而不必首先安装它的所有依赖项,这些依赖项可能是特定于 Linux 发行版的。这使得在 Debian Linux 上运行 Nginx、在 Ubuntu 上使用 Python Flask 框架以及在 alpine 上使用 MySQL 都变得很容易——这些包被封装在一起,都运行在同一台 Linux 服务器上。总之,Docker 成为以声明方式构建容器的标准方法,然后在 Linux 服务器上运行和管理它们的生命周期,利用 Linux 的底层容器技术并提供巨大的实用程序。这也就可以理解为什么当 Docker 第一次出现时就引起了大家的兴趣。

虽然 Chef 和 Puppet 等技术擅长管理物理和虚拟机的配置,但是容器很快就成为 DevOps 工程师部署应用程序的标准方式。此外,容器封装了应用程序部署逻辑的大部分,使编排的其余部分简单得多。现在正是采用更现代的以容器为中心的编排系统的时候。

然而,与此同时,还有另一种快速发展的方法将 ops 越来越多地转移到开发人员的领域:DevOps。工程师们已经发现,虽然 ops 的人想要稳定,但开发人员却一直想要发布新特性,这对 ops 所追求的稳定提出了挑战。这些相互冲突的目标,常常使团队陷入矛盾,甚至直接影响产品的发货速度。此外,当产品开发人员没有意识到他们编写的代码在生产环境中引起的所有问题时,他们往往不会花精力去修复它。这是因为生产环境原则上是 ops 团队的职责范围。为了解决这些问题,团队开始尝试一种新的方法,DevOps。想法很简单:让编写代码的人在生产环境中运行代码。这样他们就需要对自己发布的代码负责任了。如果他们想要更频繁地发布新特性,他们需要在 ops 方面保证正常。云和容器等技术及其 API 和工具使得将软件工程方法引入云操作成为可能。 快速迭代的 DevOps 团队正在构建大型应用程序,这些应用程序通常由独立开发和发布的微服务组成,而不需要更改、测试和发布一个大型的单一应用程序。 使用微服务体系结构实践 DevOps 的团队喜欢云和容器的易塑弹性,它们可以被可伸缩的工具和 API 轻松控制。

4. 进入 Kubernetes 时代

在 DevOps 和微服务与容器衔接的地方,一个新的、更本机的编排系统更有意义。Kubernetes 受谷歌的 Borg 系统启发,是一个开源的容器编排系统,最初由谷歌的工程师构建,现在由云计算基金会 CNCF 维护。作为一个容器编制平台,Kubernetes 可以帮助自动化应用程序部署、扩展和管理。像 Docker 这样的系统管理服务器内的容器,Kubernetes 做的更多,但是它的主要功能之一是管理服务器集群或可以运行容器的节点。与 Kubernetes 类似的系统有 Apache Mesos 和 Docker Swarm。尽管关于哪一种制度会成为行业标准存在争议,但到目前为止,很明显,Kubernetes 已成为赢家。在你的容器编排策略上押注 Kubernetes 是一个非常明智的决定。

不仅仅是 Docker

值得注意的是,Kubernetes 不仅可以编排 Docker 管理的容器。它还可以编排由类似于 Docker 的系统(如 ContainerD、crio 和 RktLet)管理的容器。虽然你可以使用任何这些系统创建和管理容器,但是由于本文 / 视频的初衷,我们将用“Docker”表示“容器管理”。下面,我们一起来看看 Kubernetes 的一些最重要的特性。

为什么需要 Kubernetes

要理解为什么像 Kubernetes 这样的系统很重要,最好思考一下 Docker 的功能局限在哪里。
Docker 使管理服务器内容器的生命周期变得很容易,而 Kubernetes 使管理运行 Docker 容器的服务器集群变得很容易。此外,现代的基于微服务的应用程序通常由几个容器组成。Kubernetes 提供了一个“应用程序部署”的概念,它本质上是一组组成应用程序的容器,在集群上以分布式方式运行。当你想要一个由一堆容器组成的应用程序运行时,你只需告诉 Kubernetes 它的相关信息,它就可以找出集群中的哪个节点具有足够的计算资源来运行容器,并将其调度到那里。它还可以在容器失败时重新启动容器,甚至根据一些参数扩展应用程序,通过运行更多容器来应对流量激增。这就是 Kubernetes 的精髓,这就是人们所说的“容器编排”。

当在一个集群上运行多个应用程序时,还有一些很好的特性可以帮助简化管理。Kubernetes 具有使管理应用程序配置和凭证更容易的特性。Kubernetes 还管理着其他一些基础设施,比如存储和网络。除了计算,这是构成任何基础设施的最基本的三个组件的另外两块。

管理与否

虽然可以通过从头开始在私有云上运行 Kubernetes,但更明智的做法是选择像 OpenShift 这样的 Kubernetes 发行版,它有些功能可以付费支持——至少在你扩展 Kubernetes 基础设施之前。也可以在 AWS、Azure 或 GCP 上的机器集群上安装 Kubernetes,但是所有这些公共云也提供托管 Kubernetes 产品。Kubernetes 由多个组件组成。它们协同工作,帮助运行称为计算节点的计算机集群。仍然会有 Kubernetes 组件在每个计算节点上运行。当你选择任何公共云供应商提供的托管 Kubernetes 产品时,他们通常会要求你从它们的计算产品中选择一定类型的节点,然后这些计算产品将成为 Kubernetes 集群的一部分。这些节点将部署你的容器化工作任务。Kubernetes 的主组件(也称为“控制平面”)由云提供商管理。

5. 你的公司准备好使用 Kubernetes 了吗?

这并不取决于一个因素,而是一系列因素。我们详细讨论一下这些因素。

你使用的是私有云还是公共云?

Kubernetes 可以部署在公共和私有云上。在私有云上,虽然理论上可以自己安装和维护 Kubernetes,但是最好运行一个 Kubernetes 发行版,比如 OpenShift,它可以获得供应商支持。虽然 Kubernetes 诞生于云中,是一种被称为“云原生”的技术,但是它是管理计算集群的一个很好的选择。如果你运行它是为了管理私有云,这也没关系。事实上,可以认为 Kubernetes 是管理私有云的一个很好的选择。

对于 AWS、Azure 或 GCP 等公共云,你可以通过自己设置 Kubernetes 来在一组计算节点上运行它。例如,Kops 是一种流行的解决方案,它允许你在 AWS 上运行的一组 EC2 实例上部署 Kubernetes。但是,我强烈建议你将维护 Kubernetes 控制平面的工作交给云提供商,选择使用托管 Kubernetes 提供的服务,这样你就可以专注于在 Kubernetes 上运行工作任务的机制。

你目前使用 Docker 的情况如何?

如果你想在 Kubernetes 上运行的应用程序没有被封装,那么它就不会启动。Kubernetes 是一个容器编制平台,你必须确保要在 Kubernetes 上运行的应用程序在生产中的 Docker 上经过了良好的测试。在稍后的时间里,我们将讨论一个简单的策略,即如何一步一步地推出它。Docker 被广泛使用,工具非常成熟,可以肯定地说,Docker 已经远远超过了炒作阶段。无论你的公司采用的 IT 策略多么“谨慎”,都不应该怀疑使用 Docker 带来的风险问题。另一个真正的优势是,当 Docker 与 Kubernetes 正确实施时,可以真正提高服务器的利用率。这是值得考虑的。

你的 DevOps 文化成熟度如何?

强大的 DevOps 文化的存在意味着 devs 负责运行他们在生产中开发的服务。他们总是通过在操作方面寻找自动化的方法来提高自己的生产效率。如果你的应用程序或服务基于微服务体系结构,这很棒,这意味着有许多移动部件和拥有不同微服务的团队需要彼此独立运行。如果这种文化存在,Kubernetes 对你们就再合适不过了,你们应该尽快使用它。Kubernetes 可以很好地运行单片工作任务。这里的重点是,如果有两个不同的团队,开发和运维,运维团队使用全新的部署方式,开发团队致力于采用容器化构建系统和应用程序的配置方式,然后让这两个团队进行密切的配合就有点异想天开了。

Kubernetes 人才储备

Kubernetes 可能需要一段时间来学习,只有当学习它的人已经在努力学习容器化时,它才有意义。现在市面上提到 Docker 的书不一定很多。但如果你确信 Kubernetes 适合你们,并且考虑了上文中提到的几点因素,那么你就需要更多的同事参与其中了,他们能够并且有信心在 Kubernetes 上运行生产工作任务。如果公司中员工对 Kubernetes 仅有初步的了解,那么我们将帮助你们在此基础上构建经验,同时降低风险,并为将来在 Kubernetes 上运行生产工作任务构建一条道路。下面我们来看具体怎么做。

6. Kubernetes 陷阱

如果有人把 Kubernetes 称为万能药方,那么他们并没有对 Kubernetes 进行客观的认识。下面是一些需要注意的事情。

被 Kubernetes 管理也并不能保证万全

Kubernetes 是一个由许多协同工作的软件组成的系统。不管你是直接管理还是选择管理 Kubernetes,事情都可能会出错。被管理下的 Kubernetes 在其各种组成部分中出现问题并不罕见。不要仅仅因为 Kubernetes 控制平面是由云提供商管理的,就认为什么都不会出错。你可以在 Github 上找几个云提供商提供的 Kubernetes 问题看看。当出现问题时,你可能仍然需要联系支持人员,以便解决问题。这可能会导致停机。因为控制平面中的 Kubernetes 组件只创建和监视容器,如果它们出现问题,通常不会影响已经运行的容器。对于一架由 Kubernetes 控制的飞机来说,带着所有的集装箱一起坠落是非常罕见的。但是,会导致不能创建新的容器和自动伸缩等问题。

Kubernetes 上的有状态应用程序仍在演变

Kubernetes 的用途是创建和销毁像短命昆虫一样的容器。可以创建许多容器来响应通信量的激增,并在恢复正常后销毁这些容器。这意味着这将是一个非常动态的环境,在这里,服务器被真正地进行集群处理——这与用类似于宠物的方式亲切地命名服务器的时代相去甚远。从这个意义上说,Kubernetes 对数据库等有状态的应用程序的支持似乎是有点马后炮的。 这是一个活跃的开发领域,并且现在相当稳定,但是如果与其他领域相比,假如 Kubernetes 下的有状态应用程序的工作方式继续发生相对快速的变化,人们不应该感到惊讶。

可以以云提供商中立的方式分配持久性卷,以便在 Kubernetes 本地支持的有状态应用程序中使用。

如果你想使用底层云提供商管理的有状态服务 ( 比如: RDS、DynamoDB 等),可以使用 Kubernetes 提供的原生方法 Service Catalog,这使得使用云提供商的托管服务变得更容易。

Kubernetes 升级

通过 web 搜索引擎应该会找到很多关于 Kubernetes 集群升级的恐怖故事,使你放弃更新并继续使用现有的集群设置。其实最好的方法可能是重新创建一个具有与生产集群相同版本的集群,并在其中安装关键应用程序,然后升级这个集群,在继续升级到生产集群上的新版本 Kubernetes 之前,检查是否一切正常。还是面对现实吧——如果你认真对待 Kubernetes 及其带来的好处,那么集群升级是不可避免的。所以,做好计划并执行。

可移动组件

虚拟化。这是一个我们现在认为很常见的抽象概念,一个我们经常使用的抽象产品。事实上,当有人提到“机器”或“服务器”时,他们很可能指的是虚拟机。对于应用来说,Kubernetes 极有可能成为新的标准基片。一个新的抽象层次,将成为新的常态。然而,对于虚拟机,由于大多数大型系统都标准化于 Linux 的 KVM 技术,它在很大程度上是操作系统层的一部分。尽管涉及到其他组件,但它们的级别相当低。它与 Kubernetes 非常不同,Kubernetes 中有十几个服务在一组机器之间相互通信,处理相当复杂的计算、存储、网络和自动伸缩功能。

当问题出现时,有时我们往往会深入研究 Kubernetes 去搞明白出了什么问题。 其实我们只需要在某种程度上假设 Kubernetes 使用的所有这些组件的不同版本在某种程度上是相互协调的。至少这是云提供商给我们做了保障的。

留住 Kubernetes 人才

如果你渴望大力使用 Kubernetes,但可用人力却很少,那么你这样做就是有风险的。对于你的项目 Kubernetes 是有价值的,所以让你的整个 DevOps 团队在 Kubernetes 上进行培训或自我培训是非常有必要的。毕竟,大家都希望通过培训的机会,掌握一项炙手可热的技术。从安全的角度来讲,重要的是不要只有一两个 DevOps 人员,而是要有一个能够很好地处理 Kubernetes 的团队,这样,如果你唯一的 Kubernetes 员工离开了,那么你的 Kubernetes 项目才能保持连续性。这种事经常发生——相信我,由于 Kubernetes 在他们的 LinkedIn 页面上被列为一项技能,招聘人员不会花太长时间就会打电话给他们。

7. 将 Kubernetes 引入公司

至此,如果你确信使用 Kubernetes 可以让你的公司从中获益,那么你可以参考下以下一些步骤, 以一种能够让你充分地理解 Kubernetes 以及运行它来管理生产工作任务的方式引入它。

培训或雇用 Kubernetes 人才

你需要从 DevOps 团队中选择具有 Kubernetes 实践经验的人员来执行你的计划。有了高质量的在线培训材料,他们可以进行自我培训,也可以参加更正式的培训项目。你还可以咨询云供应商,看他们是否可以为你公司提供专门的培训,或者他们是否可以给你的团队提供一些相关活动。你也可以选择一些其他的付费项目。

聘用 Kubernetes 人才是另一种途径。寻找有 Kubernetes 运行经验的人员。雇用他们之前,你可以跟他们讨论实施 Kubernetes 的工作步骤,以及他们在 Kubernetes 上运行生产工作任务时所面临的一些挑战。询问他们是否运行过任何有状态的工作任务。基于此讨论,你应该能够确定他们是否适合你的项目。

将工作任务转移到 Docker

如果你想要迁移到 Kubernetes 的工作任务还没有在 Docker 上的生产环境运行过,那么通过直接将这些工作任务迁移到 Kubernetes 会使困难度有所增加。如果你遇到任何问题,你将无法准确判断它是由构建时、运行时还是配置问题引起的。另一方面,如果你的团队已经将工作任务进行了容器化,并且使用 Docker 在生产环境中运行了这些工作任务,那么在遇到问题时,需要处理的事情就会更少。

在 Kubernetes 上运行非生产工作任务

现在你的工作任务已经封装完成,你还可以将一些非生产工作任务(比如那些在开发中或临时性的任务)转移到 Kubernetes。这样,你的大型团队就可以适应新的环境,将 Kubernetes 顺利地集成到你持续部署的管道中了。

无状态工作任务优先

在将生产工作任务迁移到 Kubernetes 时,最好先从无状态工作任务开始:容器只服务于应用程序请求,而不直接持久化任何数据。在 Kubernetes 上运行有状态工作任务需要更深入的 Kubernetes 专业知识,你可以在公司中先通过运行无状态工作任务构建它。例如,对于有状态工作任务,你需要更详细地规划如何在节点宕机时进行管理。这对于像 Elasticsearch 这样的分布式有状态应用程序尤其复杂。

移动非关键工作任务

将非关键工作任务先转移到 Kubernetes 上,并让你的团队积累在其上运行生产工作任务的经验,这也是一个不错的办法。在生产环境中运行工作任务还需要考虑其他因素,例如监视、警报和应用程序升级等。

实现飞跃

我们了解了如何在公司中实施 Kubernetes,从而在构建专业知识的同时降低风险。我们还讨论了如何从工程的角度准备好将生产工作任务封装到 Kubernetes 中,并慢慢地将其引入 Kubernetes。你是决策的关键者,知道什么时间点开始做这个事情。每个公司使用新产品的风险是不同的,要自动部署 Kubernetes 集群,我的建议是使用 Terraform 之类的工具。

8. 总结

一份好的计划会充分考虑清楚风险。这就是本文的主要思想:告诉你风险所在,以及如何在 Kubernetes 策略中避免这些风险。Kubernetes 是一项伟大的技术,在很多领域,它肯定会对你有所帮助。但是,与你打算在其上运行生产工作任务的其它技术一样,你需要权衡风险,并评估收益是否大于风险。Kubernetes 有很多失败的案例资源,这对于找出最常见的问题,甚至如何解决这些问题都很有帮助。

就我个人而言,我对 Kubernetes 感到非常满意,Kubernetes 提供的编排、自动伸缩、服务器利用率和自修复功能有很多有用之处,完全可以取代我们自己的构建。

原文链接:

https://unixism.net/2019/08/a-managers-guide-to-kubernetes-adoption/

收藏

评论

微博

用户头像
发表评论

注册/登录 InfoQ 发表评论