464 lines
8.9 KiB
Markdown
464 lines
8.9 KiB
Markdown
# 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. ✅ 详细的日志和错误处理
|
||
|
||
通过本文档的测试方法,可以验证部署的幂等性,确保在重装系统后能够完全自动化部署,无需手动调试。
|