Files
k3s_auto_deploy/IDEMPOTENCY-TEST.md

8.9 KiB
Raw Blame History

K3s集群部署幂等性测试指南

概述

本文档提供K3s集群部署幂等性的测试方法和验证标准。幂等性是指脚本可以重复执行多次每次都会产生相同的结果不会破坏现有配置或产生错误。

为什么需要幂等性?

在生产环境中,幂等性至关重要:

  1. 可靠性: 部署失败后可以安全地重试
  2. 可维护性: 配置更新可以通过重新运行脚本完成
  3. 可移植性: 重装系统后可以完全自动化重新部署
  4. 一致性: 确保多次部署产生相同的结果

幂等性测试方法

方法1: 自动化测试(推荐)

使用提供的测试脚本自动验证幂等性:

./scripts/test-idempotency.sh

测试内容:

  1. 捕获初始集群状态
  2. 重复执行部署脚本
  3. 比较部署前后状态
  4. 验证服务健康
  5. 测试单个脚本幂等性

预期结果:

  • 所有测试通过 ✓
  • 部署前后状态一致(除了时间戳等元数据)
  • 所有服务保持健康

方法2: 手动测试

步骤1: 首次部署

# 记录开始时间
date

# 执行部署
./scripts/deploy-all.sh

# 验证部署
./scripts/verify-deployment.sh

# 记录集群状态
kubectl get all -A > /tmp/state-1.txt
kubectl get nodes -o yaml > /tmp/nodes-1.yaml

步骤2: 重复部署

# 记录开始时间
date

# 再次执行部署
./scripts/deploy-all.sh

# 验证部署
./scripts/verify-deployment.sh

# 记录集群状态
kubectl get all -A > /tmp/state-2.txt
kubectl get nodes -o yaml > /tmp/nodes-2.yaml

步骤3: 比较状态

# 比较资源列表(应该完全一致)
diff /tmp/state-1.txt /tmp/state-2.txt

# 比较节点状态(忽略时间戳)
diff <(grep -v "creationTimestamp\|resourceVersion\|uid" /tmp/nodes-1.yaml) \
     <(grep -v "creationTimestamp\|resourceVersion\|uid" /tmp/nodes-2.yaml)

预期结果:

  • 资源列表完全一致
  • 节点状态一致(除了元数据)
  • 无新增或删除的资源

方法3: 压力测试

连续多次执行部署脚本,验证稳定性:

# 连续执行5次
for i in {1..5}; do
    echo "=== 第 $i 次执行 ==="
    ./scripts/deploy-all.sh
    ./scripts/verify-deployment.sh
    echo ""
done

预期结果:

  • 所有执行都成功
  • 无错误或警告
  • 服务始终保持健康

幂等性验证清单

基础验证

  • 脚本可以重复执行而不报错
  • 重复执行不会创建重复资源
  • 重复执行不会删除现有资源
  • 重复执行不会修改不应该修改的配置

K3s集群验证

  • 节点数量保持不变
  • 节点状态保持Ready
  • 系统Pod数量和状态不变
  • kubectl配置保持有效

Gitea验证

  • Gitea命名空间存在
  • Gitea部署状态不变
  • Gitea Pod数量和状态不变
  • Gitea服务配置不变
  • Gitea组织和仓库保持不变
  • Gitea用户和权限保持不变

ArgoCD验证

  • ArgoCD命名空间存在
  • ArgoCD所有组件运行正常
  • ArgoCD admin密码保持不变
  • ArgoCD Application配置不变
  • ArgoCD与Gitea连接正常

HTTPS证书验证

  • cert-manager正常运行
  • ClusterIssuer状态Ready
  • Certificate状态Ready
  • Ingress配置正确
  • HTTPS访问正常

存储验证

  • PV数量和状态不变
  • PVC数量和状态不变
  • 数据未丢失

常见幂等性问题及解决方案

问题1: 重复创建资源导致冲突

症状:

Error: resource already exists

解决方案:

  • 使用 kubectl apply 而不是 kubectl create
  • 使用 --dry-run=client -o yaml | kubectl apply -f -
  • 添加资源存在性检查

示例:

# 错误方式
kubectl create namespace argocd

# 正确方式
kubectl create namespace argocd --dry-run=client -o yaml | kubectl apply -f -

问题2: 工具重复安装

症状:

Package already installed

解决方案:

  • 安装前检查工具是否已存在
  • 使用 command -v 检查命令可用性

示例:

# 检查后安装
if ! command -v yq &> /dev/null; then
    sudo wget -qO /usr/local/bin/yq https://...
fi

问题3: 配置覆盖导致数据丢失

症状:

  • 密码被重置
  • 配置被覆盖
  • 数据丢失

解决方案:

  • 使用 kubectl patch 而不是完全替换
  • 检查资源是否已存在
  • 使用 --dry-run 预览变更

示例:

# 使用patch更新密码
kubectl -n argocd patch secret argocd-secret \
  -p '{"stringData": {"admin.password": "..."}}'

问题4: 网络下载失败

症状:

Failed to download: Connection timeout

解决方案:

  • 添加重试机制
  • 使用本地缓存
  • 提供离线安装选项

示例:

# 重试下载
for attempt in 1 2 3; do
    if curl -fsSL "$URL" -o "$OUTPUT"; then
        break
    fi
    sleep 5
done

问题5: 状态检查不完善

症状:

  • 后续步骤因前置条件不满足而失败
  • 资源未就绪就继续执行

解决方案:

  • 使用 kubectl wait 等待资源就绪
  • 添加健康检查
  • 设置合理的超时时间

示例:

# 等待部署就绪
kubectl wait --for=condition=available \
  --timeout=600s \
  deployment/argocd-server -n argocd

幂等性最佳实践

1. 使用声明式API

# 推荐: 声明式
kubectl apply -f manifest.yaml

# 不推荐: 命令式
kubectl create -f manifest.yaml

2. 检查资源存在性

# 检查命名空间
if kubectl get namespace argocd &>/dev/null; then
    echo "Namespace already exists"
else
    kubectl create namespace argocd
fi

3. 使用幂等的包管理器

# Helm自动处理幂等性
helm upgrade --install gitea gitea-charts/gitea \
  --namespace gitea \
  --values values.yaml

4. 记录部署状态

# 记录已完成的步骤
mark_step_completed() {
    echo "$1" >> .deployment-state
}

# 检查步骤是否已完成
is_step_completed() {
    grep -q "^$1$" .deployment-state 2>/dev/null
}

5. 添加重试机制

# 通用重试函数
retry() {
    local max_attempts=$1
    local delay=$2
    shift 2
    local cmd="$@"

    for attempt in $(seq 1 $max_attempts); do
        if eval "$cmd"; then
            return 0
        fi
        sleep $delay
    done
    return 1
}

6. 详细的日志记录

# 记录所有操作
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a deployment.log
}

测试场景

场景1: 全新部署

目的: 验证首次部署的完整性

步骤:

  1. 准备全新的VPS环境
  2. 配置SSH访问
  3. 运行 ./scripts/deploy-all.sh
  4. 验证所有服务

预期结果: 所有服务正常运行

场景2: 重复部署

目的: 验证幂等性

步骤:

  1. 在已部署的环境上再次运行 ./scripts/deploy-all.sh
  2. 比较部署前后状态

预期结果: 状态完全一致,无错误

场景3: 断点续传

目的: 验证失败恢复能力

步骤:

  1. 在部署中途中断Ctrl+C
  2. 再次运行 ./scripts/deploy-all.sh

预期结果: 从中断处继续,最终部署成功

场景4: 配置更新

目的: 验证配置变更的幂等性

步骤:

  1. 修改 config/cluster-vars.yml 中的某些配置
  2. 运行 ./scripts/deploy-all.sh
  3. 验证配置已更新

预期结果: 配置正确更新,其他部分不变

场景5: 网络故障恢复

目的: 验证网络问题的处理

步骤:

  1. 模拟网络故障(断网或限速)
  2. 运行 ./scripts/deploy-all.sh
  3. 恢复网络后重试

预期结果: 自动重试成功

性能基准

首次部署

  • 预期时间: 15-30分钟
  • 关键步骤:
    • K3s安装: 5-10分钟
    • Gitea部署: 3-5分钟
    • ArgoCD部署: 3-5分钟
    • HTTPS配置: 2-5分钟

重复部署

  • 预期时间: 1-3分钟
  • 原因: 大部分步骤被跳过

断点续传

  • 预期时间: 取决于中断位置
  • 优势: 无需从头开始

故障排查

查看部署日志

# 查看完整日志
cat deployment.log

# 查看最近的错误
grep ERROR deployment.log | tail -20

# 实时查看日志
tail -f deployment.log

查看部署状态

# 查看已完成的步骤
cat .deployment-state

# 重置部署状态
./scripts/deploy-all.sh --reset

手动验证

# 验证K3s
kubectl get nodes
kubectl get pods -A

# 验证Gitea
kubectl get pods -n gitea
kubectl logs -n gitea -l app.kubernetes.io/name=gitea

# 验证ArgoCD
kubectl get pods -n argocd
kubectl get application -n argocd

总结

幂等性是生产级部署的关键特性。本项目通过以下方式实现完全幂等:

  1. 统一的部署编排脚本
  2. 状态持久化和断点续传
  3. 自动工具检查和安装
  4. 网络下载重试机制
  5. 声明式资源管理
  6. 详细的日志和错误处理

通过本文档的测试方法,可以验证部署的幂等性,确保在重装系统后能够完全自动化部署,无需手动调试。