主题
生产运维
业务场景
云咖啡公司的 K8S 集群已经稳定运行,作为运维工程师,你需要掌握日常运维技能:
- 控制资源使用,防止资源滥用
- 记录操作日志,满足审计要求
- 管理证书有效期,避免服务中断
- 处理常见生产故障
学习目标
完成本阶段后,你将掌握:
- 资源配额管理:控制命名空间的资源使用
- 审计日志:记录集群操作,满足合规要求
- 证书管理:管理 K8S 证书的生命周期
- 生产故障排查:快速定位和解决常见问题
前置知识
本阶段需要以下基础知识:
- 完成前八个阶段的学习
- 熟悉 K8S 核心概念和操作
- 了解基本的运维流程
第一部分:资源配额管理
为什么需要资源配额
在多团队共享集群的环境中,如果没有资源限制:
- 某个团队可能占用过多资源,影响其他团队
- 资源成本无法控制
- 集群可能因资源耗尽而崩溃
ResourceQuota:命名空间资源配额
ResourceQuota 限制命名空间级别的资源总量。
创建 resourcequota.yaml 文件:
bash
cat > resourcequota.yaml << 'EOF'
# 资源配额配置
# 用途:限制 cloud-coffee 命名空间的资源使用总量
# 配置说明:
# - requests.cpu/memory:资源请求总量限制(用于调度)
# - limits.cpu/memory:资源限制总量限制(硬性上限)
# - 对象数量限制:Pod、Service、Secret 等的最大数量
apiVersion: v1
kind: ResourceQuota
metadata:
name: cloud-coffee-quota
namespace: cloud-coffee
spec:
hard:
# 计算资源
requests.cpu: "10" # CPU 请求总量不超过 10 核
requests.memory: 20Gi # 内存请求总量不超过 20Gi
limits.cpu: "20" # CPU 限制总量不超过 20 核
limits.memory: 40Gi # 内存限制总量不超过 40Gi
# 存储资源
requests.storage: 100Gi # 存储请求总量不超过 100Gi
persistentvolumeclaims: "10" # PVC 数量不超过 10 个
# 对象数量
pods: "50" # Pod 数量不超过 50 个
services: "10" # Service 数量不超过 10 个
secrets: "20" # Secret 数量不超过 20 个
configmaps: "20" # ConfigMap 数量不超过 20 个
replicationcontrollers: "10"
deployments.apps: "10"
EOF应用配置:
bash
kubectl apply -f resourcequota.yaml -n cloud-coffeeLimitRange:Pod/容器资源限制
LimitRange 限制单个 Pod 或容器的资源范围。
创建 limitrange.yaml 文件:
bash
cat > limitrange.yaml << 'EOF'
# 限制范围配置
# 用途:限制单个 Pod/容器的资源使用范围
# 配置说明:
# - default:默认限制值(limits)
# - defaultRequest:默认请求值(requests)
# - min/max:允许的最小和最大值
# - maxLimitRequestRatio:limits/requests 的最大比例
apiVersion: v1
kind: LimitRange
metadata:
name: cloud-coffee-limits
namespace: cloud-coffee
spec:
limits:
# 容器默认资源
- type: Container
default: # 默认限制(limits)
cpu: 500m
memory: 512Mi
defaultRequest: # 默认请求(requests)
cpu: 100m
memory: 128Mi
min: # 最小值
cpu: 50m
memory: 64Mi
max: # 最大值
cpu: 2
memory: 4Gi
maxLimitRequestRatio: # 限制与请求的最大比例
cpu: 5
memory: 3
# Pod 总资源限制
- type: Pod
max:
cpu: 4
memory: 8Gi
# PVC 存储限制
- type: PersistentVolumeClaim
min:
storage: 1Gi
max:
storage: 50Gi
EOF应用配置:
bash
kubectl apply -f limitrange.yaml -n cloud-coffee验证配额效果
bash
# 查看配额使用情况
kubectl get resourcequota -n cloud-coffee
kubectl describe resourcequota cloud-coffee-quota -n cloud-coffee
# 查看限制范围
kubectl get limitrange -n cloud-coffee
kubectl describe limitrange cloud-coffee-limits -n cloud-coffee实际应用示例
部署一个没有指定资源的 Pod,LimitRange 会自动添加默认值:
yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: cloud-coffee
spec:
containers:
- name: nginx
image: nginx:alpine查看自动添加的资源:
bash
kubectl get pod test-pod -n cloud-coffee -o yaml | grep -A 5 resources第二部分:审计日志
什么是审计日志
审计日志记录了集群中发生的所有操作,包括:
- 谁执行了操作
- 执行了什么操作
- 操作的目标资源
- 操作时间和结果
启用审计日志
步骤1:创建审计策略文件
创建 audit-policy.yaml 文件:
bash
cat > audit-policy.yaml << 'EOF'
# 审计策略配置
# 用途:定义需要记录的 API 操作
# 审计级别说明:
# - None:不记录
# - Metadata:只记录请求元数据
# - Request:记录元数据和请求体
# - RequestResponse:记录元数据、请求体和响应体
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 记录敏感资源的所有操作
- level: RequestResponse
resources:
- group: ""
resources: ["secrets", "configmaps"]
- group: "rbac.authorization.k8s.io"
resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
# 记录工作负载的变更操作
- level: Request
resources:
- group: "apps"
resources: ["deployments", "daemonsets", "statefulsets"]
verbs: ["create", "update", "patch", "delete"]
# 记录认证失败
- level: Metadata
omitStages:
- "RequestReceived"
# 其他请求只记录元数据
- level: Metadata
EOF步骤2:配置 kube-apiserver
⚠️ 生产环境注意事项
- 此操作需要访问控制平面节点
- 修改 kube-apiserver 配置需要重启服务
- 建议在维护窗口执行
- 执行前请备份现有配置
将审计策略文件复制到控制平面节点:
bash
# 创建审计日志目录
sudo mkdir -p /var/log/kubernetes
# 复制审计策略文件
sudo cp audit-policy.yaml /etc/kubernetes/audit-policy.yaml
sudo chmod 600 /etc/kubernetes/audit-policy.yaml编辑 kube-apiserver 静态 Pod 配置:
bash
# 编辑 kube-apiserver 配置
sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml在 command 部分添加以下参数:
yaml
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit.log
- --audit-log-maxage=30
- --audit-log-maxbackup=10
- --audit-log-maxsize=100添加卷挂载:
yaml
volumeMounts:
- name: audit-policy
mountPath: /etc/kubernetes/audit-policy.yaml
readOnly: true
- name: audit-log
mountPath: /var/log/kubernetes
readOnly: false添加卷定义:
yaml
volumes:
- name: audit-policy
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File
- name: audit-log
hostPath:
path: /var/log/kubernetes
type: DirectoryOrCreate保存后,kube-apiserver 会自动重启。
步骤3:查看审计日志
bash
# 查看最近的审计日志
tail -f /var/log/kubernetes/audit.log
# 搜索特定用户的操作
grep '"username":"admin"' /var/log/kubernetes/audit.log
# 搜索删除操作
grep '"verb":"delete"' /var/log/kubernetes/audit.log审计日志分析示例
json
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"stage": "ResponseComplete",
"requestReceivedTimestamp": "2024-01-15T10:30:00.000000Z",
"stageTimestamp": "2024-01-15T10:30:00.100000Z",
"verb": "create",
"objectRef": {
"resource": "pods",
"namespace": "cloud-coffee",
"name": "nginx-pod"
},
"user": {
"username": "admin",
"groups": ["system:masters"]
},
"responseStatus": {
"code": 201
}
}第三部分:证书管理
K8S 证书概述
K8S 集群使用多个证书保证通信安全:
| 证书 | 用途 |
|---|---|
| ca.crt | 集群根证书 |
| apiserver.crt | API Server 证书 |
| apiserver-kubelet-client.crt | API Server 访问 Kubelet 的证书 |
| front-proxy-ca.crt | 前端代理根证书 |
| etcd/ca.crt | etcd 根证书 |
| etcd/server.crt | etcd 服务端证书 |
查看证书有效期
bash
# 查看所有证书有效期
kubeadm certs check-expiration
# 输出示例
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Jan 15, 2025 10:00 UTC 364d ca no
apiserver Jan 15, 2025 10:00 UTC 364d ca no
apiserver-etcd-client Jan 15, 2025 10:00 UTC 364d etcd-ca no
apiserver-kubelet-client Jan 15, 2025 10:00 UTC 364d ca no
controller-manager.conf Jan 15, 2025 10:00 UTC 364d ca no
etcd-healthcheck-client Jan 15, 2025 10:00 UTC 364d etcd-ca no
etcd-peer Jan 15, 2025 10:00 UTC 364d etcd-ca no
etcd-server Jan 15, 2025 10:00 UTC 364d etcd-ca no
front-proxy-client Jan 15, 2025 10:00 UTC 364d front-proxy-ca no
scheduler.conf Jan 15, 2025 10:00 UTC 364d ca no续期证书
⚠️ 生产环境注意事项
- 证书续期操作需要访问控制平面节点
- 续期后需要重启控制平面组件,可能导致短暂的服务中断
- 建议在维护窗口执行,避免业务高峰期
- 执行前请备份现有证书(
/etc/kubernetes/pki目录)- 确保有集群的备份和恢复方案
bash
# 备份现有证书(重要!)
sudo cp -r /etc/kubernetes/pki /etc/kubernetes/pki.backup.$(date +%Y%m%d)
# 查看证书有效期
kubeadm certs check-expiration
# 续期所有证书
sudo kubeadm certs renew all
# 或者续期特定证书
sudo kubeadm certs renew apiserver
sudo kubeadm certs renew admin.conf续期后需要重启控制平面组件:
bash
# 重启控制平面组件(静态 Pod 会自动重启)
# 移动清单文件触发重启
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sudo sleep 10
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
sudo mv /etc/kubernetes/manifests/kube-controller-manager.yaml /tmp/
sudo sleep 10
sudo mv /tmp/kube-controller-manager.yaml /etc/kubernetes/manifests/
sudo mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/
sudo sleep 10
sudo mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/更新本地 kubeconfig:
bash
# 更新当前用户的 kubeconfig
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config自动续期配置
使用 kubeadm 的自动续期功能(K8S 1.22+):
yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
serverTLSBootstrap: true
rotateCertificates: true第四部分:生产故障排查
故障排查思路
发现问题 → 定位范围 → 收集信息 → 分析原因 → 解决问题 → 总结复盘常见故障场景
场景1:Pod 一直处于 Pending 状态
排查步骤:
bash
# 查看 Pod 详情
kubectl describe pod <pod-name> -n <namespace>
# 查看节点资源
kubectl describe nodes
kubectl top nodes
# 查看调度器日志
kubectl logs -n kube-system kube-scheduler-<node-name>常见原因:
- 资源不足(CPU/内存)
- 节点选择器不匹配
- 污点/容忍配置问题
- PVC 未绑定
解决方案:
- 增加节点或减少资源请求
- 检查 nodeSelector 和 affinity 配置
- 检查污点和容忍配置
场景2:Pod 频繁重启(CrashLoopBackOff)
排查步骤:
bash
# 查看 Pod 状态
kubectl get pod <pod-name> -n <namespace>
# 查看容器日志
kubectl logs <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace> --previous # 查看上一个容器的日志
# 查看事件
kubectl describe pod <pod-name> -n <namespace>常见原因:
- 应用启动失败
- 健康检查配置错误
- 资源限制过低
- 配置错误
解决方案:
- 检查应用日志定位错误
- 调整健康检查配置
- 增加资源限制
场景3:Service 无法访问
排查步骤:
bash
# 查看 Service 配置
kubectl get svc <svc-name> -n <namespace> -o yaml
# 查看 Endpoints
kubectl get endpoints <svc-name> -n <namespace>
# 查看 Pod 标签
kubectl get pods -n <namespace> --show-labels
# 测试服务连通性
kubectl run test --image=busybox --rm -it -- wget -qO- <svc-name>:<port>📌 关于
--show-labels参数的解释
--show-labels用于在输出中显示资源的标签信息。使用场景:
- 检查 Service 的 selector 与 Pod 标签是否匹配
- 查看资源的所有标签
- 排查标签选择器问题
对比
-l参数:
参数 作用 --show-labels显示资源的标签(输出更宽) -l按标签筛选资源 示例:
bash# 显示所有 Pod 的标签 kubectl get pods --show-labels # 筛选并显示标签 kubectl get pods -l app=nginx --show-labels
常见原因:
- selector 与 Pod 标签不匹配
- Pod 未就绪
- 端口配置错误
- 网络策略阻止
场景4:节点 NotReady
排查步骤:
bash
# 查看节点状态
kubectl describe node <node-name>
# 查看 kubelet 状态
systemctl status kubelet
# 查看 kubelet 日志
journalctl -u kubelet -f
# 查看容器运行时状态
systemctl status containerd # 或 docker常见原因:
- kubelet 服务异常
- 容器运行时异常
- 网络不通
- 磁盘满
故障排查工具
bash
# 查看资源使用
kubectl top nodes
kubectl top pods -n <namespace>
# 查看事件
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
# 进入容器调试
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh
# 创建临时调试 Pod
kubectl run debug --image=busybox --rm -it -- /bin/sh
kubectl run debug --image=nicolaka/netshoot --rm -it -- /bin/bash # 网络调试实战任务
完成以下任务巩固所学知识:
配置资源配额
- 为
cloud-coffee命名空间创建 ResourceQuota - 限制 CPU 请求不超过 5 核,内存请求不超过 10Gi
- 部署应用验证配额效果
- 为
分析审计日志
- 启用审计日志
- 执行一些操作(创建/删除资源)
- 在审计日志中查找这些操作记录
故障排查练习
- 故意创建一个资源请求过大的 Pod
- 观察 Pod 状态
- 分析原因并解决
课程总结
本阶段学习了 K8S 生产运维的核心技能:
| 内容 | 作用 | 生产环境重要性 |
|---|---|---|
| 资源配额 | 控制资源使用 | 高 |
| 审计日志 | 满足合规要求 | 中高 |
| 证书管理 | 保证服务安全 | 高 |
| 故障排查 | 快速恢复服务 | 高 |
下一步学习:高级发布策略