本文翻译自Github上的arschles/kube-best-practices,原文链接:arschles/kube-best-practices
可观察性原则(Observability is golden)
Kubernetes负责编排你的Pod。如果它能够监测到Pod的如下指标,它将能够更有效地管理Pod:
- 你的Pod需要什么:你可以通过添加Resource Limit来告诉K8S。
- 你的Pod内部发生了什么:确保你的Pod配置了存活探针和就绪探针。
- 同时确保你在Pod里配置了日志、监控等机制,这些机制都能够让你更清楚Pod内都发生了什么。
如果程序发生错误,请直接崩溃(When all else fails, crash)
Crash-only架构意味着你的程序遇到问题后直接崩溃而不是试着慢慢恢复自己。
Erlang语言通过引进了监管者模式推广了When all else fails, crash这个概念。监管者监管你的程序,如果你的程序崩溃了,监管者就会重启它。这种架构鼓励你的程序如果发生了错误直接崩溃即可。因为你心里有数,如果你的程序崩溃了,监管者可以马上再帮你把程序重启。
如果你的程序跑在Kubernetes上,那么Kubernetes本身就是个监管者。与其在你的程序里面写一些自我恢复的逻辑,还不如直接崩溃,让Kubernetes重启它就好了。
保证程序无序化、无状态化(Unordered is better than ordered)
不管你喜不喜欢,你的App是一个分布式系统。你不能再把你的App看成一个单一进程。所以你的App将很难处理顺序化的事件。
业界对分布式系统上的顺序化事件做了许多研究,所以如果你的业务逻辑必须依赖顺序化事件来运行的话,你需要明白分布式系统处理顺序化事件的基本方针(因果顺序关系,时间顺序关系等等),然后决定你的App使用什么顺序化事件处理策略。
或者,你也可以在你的程序里避免使用顺序化的事件,让Kubernetes自身的机制帮你处理这些。Kubernetes自身的机制可以参考以下几个文档:
去耦合(Loose coupling is better than tight coupling)
我们知道,Kubernetes会一直监控着你的App,如果环境发生了变化,它会自适应这些变化并且对你的App的部署策略做相应调整。你的App需要能够容忍这些变数。这意味着你的App需要:
- 不能依赖某个特定的Pod
- 通过Service或者Service Mesh与Pod通讯
- 如果不能获取资源或者访问其他Pod,直接崩溃即可
- 如果你需要通过Kubernetes的Api或者Kubectl查询Pod状态的话,千万不要用Pod名来检索,用Pod的Label来检索。
轻微的耦合也不一定是错的(But tight coupling isn't always wrong)
Kubernetes部署的原子组件是Pod,一个Pod可以有多个容器组成。这种设计实际上就是支持了不同容器间的轻度耦合。一个Pod内的容器要不然一起运行要不然都不运行。所以如果你的App里面有耦合组件的话,把它们部署在一个Pod里。例如:
- Fluentd作为你App的辅助组件,与你的应用容器编排在一个Pod里,负责收集应用容器的日志。
记录你的配置(Record your configuration)
Kubernetes提供了一套声明式的API,这套API允许你告诉Kubernetes你的APP的最终状态是什么。但是你不需要告诉Kubernetes怎么达到这样的最终状态。Kubernetes自己有一套调节机制,能够将集群的状态调整到你要求的状态。
你需要时刻保证你在配置区上的代码版本是健康的、可以正常部署执行的。这样你才可以把你的程序交付给Kubernetes,在这个前提下,Kubernetes可以保证你的程序一直处于你要求的最终状态。
你可以使用Helm来管理你APP的Kubernetes版本,直接使用“helm install”将你的APP部署到Kubernetes上,这样可以保证你的APP时刻处于可用状态。
最小资源原则(Ask for the least)
类似于最小权限原则,你应该告诉Kubernetes你的APP能跑起来所需要的最小资源,剩下的富余资源交给Kubernetes来管理调度。
下面是一些你需要遵循最小资源原则的Kubernetes资源:
- RBAC权限
- 单一Pod里的容器数量
- 共享的CPU资源和内存资源
- 磁盘空间
站在巨人的肩上(Build on the shoulders of giants)
Kubernetes API帮你封装了一些很有用但是非常难实现的功能。这些功能是由一群非常聪明的人实现的,并且经过了充分的测试。尽量优先使用Kubernetes自带的这些特性,而不是试着自己在应用里去实现。
你或者可以看一下cloud native的生态系统。Cloud native上有很多高质量的框架可以在你的系统里使用。
最后,如果你在开源社区找不到符合你需求的产品,那么你可以自己构建一个,但是记得把它开源哦。
我们作为开源社区的一员,一直是本着不要重复自己(don't repeat yourself)的原则做事的。