# K3s集群部署幂等性测试指南 ## 概述 本文档提供K3s集群部署幂等性的测试方法和验证标准。幂等性是指脚本可以重复执行多次,每次都会产生相同的结果,不会破坏现有配置或产生错误。 ## 为什么需要幂等性? 在生产环境中,幂等性至关重要: 1. **可靠性**: 部署失败后可以安全地重试 2. **可维护性**: 配置更新可以通过重新运行脚本完成 3. **可移植性**: 重装系统后可以完全自动化重新部署 4. **一致性**: 确保多次部署产生相同的结果 ## 幂等性测试方法 ### 方法1: 自动化测试(推荐) 使用提供的测试脚本自动验证幂等性: ```bash ./scripts/test-idempotency.sh ``` **测试内容**: 1. 捕获初始集群状态 2. 重复执行部署脚本 3. 比较部署前后状态 4. 验证服务健康 5. 测试单个脚本幂等性 **预期结果**: - 所有测试通过 ✓ - 部署前后状态一致(除了时间戳等元数据) - 所有服务保持健康 ### 方法2: 手动测试 #### 步骤1: 首次部署 ```bash # 记录开始时间 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: 重复部署 ```bash # 记录开始时间 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: 比较状态 ```bash # 比较资源列表(应该完全一致) 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: 压力测试 连续多次执行部署脚本,验证稳定性: ```bash # 连续执行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 -` - 添加资源存在性检查 **示例**: ```bash # 错误方式 kubectl create namespace argocd # 正确方式 kubectl create namespace argocd --dry-run=client -o yaml | kubectl apply -f - ``` ### 问题2: 工具重复安装 **症状**: ``` Package already installed ``` **解决方案**: - 安装前检查工具是否已存在 - 使用 `command -v` 检查命令可用性 **示例**: ```bash # 检查后安装 if ! command -v yq &> /dev/null; then sudo wget -qO /usr/local/bin/yq https://... fi ``` ### 问题3: 配置覆盖导致数据丢失 **症状**: - 密码被重置 - 配置被覆盖 - 数据丢失 **解决方案**: - 使用 `kubectl patch` 而不是完全替换 - 检查资源是否已存在 - 使用 `--dry-run` 预览变更 **示例**: ```bash # 使用patch更新密码 kubectl -n argocd patch secret argocd-secret \ -p '{"stringData": {"admin.password": "..."}}' ``` ### 问题4: 网络下载失败 **症状**: ``` Failed to download: Connection timeout ``` **解决方案**: - 添加重试机制 - 使用本地缓存 - 提供离线安装选项 **示例**: ```bash # 重试下载 for attempt in 1 2 3; do if curl -fsSL "$URL" -o "$OUTPUT"; then break fi sleep 5 done ``` ### 问题5: 状态检查不完善 **症状**: - 后续步骤因前置条件不满足而失败 - 资源未就绪就继续执行 **解决方案**: - 使用 `kubectl wait` 等待资源就绪 - 添加健康检查 - 设置合理的超时时间 **示例**: ```bash # 等待部署就绪 kubectl wait --for=condition=available \ --timeout=600s \ deployment/argocd-server -n argocd ``` ## 幂等性最佳实践 ### 1. 使用声明式API ```bash # 推荐: 声明式 kubectl apply -f manifest.yaml # 不推荐: 命令式 kubectl create -f manifest.yaml ``` ### 2. 检查资源存在性 ```bash # 检查命名空间 if kubectl get namespace argocd &>/dev/null; then echo "Namespace already exists" else kubectl create namespace argocd fi ``` ### 3. 使用幂等的包管理器 ```bash # Helm自动处理幂等性 helm upgrade --install gitea gitea-charts/gitea \ --namespace gitea \ --values values.yaml ``` ### 4. 记录部署状态 ```bash # 记录已完成的步骤 mark_step_completed() { echo "$1" >> .deployment-state } # 检查步骤是否已完成 is_step_completed() { grep -q "^$1$" .deployment-state 2>/dev/null } ``` ### 5. 添加重试机制 ```bash # 通用重试函数 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. 详细的日志记录 ```bash # 记录所有操作 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分钟 - **原因**: 大部分步骤被跳过 ### 断点续传 - **预期时间**: 取决于中断位置 - **优势**: 无需从头开始 ## 故障排查 ### 查看部署日志 ```bash # 查看完整日志 cat deployment.log # 查看最近的错误 grep ERROR deployment.log | tail -20 # 实时查看日志 tail -f deployment.log ``` ### 查看部署状态 ```bash # 查看已完成的步骤 cat .deployment-state # 重置部署状态 ./scripts/deploy-all.sh --reset ``` ### 手动验证 ```bash # 验证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. ✅ 详细的日志和错误处理 通过本文档的测试方法,可以验证部署的幂等性,确保在重装系统后能够完全自动化部署,无需手动调试。