Kubernetes Kubernetes

编写你的第一个 Kubernetes 清单

YAML 要点、每个对象都有的四个字段,以及用 Pod 完成创建、检查、删除的循环。

12 min 初级

你在 Kubernetes 中创建的一切都是在清单(manifest)中描述的对象,即一个说明你想要什么的 YAML 文件。本指南涵盖刚好足够读懂清单的 YAML,解释每个清单都共有的结构,并演示如何从文件运行一个 Pod。它假设你有一个可用的集群(参见上一篇指南)。

五分钟学会 YAML

YAML 有两个你需要认识的构件。

**映射(map)**是一组 key: value 键值对。缩进表示嵌套,缩进在某个键之下的一切都属于它。**列表(list)**是一系列条目,每个以短横线开头:

app:
  name: shop
  enabled: true
  labels:
    tier: frontend
  ports:
    - 80
    - 443

这里 app 是一个带有键 name、enabled、labels 和 ports 的映射。labels 本身是一个映射,ports 是包含两个数字的列表。使用空格,永远不要用制表符。缩进错误是清单无法应用的最常见原因,并且它会悄悄地改变什么属于什么。如果用一行只含 --- 的行分隔,几个对象可以共享一个文件。

清单的剖析

每个 Kubernetes 对象都有相同的顶层字段:

  • apiVersion 说明由哪个版本的 API 定义这种对象。
  • kind 是对象的类型,如 Pod 或 Deployment。它区分大小写。
  • metadata 标识该对象:它的 name,可选的 namespace,以及任何 labels 和 annotations。
  • spec 是期望状态,其内容取决于 kind。

Kubernetes 会添加第四个部分 status,描述实际状态。你不需要编写它。下面是一个最小的 Pod:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.25
      ports:
        - containerPort: 80

containers 是一个列表,所以一个 Pod 可以运行多个容器,每个都以自己的短横线开头。image 字段是需要再次检查的那个。拼写错误意味着 Kubernetes 无法拉取它,Pod 会停留在错误状态。

不要从零开始写清单

从 Kubernetes 文档复制一个可用的示例,或者让 kubectl 生成一个:

kubectl run web --image=nginx:1.25 --port=80 --dry-run=client -o yaml > pod.yaml

--dry-run=client 在本地构建对象而不创建它,-o yaml 将其以 YAML 打印出来。这给你一个有效的起点供编辑。

把 apiVersion 写对

不同的 kind 位于不同的 API 组和版本中。Pod 是 v1,Deployment 是 apps/v1,Ingress 是 networking.k8s.io/v1。如果你选错了,或使用了较新集群已移除的版本,你会得到诸如 no matches for kind "X" in version "Y" 的错误。要找到正确的值:

kubectl api-resources | grep -i deployment
kubectl explain deployment | head

第一个显示每个 kind 所属的组,第二个显示它的 VERSION。这在你升级集群时最为重要,因为当某个版本被移除时,旧清单可能会停止工作。Kubernetes 的弃用指南列出了每个发布版本中有哪些变化。

创建、检查与删除

kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod web
kubectl delete -f pod.yaml

在 kubectl get pods 中,READY 列显示 Pod 的多少个容器已就绪(1/1 表示健康),STATUS 显示它的阶段,RESTARTS 统计容器重启次数。一个不断增长的数字意味着有东西不断杀死容器。describe 打印 Pod 的完整详情,底部是最近的事件,出问题时这是首先要看的地方。

apply 是声明式的:如果对象不存在就创建它,如果存在就更新它,所以你可以编辑文件再次应用。kubectl create -f 在对象已存在时会失败。

命令式与声明式

像 kubectl run 和 kubectl create 这样的命令是命令式的:你告诉 Kubernetes 现在去做某件事。它们对实验和认证考试来说很快。用 kubectl apply -f 应用的清单是声明式的,对于任何真实的场景,这才是你想要的,因为文件可以放在 Git 中、被审查,并被重新应用。本系列中的 Argo CD 指南展示了如何把这一思想推向它的结论。

热门指南