Kubernetes 之所以酷
前言
当我最开始了解到 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
的博客一开始就保证的一件事是:“如果 Kubernetes
的 API
服务和其他组件都挂了,这没什么事儿,你的程序将会继续运行!”,我认为,这件事理论上听起来很酷,但我并不敢确定这是真的。
使用了这么久,这的确是真的!
我经历了一些 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),可能会简单一点,因为他为用户做了大量默认的设置,但我并没有尝试过任何一种。