Kubernetes Pods 和 Workloads
支持的版本: Kubernetes 1.32, 1.33, 1.34 最后更新: February 23, 2026
本文档详细说明 Kubernetes 中的基本执行单元 Pod(容器组),以及用于管理它们的各种 Workload 资源。从 Pod 的概念开始,我们将介绍包括 Deployments、StatefulSets、DaemonSets 等各种 Workload 资源的特性和使用场景。
实验环境设置
要跟随本文档中的示例进行操作,你需要以下工具和环境:
必需工具
- kubectl v1.34 或更高版本
- 可用的 Kubernetes cluster(EKS、minikube、kind 等)
部署示例应用程序
# Create namespace
kubectl create namespace workloads-demo
# Create a simple deployment
kubectl -n workloads-demo apply -f - <<EOF
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.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
EOF
# Check deployment status
kubectl -n workloads-demo get deployments,pods目录
- Pod 概念
- Pod 生命周期
- Pod 设计模式
- Workload 资源概览
- ReplicaSet
- Deployment
- StatefulSet
- DaemonSet
- Jobs 和 CronJobs
- 资源管理
- Pod Disruption Budget
- Horizontal Pod Autoscaling
- Vertical Pod Autoscaling
- Workload 最佳实践
- Amazon EKS Workload 注意事项
Pod 概念
关键概念: Pod 是 Kubernetes 中最小的可部署计算单元,由一个或多个共享存储和网络的 container 组组成。
Pod 是 Kubernetes 中最小的可部署计算单元。Pod 是一组共享存储和网络,并被一起调度的一个或多个 container。
Pod 特性
- 共享上下文: Pod 内的所有 container 共享同一个网络命名空间、IPC 命名空间和 UTS 命名空间。
- 同一 Node: Pod 中的所有 container 始终运行在同一个 node 上。
- 唯一 IP 地址: 每个 Pod 在 cluster 内都有唯一的 IP 地址。
- 临时性: Pod 本质上是临时的,在发生故障时可以被新的 Pod 替换。
- 原子单元: Pod 是部署、调度和复制的原子单元。
Pod 结构
Pod 由以下组件组成:
- Containers: 在 Pod 内运行的一个或多个 container
- Volumes: Pod 内 container 共享的存储
- Network: 分配给 Pod 的 IP 地址和端口
- Container Spec: Container image、环境变量、资源需求等
Pod 示例
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.21
ports:
- containerPort: 80
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: content-updater
image: alpine
command: ["/bin/sh", "-c"]
args:
- while true; do
echo "Current time: $(date)" > /content/index.html;
sleep 10;
done
volumeMounts:
- name: shared-data
mountPath: /content
volumes:
- name: shared-data
emptyDir: {}实践示例:Web 应用程序 Pod
以下是包含 web 应用程序和 sidecar container 的 Pod 示例:
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
app: web
environment: production
spec:
containers:
- name: web-application
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
- name: log-collector
image: fluentd:v1.14
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
volumes:
- name: log-volume
emptyDir: {}此示例展示了以下真实场景:
- 将 Nginx web server 作为主 container 运行
- 将 Fluentd log collector 作为 sidecar container 运行
- 在两个 container 之间共享 log volume
- 为每个 container 设置 resource requests 和 limits
此配置适合在 microservice 架构中运行紧密关联的 container,同时将日志记录、监控和代理等功能分离出来。 classDef k8sComponent fill:#326CE5,stroke:#333,stroke-width:1px,color:white; classDef userApp fill:#00C7B7,stroke:#333,stroke-width:1px,color:white; classDef dataStore fill:#3B48CC,stroke:#333,stroke-width:1px,color:white; classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px,color:black;
%% Apply classes
class Pod default;
class Container1,Container2 userApp;
class Volume dataStore;
class IP default;
### Pod 定义
Pods 使用 YAML 或 JSON 格式的 manifest 文件进行定义。下面是一个基本的 Pod 定义示例:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"单 Container 与多 Container Pod
单 Container Pod:
- 最常见的使用场景
- 仅包含一个 application container
- 结构简单直观
多 Container Pod:
- 包含多个紧密耦合的 container
- Container 之间可以进行本地通信(localhost)
- 通过 shared volumes 共享数据
- 一起扩缩容并一起放置
多 Container Pod 模式
- Sidecar Pattern: 扩展主 container 功能的辅助 container
- 示例:log collector、文件同步、proxy
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
- name: web
image: nginx:1.21
- name: log-collector
image: fluentd:v1.14
volumeMounts:
- name: logs
mountPath: /var/log/nginx
volumes:
- name: logs
emptyDir: {}- Ambassador Pattern: 充当外部 services 代理的 container
- 示例:database proxy、service mesh sidecar
apiVersion: v1
kind: Pod
metadata:
name: app-with-ambassador
spec:
containers:
- name: app
image: myapp:1.0
- name: ambassador
image: envoy:v1.20
ports:
- containerPort: 9901- Adapter Pattern: 使主 container 输出标准化的 container
- 示例:log 格式转换、metrics 转换
apiVersion: v1
kind: Pod
metadata:
name: app-with-adapter
spec:
containers:
- name: app
image: myapp:1.0
- name: adapter
image: adapter:1.0
volumeMounts:
- name: app-logs
mountPath: /var/log/app
volumes:
- name: app-logs
emptyDir: {}- Init Container Pattern: 在主 container 启动之前运行的 container
- 示例:配置文件创建、database migration、权限设置
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
initContainers:
- name: init-db
image: busybox:1.34
command: ['sh', '-c', 'until nslookup db; do echo waiting for db; sleep 2; done;']
containers:
- name: app
image: myapp:1.0Pod 网络
Pod 内的 container 具有以下网络特性:
- 相同 IP 地址: Pod 内的所有 container 共享同一个 IP 地址。
- 端口共享: Pod 内的 container 共享端口空间,因此不能使用相同端口。
- Localhost 通信: Pod 内的 container 可以通过 localhost 相互通信。
- Pod 间通信: 每个 Pod 都有唯一的 IP 地址,并且可以直接与其他 Pods 通信。
Pod 存储
Pods 可以使用各种类型的 volumes 来存储和共享数据:
- emptyDir: 创建 Pod 时创建、删除 Pod 时删除的临时 volume
- hostPath: 从 host node 的文件系统挂载到 Pod 的 volume
- persistentVolumeClaim: 请求持久存储的 volume
- configMap: 作为 volume 挂载的 ConfigMap
- secret: 作为 volume 挂载的 Secret
- projected: 将多个 volume sources 映射到同一目录
apiVersion: v1
kind: Pod
metadata:
name: pod-with-volumes
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /etc/config
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: app-configPod 生命周期
Pods 从创建到终止会经历多个生命周期阶段。理解这个生命周期对于确保应用程序的稳定性和可用性非常重要。
Pod 阶段
Pods 会经历以下阶段:
- Pending: Pod 已被 cluster 接受,但一个或多个 container 尚未完成设置
- Running: Pod 已绑定到某个 node,所有 container 已创建,并且至少有一个 container 正在运行或正在启动/重启
- Succeeded: Pod 中的所有 container 都已成功终止,并且不会被重启
- Failed: Pod 中的所有 container 都已终止,并且至少有一个 container 因失败而终止
- Unknown: 由于某种原因无法获取 Pod 的状态
Container 状态
Pod 内的每个 container 可以具有以下状态:
- Waiting: Container 运行之前的状态(下载 image、等待依赖等)
- Running: Container 正在正常运行
- Terminated: Container 已完成执行或因某种原因失败
Pod Conditions
Pods 通过以下 conditions 更具体地表示其状态:
- PodScheduled: Pod 是否已被调度到某个 node
- ContainersReady: Pod 中的所有 container 是否已就绪
- Initialized: 所有 init containers 是否已成功完成
- Ready: Pod 是否可以处理请求,并可以加入 services 的负载均衡池
Container Probes
Kubernetes 提供以下 probes 来检查 container 状态:
- livenessProbe: 检查 container 是否存活;失败时重启 container
- readinessProbe: 检查 container 是否已准备好处理请求;失败时从 service traffic 中排除
- startupProbe: 检查 container 内的应用程序是否已启动;成功之前禁用其他 probes
apiVersion: v1
kind: Pod
metadata:
name: pod-with-probes
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10Pod 终止过程
当 Pod 被终止时,会发生以下过程:
- 向 API Server 发出删除请求: 用户或 controller 请求删除 Pod
- 终止期限开始: 设置默认终止期限(30 秒)
- API 更新: API server 更新 Pod 的删除时间戳
- 从 Service 中移除: Endpoint controller 从 service endpoints 中移除 Pod
- SIGTERM 信号: kubelet 向 container 发送 SIGTERM 信号
- 优雅关闭等待: 为应用程序提供优雅关闭的时间
- SIGKILL 信号: 如果 container 在终止期限后仍未终止,则发送 SIGKILL 信号
- 资源清理: kubelet 清理 Pod 资源
Init Containers
Init containers 是在 Pod 中 app containers 启动之前运行的特殊 container:
- 顺序执行: Init containers 按定义顺序一次运行一个
- 前置条件: 每个 init container 只有在前一个 container 成功完成后才会启动
- 失败时重启: 如果 init container 失败,它会根据 Pod 的 restart policy 重启
- 用途: App container 启动前的设置、依赖验证、权限设置等
apiVersion: v1
kind: Pod
metadata:
name: init-pod
spec:
initContainers:
- name: init-myservice
image: busybox:1.34
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox:1.34
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
containers:
- name: app
image: myapp:1.0Pod Disruption
Pod disruptions 可以分为自愿中断和非自愿中断:
自愿中断: 由 cluster 管理员或自动化工具引起的中断
- Node draining
- Deployment updates
- Pod deletion
非自愿中断: 由硬件故障、kernel panic、网络分区等导致的中断
PodDisruptionBudget 可以在自愿中断期间确保最低可用性。
Pod 设计模式
设计 Pods 时需要考虑若干模式和最佳实践。理解并应用这些模式可以提升应用程序的稳定性、可扩展性和可维护性。
单一职责原则
Pods 应遵循单一职责原则:
- 一个主要功能: 每个 Pod 应负责一个主要功能或进程
- 独立扩缩容: 设计时应使每个功能都可以独立扩缩容
- 独立生命周期: 设计时应使每个功能都可以拥有自己的生命周期
Pod Templates
Pod templates 是在 Workload 资源(Deployments、StatefulSets 等)中用于创建 Pods 的规范:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template: # Pod template starts
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
# Pod template endsPod Affinity 和 Anti-Affinity
Pod affinity 和 anti-affinity 是控制 Pods 被调度到哪些 nodes 上的规则:
- Pod Affinity: 调度到与特定 Pods 相同的 node 或 topology domain 上
- Pod Anti-Affinity: 调度到与特定 Pods 不同的 node 或 topology domain 上
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cache
topologyKey: "kubernetes.io/hostname"
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: "kubernetes.io/hostname"
containers:
- name: web
image: nginx:1.21Node Affinity
Node affinity 是限制 Pods 调度到特定 nodes 上的规则:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"
containers:
- name: gpu-container
image: gpu-app:1.0Taints 和 Tolerations
Taints 应用于 nodes,用于阻止某些 Pods 被调度;tolerations 应用于 Pods,用于允许调度到带有 taints 的 nodes 上:
# Apply taint to node
kubectl taint nodes node1 key=value:NoSchedule
# Apply toleration to Pod
apiVersion: v1
kind: Pod
metadata:
name: tolerant-pod
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: app
image: myapp:1.0Resource Requests 和 Limits
为 Pods 中的 container 设置 resource requests 和 limits,对于高效使用 cluster 资源以及确保稳定性非常重要:
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: app
image: myapp:1.0
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"Pod Security Context
Security context 定义 Pod 或 container 级别的安全设置:
apiVersion: v1
kind: Pod
metadata:
name: security-pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALLPod Priority 和 Preemption
Pod priority 和 preemption 决定在 cluster 资源不足时哪些 Pods 会被调度,哪些 Pods 会被抢占:
# Priority class definition
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for critical pods only."
# Pod using priority class
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority
containers:
- name: app
image: myapp:1.0Workload 资源概览
Kubernetes 提供多种 Workload 资源来管理 Pods。每种 Workload 资源都面向特定的使用场景和需求而设计。
Workload 资源类型
Kubernetes 中的主要 Workload 资源包括:
- ReplicaSet: 维护指定数量的 Pod replicas
- Deployment: 管理 ReplicaSets 以提供声明式更新
- StatefulSet: 用于需要状态持久性的应用程序的资源
- DaemonSet: 在所有 nodes 上运行一个 Pod 副本
- Job: 完成后终止的一次性任务
- CronJob: 按计划周期性运行 Jobs
Workload 资源选择标准
选择合适 Workload 资源的标准:
- 状态持久性: 应用程序是否需要维护状态
- 执行模式: 是持续运行、一次性运行还是周期性运行
- 部署需求: 对 rolling updates、blue/green deployments 等的需求
- Node 覆盖范围: 是否需要在所有 nodes 上运行
- 可扩展性需求: 是否需要水平扩缩容
ReplicaSet
ReplicaSet 确保指定数量的 Pod replicas 始终运行。如果 Pods 失败或被删除,ReplicaSet 会自动创建替代 Pods。
ReplicaSet 的主要特性
- 维护 Pod Replicas: 维护指定数量的 Pod replicas
- Pod 选择: 通过 label selectors 识别要管理的 Pods
- Pod 创建: 必要时创建新的 Pods
- Pod 删除: 删除多余的 Pods
ReplicaSet 定义
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80ReplicaSet 工作方式
- Label Selector 匹配: ReplicaSet 识别匹配 label selector 的 Pods
- 检查当前状态: 验证当前正在运行的 Pods 数量
- 与期望状态比较: 将当前 Pod 数量与期望 replica 数量进行比较
- 调整操作: 根据需要创建或删除 Pods
ReplicaSet vs Replication Controller
ReplicaSet 是 Replication Controller 的后继者,并提供更强大的 label selectors:
- Replication Controller: 仅支持基于等值的 selectors(例如 app=nginx)
- ReplicaSet: 支持基于集合的 selectors(例如 app in (nginx, apache))
ReplicaSet 使用场景
ReplicaSets 通常通过 Deployments 间接使用,而不是直接使用。不过,在以下情况下也可以直接使用:
- 简单复制: 仅需维护 Pod replicas 时
- 自定义更新: 需要自定义更新机制时
- 旧版支持: 支持 legacy applications
Deployment
Deployment 管理 ReplicaSets,以便为 Pods 提供声明式更新。Deployments 为应用程序管理 rolling updates、rollbacks、scaling 等。
Deployment 的主要特性
- 声明式更新: 声明期望状态,Deployment 将当前状态变更为期望状态
- Rolling Updates: 无停机更新应用程序
- Rollback: 轻松回滚到以前版本
- Scaling: 调整应用程序 replicas 数量
- Deployment History: 维护以前部署版本的记录
Deployment 定义
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 200m
memory: 200Mi
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5Deployment 更新策略
Deployments 提供两种更新策略:
RollingUpdate: 为部署逐步更新 Pods,避免停机(默认)
- maxSurge: 可在期望 Pod 数量之上额外创建的最大 Pods 数量
- maxUnavailable: 更新期间不可用的最大 Pods 数量
Recreate: 创建新 Pods 之前删除所有现有 Pods(会导致临时停机)
Deployment 回滚
Deployments 支持回滚到以前版本:
# Check deployment history
kubectl rollout history deployment/nginx-deployment
# Check details of specific version
kubectl rollout history deployment/nginx-deployment --revision=2
# Rollback to previous version
kubectl rollout undo deployment/nginx-deployment
# Rollback to specific version
kubectl rollout undo deployment/nginx-deployment --to-revision=2Deployment 扩缩容
Deployments 可以轻松扩缩容:
# Imperative scaling
kubectl scale deployment/nginx-deployment --replicas=5
# Declarative scaling (after modifying YAML file)
kubectl apply -f deployment.yamlDeployment 暂停与恢复
Deployment rollouts 可以暂停和恢复:
# Pause rollout
kubectl rollout pause deployment/nginx-deployment
# Apply multiple changes
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=256Mi
# Resume rollout
kubectl rollout resume deployment/nginx-deploymentDeployment 状态
Deployments 可以具有以下状态:
- Progressing: 正在创建新的 ReplicaSet 或进行扩缩容
- Complete: 所有 replicas 都已更新并可用
- Failed: 部署期间发生错误(例如 image 拉取失败、资源不足)
StatefulSet
StatefulSet 是用于需要状态持久性的应用程序的 Workload 资源。它为每个 Pod 分配唯一标识符,并提供稳定的网络标识符和持久存储。
StatefulSet 的主要特性
- 稳定且唯一的网络标识符: Pod names 和 hostnames 即使在重启后也会保持不变
- 稳定且持久的存储: 即使 Pods 被重新调度,也能访问相同的存储
- 顺序部署和扩缩容: Pods 按顺序创建、更新和删除
- 顺序自动 Rolling Updates: Pods 按顺序更新
StatefulSet 定义
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
updateStrategy:
type: RollingUpdate
podManagementPolicy: OrderedReady
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 1GiStatefulSet Pod 标识符
StatefulSet 按以下格式为 Pods 分配唯一标识符:
<StatefulSet name>-<ordinal index>例如,web StatefulSet 会创建类似 web-0、web-1、web-2 的 Pods。
StatefulSet Headless Service
StatefulSets 通常与 headless service(clusterIP: None)一起使用。这会为每个 Pod 创建 DNS 记录:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx这样,每个 Pod 都拥有以下格式的 DNS 名称:
<Pod name>.<service name>.<namespace>.svc.cluster.local示例:web-0.nginx.default.svc.cluster.local
StatefulSet 存储
StatefulSets 使用 volumeClaimTemplates 为每个 Pod 自动创建 Persistent Volume Claims(PVCs)。即使 Pods 被重新调度,这些 PVCs 也会被保留。
StatefulSet 更新策略
StatefulSets 提供两种更新策略:
- RollingUpdate: 按顺序更新 Pods(默认)
- OnDelete: 仅在 Pods 被删除时更新
Pod 管理策略
StatefulSets 提供两种 Pod 管理策略:
- OrderedReady: 按顺序创建和终止 Pods(默认)
- Parallel: 并行创建和终止 Pods
StatefulSet 使用场景
StatefulSets 适用于以下应用程序:
- Databases: MySQL、PostgreSQL、MongoDB 等
- Distributed Systems: Kafka、ZooKeeper、Elasticsearch 等
- Message Queues: RabbitMQ 等
- 其他 Stateful Applications: File servers、session stores 等
StatefulSet 示例:MySQL Replication
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 3
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:5.7
command:
- bash
- "-c"
- |
set -ex
# Generate server ID based on Pod index
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
# Master or slave configuration
if [[ $ordinal -eq 0 ]]; then
echo [mysqld] > /mnt/conf.d/master.cnf
echo log-bin=mysql-bin >> /mnt/conf.d/master.cnf
else
echo [mysqld] > /mnt/conf.d/slave.cnf
echo super-read-only >> /mnt/conf.d/slave.cnf
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
- name: clone-mysql
image: gcr.io/google-samples/xtrabackup:1.0
command:
- bash
- "-c"
- |
set -ex
# Only perform replication if not the first Pod
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
if [[ $ordinal -eq 0 ]]; then
exit 0
fi
# Replicate data from previous Pod
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
# Prepare backup
xtrabackup --prepare --target-dir=/var/lib/mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- name: mysql
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 500m
memory: 1Gi
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
exec:
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 2
timeoutSeconds: 1
- name: xtrabackup
image: gcr.io/google-samples/xtrabackup:1.0
ports:
- name: xtrabackup
containerPort: 3307
command:
- bash
- "-c"
- |
set -ex
cd /var/lib/mysql
# Start slave
if [[ -f xtrabackup_slave_info ]]; then
cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql
mysql -h 127.0.0.1 -e "$(cat change_master_to.sql); RESET SLAVE; START SLAVE;"
# If replicated from master
elif [[ -f xtrabackup_binlog_info ]]; then
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
[[ $ordinal -eq 0 ]] && exit 0
master_host=mysql-0.mysql
master_log_file=$(cat xtrabackup_binlog_info | awk '{print $1}')
master_log_pos=$(cat xtrabackup_binlog_info | awk '{print $2}')
mysql -h 127.0.0.1 -e "CHANGE MASTER TO MASTER_HOST='$master_host', MASTER_USER='root', MASTER_PASSWORD='$MYSQL_ROOT_PASSWORD', MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=$master_log_pos; RESET SLAVE; START SLAVE;"
fi
# Start backup server
exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 100m
memory: 100Mi
volumes:
- name: conf
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard
resources:
requests:
storage: 10GiDaemonSet
DaemonSet 确保一个 Pod 的副本运行在所有 nodes(或特定 nodes)上。当 node 添加到 cluster 时,Pods 会自动添加;当 node 被移除时,Pods 也会被移除。
DaemonSet 的主要特性
- 在所有 Nodes 上运行: 在 cluster 中的所有 nodes 上运行 Pods
- Node 选择: 可以通过 node selectors 仅在特定 nodes 上运行
- 自动部署: 添加新 nodes 时自动部署 Pods
- 自动清理: 移除 nodes 时自动清理 Pods
DaemonSet 定义
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containersDaemonSet 更新策略
DaemonSets 提供两种更新策略:
RollingUpdate: 按顺序更新 Pods(默认)
- maxUnavailable: 更新期间不可用的最大 Pods 数量
OnDelete: 仅在 Pods 被删除时更新
DaemonSet Node 选择
DaemonSets 可以配置为仅在特定 nodes 上运行:
spec:
template:
spec:
nodeSelector:
disk: ssdDaemonSet Taint Tolerations
DaemonSets 可以设置 tolerations,以便在带有 taints 的 nodes 上运行:
spec:
template:
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoScheduleDaemonSet 使用场景
DaemonSets 用于以下目的:
- Log Collectors: Fluentd、Logstash 等
- Monitoring Agents: Prometheus Node Exporter、Datadog Agent 等
- Network Plugins: Calico、Cilium、Weave Net 等
- Storage Daemons: Ceph、GlusterFS 等
- Security Agents: Falco、Sysdig 等
DaemonSet 示例:Prometheus Node Exporter
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
labels:
app: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
hostPID: true
containers:
- name: node-exporter
image: prom/node-exporter:v1.3.1
args:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --path.rootfs=/host/root
- --web.listen-address=:9100
ports:
- containerPort: 9100
protocol: TCP
name: http
resources:
limits:
cpu: 250m
memory: 180Mi
requests:
cpu: 102m
memory: 180Mi
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
- name: root
mountPath: /host/root
readOnly: true
tolerations:
- operator: "Exists"
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: root
hostPath:
path: /Jobs 和 CronJobs
Jobs 和 CronJobs 是用于运行一次性或周期性任务的 Workload 资源。
Job
Job 创建一个或多个 Pods,并持续执行,直到指定数量的 Pods 成功终止。
Job 的主要特性
- 完成保证: 一直运行,直到指定数量的 Pods 成功完成
- 并行执行: 可以并行运行多个 Pods
- 重试: 自动重试失败的 Pods
- 完成后清理: 可选地在 job 完成后清理 Pods
Job 定义
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
completions: 5 # Number of Pods that must successfully complete
parallelism: 2 # Number of Pods to run in parallel
backoffLimit: 4 # Number of retries on failure
activeDeadlineSeconds: 100 # Job time limit (seconds)
ttlSecondsAfterFinished: 100 # Deletion time after completion (seconds)
template:
spec:
containers:
- name: pi
image: perl:5.34
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
cpu: 100m
memory: 100Mi
restartPolicy: Never # or OnFailureJob 完成模式
Jobs 提供两种完成模式:
- NonIndexed: 标准 job 模式,在指定数量的 Pods 成功完成时 job 完成
- Indexed: 每个 Pod 从 0 开始分配一个 index,用于处理特定 index 范围的任务
apiVersion: batch/v1
kind: Job
metadata:
name: indexed-job
spec:
completions: 5
parallelism: 3
completionMode: Indexed # Enable Indexed mode
template:
spec:
containers:
- name: worker
image: busybox:1.34
command: ["sh", "-c", "echo Processing item ${JOB_COMPLETION_INDEX}"]
restartPolicy: NeverJob 使用场景
Jobs 用于以下目的:
- Batch Processing: 数据处理、ETL tasks
- Computation Tasks: 科学计算、rendering
- Database Migrations: Schema updates
- 一次性管理任务: Backups、cleanup tasks
CronJob
CronJobs 根据指定计划周期性运行 Jobs。它们的工作方式类似于 Linux cron jobs。
CronJob 的主要特性
- 计划执行: 使用 cron expressions 指定执行计划
- Job 管理: 根据计划创建 Jobs
- Concurrency Policy: 定义前一个 job 仍在运行时的行为
- History Limit: 限制已完成 jobs 的历史记录
CronJob 定义
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" # Run every minute
timeZone: "America/New_York" # Timezone (Kubernetes 1.24+)
concurrencyPolicy: Forbid # Allow, Forbid, Replace
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
startingDeadlineSeconds: 60
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.34
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailureCron Expression
Cron expressions 具有以下格式:
+------------------- minute (0 - 59)
| +----------------- hour (0 - 23)
| | +--------------- day of month (1 - 31)
| | | +------------- month (1 - 12)
| | | | +----------- day of week (0 - 6) (Sunday to Saturday; 7 is also Sunday)
| | | | |
| | | | |
* * * * *常见 cron expression 示例:
*/5 * * * *: 每 5 分钟0 * * * *: 每小时整点0 0 * * *: 每天午夜0 0 * * 0: 每周日午夜0 0 1 * *: 每月 1 日午夜0 0 1 1 *: 每年 1 月 1 日午夜
Concurrency Policy
CronJobs 提供三种 concurrency policies:
- Allow: 多个 Jobs 可以同时运行(默认)
- Forbid: 如果前一个 Job 仍在运行,则跳过新的 Job
- Replace: 如果前一个 Job 仍在运行,则用新的 Job 替换前一个 Job
CronJob 使用场景
CronJobs 用于以下目的:
- Regular Backups: Database backups、snapshot creation
- Data Synchronization: 周期性数据同步
- Report Generation: 每日/每周/每月报告生成
- Cleanup Tasks: 临时文件清理、log rotation
- Notifications and Monitoring: 状态检查、alert sending
CronJob 示例:Database Backup
apiVersion: batch/v1
kind: CronJob
metadata:
name: database-backup
spec:
schedule: "0 2 * * *" # Run daily at 02:00
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:14
env:
- name: PGHOST
value: postgres-service
- name: PGUSER
valueFrom:
secretKeyRef:
name: postgres-secret
key: username
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
command:
- /bin/sh
- -c
- |
pg_dump -Fc > /backup/db-$(date +%Y%m%d-%H%M%S).dump
find /backup -type f -mtime +7 -delete # Delete backups older than 7 days
volumeMounts:
- name: backup-volume
mountPath: /backup
restartPolicy: OnFailure
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: backup-pvc总结
本文档介绍了 Pods(Kubernetes 的基本构建块)以及各种 Workload 资源。从 Pod 的概念开始,我们探讨了包括 Deployments、StatefulSets、DaemonSets、Jobs 和 CronJobs 在内的各种 Workload 资源的特性和使用场景。这些资源各自具有独特的目的和功能,适当地使用它们可以实现高效的应用程序部署和管理。
测验
要测试你在本章中学到的内容,请尝试 Pods 和 Workloads 测验。