Pod 详解
Pod 是 Kubernetes 中最小且最简单的部署单元,是 Kubernetes 集群中最基本的构建块。
什么是 Pod?
Pod 是 Kubernetes 中的最小部署单元,代表一个或多个共享存储和网络的容器组。
Pod 的特点
- 共享网络:同一 Pod 中的容器共享相同的网络命名空间
- 共享存储:可以挂载共享的 Volume
- 原子调度:Pod 中的容器始终在同一节点上调度
- 生命周期短暂:Pod 是临时的,创建后可能被销毁
Pod 的结构
基础 Pod 定义
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
env:
- name: APP_ENV
value: "production"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
多容器 Pod
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
# 主容器
- name: web
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
# Sidecar 容器
- name: sidecar
image: busybox:1.36
command: ['sh', '-c', 'while true; do sleep 30; done']
volumeMounts:
- name: html
mountPath: /data
# 共享卷
volumes:
- name: html
emptyDir: {}
Pod 生命周期
Pod 的生命周期包括多个阶段:
Pod 状态
| 状态 | 说明 |
|---|---|
| Pending | Pod 已被创建,正在等待调度或拉取镜像 |
| Running | Pod 已绑定到节点,所有容器已创建 |
| Succeeded | 所有容器正常退出 |
| Failed | 至少有一个容器异常退出 |
| Unknown | 无法获取 Pod 状态 |
Pod 配置详解
镜像配置
spec:
containers:
- name: my-app
# 指定镜像
image: nginx:1.25
# 镜像拉取策略
imagePullPolicy: Always # Always/IfNotPresent/Never
# 拉取私有镜像
imagePullSecrets:
- name: my-registry-secret
资源配额
spec:
containers:
- name: app
resources:
# 需求:调度时需要的最小资源
requests:
memory: "128Mi"
cpu: "100m"
# 限制:容器可以使用的最大资源
limits:
memory: "256Mi"
cpu: "500m"
环境变量
spec:
containers:
- name: app
env:
# 简单值
- name: APP_ENV
value: "production"
# 来自 ConfigMap
- name: CONFIG_VALUE
valueFrom:
configMapKeyRef:
name: my-config
key: config.key
# 来自 Secret
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
# 来自 Pod 字段
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
启动命令
spec:
containers:
- name: my-app
image: my-app:latest
# 覆盖默认命令
command: ["/bin/sh", "-c"]
# 传递参数
args:
- "-c"
- "echo Starting app && nginx -g 'daemon off;'"
# 工作目录
workingDir: /app
健康检查
spec:
containers:
- name: my-app
image: my-app:latest
# 存活探针 - 检查容器是否存活
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
# 就绪探针 - 检查容器是否就绪
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# 启动探针 - 容器启动完成检查
startupProbe:
httpGet:
path: /started
port: 8080
failureThreshold: 30
periodSeconds: 10
探针类型
| 类型 | 用途 | 成功标准 |
|---|---|---|
| exec | 执行命令 | 退出码为 0 |
| httpGet | HTTP GET 请求 | 状态码 200-399 |
| tcpSocket | TCP 端口检查 | 端口可连接 |
| grpc | gRPC 健康检查 | 返回 SERVING |
Volume 存储
emptyDir
临时共享存储,Pod 删除时也会被删除:
spec:
volumes:
- name: cache
emptyDir:
sizeLimit: 100Mi
containers:
- name: app
volumeMounts:
- name: cache
mountPath: /tmp/cache
hostPath
挂载节点上的文件系统:
spec:
volumes:
- name: logs
hostPath:
path: /var/log/myapp
type: Directory
containers:
- name: app
volumeMounts:
- name: logs
mountPath: /var/log
PersistentVolumeClaim
使用持久化存储:
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc
containers:
- name: app
volumeMounts:
- name: data
mountPath: /data
Pod 调度
节点选择
spec:
# 节点选择器
nodeSelector:
disktype: ssd
# 节点亲和性
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-west-2a
# Pod 反亲和性
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
污点和容忍
# 节点污点
spec:
taints:
- key: "dedicated"
value: "gpu"
effect: NoSchedule
# Pod 容忍
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
Pod 管理命令
创建和删除
# 创建 Pod
kubectl apply -f pod.yaml
# 查看 Pod
kubectl get pods
# 查看 Pod 详情
kubectl describe pod my-pod
# 查看 Pod 日志
kubectl logs my-pod
# 实时日志
kubectl logs -f my-pod
# 删除 Pod
kubectl delete pod my-pod
调试
# 进入容器
kubectl exec -it my-pod -- /bin/sh
# 查看容器列表
kubectl exec -it my-pod -- container-name -- /bin/sh
# 端口转发
kubectl port-forward my-pod 8080:80
# 复制文件
kubectl cp my-pod:/app/logs ./logs
最佳实践
1. 使用 Controller 而非直接创建 Pod
# 错误:不直接创建 Pod
apiVersion: v1
kind: Pod
metadata:
name: my-pod
# 正确:使用 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
# ...
2. 设置资源限制
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "200m"
3. 使用健康检查
livenessProbe:
httpGet:
path: /healthz
port: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
4. 避免敏感信息明文
# 使用 Secret
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: api-secret
key: key
小结
本章我们学习了:
- Pod 概念:最小部署单元,容器组
- Pod 结构:共享网络、存储、生命周期
- Pod 配置:镜像、资源、健康检查
- Volume:临时存储和持久化存储
- 调度:节点选择器、亲和性、污点容忍
- 管理:创建、调试、最佳实践
练习
- 创建一个包含两个容器的 Pod,共享一个 Volume
- 为 Pod 添加存活探针和就绪探针
- 使用节点选择器将 Pod 调度到特定节点
- 使用 kubectl 调试 Pod,进入容器查看状态
准备好继续学习了吗?点击下一章了解 Deployment!