TT Lab
开始
学习 学习路径 课程

CKA — Kubernetes 管理员

Kustomize 覆盖层与资源指标流水线

在 TT Lab 中继续学习

一句话总结

Kustomize 是不修改原始 YAML、而是按环境叠加差异的工具;kubectl top 是读取值的命令,这些值由 metrics-server 从各节点的 kubelet 收集后,通过 Metrics API 提供。两者都要知道“这个结果是从哪里产生的”,这样无论在考场还是在现场,都不会卡住。

为什么需要它

把同一个应用部署到开发和生产环境时,复制 YAML 只改名称和副本数的副本会越来越多。副本超过三份,就没有人知道哪个是原件了,只改了一边的变更会悄悄地漏掉另一边。Helm 用模板语言来解决这个问题,但学习模板要付出成本。Kustomize 选择了不用模板、保留原件不动,在其上叠加补丁的方式。根据 用 Kustomize 声明式管理 Kubernetes 对象 文档,从 kubectl 1.14 开始,无需另行安装,就可以用 kubectl apply -k 使用它。

资源使用量方面的问题则不同。在新建的集群上输入 kubectl top nodes,得到的回答是“Metrics API not available”。因为 kubelet 只知道自己节点的使用量,而默认安装中没有把这些数据汇总到整个集群并通过 API 提供出来的组件。资源指标管道 文档明确指出“要访问 Metrics API,必须部署 metrics-server 或替代它的适配器”。所以 kubectl top 用不了,并不是命令坏了,而是管道缺了一环。

工作原理

Kustomize——base 与 overlay

base 是包含 kustomization.yaml 和资源文件的目录。overlay 是通过 resources 引用另一个 kustomization 目录的目录,并在所引用的资源之上叠加自己的变更。文档强调的性质只有一个——base 不知道 overlay 的存在。因此,一个 base 可以被多个 overlay 共同使用。

# base/kustomization.yaml
resources:
  - deployment.yaml
  - service.yaml

# overlays/dev/kustomization.yaml
resources:
  - ../../base
namePrefix: dev-
patches:
  - path: replicas.yaml

补丁写在 patches 字段中。根据文档,Kustomize 支持 StrategicMerge 和 Json6902 两种补丁方式,补丁可以是文件也可以是内联字符串,并按所写的顺序应用。补丁的目标通过 group、version、kind、name、namespace、labelSelector、annotationSelector 来选择。文档建议使用“只做一件事的小补丁”——也就是说,把提高副本数的补丁和设置内存限制的补丁分开放。StrategicMerge 补丁是叠写与原件形状相同的 YAML 片段,所以容易阅读;Json6902 补丁是指定路径后执行 add、replace、remove,用于列表中特定项目这类难以靠叠写来表达的地方。

除了补丁,还有一些常用的字段。images 无需补丁,只修改镜像名称、标签和摘要;namePrefix、nameSuffix 在所有资源名称的前后添加字符串;configMapGenerator、secretGenerator 则从文件或字面量生成 ConfigMap 和 Secret。由生成器创建的对象,名称后面会附加内容哈希。内容一变,名称就变,引用它的 Deployment 的 spec 也随之改变,所以滚动更新会自动发生。要关闭这一行为,使用 generatorOptions 的 disableNameSuffixHash。

应用之前想看结果,可以用 kubectl kustomize <디렉터리>(占位符为目录)输出渲染后的 YAML,确认无误后再用 kubectl apply -k <디렉터리>(占位符为目录)应用。kubectl diff -k 和 kubectl delete -k 也是同样的方式。-k 必须指向包含 kustomization.yaml 的目录,而不是文件。

资源使用量——指标经过的路径

资源指标管道 文档所描绘的流程如下。

步骤 组件 做什么
1 cAdvisor 包含在 kubelet 中的守护进程。收集、汇总并暴露容器指标
2 kubelet 通过 /metrics/resource 和 /stats 端点提供节点级别的摘要
3 metrics-server 从各个 kubelet 拉取指标并汇总的集群插件
4 Metrics API metrics.k8s.io 组。由 API 服务器作为扩展 API 提供服务
5 消费者 HPA、VPA,以及 kubectl top

metrics-server 是 Metrics API 的参考实现。要接入 API 服务器,必须启用 aggregation layer,并注册针对 metrics.k8s.io 的 APIService。metrics-server 仓库 还列出了更多要求——节点的 kubelet 要启用 Webhook 认证和授权;kubelet 证书要由集群 CA 签名(否则用 --kubelet-insecure-tls 关闭验证);控制平面要能访问 metrics-server Pod;metrics-server 要能访问所有节点的 kubelet 端口。采集周期是 15 秒,metrics-server v0.6.0 及以上版本读取 kubelet 的 /metrics/resource。

还要了解这些值的含义。CPU 是根据内核提供的累计计数器的变化率计算出的平均核心使用量,计算区间出现在 Metrics API 响应的 window 字段中。内存是采集时刻的 working set,即即使在内存压力下也无法释放的、正在使用的内存。所以 kubectl top pod 的内存值既不同于 RSS,也不同于包含全部缓存的值。

仓库文档里有一条提醒。metrics-server 仅用于自动伸缩,不要把它用作监控系统的数据来源。如果需要准确的使用量记录,文档建议让 Prometheus 这类监控工具直接抓取 kubelet 的 /metrics/resource。

在现场相遇的样子

应用了 overlay,却看不到对象。如果在 overlay 中设置了 namePrefix: dev-,生成的 Deployment 名称就不是 my-nginx,而是 dev-my-nginx。用 kubectl get deploy my-nginx 去找,会提示不存在。文档中的示例输出也是 deployment.apps/dev-my-nginx created。应用之前先用 kubectl kustomize 看一眼渲染结果,这个习惯可以消除这种混乱。

部署了 metrics-server,kubectl top 却一直失败。在用 kubeadm 创建的集群中经常见到。根据 kubeadm 证书管理 文档,kubeadm 部署的 kubelet serving 证书默认是自签名的,所以当 metrics-server 这类外部服务通过 TLS 连接 kubelet 时,验证会失败。在实验用集群中,可以用 --kubelet-insecure-tls 绕过;在生产集群中,应按同一文档中的“启用已签名的 kubelet serving 证书”流程,让它获得由集群 CA 签名的证书。

接下来的理论要看什么

下一篇阅读将讲解名称解析。Pod 调用 my-svc 时,哪台服务器按什么顺序回答,CoreDNS 的 Corefile 是什么结构,以及解析受阻时从哪里开始查看,我们将按照官方调试流程来学习。