Skip to content

第七部分 运维自动化与平台化

自动化是运维工程师的核心能力。本部分讲解如何使用 Shell、Python、Go 编写自动化脚本,以及如何建设自动巡检、批量变更、资源回收、弹性伸缩、成本统计、故障自愈和 Runbook 等平台化能力。


第 25 章 运维自动化基础

25.1 为什么要自动化

  • 减少重复劳动
  • 降低人为错误
  • 提高响应速度
  • 提升可审计性
  • 支持大规模运维

25.2 自动化原则

  • 幂等性:多次执行结果一致
  • 可观测:每个操作都有日志和结果反馈
  • 可回滚:失败时能够恢复
  • 最小权限:只执行必要的操作
  • 可审计:操作记录可追溯

25.3 自动化层级

层级说明例子
脚本级单个脚本完成特定任务备份脚本、清理脚本
工具级可复用的工具CLI 工具、Operator
平台级完整的运维平台自动化运维平台、SRE 平台

25.4 版本控制

所有脚本和配置都应该使用 Git 管理。

bash
# 初始化仓库
git init

# 添加文件
git add .

# 提交
git commit -m "feat: add k8s inspection script"

# 查看历史
git log --oneline

25.5 本章练习

  1. 创建一个 Git 仓库管理你的运维脚本。
  2. 思考你日常工作中可以自动化的 3 个任务。
  3. 解释幂等性和可回滚的重要性。

第 26 章 Shell/Python/Go 脚本开发

26.1 Shell 脚本

Shell 脚本是运维自动化的基础。

bash
#!/bin/bash
# backup_etcd.sh

set -euo pipefail

BACKUP_DIR="/backup/etcd"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/etcd-${DATE}.db"

mkdir -p "${BACKUP_DIR}"

# 使用 etcdctl 备份
ETCDCTL_API=3 etcdctl snapshot save "${BACKUP_FILE}" \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# 保留最近 7 天备份
find "${BACKUP_DIR}" -type f -mtime +7 -delete

echo "Backup completed: ${BACKUP_FILE}"

26.2 Python 脚本

Python 适合处理复杂逻辑和 API 调用。

python
#!/usr/bin/env python3
# check_pods.py

from kubernetes import client, config

def main():
    config.load_kube_config()
    v1 = client.CoreV1Api()
    
    print("=== 异常 Pod 检查 ===")
    pods = v1.list_pod_for_all_namespaces(watch=False)
    for pod in pods.items:
        if pod.status.phase not in ['Running', 'Succeeded']:
            print(f"[{pod.metadata.namespace}] {pod.metadata.name}: {pod.status.phase}")
            
        # 检查重启次数
        if pod.status.container_statuses:
            for cs in pod.status.container_statuses:
                if cs.restart_count > 5:
                    print(f"[WARN] {pod.metadata.namespace}/{pod.metadata.name} "
                          f"container {cs.name} restarted {cs.restart_count} times")

if __name__ == '__main__':
    main()

安装依赖:

bash
pip install kubernetes

26.3 Go 脚本/工具

Go 适合构建高性能运维工具。

go
// main.go - 简单的 K8s Pod 检查工具
package main

import (
    "context"
    "fmt"
    "os"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    kubeconfig := os.Getenv("HOME") + "/.kube/config"
    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
    if err != nil {
        panic(err)
    }

    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err)
    }

    pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        panic(err)
    }

    fmt.Printf("Total pods: %d\n", len(pods.Items))
    for _, pod := range pods.Items {
        if pod.Status.Phase != "Running" && pod.Status.Phase != "Succeeded" {
            fmt.Printf("[%s] %s: %s\n", pod.Namespace, pod.Name, pod.Status.Phase)
        }
    }
}
bash
go mod init k8s-tool
go get k8s.io/client-go@v0.30.0
go run main.go

26.4 脚本管理最佳实践

  • 使用统一的目录结构
  • 脚本添加帮助信息和参数校验
  • 使用日志库记录操作
  • 配置文件与脚本分离
  • 错误处理完善

26.5 本章实验

实验 26-1:编写 Pod 清理脚本

bash
#!/bin/bash
# cleanup_failed_pods.sh

set -euo pipefail

NAMESPACE=${1:-default}

echo "Cleaning up failed pods in namespace: ${NAMESPACE}"

kubectl get pods -n "${NAMESPACE}" --field-selector=status.phase=Failed \
  -o jsonpath='{.items[*].metadata.name}' | \
  tr ' ' '\n' | \
  while read -r pod; do
    if [ -n "$pod" ]; then
      kubectl delete pod "$pod" -n "${NAMESPACE}"
    fi
  done

echo "Cleanup completed"

26.6 本章练习

  1. 编写一个 Shell 脚本,批量检查多个节点的磁盘空间。
  2. 使用 Python 脚本获取所有 Deployment 的副本数并输出。
  3. 使用 Go 编写一个查询 K8s 节点信息的工具。
  4. 为你的脚本添加命令行参数和错误处理。

第 27 章 自动巡检与批量变更

27.1 自动巡检设计

巡检内容应覆盖:

  • 系统层面:CPU、内存、磁盘、网络
  • K8s 层面:节点、Pod、事件、证书
  • 应用层面:服务可用性、错误率
  • 安全层面:权限、证书、漏洞

27.2 巡检脚本示例

bash
#!/bin/bash
# daily_inspection.sh

REPORT_FILE="/var/log/k8s-inspection-$(date +%Y%m%d).log"

echo "===== K8s 每日巡检 $(date) =====" | tee -a "${REPORT_FILE}"

echo "--- 节点状态 ---" | tee -a "${REPORT_FILE}"
kubectl get nodes -o wide | tee -a "${REPORT_FILE}"

echo "--- 异常 Pod ---" | tee -a "${REPORT_FILE}"
kubectl get pods -A --field-selector=status.phase!=Running | tee -a "${REPORT_FILE}"

echo "--- 资源使用 Top 10 ---" | tee -a "${REPORT_FILE}"
kubectl top pods -A --sort-by=cpu | head -10 | tee -a "${REPORT_FILE}"

echo "--- 最近警告事件 ---" | tee -a "${REPORT_FILE}"
kubectl get events -A --field-selector type=Warning --sort-by='.lastTimestamp' | tail -20 | tee -a "${REPORT_FILE}"

echo "--- 证书过期检查 ---" | tee -a "${REPORT_FILE}"
kubeadm certs check-expiration 2>/dev/null | tee -a "${REPORT_FILE}"

echo "巡检完成,报告保存在: ${REPORT_FILE}"

27.3 批量变更

批量变更需谨慎,建议:

  • 先在小范围验证
  • 使用灰度发布
  • 记录变更内容
  • 准备回滚方案
bash
#!/bin/bash
# batch_update_image.sh
# 批量更新多个 Deployment 的镜像

NEW_TAG=${1:-"v2.0"}
DEPLOYMENTS=("app1" "app2" "app3")
NAMESPACE="default"

for deploy in "${DEPLOYMENTS[@]}"; do
    echo "Updating ${deploy} to tag ${NEW_TAG}"
    kubectl set image deployment/${deploy} "${deploy}"=${deploy}:${NEW_TAG} -n "${NAMESPACE}"
    kubectl rollout status deployment/${deploy} -n "${NAMESPACE}"
done

27.4 本章练习

  1. 设计一个完整的 K8s 巡检 checklist。
  2. 编写一个定时巡检脚本并加入 cron。
  3. 编写一个批量更新镜像的脚本,要求支持灰度(先更新一个,观察后再继续)。

第 28 章 弹性伸缩与成本优化

28.1 弹性伸缩体系

层次工具触发条件
Pod 水平伸缩HPACPU/内存/自定义指标
Pod 垂直伸缩VPA历史资源使用
节点伸缩Cluster AutoscalerPod 无法调度
定时伸缩CronHPA/KEDA时间 schedule

28.2 KEDA

KEDA(Kubernetes Event-driven Autoscaling)是基于事件驱动的自动伸缩组件。

支持的事件源:

  • Kafka 消息队列长度
  • RabbitMQ 队列长度
  • Prometheus 指标
  • Cron 定时
yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-scaledobject
spec:
  scaleTargetRef:
    name: consumer
  triggers:
  - type: kafka
    metadata:
      bootstrapServers: kafka:9092
      consumerGroup: my-group
      topic: orders
      lagThreshold: "100"
  minReplicaCount: 1
  maxReplicaCount: 10

28.3 成本统计

成本优化方向:

  • 资源请求合理化
  • 使用 Spot 实例
  • 回收闲置资源
  • 按团队/项目打标签分摊成本
  • 使用 Kubecost 等成本分析工具
bash
# 查看所有命名空间资源请求总和
kubectl get pods -A -o json | \
  jq -r '.items[] | "\(.metadata.namespace) \(.spec.containers[].resources.requests.cpu // "0") \(.spec.containers[].resources.requests.memory // "0")"'

28.4 本章练习

  1. 为一个消费者应用配置基于 Kafka 队列长度的 KEDA 伸缩。
  2. 使用标签统计各团队的资源使用。
  3. 找出集群中 CPU/内存请求较低但实际使用较高的 Pod。

第 29 章 故障自愈与 Runbook

29.1 故障自愈

故障自愈是指系统自动检测并修复常见问题,减少人工干预。

常见自愈场景:

  • Pod 异常自动重启(K8s 自带)
  • 节点异常自动隔离和替换
  • 服务异常自动切换流量
  • 证书过期自动续期(cert-manager)
  • 磁盘满自动清理日志

29.2 Kubernetes Operator

Operator 是一种用于自动化复杂应用运维的模式。

常见 Operator:

  • cert-manager:证书管理
  • prometheus-operator:监控管理
  • rook-ceph:存储管理
  • etcd-operator:etcd 集群管理

29.3 Runbook

Runbook 是标准化的操作手册,描述如何处理特定故障。

一个好的 Runbook 应包含:

  • 故障现象
  • 影响范围评估
  • 排查步骤
  • 修复步骤
  • 验证步骤
  • 升级路径
  • 相关人员和联系方式

29.4 Runbook 示例模板

markdown
# Runbook:Pod 处于 CrashLoopBackOff

## 现象
Pod 状态为 CrashLoopBackOff,应用无法提供服务。

## 影响范围
- 服务可用性下降
- 可能影响用户体验

## 排查步骤
1. `kubectl get pods` 确认状态
2. `kubectl describe pod <pod>` 查看事件
3. `kubectl logs <pod> --previous` 查看上次崩溃日志
4. 检查 ConfigMap/Secret 配置
5. 检查依赖服务是否可用

## 修复步骤
- 配置错误:修正 ConfigMap/Secret 后重启 Pod
- 依赖不可用:恢复依赖服务
- 代码 Bug:回滚到上一个稳定版本

## 验证
- Pod 状态变为 Running
- 服务响应正常
- 监控无异常告警

## 升级
- 如 15 分钟内无法解决,升级至开发团队负责人

29.5 本章练习

  1. 安装 cert-manager,为一个 Ingress 配置自动 HTTPS 证书续期。
  2. 编写 3 个常见 K8s 故障的 Runbook。
  3. 设计一个自动清理日志的脚本,防止磁盘满。

第七部分总结

完成本阶段学习后,你应该能够:

  • 使用 Shell/Python/Go 编写运维脚本
  • 建立自动巡检体系
  • 安全执行批量变更
  • 配置 HPA/VPA/KEDA/Cluster Autoscaler 弹性伸缩
  • 使用 Operator 实现故障自愈
  • 编写标准化 Runbook

进入下一阶段:AI Agent 辅助运维