GCE 的 Kubernetes 最佳实践系列
Table of Contents
1. 使用命令空间进行组织
命名空间可以理解成 Kubernetes 集群中的虚拟集群,一个 Kubernetes 集群中可以包含多个命名空间,逻辑上相互隔离;
一般情况下,Kubernetes 默认会创建三个空间:
default
kube-system
用于 Kubernetes 组件kube-public
用户公共资源
kube-public
通常不怎么使用, kube-system
相对独立,所以你的 services 和 apps 通常会被创建在 default
空间中。
default
空间没有什么特别的,除了默认会创建还有你不能通过 kubectl 删掉他。适合很小的集群,但是不建议在生产环境中这么用
(同一个空间中的应用名是不可重复的,所以很容易被别人覆盖掉)。
1.1. 服务发现
Kubernetes 中 Services 使用以下的通用 DNS 模式来暴露他们的端点(endpoints)。类似这样:
<Service Name>.<Namespace Name>.svc.cluster.local
通常只需要指定 Service 名字,DNS 会自动解析全路径。跨空间的情况下需要携带空间名字,比如: database.test
database.production
。
警告: 如果你创建一个 com
或者 org
这样的顶级域名,然后创建和网站同名的服务,比如 "google" 或者 "reddit" 。这会导致你的服务请求 "google.com"
会映射到 Service 上。这通常对于测试和代理非常有用,但也很容易破坏集群中的东西。
*注意:*如果你想隔离命名空间,你应该使用 网络策略 来实现他。
1.2. 空间的粒度
视公司的阶段和规模而定。大公司下业务比较复杂(技术栈丰富),团队较多,需要配合 CI/CD 工具来使用,使用 RBAC 和资源配合是个好主意。
3. 资源的 requests 和 limits
requests 和 limits 是 Kubernetes 控制 CPU 和内存资源的机制。Requests 的值是 Kubernetes 一定给服务分配到的,分配不到就会提示 资源不足;Limits 是服务可用的最大资源限制。所以 Limits 的值不能小于 Requests(否则会抛错,容器也运行不起来)。
- CPU 到达 Limits 之后,程序的性能会受影响,但是不会被终止(因为 CPU 是可压缩的资源);
- 内存到达 Limits 之后,程序会被终止(OOM,因为内存是不可压缩的资源);
命名空间级别也可以配置资源限制:通过 ResourceQuotas 和 LimitRanges。
4. 优雅终止
- Pod 被设置为 "Terminating" 时,会从 Service 中的 endpoints 列表中移出;
- 执行 preStop Hook,preStop Hook 可以帮助你做应用程序的优雅关闭;
- SIGTERM 信号发送到 Pod(此时应用程序判断 TERM 信号,然后优雅退出);
- Kubernetes 等待宽限期(grace period):Kubernetes 会等待 preStop Hook 和 Pod 的结束(注意:preStop Hook 和 Pod 的终止是并行执行的),
- 如果程序在 terminationGracePeriod 之前执行完成,Kubernetes 会立即执行下一步。默认的宽限期是 30s;
- 一般情况下使用 preStop Hook 要手动设置 terminationGracePeriod 一起来操作,来增加宽限期;
- 向 Pod 发送 SIGKILL,移出 Pod。也就是说如果 terminationGracePeriod 内进程没有自动退出,会强制杀掉进程。
5. 外部服务映射
类似数据库这样的服务通常是运行在集群外部的,在集群内部通常会有这样一个需求:一个服务在不同的环境,有相同的配置,但是却要连到不同 的数据库上(测试用测试的,生产用生产的,但是他们连接配置的名字希望是一样的)。
这种需求下,你可以指定将 Service 的 type
指定为 ExternalName
来实现。具体见: