亲手把集群打开看看
目标
连接真实的 Kubernetes 集群,亲自查询命名空间、节点和 API 资源,使用标签选择器和 -o jsonpath 只提取所需值,再以命令式和声明式两种方式创建同一个 Deployment,直观比较差异。
为什么重要
Kubernetes 用户大致分为两类:每次搜索文档网站的人,以及直接询问集群的人。kubectl api-resources 和 kubectl explain 会告诉你当前集群真正了解的内容,因此比文档更准确,也会列出由 CRD 扩展的资源。
标签选择器同样重要。Kubernetes 对象之间几乎没有直接引用。Service 查找 Pod、ReplicaSet 统计自己的 Pod,全部依赖标签选择器。这种松耦合让 Pod 可以自由替换,但代价是:选择器拼写错误不会报错,只会悄无声息地找不到任何对象。
最后是声明式操作。kubectl run 很方便,却不会留下创建内容的记录。把清单保存在文件中并执行 apply,该文件就成为集群的事实来源,从而可以评审、版本管理和回滚。GitOps 只是把这一习惯扩展到组织规模。
步骤
- 创建命名空间
kcna-arch,并添加标签tier=lab。 - 将集群中所有节点名称逐行保存到
/root/kcna-arch/nodes.txt。只保存名称,不要包含node/等前缀。 - 查看
kubectl api-resources,将deployments的 APIVERSION 值保存为/root/kcna-arch/deploy-apiversion.txt,将services的缩写(SHORTNAMES)保存为/root/kcna-arch/svc-short.txt,各占一行。 - 使用
kubectl explain找到无需调度器、直接把 Pod 放到指定节点的spec字段,再用该字段在命名空间kcna-arch中创建镜像为nginx:1.27-alpine的 Podpinned。节点名称必须来自第 2 步的列表。 - 在
/root/kcna-arch/components.txt中原样填写以下四行:在serve-rest-api=、store-cluster-state=、watch-and-place-pods=、reconcile-desired-state=后分别填写正确组件名(kube-apiserver、etcd、kube-scheduler、kube-controller-manager)。然后使用kubectl get --raw调用 API 服务器的/healthz,将响应保存到/root/kcna-arch/healthz.txt。 - 在命名空间
kcna-arch中创建三个 Pod:web-1(app=web,tier=front)、web-2(app=web,tier=back)、db-1(app=db,tier=back)。随后使用选择器app=web,tier=back,将选中的 Pod 名称逐行保存到/root/kcna-arch/selected.txt。 - 为
kubectl create deployment添加--dry-run=client -o yaml,生成名称为kcna-web、镜像为nginx:1.27-alpine、replicas 为 2 的 Deployment 清单,保存到/root/kcna-arch/kcna-web.yaml,再将该文件以声明式方式应用到命名空间kcna-arch。
参考
- 如
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'所示,用range循环即可逐行提取。 kubectl explain pod.spec --recursive会显示完整字段树。不知道名称时配合grep使用会很快。- 常见错误 1:第 3 步填写
deployments.apps之类的资源名称。需要的是 APIVERSION 列的值。 - 常见错误 2:第 7 步直接用
kubectl create deployment在集群中创建对象。这样即使存在清单文件,对象也没有声明式应用的痕迹,无法通过评分。
创建工作命名空间
创建命名空间 kcna-arch,并添加标签 tier=lab。
命名空间是集群内的名称空间。可以在创建时添加标签,也可创建后用 kubectl label 添加。标签键为 tier,值为 lab。
将节点列表导出到文件
将集群中所有节点名称逐行保存到 /root/kcna-arch/nodes.txt。只保存名称,不要包含 node/ 等前缀。
kubectl get nodes 的默认输出混有表头和多列。这里只需逐行保存名称,因此最好用 -o 改变输出格式。也请注意,使用 -o name 会带上 node/ 前缀。
用 api-resources 查找 API 组和缩写
查看 kubectl api-resources,将 deployments 的 APIVERSION 值保存为 /root/kcna-arch/deploy-apiversion.txt,将 services 的缩写(SHORTNAMES)保存为 /root/kcna-arch/svc-short.txt,各占一行。
kubectl api-resources 以 NAME/SHORTNAMES/APIVERSION/NAMESPACED/KIND 列显示集群认识的全部资源,可用 grep 缩小范围。APIVERSION 采用“组/版本”形式;核心组的组名为空。
用 explain 查字段并将 Pod 固定到节点
使用 kubectl explain 找到无需调度器、直接把 Pod 放到指定节点的 spec 字段,再用该字段在命名空间 kcna-arch 中创建镜像为 nginx:1.27-alpine 的 Pod pinned。节点名称必须来自第 2 步的列表。
运行 kubectl explain pod.spec 可看到 spec 下的字段说明,其中有绕过调度器直接放到指定节点的字段。节点名称任选第 2 步列表中的一个。
整理组件职责并获取 API 服务器状态
在 /root/kcna-arch/components.txt 中原样填写以下四行:在 serve-rest-api=、store-cluster-state=、watch-and-place-pods=、reconcile-desired-state= 后分别填写正确组件名(kube-apiserver、etcd、kube-scheduler、kube-controller-manager)。然后使用 kubectl get --raw 调用 API 服务器的 /healthz,将响应保存到 /root/kcna-arch/healthz.txt。
将阅读材料中的四个组件职责逐行写成 key=value。kubectl 可用 --raw 选项直接调用 API 服务器的任意路径。健康端点的响应非常短。
添加标签并用选择器筛选
在命名空间 kcna-arch 中创建三个 Pod:web-1(app=web,tier=front)、web-2(app=web,tier=back)、db-1(app=db,tier=back)。随后使用选择器 app=web,tier=back,将选中的 Pod 名称逐行保存到 /root/kcna-arch/selected.txt。
给三个 Pod 添加不同标签组合。在 kubectl get 的 -l 选项中用逗号连接条件时,它们按 AND 工作。保存结果时请指定只输出名称的格式。
将命令式生成的 YAML 声明式应用
为 kubectl create deployment 添加 --dry-run=client -o yaml,生成名称为 kcna-web、镜像为 nginx:1.27-alpine、replicas 为 2 的 Deployment 清单,保存到 /root/kcna-arch/kcna-web.yaml,再将该文件以声明式方式应用到命名空间 kcna-arch。
给 kubectl create 添加 --dry-run=client -o yaml,可在不修改集群的情况下只生成清单。用 apply 应用该文件后,对象会出现直接用 create 创建时没有的注解,评分以此区分两种方式。