diff --git a/.gitea/workflows/quick-test.yml b/.gitea/workflows/quick-test.yml new file mode 100644 index 0000000..b7d9993 --- /dev/null +++ b/.gitea/workflows/quick-test.yml @@ -0,0 +1,169 @@ +name: 快速测试 Setup Environment + +on: + workflow_dispatch: + inputs: + quick_test_type: + description: '选择快速测试类型' + required: true + default: 'smoke' + type: choice + options: + - smoke # 烟雾测试 - 最基本功能 + - docker # Docker 功能测试 + - network # 网络连接测试 + +jobs: + smoke-test: + if: ${{ inputs.quick_test_type == 'smoke' }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 烟雾测试 - 基本功能验证 + id: smoke + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + cache-key: 'smoke-test' + + - name: 验证核心功能 + run: | + echo "🚀 烟雾测试开始..." + + # 验证 Docker + docker --version || exit 1 + echo "✅ Docker 可用" + + # 验证 kubectl + kubectl version --client || exit 1 + echo "✅ kubectl 可用" + + # 验证 Git 配置 + [[ "$(git config --global user.name)" == "GiteaActions" ]] || exit 1 + echo "✅ Git 配置正确" + + # 验证输出 + echo "缓存状态: ${{ steps.smoke.outputs.cache-hit }}" + echo "Docker 版本: ${{ steps.smoke.outputs.docker-version }}" + echo "kubectl 版本: ${{ steps.smoke.outputs.kubectl-version }}" + + echo "🎉 烟雾测试通过!" + + docker-test: + if: ${{ inputs.quick_test_type == 'docker' }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: Docker 功能测试 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + skip-kubectl: 'true' + cache-key: 'docker-test' + + - name: 测试 Docker 完整功能 + run: | + echo "🐳 Docker 功能测试..." + + # 基本 Docker 命令 + docker info + docker version + + # 测试镜像拉取 + docker pull alpine:latest + echo "✅ 镜像拉取成功" + + # 测试容器运行 + docker run --rm alpine:latest echo "容器运行测试" + echo "✅ 容器运行成功" + + # 测试 Docker Compose + docker compose version + echo "✅ Docker Compose 可用" + + # 测试 Buildx + docker buildx version + echo "✅ Docker Buildx 可用" + + echo "🎉 Docker 功能测试完成!" + + network-test: + if: ${{ inputs.quick_test_type == 'network' }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 网络连接测试配置 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + use-aliyun-mirror: 'true' + cache-key: 'network-test' + + - name: 测试网络连接 + run: | + echo "🌐 网络连接测试..." + + # 测试基本网络连通性 + echo "测试 GitHub 连接..." + curl -I https://github.com --connect-timeout 10 || echo "❌ GitHub 连接失败" + + echo "测试阿里云镜像源..." + curl -I https://mirrors.aliyun.com --connect-timeout 10 || echo "❌ 阿里云连接失败" + + echo "测试 Docker Hub..." + curl -I https://hub.docker.com --connect-timeout 10 || echo "❌ Docker Hub 连接失败" + + echo "测试私有仓库..." + curl -I https://docker-registry.bjxgj.com/v2/ --connect-timeout 10 || echo "❌ 私有仓库连接失败" + + # 测试 DNS 解析 + echo "测试 DNS 解析..." + nslookup github.com || echo "❌ DNS 解析失败" + + # 测试 Docker 镜像拉取 + echo "测试 Docker 镜像拉取..." + docker pull alpine:latest && echo "✅ Alpine 镜像拉取成功" || echo "❌ 镜像拉取失败" + + echo "🎉 网络测试完成!" + + quick-summary: + needs: [smoke-test, docker-test, network-test] + if: always() + runs-on: ubuntu-node-20 + steps: + - name: 快速测试总结 + run: | + echo "## ⚡ 快速测试报告" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 测试类型: ${{ inputs.quick_test_type }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [[ "${{ needs.smoke-test.result }}" == "success" ]]; then + echo "✅ **烟雾测试通过** - 基本功能正常" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.smoke-test.result }}" == "failure" ]]; then + echo "❌ **烟雾测试失败** - 基本功能异常" >> $GITHUB_STEP_SUMMARY + fi + + if [[ "${{ needs.docker-test.result }}" == "success" ]]; then + echo "✅ **Docker 测试通过** - Docker 功能正常" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.docker-test.result }}" == "failure" ]]; then + echo "❌ **Docker 测试失败** - Docker 功能异常" >> $GITHUB_STEP_SUMMARY + fi + + if [[ "${{ needs.network-test.result }}" == "success" ]]; then + echo "✅ **网络测试通过** - 网络连接正常" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.network-test.result }}" == "failure" ]]; then + echo "❌ **网络测试失败** - 网络连接异常" >> $GITHUB_STEP_SUMMARY + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 下一步" >> $GITHUB_STEP_SUMMARY + echo "- 如果测试通过,可以在生产环境中使用" >> $GITHUB_STEP_SUMMARY + echo "- 如果测试失败,请检查错误日志和配置" >> $GITHUB_STEP_SUMMARY + echo "- 可以运行完整测试获取更多信息" >> $GITHUB_STEP_SUMMARY diff --git a/.gitea/workflows/test-setup-env.yml b/.gitea/workflows/test-setup-env.yml new file mode 100644 index 0000000..9ba55c3 --- /dev/null +++ b/.gitea/workflows/test-setup-env.yml @@ -0,0 +1,354 @@ +name: 测试 Setup Environment Action + +on: + workflow_dispatch: + inputs: + test_scope: + description: '选择测试范围' + required: true + default: 'basic' + type: choice + options: + - basic + - docker-only + - kubectl-only + - full + - debug + use_aliyun_mirror: + description: '使用阿里云镜像源' + required: false + default: true + type: boolean + test_kubectl: + description: '测试 kubectl 功能' + required: false + default: false + type: boolean + +env: + TEST_REGISTRY: docker-registry.bjxgj.com + TEST_IMAGE: test-setup-env + +jobs: + # 基础测试 - 最小配置 + test-basic: + if: ${{ inputs.test_scope == 'basic' || inputs.test_scope == 'full' }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 基础环境配置测试 + id: setup-basic + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + use-aliyun-mirror: ${{ inputs.use_aliyun_mirror }} + cache-key: 'test-basic-${{ github.run_id }}' + + - name: 验证基础配置 + run: | + echo "🔍 验证基础配置结果..." + echo "缓存命中: ${{ steps.setup-basic.outputs.cache-hit }}" + echo "Docker 版本: ${{ steps.setup-basic.outputs.docker-version }}" + echo "kubectl 版本: ${{ steps.setup-basic.outputs.kubectl-version }}" + + # 验证 Docker 是否可用 + if command -v docker &> /dev/null; then + echo "✅ Docker 已安装: $(docker --version)" + docker info | head -10 + else + echo "❌ Docker 未安装" + exit 1 + fi + + # 验证 Git 配置 + echo "Git 用户: $(git config --global user.name)" + echo "Git 邮箱: $(git config --global user.email)" + + - name: 测试 Docker 功能 + run: | + echo "🐳 测试 Docker 功能..." + + # 创建测试 Dockerfile + cat > Dockerfile.test << 'EOF' + FROM alpine:latest + RUN echo "Setup Environment Action Test" > /test.txt + CMD cat /test.txt + EOF + + # 构建测试镜像 + docker build -f Dockerfile.test -t ${{ env.TEST_IMAGE }}:test . + + # 运行测试容器 + docker run --rm ${{ env.TEST_IMAGE }}:test + + echo "✅ Docker 功能测试通过" + + # Docker 专项测试 + test-docker-only: + if: ${{ inputs.test_scope == 'docker-only' || inputs.test_scope == 'full' }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: Docker 专项配置 + id: setup-docker + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + skip-kubectl: 'true' + use-aliyun-mirror: ${{ inputs.use_aliyun_mirror }} + cache-key: 'test-docker-${{ github.run_id }}' + + - name: 验证 Docker 专项配置 + run: | + echo "🐳 验证 Docker 专项配置..." + + # 检查 kubectl 是否被跳过 + if command -v kubectl &> /dev/null; then + echo "⚠️ kubectl 应该被跳过但仍然存在" + else + echo "✅ kubectl 正确跳过" + fi + + # 验证 Docker 功能 + docker version + docker info | grep -E "(Server Version|Storage Driver|Logging Driver)" + + - name: 测试 Docker Buildx 功能 + run: | + echo "🔧 测试 Docker Buildx 功能..." + docker buildx version + docker buildx ls + + # 创建多平台构建测试 + cat > Dockerfile.multiarch << 'EOF' + FROM --platform=$TARGETPLATFORM alpine:latest + RUN echo "Platform: $TARGETPLATFORM" > /platform.txt + CMD cat /platform.txt + EOF + + docker buildx build \ + --platform linux/amd64 \ + -f Dockerfile.multiarch \ + -t ${{ env.TEST_IMAGE }}:multiarch \ + --load \ + . + + docker run --rm ${{ env.TEST_IMAGE }}:multiarch + echo "✅ Docker Buildx 测试通过" + + # kubectl 专项测试 + test-kubectl-only: + if: ${{ (inputs.test_scope == 'kubectl-only' || inputs.test_scope == 'full') && inputs.test_kubectl }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: kubectl 专项配置 + id: setup-kubectl + uses: xgj/actions/setup-env@v1 + with: + kube-config: ${{ secrets.KUBE_CONFIG }} + skip-docker-login: 'true' + use-aliyun-mirror: ${{ inputs.use_aliyun_mirror }} + cache-key: 'test-kubectl-${{ github.run_id }}' + + - name: 验证 kubectl 配置 + run: | + echo "☸️ 验证 kubectl 配置..." + + if command -v kubectl &> /dev/null; then + echo "✅ kubectl 已安装: $(kubectl version --client --short 2>/dev/null || kubectl version --client)" + + # 验证配置文件 + if [[ -f ~/.kube/config ]]; then + echo "✅ kubectl 配置文件存在" + kubectl config view --minify + else + echo "❌ kubectl 配置文件不存在" + exit 1 + fi + + # 测试集群连接(如果配置了) + if [[ -n "${{ secrets.KUBE_CONFIG }}" ]]; then + echo "测试集群连接..." + kubectl cluster-info --request-timeout=10s || echo "⚠️ 集群连接失败或无权限" + fi + else + echo "❌ kubectl 未安装" + exit 1 + fi + + # 调试模式测试 + test-debug: + if: ${{ inputs.test_scope == 'debug' || inputs.test_scope == 'full' }} + runs-on: ubuntu-node-20 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 调试模式配置 + id: setup-debug + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG }} + use-aliyun-mirror: ${{ inputs.use_aliyun_mirror }} + cache-key: 'test-debug-${{ github.run_id }}' + env: + ACTIONS_STEP_DEBUG: true + ACTIONS_RUNNER_DEBUG: true + + - name: 系统信息收集 + run: | + echo "🔍 收集系统信息..." + + echo "=== 系统基本信息 ===" + uname -a + cat /etc/os-release + + echo -e "\n=== 已安装工具版本 ===" + echo "Docker: ${{ steps.setup-debug.outputs.docker-version }}" + echo "kubectl: ${{ steps.setup-debug.outputs.kubectl-version }}" + echo "Git: $(git --version)" + echo "Curl: $(curl --version | head -1)" + echo "GPG: $(gpg --version | head -1)" + + echo -e "\n=== 缓存信息 ===" + echo "Cache Hit: ${{ steps.setup-debug.outputs.cache-hit }}" + + echo -e "\n=== 网络测试 ===" + echo "测试外部连接..." + curl -I https://github.com --connect-timeout 5 || echo "GitHub 连接失败" + curl -I https://mirrors.aliyun.com --connect-timeout 5 || echo "阿里云连接失败" + curl -I ${{ env.TEST_REGISTRY }}/v2/ --connect-timeout 5 || echo "私有仓库连接失败" + + - name: 环境压力测试 + run: | + echo "🏋️ 环境压力测试..." + + # 并发 Docker 操作测试 + for i in {1..3}; do + ( + echo "启动并发任务 $i..." + docker run --rm alpine:latest echo "任务 $i 完成" + ) & + done + wait + echo "✅ 并发测试完成" + + # 磁盘空间检查 + echo -e "\n💾 磁盘空间:" + df -h / + + # 内存使用检查 + echo -e "\n🧠 内存使用:" + free -h + + # 缓存测试 + test-cache: + if: ${{ inputs.test_scope == 'full' }} + runs-on: ubuntu-node-20 + strategy: + matrix: + cache_test: [first-run, second-run] + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 缓存测试 - ${{ matrix.cache_test }} + id: setup-cache + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + cache-key: 'test-cache-shared' + use-aliyun-mirror: ${{ inputs.use_aliyun_mirror }} + + - name: 验证缓存行为 + run: | + echo "🗄️ 验证缓存行为 - ${{ matrix.cache_test }}..." + echo "Cache Hit: ${{ steps.setup-cache.outputs.cache-hit }}" + + if [[ "${{ matrix.cache_test }}" == "first-run" ]]; then + if [[ "${{ steps.setup-cache.outputs.cache-hit }}" == "true" ]]; then + echo "⚠️ 首次运行不应该命中缓存" + else + echo "✅ 首次运行正确未命中缓存" + fi + else + if [[ "${{ steps.setup-cache.outputs.cache-hit }}" == "true" ]]; then + echo "✅ 第二次运行正确命中缓存" + else + echo "⚠️ 第二次运行应该命中缓存" + fi + fi + + # 测试总结 + test-summary: + needs: [test-basic, test-docker-only, test-kubectl-only, test-debug, test-cache] + if: always() + runs-on: ubuntu-node-20 + steps: + - name: 生成测试报告 + run: | + echo "## 🧪 Setup Environment Action 测试报告" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 测试配置" >> $GITHUB_STEP_SUMMARY + echo "- **测试范围**: ${{ inputs.test_scope }}" >> $GITHUB_STEP_SUMMARY + echo "- **阿里云镜像**: ${{ inputs.use_aliyun_mirror }}" >> $GITHUB_STEP_SUMMARY + echo "- **kubectl 测试**: ${{ inputs.test_kubectl }}" >> $GITHUB_STEP_SUMMARY + echo "- **运行 ID**: ${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "### 测试结果" >> $GITHUB_STEP_SUMMARY + + # 检查各个任务的结果 + if [[ "${{ needs.test-basic.result }}" == "success" ]]; then + echo "- ✅ 基础测试: 通过" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.test-basic.result }}" == "skipped" ]]; then + echo "- ⏭️ 基础测试: 跳过" >> $GITHUB_STEP_SUMMARY + else + echo "- ❌ 基础测试: 失败" >> $GITHUB_STEP_SUMMARY + fi + + if [[ "${{ needs.test-docker-only.result }}" == "success" ]]; then + echo "- ✅ Docker 专项测试: 通过" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.test-docker-only.result }}" == "skipped" ]]; then + echo "- ⏭️ Docker 专项测试: 跳过" >> $GITHUB_STEP_SUMMARY + else + echo "- ❌ Docker 专项测试: 失败" >> $GITHUB_STEP_SUMMARY + fi + + if [[ "${{ needs.test-kubectl-only.result }}" == "success" ]]; then + echo "- ✅ kubectl 专项测试: 通过" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.test-kubectl-only.result }}" == "skipped" ]]; then + echo "- ⏭️ kubectl 专项测试: 跳过" >> $GITHUB_STEP_SUMMARY + else + echo "- ❌ kubectl 专项测试: 失败" >> $GITHUB_STEP_SUMMARY + fi + + if [[ "${{ needs.test-debug.result }}" == "success" ]]; then + echo "- ✅ 调试模式测试: 通过" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.test-debug.result }}" == "skipped" ]]; then + echo "- ⏭️ 调试模式测试: 跳过" >> $GITHUB_STEP_SUMMARY + else + echo "- ❌ 调试模式测试: 失败" >> $GITHUB_STEP_SUMMARY + fi + + if [[ "${{ needs.test-cache.result }}" == "success" ]]; then + echo "- ✅ 缓存测试: 通过" >> $GITHUB_STEP_SUMMARY + elif [[ "${{ needs.test-cache.result }}" == "skipped" ]]; then + echo "- ⏭️ 缓存测试: 跳过" >> $GITHUB_STEP_SUMMARY + else + echo "- ❌ 缓存测试: 失败" >> $GITHUB_STEP_SUMMARY + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 建议" >> $GITHUB_STEP_SUMMARY + echo "- 如果测试失败,请检查 secrets 配置" >> $GITHUB_STEP_SUMMARY + echo "- 可以通过调试模式获取更多信息" >> $GITHUB_STEP_SUMMARY + echo "- 确保运行器有足够的权限安装软件包" >> $GITHUB_STEP_SUMMARY diff --git a/setup-env/README.md b/setup-env/README.md new file mode 100644 index 0000000..53d56bf --- /dev/null +++ b/setup-env/README.md @@ -0,0 +1,199 @@ +# Setup Build Environment Action + +这是一个用于配置构建和部署环境的 GitHub Action,专门为 CI/CD 流水线设计。它能够自动安装和配置 Docker、kubectl 以及其他必要的构建工具。 + +## 🚀 特性 + +- ✅ 自动配置 Git 用户信息 +- 🐳 安装 Docker CLI 和相关插件 +- ☸️ 安装和配置 kubectl +- 🗄️ 智能缓存机制,提高构建速度 +- 🌏 支持阿里云镜像源,提升国内访问速度 +- 🔐 自动登录私有 Docker 仓库 +- 📋 详细的日志输出和错误处理 +- ⚡ 灵活的配置选项 + +## 📋 输入参数 + +| 参数名 | 描述 | 必填 | 默认值 | +| ------------------- | ------------------------------ | ---- | --------------------------- | +| `docker-registry` | Docker 私有仓库地址 | ❌ | `docker-registry.bjxgj.com` | +| `docker-username` | Docker 仓库用户名 | ❌ | `ci-action` | +| `docker-password` | Docker 仓库密码 | ✅ | - | +| `kube-config` | Base64 编码的 kubectl 配置文件 | ❌ | `''` | +| `cache-key` | 缓存键值 | ❌ | `setup-env` | +| `use-aliyun-mirror` | 是否使用阿里云镜像源 | ❌ | `true` | +| `git-user-name` | Git 用户名 | ❌ | `GiteaActions` | +| `git-user-email` | Git 用户邮箱 | ❌ | `actions@gitea.com` | +| `skip-kubectl` | 跳过 kubectl 安装和配置 | ❌ | `false` | +| `skip-docker-login` | 跳过 Docker 登录 | ❌ | `false` | + +## 📤 输出参数 + +| 参数名 | 描述 | +| ----------------- | ------------------- | +| `cache-hit` | 缓存是否命中 | +| `kubectl-version` | 安装的 kubectl 版本 | +| `docker-version` | 安装的 Docker 版本 | + +## 🏗️ 基本使用 + +### 最简配置 + +```yaml +- name: 配置构建环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} +``` + +### 完整配置 + +```yaml +- name: 配置构建环境 + uses: xgj/actions/setup-env@v1 + with: + docker-registry: "your-registry.com" + docker-username: "your-username" + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG }} + cache-key: "my-project-env" + use-aliyun-mirror: "true" + git-user-name: "CI Bot" + git-user-email: "ci@yourcompany.com" +``` + +### 仅 Docker 环境 + +```yaml +- name: 配置 Docker 环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + skip-kubectl: "true" +``` + +### 仅 kubectl 环境 + +```yaml +- name: 配置 Kubernetes 环境 + uses: xgj/actions/setup-env@v1 + with: + kube-config: ${{ secrets.KUBE_CONFIG }} + skip-docker-login: "true" +``` + +## 📝 完整工作流示例 + +```yaml +name: Build and Deploy +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置构建环境 + id: setup + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG }} + cache-key: "build-${{ github.sha }}" + + - name: 检查环境信息 + run: | + echo "缓存命中: ${{ steps.setup.outputs.cache-hit }}" + echo "Docker 版本: ${{ steps.setup.outputs.docker-version }}" + echo "kubectl 版本: ${{ steps.setup.outputs.kubectl-version }}" + + - name: 构建 Docker 镜像 + run: | + docker build -t my-app:latest . + + - name: 部署到 Kubernetes + run: | + kubectl apply -f k8s/ +``` + +## 🔧 高级配置 + +### 自定义缓存策略 + +```yaml +- name: 配置环境(自定义缓存) + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + cache-key: 'env-${{ matrix.os }}-${{ hashFiles("Dockerfile") }}' +``` + +### 多环境部署 + +```yaml +strategy: + matrix: + environment: [dev, staging, prod] +steps: + - name: 配置环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets[format('KUBE_CONFIG_{0}', matrix.environment)] }} + cache-key: "deploy-${{ matrix.environment }}" +``` + +## 🛠️ 故障排除 + +### 常见问题 + +1. **Docker 登录失败** + + - 检查 `docker-password` 是否正确设置 + - 确认 Docker 仓库地址和用户名 + +2. **kubectl 连接失败** + + - 验证 `kube-config` 是否正确的 Base64 编码 + - 检查集群网络连接 + +3. **缓存未命中** + - 检查 `cache-key` 配置 + - 确认文件哈希是否变化 + +### 调试模式 + +启用详细日志输出: + +```yaml +- name: 配置环境(调试模式) + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + env: + ACTIONS_STEP_DEBUG: true +``` + +## 📋 环境要求 + +- **操作系统**: Ubuntu 18.04+, Debian 10+ +- **权限**: 需要 sudo 权限安装软件包 +- **网络**: 需要访问外部软件包仓库 + +## 🔒 安全考虑 + +- 使用 GitHub Secrets 存储敏感信息 +- 定期更新依赖版本 +- 限制 kubectl 权限范围 +- 使用最小权限原则 + +## 🤝 贡献 + +欢迎提交 Issue 和 Pull Request! + +## 📄 许可证 + +MIT License diff --git a/setup-env/action.yml b/setup-env/action.yml new file mode 100644 index 0000000..a3733d6 --- /dev/null +++ b/setup-env/action.yml @@ -0,0 +1,174 @@ +name: 'Setup Build Environment' +description: '配置构建发布环境,包括 Docker、kubectl 和基础工具' +author: 'Your Organization' + +branding: + icon: 'settings' + color: 'blue' + +inputs: + docker-registry: + description: 'Docker 私有仓库地址' + required: false + default: 'docker-registry.bjxgj.com' + + docker-username: + description: 'Docker 仓库用户名' + required: false + default: 'ci-action' + + docker-password: + description: 'Docker 仓库密码' + required: true + + kube-config: + description: 'Base64 编码的 kubectl 配置文件' + required: false + default: '' + + cache-key: + description: '缓存键值,用于依赖缓存' + required: false + default: 'setup-env' + + use-aliyun-mirror: + description: '是否使用阿里云镜像源 (true/false)' + required: false + default: 'true' + + git-user-name: + description: 'Git 用户名' + required: false + default: 'GiteaActions' + + git-user-email: + description: 'Git 用户邮箱' + required: false + default: 'actions@gitea.com' + + skip-kubectl: + description: '跳过 kubectl 安装和配置 (true/false)' + required: false + default: 'false' + + skip-docker-login: + description: '跳过 Docker 登录 (true/false)' + required: false + default: 'false' + +outputs: + cache-hit: + description: '缓存是否命中' + value: ${{ steps.cache-setup.outputs.cache-hit }} + + kubectl-version: + description: '安装的 kubectl 版本' + value: ${{ steps.kubectl-version.outputs.version }} + + docker-version: + description: '安装的 Docker 版本' + value: ${{ steps.docker-version.outputs.version }} + +runs: + using: 'composite' + steps: + - name: 配置Git + shell: bash + run: | + echo "🔧 配置 Git 用户信息..." + git config --global user.name "${{ inputs.git-user-name }}" + git config --global user.email "${{ inputs.git-user-email }}" + echo "✅ Git 配置完成" + + - name: 缓存依赖与配置环境 + id: cache-setup + uses: actions/cache@v4 + with: + path: | + /var/cache/apt/archives + /var/lib/apt/lists + /usr/bin/curl + /usr/bin/gpg + /usr/bin/base64 + /usr/share/ca-certificates + /etc/apt/keyrings/docker.gpg + /etc/apt/keyrings/kubernetes-apt-keyring.gpg + /etc/apt/sources.list.d/kubernetes.list + /etc/apt/sources.list.d/docker.list + /usr/bin/docker + /usr/bin/buildx + /usr/bin/docker-compose + /usr/libexec/docker/cli-plugins/docker-buildx + /usr/libexec/docker/cli-plugins/docker-compose + /usr/bin/kubectl + key: ${{ runner.os }}-${{ inputs.cache-key }}-${{ hashFiles('**/action.yml') }}-v2 + restore-keys: | + ${{ runner.os }}-${{ inputs.cache-key }}- + + - name: 配置环境(如果未命中缓存) + if: steps.cache-setup.outputs.cache-hit != 'true' + shell: bash + run: ${{ github.action_path }}/scripts/setup-environment.sh + env: + USE_ALIYUN_MIRROR: ${{ inputs.use-aliyun-mirror }} + SKIP_KUBECTL: ${{ inputs.skip-kubectl }} + + - name: 获取 Docker 版本 + id: docker-version + shell: bash + run: | + if command -v docker &> /dev/null; then + VERSION=$(docker --version | cut -d' ' -f3 | cut -d',' -f1) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "🐳 Docker 版本: $VERSION" + else + echo "version=not-installed" >> $GITHUB_OUTPUT + echo "⚠️ Docker 未安装" + fi + + - name: 获取 kubectl 版本 + id: kubectl-version + if: ${{ inputs.skip-kubectl != 'true' }} + shell: bash + run: | + if command -v kubectl &> /dev/null; then + VERSION=$(kubectl version --client --short 2>/dev/null | cut -d' ' -f3 || echo "unknown") + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "☸️ kubectl 版本: $VERSION" + else + echo "version=not-installed" >> $GITHUB_OUTPUT + echo "⚠️ kubectl 未安装" + fi + + - name: 配置 kubectl + if: ${{ inputs.kube-config != '' && inputs.skip-kubectl != 'true' }} + shell: bash + run: ${{ github.action_path }}/scripts/setup-kubectl.sh + env: + KUBE_CONFIG_BASE64: ${{ inputs.kube-config }} + + - name: 验证 kubectl 配置 + if: ${{ inputs.kube-config != '' && inputs.skip-kubectl != 'true' }} + shell: bash + run: ${{ github.action_path }}/scripts/verify-kubectl.sh + + - name: 登录私有 Docker 仓库 + if: ${{ inputs.skip-docker-login != 'true' }} + uses: docker/login-action@v3 + with: + registry: ${{ inputs.docker-registry }} + username: ${{ inputs.docker-username }} + password: ${{ inputs.docker-password }} + + - name: 环境配置完成 + shell: bash + run: | + echo "🎉 环境配置完成!" + echo "📋 已安装的工具:" + if command -v docker &> /dev/null; then + echo " - Docker: $(docker --version | cut -d' ' -f3 | cut -d',' -f1)" + fi + if command -v kubectl &> /dev/null && [[ "${{ inputs.skip-kubectl }}" != "true" ]]; then + echo " - kubectl: $(kubectl version --client --short 2>/dev/null | cut -d' ' -f3 || echo "已安装")" + fi + echo " - Git: $(git --version | cut -d' ' -f3)" diff --git a/setup-env/examples/basic-workflow.yml b/setup-env/examples/basic-workflow.yml new file mode 100644 index 0000000..20f5f40 --- /dev/null +++ b/setup-env/examples/basic-workflow.yml @@ -0,0 +1,30 @@ +# 基本使用示例 +name: Basic Build and Deploy +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置构建环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: 构建应用 + run: | + echo "开始构建应用..." + docker build -t my-app:${{ github.sha }} . + echo "构建完成!" + + - name: 推送镜像 + run: | + docker push my-app:${{ github.sha }} + echo "镜像推送完成!" diff --git a/setup-env/examples/full-deployment.yml b/setup-env/examples/full-deployment.yml new file mode 100644 index 0000000..eadfc15 --- /dev/null +++ b/setup-env/examples/full-deployment.yml @@ -0,0 +1,107 @@ +# 完整部署示例 +name: Full Build and Deploy Pipeline +on: + workflow_dispatch: + inputs: + environment: + description: '部署环境' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + - prod + +env: + REGISTRY: docker-registry.bjxgj.com + IMAGE_NAME: my-application + +jobs: + build: + runs-on: ubuntu-latest + outputs: + image-tag: ${{ steps.meta.outputs.tags }} + cache-hit: ${{ steps.setup.outputs.cache-hit }} + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置构建环境 + id: setup + uses: xgj/actions/setup-env@v1 + with: + docker-registry: ${{ env.REGISTRY }} + docker-username: ci-action + docker-password: ${{ secrets.DOCKER_PASSWORD }} + cache-key: 'build-${{ github.sha }}' + use-aliyun-mirror: 'true' + + - name: 生成镜像元数据 + id: meta + run: | + IMAGE_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}" + echo "tags=$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "Generated image tag: $IMAGE_TAG" + + - name: 构建 Docker 镜像 + run: | + docker build \ + --tag ${{ steps.meta.outputs.tags }} \ + --label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \ + --label "org.opencontainers.image.revision=${{ github.sha }}" \ + --label "org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \ + . + + - name: 推送镜像 + run: | + docker push ${{ steps.meta.outputs.tags }} + + - name: 构建摘要 + run: | + echo "## 🐳 构建信息" >> $GITHUB_STEP_SUMMARY + echo "- **镜像**: ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + echo "- **缓存命中**: ${{ steps.setup.outputs.cache-hit }}" >> $GITHUB_STEP_SUMMARY + echo "- **Docker 版本**: ${{ steps.setup.outputs.docker-version }}" >> $GITHUB_STEP_SUMMARY + + deploy: + needs: build + runs-on: ubuntu-latest + environment: ${{ inputs.environment }} + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置部署环境 + id: setup + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets[format('KUBE_CONFIG_{0}', inputs.environment)] }} + cache-key: 'deploy-${{ inputs.environment }}' + + - name: 部署到 Kubernetes + run: | + # 替换镜像标签 + sed -i "s|{{IMAGE_TAG}}|${{ needs.build.outputs.image-tag }}|g" k8s/deployment.yaml + + # 应用配置 + kubectl apply -f k8s/ -n ${{ inputs.environment }} + + # 等待部署完成 + kubectl rollout status deployment/my-application -n ${{ inputs.environment }} --timeout=300s + + - name: 验证部署 + run: | + # 检查 Pod 状态 + kubectl get pods -n ${{ inputs.environment }} -l app=my-application + + # 检查服务状态 + kubectl get svc -n ${{ inputs.environment }} -l app=my-application + + - name: 部署摘要 + run: | + echo "## ☸️ 部署信息" >> $GITHUB_STEP_SUMMARY + echo "- **环境**: ${{ inputs.environment }}" >> $GITHUB_STEP_SUMMARY + echo "- **镜像**: ${{ needs.build.outputs.image-tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **kubectl 版本**: ${{ steps.setup.outputs.kubectl-version }}" >> $GITHUB_STEP_SUMMARY diff --git a/setup-env/examples/multi-environment.yml b/setup-env/examples/multi-environment.yml new file mode 100644 index 0000000..4b8590e --- /dev/null +++ b/setup-env/examples/multi-environment.yml @@ -0,0 +1,110 @@ +# 多环境部署示例 +name: Multi-Environment Deploy +on: + push: + branches: [ main ] + tags: [ 'v*' ] + +jobs: + build: + runs-on: ubuntu-latest + outputs: + image-tag: ${{ steps.meta.outputs.tags }} + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置构建环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + cache-key: 'multi-env-build' + + - name: 生成镜像标签 + id: meta + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION=${GITHUB_SHA::7} + fi + IMAGE_TAG="docker-registry.bjxgj.com/my-app:$VERSION" + echo "tags=$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: 构建并推送 + run: | + docker build -t ${{ steps.meta.outputs.tags }} . + docker push ${{ steps.meta.outputs.tags }} + + deploy-dev: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + environment: development + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置开发环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG_DEV }} + cache-key: 'deploy-dev' + + - name: 部署到开发环境 + run: | + sed -i "s|{{IMAGE_TAG}}|${{ needs.build.outputs.image-tag }}|g" k8s/dev/deployment.yaml + kubectl apply -f k8s/dev/ -n development + kubectl rollout status deployment/my-app -n development + + deploy-staging: + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + environment: staging + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置预发布环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG_STAGING }} + cache-key: 'deploy-staging' + + - name: 部署到预发布环境 + run: | + sed -i "s|{{IMAGE_TAG}}|${{ needs.build.outputs.image-tag }}|g" k8s/staging/deployment.yaml + kubectl apply -f k8s/staging/ -n staging + kubectl rollout status deployment/my-app -n staging + + deploy-production: + needs: [build, deploy-staging] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + environment: production + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置生产环境 + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG_PROD }} + cache-key: 'deploy-production' + use-aliyun-mirror: 'false' # 生产环境使用官方源 + + - name: 部署到生产环境 + run: | + sed -i "s|{{IMAGE_TAG}}|${{ needs.build.outputs.image-tag }}|g" k8s/prod/deployment.yaml + kubectl apply -f k8s/prod/ -n production + kubectl rollout status deployment/my-app -n production + + - name: 健康检查 + run: | + kubectl get pods -n production -l app=my-app + # 可以添加更多健康检查逻辑 diff --git a/setup-env/examples/troubleshooting.yml b/setup-env/examples/troubleshooting.yml new file mode 100644 index 0000000..d386bbe --- /dev/null +++ b/setup-env/examples/troubleshooting.yml @@ -0,0 +1,132 @@ +# 故障排除和调试示例 +name: Troubleshooting Example +on: + workflow_dispatch: + inputs: + debug_mode: + description: '启用调试模式' + required: false + default: false + type: boolean + +jobs: + debug-setup: + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 配置环境(调试模式) + id: setup + uses: xgj/actions/setup-env@v1 + with: + docker-password: ${{ secrets.DOCKER_PASSWORD }} + kube-config: ${{ secrets.KUBE_CONFIG }} + cache-key: 'debug-env' + env: + # 启用详细日志 + ACTIONS_STEP_DEBUG: ${{ inputs.debug_mode }} + ACTIONS_RUNNER_DEBUG: ${{ inputs.debug_mode }} + + - name: 环境信息检查 + run: | + echo "=== 系统信息 ===" + uname -a + cat /etc/os-release + + echo -e "\n=== 已安装工具版本 ===" + echo "Docker: ${{ steps.setup.outputs.docker-version }}" + echo "kubectl: ${{ steps.setup.outputs.kubectl-version }}" + echo "Git: $(git --version)" + + echo -e "\n=== 缓存状态 ===" + echo "Cache Hit: ${{ steps.setup.outputs.cache-hit }}" + + echo -e "\n=== Docker 状态 ===" + docker version || echo "Docker 命令失败" + docker info || echo "Docker info 失败" + + echo -e "\n=== kubectl 状态 ===" + kubectl version --client || echo "kubectl 客户端版本获取失败" + kubectl config current-context || echo "kubectl 上下文获取失败" + + - name: 网络连接测试 + run: | + echo "=== 网络连接测试 ===" + + # 测试 Docker 仓库连接 + echo "测试 Docker 仓库连接..." + curl -I https://docker-registry.bjxgj.com/v2/ || echo "Docker 仓库连接失败" + + # 测试 Kubernetes API + if [[ -n "${{ secrets.KUBE_CONFIG }}" ]]; then + echo "测试 Kubernetes API 连接..." + kubectl cluster-info --request-timeout=10s || echo "Kubernetes API 连接失败" + fi + + # 测试外部网络 + echo "测试外部网络连接..." + curl -I https://github.com || echo "GitHub 连接失败" + curl -I https://mirrors.aliyun.com || echo "阿里云镜像连接失败" + + - name: 权限检查 + run: | + echo "=== 权限检查 ===" + + # 检查文件权限 + ls -la ~/.kube/ || echo "kubectl 配置目录不存在" + ls -la ~/.docker/ || echo "Docker 配置目录不存在" + + # 检查用户权限 + id + groups + + # 检查 sudo 权限 + sudo -n true && echo "具有 sudo 权限" || echo "无 sudo 权限" + + - name: 清理和重试(失败时) + if: failure() + run: | + echo "=== 清理环境 ===" + + # 清理 Docker 配置 + rm -rf ~/.docker/config.json || true + + # 清理 kubectl 配置 + rm -rf ~/.kube/config || true + + # 清理缓存 + rm -rf /tmp/setup-env-* || true + + echo "环境已清理,建议重新运行" + + - name: 收集日志 + if: always() + run: | + echo "=== 收集系统日志 ===" + + # 收集系统日志 + sudo dmesg | tail -50 || echo "无法获取系统日志" + + # 收集 Docker 日志 + sudo journalctl -u docker --no-pager --lines=20 || echo "无法获取 Docker 日志" + + # 收集网络信息 + ip addr show || echo "无法获取网络信息" + ss -tuln || echo "无法获取端口信息" + + - name: 生成故障报告 + if: failure() + run: | + echo "## 🚨 故障报告" >> $GITHUB_STEP_SUMMARY + echo "### 环境信息" >> $GITHUB_STEP_SUMMARY + echo "- **运行器**: ${{ runner.os }}" >> $GITHUB_STEP_SUMMARY + echo "- **缓存命中**: ${{ steps.setup.outputs.cache-hit }}" >> $GITHUB_STEP_SUMMARY + echo "- **Docker 版本**: ${{ steps.setup.outputs.docker-version }}" >> $GITHUB_STEP_SUMMARY + echo "- **kubectl 版本**: ${{ steps.setup.outputs.kubectl-version }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 建议解决方案" >> $GITHUB_STEP_SUMMARY + echo "1. 检查网络连接" >> $GITHUB_STEP_SUMMARY + echo "2. 验证 secrets 配置" >> $GITHUB_STEP_SUMMARY + echo "3. 清除缓存重试" >> $GITHUB_STEP_SUMMARY + echo "4. 联系运维团队" >> $GITHUB_STEP_SUMMARY diff --git a/setup-env/scripts/setup-environment.sh b/setup-env/scripts/setup-environment.sh new file mode 100755 index 0000000..3c51de5 --- /dev/null +++ b/setup-env/scripts/setup-environment.sh @@ -0,0 +1,204 @@ +#!/bin/bash +set -euo pipefail + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 输出函数 +log_info() { + echo -e "${BLUE}ℹ️ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}⚠️ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +# 检查是否为 root 用户 +check_root() { + if [[ $EUID -ne 0 ]]; then + log_error "此脚本需要 root 权限运行" + exit 1 + fi +} + +# 配置阿里云镜像源 +setup_aliyun_sources() { + log_info "配置阿里云镜像源..." + + # 备份原始源列表 + if [[ -f /etc/apt/sources.list ]]; then + cp /etc/apt/sources.list /etc/apt/sources.list.backup + fi + + # 设置阿里云镜像源 + cat > /etc/apt/sources.list << 'EOF' +deb https://mirrors.aliyun.com/debian/ bullseye main contrib non-free +deb https://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free +deb https://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free +EOF + + log_success "阿里云镜像源配置完成" +} + +# 安装基础依赖 +install_base_packages() { + log_info "更新包列表并安装基础依赖..." + + apt-get update + apt-get install -y \ + ca-certificates \ + curl \ + gnupg \ + coreutils \ + lsb-release \ + software-properties-common \ + apt-transport-https + + log_success "基础依赖安装完成" +} + +# 安装 Docker +install_docker() { + log_info "安装 Docker..." + + # 创建密钥目录 + mkdir -p /etc/apt/keyrings + + # 下载 Docker GPG 密钥 + if [[ "${USE_ALIYUN_MIRROR:-true}" == "true" ]]; then + log_info "使用阿里云 Docker 镜像源..." + curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | \ + gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg + else + log_info "使用官方 Docker 源..." + curl -fsSL https://download.docker.com/linux/debian/gpg | \ + gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg + fi + + chmod a+r /etc/apt/keyrings/docker.gpg + + # 添加 Docker 源 + if [[ "${USE_ALIYUN_MIRROR:-true}" == "true" ]]; then + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + else + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + fi + + # 更新源并安装 Docker + apt-get update + apt-get install -y \ + docker-ce-cli \ + docker-buildx-plugin \ + docker-compose-plugin + + log_success "Docker 安装完成" +} + +# 安装 kubectl +install_kubectl() { + if [[ "${SKIP_KUBECTL:-false}" == "true" ]]; then + log_info "跳过 kubectl 安装" + return 0 + fi + + log_info "安装 kubectl..." + + # 添加 Kubernetes GPG 密钥 + curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | \ + gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg + chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg + + # 添加 Kubernetes apt 仓库 + echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' | \ + tee /etc/apt/sources.list.d/kubernetes.list + chmod 644 /etc/apt/sources.list.d/kubernetes.list + + # 更新包索引并安装 kubectl + apt-get update + apt-get install -y kubectl + + log_success "kubectl 安装完成" +} + +# 验证安装 +verify_installation() { + log_info "验证安装..." + + # 验证 Docker + if command -v docker &> /dev/null; then + DOCKER_VERSION=$(docker --version | cut -d' ' -f3 | cut -d',' -f1) + log_success "Docker 版本: $DOCKER_VERSION" + else + log_error "Docker 安装失败" + exit 1 + fi + + # 验证 kubectl (如果安装了) + if [[ "${SKIP_KUBECTL:-false}" != "true" ]]; then + if command -v kubectl &> /dev/null; then + KUBECTL_VERSION=$(kubectl version --client --short 2>/dev/null | cut -d' ' -f3 || echo "已安装") + log_success "kubectl 版本: $KUBECTL_VERSION" + else + log_error "kubectl 安装失败" + exit 1 + fi + fi +} + +# 清理临时文件 +cleanup() { + log_info "清理临时文件..." + apt-get clean + rm -rf /var/lib/apt/lists/* + log_success "清理完成" +} + +# 主函数 +main() { + log_info "开始配置构建环境..." + + # 检查 root 权限 + check_root + + # 配置镜像源 + if [[ "${USE_ALIYUN_MIRROR:-true}" == "true" ]]; then + setup_aliyun_sources + fi + + # 安装基础包 + install_base_packages + + # 安装 Docker + install_docker + + # 安装 kubectl + install_kubectl + + # 验证安装 + verify_installation + + # 清理 + cleanup + + log_success "环境配置完成!" +} + +# 错误处理 +trap 'log_error "脚本执行失败,退出码: $?"' ERR + +# 执行主函数 +main "$@" diff --git a/setup-env/scripts/setup-kubectl.sh b/setup-env/scripts/setup-kubectl.sh new file mode 100755 index 0000000..abf0cc3 --- /dev/null +++ b/setup-env/scripts/setup-kubectl.sh @@ -0,0 +1,67 @@ +#!/bin/bash +set -euo pipefail + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 输出函数 +log_info() { + echo -e "${BLUE}ℹ️ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}⚠️ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +# 配置 kubectl +setup_kubectl_config() { + log_info "配置 kubectl..." + + # 检查环境变量 + if [[ -z "${KUBE_CONFIG_BASE64:-}" ]]; then + log_error "KUBE_CONFIG_BASE64 环境变量未设置" + exit 1 + fi + + # 创建 .kube 目录 + mkdir -p "$HOME/.kube" + + # 解码并写入配置文件 + echo "$KUBE_CONFIG_BASE64" | base64 -d > "$HOME/.kube/config" + + # 设置正确的权限 + chmod 600 "$HOME/.kube/config" + + log_success "kubectl 配置文件已创建" + + # 验证配置文件格式 + if ! kubectl config view --minify >/dev/null 2>&1; then + log_error "kubectl 配置文件格式无效" + exit 1 + fi + + log_success "kubectl 配置验证通过" +} + +# 主函数 +main() { + setup_kubectl_config +} + +# 错误处理 +trap 'log_error "kubectl 配置失败,退出码: $?"' ERR + +# 执行主函数 +main "$@" diff --git a/setup-env/scripts/verify-kubectl.sh b/setup-env/scripts/verify-kubectl.sh new file mode 100755 index 0000000..50f5e3f --- /dev/null +++ b/setup-env/scripts/verify-kubectl.sh @@ -0,0 +1,76 @@ +#!/bin/bash +set -euo pipefail + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 输出函数 +log_info() { + echo -e "${BLUE}ℹ️ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}⚠️ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +# 验证 kubectl 连接 +verify_kubectl_connection() { + log_info "验证 kubectl 连接..." + + # 设置超时时间 + TIMEOUT=30 + + # 检查集群连接 + if timeout $TIMEOUT kubectl cluster-info >/dev/null 2>&1; then + log_success "集群连接成功" + + # 显示集群信息 + log_info "集群信息:" + kubectl cluster-info + + # 显示节点信息 + log_info "集群节点:" + if kubectl get nodes >/dev/null 2>&1; then + kubectl get nodes + else + log_warning "无法获取节点信息(可能权限不足)" + fi + + # 显示当前上下文 + CURRENT_CONTEXT=$(kubectl config current-context 2>/dev/null || echo "未知") + log_info "当前上下文: $CURRENT_CONTEXT" + + # 显示 kubectl 版本 + log_info "kubectl 版本信息:" + kubectl version --short 2>/dev/null || kubectl version --client + + else + log_error "kubectl 连接验证失败" + log_info "尝试显示详细错误信息..." + kubectl cluster-info || true + exit 1 + fi +} + +# 主函数 +main() { + verify_kubectl_connection +} + +# 错误处理 +trap 'log_error "kubectl 验证失败,退出码: $?"' ERR + +# 执行主函数 +main "$@"