前言

当我最开始了解到 Kubernetes 的时候(大概一年半以前?),我真的找不出需要关注它的理由。

满打满算,我已经使用 Kubernetes 快三个月以上了。关于为什么我觉得它非常有用,有了一些想法,虽然我仍然还算是一个刚入门的,不过,幸运的是,本文依然能够向您阐述一下,Kubernetes 究竟是怎么一回事。

我在向您解释 Kubernetes 多么有趣的过程中,会尽量避免使用一些太专业的名词,比如 Native Cloud、Orchestration、Container、Kubernetes 的一些专用语😁 。我主要是从一个 Kubernetes 运维工程师的角度向你解释,因为我当前的工作就是搭建并配置 Kubernetes 运行环境,并让他正常运行。

我不会去讨论如“我是否应该把 Kubernetes 应用到生产环境中?”这种不是一两句话能说明的问题(因为“是否用于生产环境”完全取决于你做的是什么)。

Kubernetes 让你无需启动新服务器就直接在生产环境运行代码

我最开始接触 Kubernetes 是源自于和我同事 Kamal 的对话:

  • Kamal:用 Kubernetes 你只需要简单的一个命令就能启动一个新服务
  • Julia:这怎么可能?
  • Kamal:比如,你只需要写一份配置文件,然后应用它,然后你就有了一个运行在生产环境的
    HTTP 服务
  • Julia:但是,当前如果我要新建一个 AWS(亚马逊云服务)实例,需要写一个
    manifest,然后启动服务发现,配置我的负载均衡,配置我们的开发软件,还要保证 DNS 工作正常,就算这切都顺利完成,也要至少 4 个小时的时间啊!
  • Kamal:Yeah。用 Kubernetes ,你就不再需要做这些事情了,你能够在 5 分钟内启动一个 HTTP 服务,并且他将自动运行。只要你集群有相应的空间容纳这个服务,它就直接能用!
  • Julia:估计这里面有不少坑吧。

这里面的坑,应该要算配置 Kubernetes 了,确确实实不简单(以我的经验来说),你可以查看这个Kubernetes The Hard Way。但至少目前来说,我们不用担心这个事情。

呐,现在第一个酷的地方在于,Kubernetes 有巨大的潜力让开发者轻松地部署服务到生产环境。这真的很酷,使用 Kubernetes 工作,你真的可以在 5 分钟内,用一个配置文件启动一个新的 HTTP 服务(包括“启动 5 个服务程序”、“配置负载均衡”、“配置 DNS”),值得了解一下。

Kubernetes 提供可视化界面让你管理你运行的代码

在我看来,你在了解 Kubernetes 之前,必须要了解 etcd。那就让我们先看看 etcd
是个什么!

想象一下,今天我问你“告诉我,生产环境中现在都运行了些什么应用?都运行在哪些主机上的?服务状态正常吗?是否有 DNS 绑定?”,我不清楚你的情况,我只知道,如果是我,我需要查看一大堆不同位置的服务器,花我一小会儿时间才能搞明白并回答这些问题,不可能通过一个 API 就能得到所有信息。

Kubernetes 上,你集群中所有的状态:运行的应用、节点、DNS 名、定时任务等等,都存储在一个统一的数据库中,Kubernetes 所有的组建都是无状态的,并且都是通过一下过程来运行的:

  • etcd 中读取状态,比如:1 号节点中的应用清单
  • 改变状态,比如:在 1 号节点中启动一个应用 A
  • 更新 etcd 中的状态,比如:将应用 A 的状态设置为“运行中”

这意味着,如果你想要回答一个问题“嘿,在可用区域中,有多少 nginx 在运行?”,你只需要查询一个统一的 API(Kubernetes提供)即可,Kubernetes 中其他的组建也都能通过这种简单的 API 方式使用。

这同时也意味着,你能够通过一个简单的方式,控制所有 Kubernetes 中运行的东西。只要你愿意,你可以这样做:

  • 执行一个复杂的发布策略(部署 1 个任务,等待 5 分钟,部署 5 个或更多,等待 3.7 分钟等等)
  • 在将一个分支提交到 Github 后,自动启动一个 webserver
  • 监控所有运行中的应用,以确保他们每个都有一个合理的 cgroups 内存上线

你所需要做的只是写一个调用 Kubernetes API 的程序(控制器“controller”)

另一个比较酷的关于 Kubernetes API 的事情就是,你不用局限于 Kubernetes 所提供的一些管理方式,你可以自己编写程序调用 Kubernetes API 实现自定义的 部署/新建/监测任务。他让你能做所有你需要的事情!

就算 Kubernetes 所有组件都挂了,你的应用照样运行

许多写 Kubernetes 的博客一开始就保证的一件事是:“如果 KubernetesAPI 服务和其他组件都挂了,这没什么事儿,你的程序将会继续运行!”,我认为,这件事理论上听起来很酷,但我并不敢确定这是真的。

使用了这么久,这的确是真的!

我经历了一些 etcd 挂掉的情况,但是:

  • 所有程序都照常在运行
  • 没有其他新的连锁事件发生(当然,你无法部署新的程序或者提交修改,定时任务也会停止运行)
  • 当所有问题都修复后,集群会重新搜集之前丢失的信息

当然这也意味着,如果 etcd 挂了,然后某个运行中的程序崩溃了或者发生其他错误,在 etcd 重新启动之前他将无法自动处理问题。

Kubernetes 的设计帮助其不会轻易被 bug 搞崩溃

像其他软件一样,Kubernetes 也会有 bug。比如,现在我们集群中的控制器就有内存泄漏的问题,调度器经常崩溃。Bug 当然不是什么好东西,但是使用下来,我发现 Kubernetes 的设计帮助其减少了很多在核心组件中潜在的 bug

如果你重启任何一个组建,将会发生:

  • etcd 中读取所有相关的状态数据
  • 开始执行一些基于当前状态必要的操作(调度应用、垃圾回收、调度任务、部署守护进程等等)

因为所有的组建都不在内存中保存其状态,所以你能够在任何时候重启组件,这通常还能避免一些 bug 的发生。

例如,你的控制管理组件有内存泄漏的问题,由于控制管理组件是无状态的,你能够间歇的重启它,比如每小时一次,并且完全不会产生其他不好的连锁反应。又比如,我们的调度器出了 bug,他有时会落下某些程序然后从不调度他们。你就可以通过每十分钟重启一次调度器来减少这个问题的发生。(我们没这样做,因为我们修复了这个 bug,但你可以这样做啊🤣 )

因此我觉得,我能够相信 Kubernetes 的设计,相信它能够保证即使核心组件出了问题,也能够保持集群状态的连续性。并且一般来说,我认为软件的质量是随着时间慢慢提高的,现在有状态的并且需要你操作的,就只有 etcd

关于 state 我就不再多说什么了,我认为你唯一需要解决的备份/恢复问题就只有 etcd(除非你应用都是写入到永久存储器上的)。我认为,这让 Kubernetes 的操作变得简单了很多。

在 Kubernetes 上部署新发布的组件系统

假设你想部署一个新发布的定时任务系统!用其他方式做的话,这将是成吨的工作量。但是,在 Kubernetes 上部署一个新的发布的定时任务系统却相当简单!(它仍然只是一个发布系统)

最开始我读 Kubernetes 定时任务控制器代码的时候,我真的很开心,因为他代码很简单。点击这里阅读cronjob_controller.go,主要逻辑代码也就 400 多行的 go 代码。

定时任务管理器的主要工作是:

  • 每 10 秒:
    • 列出存在的定时任务
    • 检查每一个任务,看是否需要运行
    • 如果需要运行,新建一个需要调度的任务对象,然后被其他 Kubernetes 控制器组件执行
    • 清除已经完成的任务
    • 重复

Kubernetes 的模型挺限制的(他是这么一种模式:资源都定义在 etcd 中,控制器通过读取这些资源然后更新 etcd),并且我认为这种相关的选项和限制性的模型会让你在 Kubernetes 的框架中开发自己的发布系统更加简单。

Kamal 给我传递了这么一种思想:“Kubernetes 是一个编写你自己发布系统的好平台”而不仅仅是 “Kubernetes 是一个你能使用的发布系统”,我认为这很有趣。他有一个原型放在 Github 上的 system to run an HTTP service for every branch you push to github。这花了他两周的时间,好像只有 800 行的 go 代码,这让我眼前一亮!

Kubernetes 能让你做一些神奇的事情

我一开始就说 “Kubernetes 让你做很多神奇的事情,你仅仅只需要用一个配置文件,就能串起大量的部件以及流程,这让人难以置信”,当然这是真的!

为什么我说 “Kubernetes 并不是那么简单”是因为 Kubernetes 有很多部件,要想学会如何配置一个高可用的 Kubernetes 集群需要大量的工作。比如我发现他给了我很多抽象的接口,我需要了解这些接口底层都是怎么实现的,才能让我更快速的调试以及写出更好的配置。我喜欢学习新事物,所以这并没有让我感到不开心或者其他什么的,我只是觉得,这个认识很重要!

一个更加实际的,关于“我不能仅仅依靠这些抽象的接口”的例子。我很挣扎地学习 linux 的网络知识,才能让我很自信的配置 Kubernetes 的网络,肯定会比我完全不了解网络更好。这会很有趣,但是也很耗时间。以后我或许会写一些关于配置 Kubernetes 网络的难与乐。

另外我写了一篇 2000 字的博文,讲了在配置 Kubernetes CA 中,所有必须学习的、关于 Kubernetes 证书认证的不同配置项的知识。

我认为一些 Kubernetes 系统管理软件,比如 GKE (google’s kubernetes product),可能会简单一点,因为他为用户做了大量默认的设置,但我并没有尝试过任何一种。