【k8s应用管理】kubernetes Pod控制器
文章目录
- Kubernetes Pod 控制器
- 概述
- Deployment
- StatefulSet
- StatefulSet 核心特性
- StatefulSet 组成
- 创建 StatefulSet 的步骤
- 配置 NFS 存储(示例)
- 定义 PV 资源
- 创建 StatefulSet
- 应用配置
- 验证与操作
- 查看资源状态
- 测试 DNS 解析
- 滚动更新
- 扩展与缩容
- 与 Deployment 的对比
- 注意
- DaemonSet
- DaemonSet 核心特性
- DaemonSet 示例
- 创建 DaemonSet
- 应用配置
- 查看 Pod 状态
- DaemonSet 与 Deployment 的对比
- 高级配置
- 节点选择器(nodeSelector)
- 污点与容忍(Taints and Tolerations)
- 更新策略(updateStrategy)
- 常用操作
- 查看 DaemonSet 状态
- 删除 DaemonSet
- Job
- CronJob
- 总结
- 1. Deployment + ReplicaSet
- 2. StatefulSet(STS)
- 3. DaemonSet
- 4. Job
- 5. CronJob
- ConfigMap(CM)
Kubernetes Pod 控制器
Pod控制器,又称之为工作负载(workload),是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。
Pod与控制器之间的关系:
controllers:在集群上管理和运行容器的 pod 对象, 控制器 通过 label-selector 与 Pod 相关联。
Pod 通过控制器实现应用的运维,如伸缩,升级等。
概述
- 作用:用于管理 Pod 的中间层,确保 Pod 资源符合预期状态。当 Pod 出现故障时,控制器会尝试重启或重建 Pod。
- 常见类型:
- ReplicaSet:确保指定数量的 Pod 副本运行。
- Deployment:管理无状态应用,支持滚动更新和回滚。
- DaemonSet:确保每个节点运行一个 Pod 副本。
- StatefulSet:管理有状态应用,支持稳定的网络标识和持久化存储。
- Job:运行一次性任务。
- CronJob:运行周期性任务。
Deployment
- 功能:管理无状态应用,支持滚动更新、回滚和声明式配置。
- 应用场景:Web 服务等无状态应用。
- 示例:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.4 ports: - containerPort: 80
- 常用命令:
kubectl create -f nginx-deployment.yaml #创建部署 kubectl get pods,deploy,rs#获取Pods、部署和副本集信息 kubectl rollout history deployment/nginx-deployment#查看部署的滚动更新历史
kubectl edit deployment/nginx-deployment
apiVersion: apps/v1
kind: Deployment
metadata:
# 元数据,包括创建时间、标签、名称等
annotations:
deployment.kubernetes.io/revision: "1" # 部署的修订版本
creationTimestamp: "2021-04-19T08:13:50Z" # 创建时间
labels:
app: nginx # Deployment资源的标签,用于选择器和过滤
name: nginx-deployment # Deployment的名称
namespace: default # 所在的命名空间
...
spec:
# 规格说明,定义了Deployment的行为和配置
replicas: 3 # 期望的Pod副本数量
revisionHistoryLimit: 10 # 保留的旧修订版本数量
selector:
matchLabels:
app: nginx # 用于选择Pod的标签选择器
strategy:
# 滚动更新策略
rollingUpdate:
maxSurge: 25% # 滚动更新时,允许的最大额外Pod数量(相对于期望副本数)
maxUnavailable: 25% # 滚动更新时,允许的最大不可用Pod数量(相对于期望副本数)
type: RollingUpdate # 更新类型,这里是滚动更新
template:
# Pod模板,定义了Pod的规格
metadata:
labels:
app: nginx # Pod的标签
spec:
containers:
- image: nginx:1.15.4 # 容器使用的镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略,如果镜像已经存在则不拉取
name: nginx # 容器的名称
ports:
- containerPort: 80 # 容器暴露的端口
protocol: TCP # 端口协议
...
restartPolicy: Always # Pod的重启策略,总是重启
StatefulSet
StatefulSet 核心特性
-
稳定的持久化存储:
- 通过
volumeClaimTemplates
自动创建 PVC,确保 Pod 重新调度后仍能访问相同数据。 - 每个 Pod 拥有独立的存储卷,数据与 Pod 生命周期解耦。
- 通过
-
稳定的网络标识:
- 基于 Headless Service(无头服务)提供唯一且固定的 DNS 记录。
- Pod 名称格式:
<Pod名称>.<Headless Service名称>.<命名空间>.svc.cluster.local
。
-
有序部署与伸缩:
- 部署/扩容时按顺序创建(0 → N-1),缩容时按逆序删除(N-1 → 0)。
- 确保前一个 Pod 就绪后才操作下一个。
StatefulSet 组成
组件 | 作用 |
---|---|
Headless Service | 提供 Pod 的 DNS 解析,无 ClusterIP,直接暴露 Pod IP。 |
volumeClaimTemplates | 为每个 Pod 自动生成 PVC,绑定专用 PV,实现持久化存储。 |
StatefulSet | 管理 Pod 副本,确保网络标识和存储的稳定性。 |
创建 StatefulSet 的步骤
配置 NFS 存储(示例)
# 在 NFS 服务器创建共享目录
mkdir -p /data/volumes/v{1,2,3,4,5}
# 配置 NFS 共享
vim /etc/exports
/data/volumes/v1 192.168.80.0/24(rw,no_root_squash)
...
exportfs -arv
systemctl restart nfs
定义 PV 资源
# pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
spec:
nfs:
path: /data/volumes/v1
server: stor01
accessModes: ["ReadWriteMany", "ReadWriteOnce"]
capacity:
storage: 1Gi
---
# 定义其他 PV(pv002-pv005)...
创建 StatefulSet
# stateful-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
clusterIP: None # Headless Service
ports:
- port: 80
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp-svc
replicas: 3
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 2Gi
应用配置
kubectl apply -f pv-demo.yaml
kubectl apply -f stateful-demo.yaml
验证与操作
查看资源状态
kubectl get sts,pvc,pv,pods
输出示例:
NAME READY AGE
myapp 3/3 2m
NAME STATUS VOLUME CAPACITY
myappdata-myapp-0 Bound pv002 2Gi
myappdata-myapp-1 Bound pv003 2Gi
myappdata-myapp-2 Bound pv004 2Gi
NAME STATUS AGE
pv001 Available 5m
pv002 Bound 5m
...
NAME READY STATUS AGE
myapp-0 1/1 Running 2m
myapp-1 1/1 Running 2m
myapp-2 1/1 Running 2m
测试 DNS 解析
kubectl exec -it myapp-0 -- nslookup myapp-1.myapp-svc
# 输出示例:
# Name: myapp-1.myapp-svc.default.svc.cluster.local
# Address: 10.244.1.14
滚动更新
# 修改镜像版本后重新应用
kubectl apply -f stateful-demo.yaml
kubectl get pods -w # 观察更新顺序(倒序:2 → 1 → 0)
扩展与缩容
# 扩容到4个副本
kubectl scale sts myapp --replicas=4
# 缩容到2个副本
kubectl patch sts myapp -p '{"spec":{"replicas":2}}'
与 Deployment 的对比
特性 | Deployment | StatefulSet |
---|---|---|
适用场景 | 无状态应用(如 Web 服务) | 有状态应用(如数据库、中间件) |
网络标识 | 随机 Pod 名称,无固定 DNS | 固定 Pod 名称,稳定的 DNS 记录 |
存储 | 共享存储卷 | 每个 Pod 独立存储卷 |
扩缩容顺序 | 无序 | 有序(扩容 0→N-1,缩容 N-1→0) |
服务发现 | 通过 Service ClusterIP | 通过 Headless Service 直接解析 Pod IP |
注意
-
删除 StatefulSet:
- 需先缩容到 0 副本再删除,否则可能残留 Pod。
- PVC 默认保留,需手动清理。
-
存储回收策略:
- 静态 PV 默认策略为
Retain
,动态 PV 默认为Delete
。
- 静态 PV 默认策略为
-
滚动更新策略:
- 默认按倒序更新 Pod,可通过
updateStrategy
配置。
- 默认按倒序更新 Pod,可通过
- 功能:管理有状态应用,支持稳定的网络标识和持久化存储。
- 应用场景:数据库等有状态应用。
- 示例:
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: k8s.gcr.io/nginx-slim:0.8 ports: - containerPort: 80 volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "my-storage-class" resources: requests: storage: 1Gi
- 常用命令:
kubectl apply -f stateful-demo.yaml kubectl get sts,pvc,pv kubectl scale sts myapp --replicas=4
DaemonSet
DaemonSet 核心特性
-
功能:确保每个节点(或部分节点)运行一个 Pod 副本。
-
特点:
- 当新节点加入集群时,自动创建 Pod。
- 当节点从集群移除时,自动删除 Pod。
- 删除 DaemonSet 会删除其创建的所有 Pod。
-
适用场景:
- 集群存储守护进程(如
glusterd
、ceph
)。 - 日志收集守护进程(如
fluentd
、logstash
)。 - 监控守护进程(如
Prometheus Node Exporter
、Datadog 代理
)。
- 集群存储守护进程(如
DaemonSet 示例
创建 DaemonSet
# ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonSet
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
ports:
- containerPort: 80
应用配置
kubectl apply -f ds.yaml
查看 Pod 状态
kubectl get pods -o wide
输出示例:
NAME READY STATUS RESTARTS AGE IP NODE
nginx-daemonSet-4kr6h 1/1 Running 0 35s 10.244.1.2 node01
nginx-daemonSet-8jrg5 1/1 Running 0 35s 10.244.2.3 node02
DaemonSet 与 Deployment 的对比
特性 | Deployment | DaemonSet |
---|---|---|
副本分布 | 根据副本数随机分配到节点 | 每个节点运行一个 Pod 副本 |
适用场景 | 无状态应用(如 Web 服务) | 守护进程类应用(如日志收集、监控) |
扩缩容 | 通过 replicas 控制副本数 | 自动与节点数量同步 |
节点变化 | 不感知节点变化 | 自动根据节点变化调整 Pod |
高级配置
节点选择器(nodeSelector)
通过 nodeSelector
指定 DaemonSet 在特定节点上运行:
spec:
template:
spec:
nodeSelector:
disktype: ssd
污点与容忍(Taints and Tolerations)
通过 tolerations
允许 DaemonSet 在带有污点的节点上运行:
spec:
template:
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
更新策略(updateStrategy)
通过 updateStrategy
配置 DaemonSet 的更新策略:
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
常用操作
查看 DaemonSet 状态
kubectl get daemonset
输出示例:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
nginx-daemonSet 2 2 2 2 2 <none> 5m
删除 DaemonSet
kubectl delete daemonset nginx-daemonSet
- DaemonSet 是 Kubernetes 中用于管理守护进程类应用的核心控制器。
- 通过自动与节点同步,确保每个节点运行一个 Pod 副本。
- 适用于日志收集、监控代理、存储守护进程等场景。
- 支持节点选择器、污点容忍和滚动更新等高级配置。
Job
- 功能:运行一次性任务。
- 应用场景:数据库迁移、批处理脚本、kube-bench扫描、离线数据处理,视频解码等业务等。
- 示例:
apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4
.spec.template.spec.restartPolicy
该属性拥有三个候选值:OnFailure,Never和Always。默认值为Always。它主要用于描述Pod内容器的重启策略。在Job中只能将此属性设置为OnFailure或Never,否则Job将不间断运行。
.spec.backoffLimit
用于设置job失败后进行重试的次数,默认值为6。默认情况下,除非Pod失败或容器异常退出,Job任务将不间断的重试,此时Job遵循.spec.backoffLimit
上述说明。 一旦.spec.backoffLimit
达到,作业将被标记为失败。
- 常用命令:
kubectl apply -f job.yaml kubectl get pods kubectl logs pi-bqtf7
CronJob
- 功能:运行周期性任务,像Linux的Crontab一样。
- 应用场景:定时备份、通知等。
- 示例:
apiVersion: batch/v1beta1 kind: CronJob metadata: name: hello spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date; echo Hello from the Kubernetes cluster restartPolicy: OnFailure
cronjob其它可用参数的配置
spec:
concurrencyPolicy: Allow #声明了 CronJob 创建的任务执行时发生重叠如何处理(并发性规则仅适用于相同 CronJob 创建的任务)。spec仅能声明下列规则中的一种:
●Allow (默认):CronJob 允许并发任务执行。
●Forbid:CronJob 不允许并发任务执行;如果新任务的执行时间到了而老任务没有执行完,CronJob 会忽略新任务的执行。
●Replace:如果新任务的执行时间到了而老任务没有执行完,CronJob 会用新任务替换当前正在运行的任务。
startingDeadlineSeconds: 15 #它表示任务如果由于某种原因错过了调度时间,开始该任务的截止时间的秒数。过了截止时间,CronJob 就不会开始任务,且标记失败.如果此字段未设置,那任务就没有最后期限。
successfulJobsHistoryLimit: 3 #要保留的成功完成的任务数(默认为3)
failedJobsHistoryLimit:1 #要保留多少已完成和失败的任务数(默认为1)
suspend:true #如果设置为 true ,会被挂起后续发生的执行。 这个设置对已经开始的执行不起作用。默认是 false。
schedule: '*/1 * * * *' #必需字段,作业时间表。在此示例中,作业将每分钟运行一次
jobTemplate: #必需字段,作业模板。这类似于工作示例
- 常用命令:
kubectl create -f cronjob.yaml kubectl get cronjob kubectl get pods kubectl logs hello-1621587180-mffj6
如果报错:
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log hello-1621587780-c7v54)
解决办法:绑定一个cluster-admin的权限
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous
总结
1. Deployment + ReplicaSet
- 功能:部署无状态应用(无需本地存储实时数据的应用)。
- 特点:
- Deployment 负责创建和管理 ReplicaSet(RS)。
- ReplicaSet 负责维护 Pod 副本数与期望状态一致。
- 支持滚动更新(默认策略)和回滚操作。
- 常用命令:
kubectl create deployment <name> --image=<image> # 创建 Deployment kubectl expose deployment <name> --port=<port> # 暴露 Deployment 为 Service kubectl set image deployment <name> <container>=<image> # 更新镜像 kubectl rollout undo deployment <name> # 回滚 Deployment kubectl delete deployment <name> # 删除 Deployment
2. StatefulSet(STS)
- 功能:部署有状态应用(需要本地存储实时数据且数据有上下文关系的应用)。
- 特点:
- 需要提前创建 Headless Service(ClusterIP 为 None)。
- 每个 Pod 名称唯一且固定(标识为 0 到 n-1)。
- 支持通过
<Pod名称>.<Headless Service名称>.<命名空间>
解析 Pod IP。 - 每个 Pod 可拥有专属持久化存储(通过
volumeClaimTemplates
配置)。 - 默认有序部署、扩容、缩容和滚动更新(可通过
podManagementPolicy
修改为并行)。
- Service 类型:
- 4 种常规类型:ClusterIP、NodePort、LoadBalancer、ExternalName。
- 1 种特殊类型:Headless Service。
3. DaemonSet
- 功能:在每个 Node 节点上部署守护进程级别的无状态应用。
- 特点:
- 每个 Node 节点上运行一个 Pod 副本(受污点和调度策略影响)。
- 无需设置
replicas
字段。
- 适用场景:日志收集、监控代理、网络插件等。
4. Job
- 功能:一次性部署短期任务 Pod,任务完成后容器成功退出且不再重启。
- 特点:
- 容器重启策略
restartPolicy
不能为Always
,通常为Never
或OnFailure
。 - 任务失败时,根据
backoffLimit
字段重试(默认 6 次)。
- 容器重启策略
- 适用场景:批处理任务、数据处理任务。
5. CronJob
- 功能:周期性部署短期任务 Pod。
- 特点:
- 容器重启策略
restartPolicy
不能为Always
,通常为Never
或OnFailure
。 - 根据
schedule
字段配置任务周期(格式:分 时 日 月 周
)。
- 容器重启策略
- 适用场景:定时任务、周期性任务。
ConfigMap(CM)
- 功能:保存配置文件、环境变量等非加密信息,实现配置与应用程序解耦。
- 创建与查看:
kubectl create cm <name> -n <namespace> --from-file=<file> --from-literal=<key>=<value> # 创建 CM kubectl get cm <name> -n <namespace> -o yaml # 查看 CM 详情 kubectl describe cm <name> -n <namespace> # 查看 CM 描述
- 使用方式:
1.作为存储卷挂载的方式- 在Pod资源配置中使用
volumes
字段设置configMap
类型的卷 - 在容器配置中使用
volumeMounts.mountPath
字段将卷挂载到指定的容器目录,cm资源数据的键名会作为文件名,键值会作为文件内容生成在挂载点目录中,支持cm热更新配置 - 在容器配置中使用
volumeMounts.mountPath
字段指定的容器文件,volumeMounts.subPath
字段指定文件名,实现将卷挂载到容器的文件上,不支持cm热更新配置
- 在Pod资源配置中使用
- 作为容器环境变量的方式(不支持cm热更新配置)
- 在容器配置中使用
env.name
指定自定义的环境变量名,使用env.valueFrom.configMapKeyRef.name|key
字段指定环境变量的值从哪个cm资源的key获取 - 在容器配置中使用
envFrom.configMapRef.name
字段指定cm资源名称,实现将cm资源数据的键值直接作为容器环境变量名和值
- 在容器配置中使用
- Deployment:适合无状态应用,支持滚动更新和回滚。
- StatefulSet:适合有状态应用,支持有序部署和专属存储。
- DaemonSet:适合在每个节点上运行的守护进程。
- Job:适合一次性短期任务。
- CronJob:适合周期性短期任务。
- ConfigMap:用于管理配置信息,支持挂载和环境变量注入。