Pod 控制器与配置资源管理
前言
Pod 控制器(Workloads)概述
Deployment(无状态)——示例与实验
核心特性
实验:创建一个 nginx Deployment
StatefulSet
为什么用 StatefulSet?
三个核心组件
实验:StatefulSet + Headless Service + NFS
定义 Headless Service(stateful-headless.yaml)
定义 StatefulSet(stateful-demo.yaml)
Pod 名称解析验证
StatefulSet 滚动更新行为
DaemonSet(守护进程)——示例与说明
功能
示例:ds.yaml
Job 与 CronJob(一次性与周期性任务)
Job(一次性任务)
实验 1:计算 π(job.yaml)
实验 2:失败重试示例(job-limit.yaml)
CronJob(周期性任务)
示例(每分钟打印 hello)
配置资源管理:Secret 与 ConfigMap
Secret(秘钥管理)
创建方法 A:从文件创建
创建方法 B:YAML(Base64 编码)
使用 Secret:挂载为文件
使用 Secret:作为环境变量
ConfigMap(非敏感配置)
创建:从目录 / 文件 / 字面值
在 Pod 中使用(3 种方式)
ConfigMap 热更新(挂载为 Volume)
无状态 vs 有状态:快速对比
总结
Pod 控制器分类与作用
配置资源管理对比
实践与实验重点
运维建议
前言
Kubernetes 把“期望状态”与“实际状态”分离开来,Pod 控制器(Workload controllers)负责把集群中的 Pod 保持在用户定义的期望状态。本文围绕常见几类控制器 —— Deployment
、StatefulSet
、DaemonSet
、Job
、CronJob
—— 展示原理、配置与完整实验步骤;并详细介绍配置资源 Secret
与 ConfigMap
的创建、使用方式、以及在 Pod 中的验证方法。
Pod 控制器(Workloads)概述
功能:
-
保证副本数、自动重建失败 Pod、支持扩缩容、滚动更新与回滚等。
-
常见类型:
ReplicaSet
、Deployment
、StatefulSet
、DaemonSet
、Job
、CronJob
。 (适用场景见下文各节详细说明。)
Deployment(无状态)——示例与实验
核心特性
-
适合无状态应用(Web 服务等)
-
支持声明式更新、滚动升级、回滚
-
由
ReplicaSet
管理具体 Pod 副本
实验:创建一个 nginx Deployment
文件:nginx-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploymentlabels:app: nginx spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.15.4ports:- containerPort: 80
命令:
kubectl apply -f nginx-deployment.yaml kubectl get pods,deploy,rs
查看与编辑:
kubectl edit deployment/nginx-deployment kubectl rollout history deployment nginx-deployment
关键字段说明(常查):
-
.spec.replicas
:期望副本数(默认 1) -
.spec.strategy.rollingUpdate.maxSurge
/maxUnavailable
:滚动更新策略 -
.spec.template.metadata.labels
:Pod 模板的标签,用于 ReplicaSet 匹配
实验验证要点:
-
部署后用
kubectl get pods
查看 3 个 Pod 是否就绪。 -
修改镜像版本并观察滚动更新(
kubectl set image
或kubectl edit
),用kubectl get pods -w
观察 Pod 替换过程。
StatefulSet
为什么用 StatefulSet?
-
每个 Pod 需要稳定标识(固定 DNS 名称)与独立持久化存储(每个 Pod 自己的 PVC)。
-
有序创建/删除(0 → N-1 创建,N-1 → 0 删除)。
三个核心组件
-
Headless Service(
clusterIP: None
) — 为 Pod 提供稳定 DNS 名称解析 -
volumeClaimTemplates — 为每个 Pod 自动创建 PVC,从而绑定独立 PV
-
StatefulSet 本体
实验:StatefulSet + Headless Service + NFS
定义 Headless Service(stateful-headless.yaml
)
apiVersion: v1 kind: Service metadata:name: myapp-svc spec:ports:- port: 80name: webclusterIP: Noneselector:app: myapp-pod kubectl apply -f stateful-headless.yaml
定义 StatefulSet(stateful-demo.yaml
)
apiVersion: apps/v1 kind: StatefulSet metadata:name: myapp spec:serviceName: myapp-svcreplicas: 3selector:matchLabels:app: myapp-podtemplate:metadata:labels:app: myapp-podspec:containers:- name: myappimage: ikubernetes/myapp:v1ports:- containerPort: 80name: webvolumeMounts:- name: myappdatamountPath: /usr/share/nginx/htmlvolumeClaimTemplates:- metadata:name: myappdata#动态PV创建时,使用annotations在PVC里声明一个StorageClass对象的标识进行关联annotations:volume.beta.kubernetes.io/storage-class: nfs-client-storageclassspec:accessModes: ["ReadWriteOnce"]resources:requests:storage: 2Gi
创建与验证:
kubectl apply -f stateful-demo.yaml kubectl get sts,pvc,pv,pods
你会看到 myapp-0
、myapp-1
、myapp-2
,每个都有对应的 PVC(例如 myapp-myappdata-myapp-0
)并绑定 PV。
Pod 名称解析验证
kubectl exec -it myapp-0 -- nslookup myapp-1.myapp-svc.default.svc.cluster.local # 在 Pod 中可以解析到对应 IP
DNS 格式:(pod_name).(service_name).(namespace).svc.cluster.local
。
StatefulSet 滚动更新行为
-
StatefulSet 以序号从高到低更新(例如 2 → 1 → 0),且在更新前会等待当前 Pod 就绪,确保有序安全的升级。
-
修改镜像:
kubectl edit sts myapp
,观察kubectl get pods -w
的按序更新。
DaemonSet(守护进程)——示例与说明
功能
确保每个 Node 上运行指定 Pod,典型用于日志、监控 agent 或存储守护进程。
示例:ds.yaml
apiVersion: apps/v1 kind: DaemonSet metadata:name: nginx-daemonSetlabels:app: nginx spec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.15.4ports:- containerPort: 80
验证:
kubectl apply -f ds.yaml kubectl get daemonset,pods -o wide
输出会显示每个 Node(可调度)上都有一个 nginx-daemonSet
的 Pod(除非 Node 有污点或调度约束)。
Job 与 CronJob(一次性与周期性任务)
Job(一次性任务)
用途: 数据迁移、批处理等,一次运行完成后退出。
实验 1:计算 π(job.yaml
)
apiVersion: batch/v1 kind: Job metadata:name: pi spec:template:spec:containers:- name: piimage: perlcommand: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]restartPolicy: NeverbackoffLimit: 4
命令:
kubectl apply -f job.yaml kubectl get pods kubectl logs <pi-pod-name> # 清理 kubectl delete -f job.yaml
实验 2:失败重试示例(job-limit.yaml
)
apiVersion: batch/v1 kind: Job metadata:name: busybox spec:template:spec:containers:- name: busyboximage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 10;date;exit 1"]restartPolicy: NeverbackoffLimit: 2
效果: Pod 会失败并重试,达到 backoffLimit
后 Job 标记为失败;用 kubectl describe job busybox
查看 BackoffLimitExceeded
。
CronJob(周期性任务)
用途: 定期备份、日志清理等。
示例(每分钟打印 hello)
apiVersion: batch/v1beta1 kind: CronJob metadata:name: hello spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboxargs:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterrestartPolicy: OnFailure
验证:
kubectl create -f cronjob.yaml kubectl get cronjob kubectl get pods --watch kubectl logs <hello-pod>
注意点:
-
concurrencyPolicy
、startingDeadlineSeconds
、successfulJobsHistoryLimit
等参数可以控制并发、准时性与历史保留。 -
常见权限错误例如
Forbidden
(匿名用户查看 nodes)可通过创建适当的ClusterRoleBinding
(谨慎授予权限)解决。
配置资源管理:Secret 与 ConfigMap
Secret(秘钥管理)
用途: 存储密码、Token、证书等敏感信息(建议配合 RBAC 使用)。
创建方法 A:从文件创建
echo -n 'zhangsan' > username.txt echo -n 'abc1234' > password.txt kubectl create secret generic mysecret --from-file=username.txt --from-file=password.txt kubectl get secrets kubectl describe secret mysecret
创建方法 B:YAML(Base64 编码)
echo -n zhangsan | base64 # emhhbmdzYW4= echo -n abc1234 | base64 # YWJjMTIzNA== # secret.yaml apiVersion: v1 kind: Secret metadata:name: mysecret1 type: Opaque data:username: 'emhhbmdzYW4='password: 'YWJjMTIzNA==' kubectl apply -f secret.yaml kubectl get secret mysecret1 -o yaml
使用 Secret:挂载为文件
apiVersion: v1 kind: Pod metadata:name: mypod spec:containers:- name: nginximage: nginxvolumeMounts:- name: secretsmountPath: "/etc/secrets"readOnly: truevolumes:- name: secretssecret:secretName: mysecret
验证:kubectl exec -it mypod -- ls /etc/secrets
使用 Secret:作为环境变量
env:- name: TEST_USERvalueFrom:secretKeyRef:name: mysecret1key: username
验证:kubectl exec -it mypod1 -- printenv | grep TEST
注意:
kubectl describe secret
不会直接显示明文(出于安全)。
ConfigMap(非敏感配置)
用途: 存放普通配置,如配置文件、命令参数或环境变量。
创建:从目录 / 文件 / 字面值
# 从目录(会把目录下每个文件作为键) kubectl create configmap game-config --from-file=/opt/configmap/ # 从字面值 kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=good
在 Pod 中使用(3 种方式)
作为环境变量注入
vim env.yaml apiVersion: v1 kind: ConfigMap metadata:name: special-confignamespace: default data:special.how: veryspecial.type: good --- apiVersion: v1 kind: ConfigMap metadata:name: env-confignamespace: default data:log_level: INFO kubectl create -f env.yaml -------------------------------------------------------------- //Pod的创建 vim test-pod.yaml apiVersion: v1 kind: Pod metadata:name: test-pod spec:containers:- name: busyboximage: busybox:1.28.4command: ["/bin/sh", "-c", "env"]env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Never
作为命令行参数
vim test-pod2.yaml apiVersion: v1 kind: Pod metadata:name: test-pod2 spec:containers:- name: busyboximage: busybox:1.28.4command: - /bin/sh- -c- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Never kubectl create -f test-pod2.yaml
以 Volume 挂载(文件形式)
在数据卷里面使用 ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容 vim test-pod3.yaml apiVersion: v1 kind: Pod metadata:name: test-pod3 spec:containers:- name: busyboximage: busybox:1.28.4command: [ "/bin/sh", "-c", "sleep 36000" ]volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: special-configrestartPolicy: Neverkubectl create -f test-pod3.yaml
验证:kubectl exec -it test-pod3 -- ls /etc/config
ConfigMap 热更新(挂载为 Volume)
-
修改 ConfigMap(
kubectl edit configmap log-config
)后,挂载的 Volume 通常在约 10 秒 内同步更新(实际环境可能略有差异)。 -
环境变量不会自动更新(因为 env 是在 Pod 启动时注入的)。
触发滚动更新的方法(当你需要让 Pod 重新读取 env / 配置时)
kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20210525" }}}}}'
上述做法通过更改 Pod 模板 annotation 强制触发 Deployment 的滚动更新,从而重启 Pod,使新的 env/config 被读取。
无状态 vs 有状态:快速对比
对比项 | 无状态(Deployment) | 有状态(StatefulSet) |
---|---|---|
Pod 名称 | 随机 | 固定、有序(0→N-1) |
存储 | 共享或无持久卷 | 每个 Pod 独立 PVC |
网络标识 | 不固定 | 稳定 DNS 名称 |
扩缩容顺序 | 无序 | 有序(创建/删除顺序) |
适合场景 | Web/API | 数据库、Etcd、ZK |
总结
Pod 控制器分类与作用
控制器 | 特点 | 典型场景 |
---|---|---|
Deployment | 无状态、可滚动更新、自动回滚 | Web 服务、API 应用 |
StatefulSet | 有状态、稳定网络标识与独立存储、顺序创建 | 数据库、缓存、Zookeeper |
DaemonSet | 每个节点一个 Pod,自动随节点增删 | 日志收集、监控 agent |
Job | 一次性任务、失败可重试 | 数据初始化、批处理 |
CronJob | 定时任务 | 备份、日志清理、周期性计算 |
配置资源管理对比
类型 | 主要用途 | 特点 |
---|---|---|
ConfigMap | 存放普通配置(非敏感) | 可热更新(挂载卷方式) |
Secret | 存放敏感信息(密码、证书) | Base64 编码,访问受控 |
挂载方式:
-
环境变量(启动时加载,无法热更新)
-
Volume(文件形式,10 秒左右可自动同步更新)
触发应用重新加载配置的两种方式:
-
对挂载卷的 ConfigMap,Kubernetes 自动检测变更;
-
对环境变量,可通过修改 Deployment 的 annotation 强制滚动更新:
kubectl patch deployment my-nginx --patch '{"spec":{"template":{"metadata":{"annotations":{"version/config":"20210525"}}}}}'
实践与实验重点
-
Deployment 实验:验证副本控制、滚动更新、历史回滚。
-
StatefulSet 实验:结合 Headless Service 与 NFS,验证固定 Pod 名称和独立 PVC。
-
DaemonSet 实验:确认每个 Node 均自动运行 Pod。
-
Job/CronJob 实验:掌握一次性与定时任务的行为与失败重试逻辑。
-
Secret/ConfigMap 实验:通过文件、环境变量挂载验证使用效果与安全特性。
运维建议
-
无状态应用 → Deployment
-
有状态服务 → StatefulSet + Headless Service + PVC
-
节点级任务 → DaemonSet
-
定期任务 → CronJob
-
配置与敏感信息 → ConfigMap + Secret
-
应用配置变化后 → 使用 滚动更新机制 替代手动重启