Kubernetes Manifests 资源清单核心概念
·
Kubernetes Manifests 资源清单核心概念
一、什么是 Kubernetes Manifests ?
Manifests 就是用 YAML(或 JSON)文件描述“你希望 Kubernetes 集群长什么样子”的一份声明性配置。
Kubernetes 是声明式系统(Declarative),你只需要告诉它“我想要什么”,不需要告诉它“怎么一步步去做”。 只要写好 Manifests 通过 kubectl apply -f xxx.yaml 应用到 Kubernetes 会自动把集群变成你描述的样子。
对比命令式(Imperative):
- 命令式:
kubectl run nginx --image=nginx:1.14 --port=80 --replicas=3(不推荐长期使用) - 声明式:写一个 YAML 文件,然后
kubectl apply -f nginx.yaml(生产)
二、为什么一定要用 Manifests?
| 优势 | 说明 |
|---|---|
| 声明式管理 | 只关心最终状态,不关心执行路径,出错自动修复(自愈) |
| 可版本化(GitOps 基础) | YAML 文件可以放进 Git,历史可追溯、代码审查、回滚一键完成 |
| 环境一致性 | 开发、测试、生产环境使用同一份文件(稍改参数即可),杜绝“在我机器上能跑”问题 |
| 自动化部署 | 配合 ArgoCD、Flux、Jenkins 等 CI/CD 工具实现自动化甚至零人工干预 |
| 团队协作 | 所有人修改的都是同一份配置文件,避免口口相传或脚本到处飞 |
三、一个最经典的 Manifests 示例
nginx-deployment.yaml
apiVersion: apps/v1 # 1. 必须字段:用哪个 API 版本
kind: Deployment # 2. 必须字段:资源类型,这里是 Deployment
metadata: # 3. 必须字段:资源的元数据
name: nginx-deployment # Deployment 的名字
labels: # (可选)给 Deployment 自己打标签
app: nginx
spec: # 4. 必须字段:期望的状态(Specification)
replicas: 2 # 我想要 2 个副本
selector: # 【关键!】Deployment 通过这个选择器找到它要管理的 Pod
matchLabels:
app: nginx # 必须和下面 template 中的 label 完全一致!
template: # Pod 模板:真正的 Pod 长什么样子
metadata:
labels: # 【关键!】这里必须和上面的 selector.matchLabels 保持一致
app: nginx
spec: # Pod 里面容器的详细定义
containers:
- name: nginx # 容器名字
image: nginx:1.14-alpine # 使用哪个镜像
ports:
- containerPort: 80 # 容器暴露的端口(只是声明,Service 才能真正对外访问)
resources: # (可选)资源限制
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "200m"
memory: "256Mi"
执行:
kubectl apply -f nginx-deployment.yaml
效果:
Kubernetes 会自动创建 1 个 Deployment + 1 个 ReplicaSet + 2 个 Pod
四、Manifests 必填的 4 个顶级字段
所有 Kubernetes 资源清单都必须包含这四个字段:
| 字段 | 含义 | |
|---|---|---|
| apiVersion | 使用哪个版本的 Kubernetes API | |
| kind | 创建什么资源(Pod、Deployment、Service…) | |
| metadata | 资源的元数据(名字、标签、注解等) | |
| spec | 你期望的详细状态 |
五、YAML 语法规范
# 1. Maps(字典/键值对) → 用冒号 :
name: zhangsan
age: 18
# 2. Lists(列表) → 用短横线 -
fruits:
- apple
- banana
- orange
# 3. 嵌套(最常见)
spec:
containers:
- name: nginx
image: nginx:1.14
ports:
- containerPort: 80
注意事项:
- 缩进只能用空格,绝对不能用 Tab(很多编辑器会偷偷帮你转 Tab)
- 冒号后面必须加一个空格(如
image: nginximage:nginx错误写法 ) - 大小写敏感:apiVersion ≠ apiversion
六、如何知道每个资源有哪些字段
使用explain命令查看层级字段
# 查看某种资源有哪些一级字段
kubectl explain deployment
# 继续深挖某个字段
kubectl explain deployment.spec
kubectl explain deployment.spec.template.spec
# 查看 Pod 所有字段(最全参考)
kubectl explain pod
# 甚至可以直接生成模板
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > nginx.yaml
七、写 Manifests 的正确姿势
- 先想清楚要创建什么资源(Pod?Deployment?Service?Ingress?)
- 用
kubectl explain资源名 查看字段 - 推荐做法:先用命令生成模板,再修改如:
kubectl create deployment myapp --image=nginx --dry-run=client -o yaml > myapp.yaml`
改完后再用kubectl apply -f myapp.yaml部署
4.放入 Git仓库,拥抱 GitOps 时代
这样写出来的 Manifests 既规范又不容易出错,团队协作也完全没问题。
八、完整资源清单参考
下面是一份完整、规范、最新(Kubernetes 1.30+ 适用)且经过实际生产验证的 Pod 资源清单参考模板,包含所有常用字段、正确层级、官方推荐写法仅供参考。
apiVersion: v1 # 必填:Pod 属于 core/v1 组,几乎永远是 v1
kind: Pod # 必填:资源类型为 Pod
metadata: # 必填:元数据
name: nginx-pod # 必填:Pod 名字,全集群 + namespace 唯一
namespace: default # 可选:命名空间,默认 default
labels: # 推荐:标签,用于 Service、Deployment 选择
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx-01
env: production
annotations: # 可选:注解,常用于工具标记、配置下发等
prometheus.io/scrape: "true"
prometheus.io/port: "80"
k8s.aliyun.com/ingress: "true"
spec: # 必填:Pod 的详细规格(期望状态)
restartPolicy: Always # 可选:重启策略,Pod 直接使用时推荐 Always(默认)
# Always(默认) / OnFailure / Never
terminationGracePeriodSeconds: 30 # 可选:优雅终止等待时间,默认 30s
dnsPolicy: ClusterFirst # 可选:DNS 策略,常用 ClusterFirst | Default | None
nodeSelector: # 可选:节点选择器
kubernetes.io/hostname: node-01
nodeName: node-02 # 可选:直接调度到指定节点(强绑定,慎用)
hostNetwork: false # 可选:是否使用宿主机网络(常用于 DaemonSet)
hostPID: false # 可选:是否共享宿主机 PID 命名空间
hostIPC: false # 可选:是否共享宿主机 IPC 命名空间
hostname: my-nginx # 可选:设置 Pod 内的 hostname
subdomain: nginx-service # 可选:配合 headless Service 设置子域名
serviceAccountName: nginx-sa # 可选:使用的 ServiceAccount(RBAC 权限相关)
automountServiceAccountToken: true # 是否自动挂载 SA token
imagePullSecrets: # 可选:拉取私有镜像仓库需要的 secret
- name: docker-registry-secret
tolerations: # 可选:容忍污点,让 Pod 可以调度到有污点的节点
- key: "node-type"
operator: "Equal"
value: "special"
effect: "NoSchedule"
containers: # 必填:容器列表(至少一个)
- name: nginx # 必填:容器名称(同一个 Pod 内唯一)
image: nginx:1.25-alpine # 必填:镜像地址(建议带具体 tag)
imagePullPolicy: IfNotPresent # 可选:拉取策略
# Always(每次都拉) / IfNotPresent(默认,本地有就不拉) / Never(只用本地)
command: # 可选:覆盖镜像 Entrypoint
- nginx
- -g
- daemon off;
args: [] # 可选:覆盖镜像 CMD(command 和 args 不能同时有内容时都用 args)
workingDir: /usr/share/nginx/html # 可选:容器工作目录
ports: # 可选:仅声明,不真正暴露(Service 负责暴露)
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
env: # 可选:环境变量(明文)
- name: ENV
value: "production"
- name: NGINX_PORT
value: "80"
envFrom: # 可选:从 ConfigMap 或 Secret 批量导入环境变量
- configMapRef:
name: nginx-config
- secretRef:
name: nginx-secret
resources: # 强烈推荐:资源请求与限制
requests: # 调度时最低保证
cpu: "100m" # 0.1 核
memory: "128Mi"
limits: # 硬限制,超过会被 OOM 或 CPU 节流
cpu: "500m"
memory: "512Mi"
volumeMounts: # 可选:挂载卷到容器内
- name: web-root
mountPath: /usr/share/nginx/html
readOnly: false
- name: config-volume
mountPath: /etc/nginx/conf.d
- name: secret-volume
mountPath: /etc/ssl/certs
readOnly: true
livenessProbe: # 存活探针(不健康 → 重启容器)
httpGet:
path: /healthz
port: 80
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe: # 就绪探针(不就绪 → 从 Service 剔除流量)
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe: # 启动探针(慢启动应用专用,避免被 liveness 误杀)
httpGet:
path: /startup
port: 80
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 30 # 允许 5 分钟启动时间
timeoutSeconds: 5
lifecycle: # 生命周期钩子
postStart:
exec:
command: ["/bin/sh", "-c", "echo Pod started >> /var/log/start.log"]
preStop:
exec:
command: ["/bin/sh", "-c", "nginx -s quit; sleep 10"]
securityContext: # 容器级安全上下文
privileged: false
runAsUser: 1001 # 推荐非 root 用户运行
runAsGroup: 1001
fsGroup: 1001
capabilities:
drop:
- ALL
# add: ["NET_ADMIN"] # 如需特殊权限再加
initContainers: # 可选:Init 容器(先于业务容器运行,常用于初始化)
- name: init-config
image: busybox:1.36
command: ['sh', '-c', 'wget -O /data/config.yaml http://config-server/config.yaml']
volumeMounts:
- name: web-root
mountPath: /data
volumes: # 可选:在 Pod 级别定义共享卷
- name: web-root
emptyDir: {} # 临时目录,Pod 删就没了
- name: config-volume
configMap:
name: nginx-conf
items:
- key: nginx.conf
path: nginx.conf
- name: secret-volume
secret:
secretName: nginx-tls
items:
- key: tls.crt
path: nginx.crt
- key: tls.key
path: nginx.key
- name: persistent-data
persistentVolumeClaim:
claimName: nginx-pvc
# 以下为较少用但偶尔需要的字段
# affinity: ... # 亲和性与反亲和性调度
# topologySpreadConstraints: ... # 拓扑分布约束(1.21+)
# priorityClassName: high-priority
# schedulerName: my-scheduler
# shareProcessNamespace: true # 容器间共享 PID namespace(如调试)
原文链接:https://www.rzzz.net/cloudnative/k8s/7-k8s-Manifests.html
更多推荐
所有评论(0)