跳转到内容

生产运维

业务场景

云咖啡公司的 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-coffee

LimitRange: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.crtAPI Server 证书
apiserver-kubelet-client.crtAPI Server 访问 Kubelet 的证书
front-proxy-ca.crt前端代理根证书
etcd/ca.crtetcd 根证书
etcd/server.crtetcd 服务端证书

查看证书有效期

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  # 网络调试

实战任务

完成以下任务巩固所学知识:

  1. 配置资源配额

    • cloud-coffee 命名空间创建 ResourceQuota
    • 限制 CPU 请求不超过 5 核,内存请求不超过 10Gi
    • 部署应用验证配额效果
  2. 分析审计日志

    • 启用审计日志
    • 执行一些操作(创建/删除资源)
    • 在审计日志中查找这些操作记录
  3. 故障排查练习

    • 故意创建一个资源请求过大的 Pod
    • 观察 Pod 状态
    • 分析原因并解决

课程总结

本阶段学习了 K8S 生产运维的核心技能:

内容作用生产环境重要性
资源配额控制资源使用
审计日志满足合规要求中高
证书管理保证服务安全
故障排查快速恢复服务

下一步学习高级发布策略

评论区

专业的Linux技术学习平台,从入门到精通的完整学习路径