技术文章2026 年 7 月 5 日约 3 分钟

Kubernetes CI/CD:GitHub Actions 构建并发布镜像

用 GitHub Actions 搭发布流水线:OIDC 短期凭据、不可变镜像、环境审批与 rollout 验证。

CI/CD 流水线最容易出问题的地方不在「构建镜像」,而在「部署凭据怎么给」和「发布后怎么确认」。这篇文章写一条我实际在用的发布流水线:测试 → 构建 → 扫描 → 推送 → 部署 → 验证,每一步都说清楚为什么。

#凭据:用 OIDC,别把 kubeconfig 塞进仓库

最不安全的做法是把 KUBECONFIG、长期 Token 直接写进 GitHub Secrets 甚至仓库文件。正确姿势是用 OIDC 短期令牌:GitHub Actions 向云厂商/集群换取几分钟有效的凭据,用完即失效,没有长期泄露面。

yaml
permissions:
  id-token: write          # 允许换取 OIDC token
  contents: read
  packages: write

配置一个 federation 之后,凭据通过 configure-kubeconfig 之类的 action 注入,流水线里不需要任何明文密钥。这一步把「凭据泄露」这个 CI/CD 最大的风险直接消掉,值得花半天时间配好。

#流水线:测试、构建、扫描、发布

yaml
name: release
on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: go test ./...

      - name: Build and push
        run: |
          docker build -t ghcr.io/acme/demo-api:${{ github.sha }} .
          docker push ghcr.io/acme/demo-api:${{ github.sha }}

      - name: Configure kubeconfig
        uses: azure/k8s-set-context@v4
        with:
          method: oidc
          cluster: ${{ vars.CLUSTER_NAME }}

      - name: Deploy
        run: |
          kubectl set image deployment/demo-api             api=ghcr.io/acme/demo-api:${{ github.sha }}

      - name: Verify rollout
        run: kubectl rollout status deployment/demo-api --timeout=180s

几个细节值得展开:

  • 镜像 tag 用 commit SHA(${{ github.sha }}),不可变、可追溯。别用 latest——latest 是可变的,出问题你根本不知道线上跑的是哪一版。配合 digest 更严谨,但 SHA tag 已能满足绝大多数场景。
  • 构建和部署分步,构建失败不会触发部署,部署失败会有明确的 step 标红。
  • kubectl rollout status 必须作为流水线最后一步。很多人部署完就结束,发布失败全靠人工发现。rollout 超时会返回非零退出码,让 CI 直接失败,这才是「发布失败能被及时发现」的机制。

#环境隔离:dev / prod 分开,别一套脚本打天下

on: push: branches: [main] 直接发布生产是最危险的做法。至少做到:

  • 生产环境用 GitHub Environments(environment: production),开启「需要审批」——代码合并自动发测试,生产发布必须点一下确认。
  • 不同环境用不同的 vars(镜像仓库、namespace、values 文件),配置不写死在流水线里。
yaml
deploy-prod:
  needs: [build-and-deploy]
  environment: production          # 审批 + 保护规则
  runs-on: ubuntu-latest
  steps:
    - run: |
        kubectl -n production set image deployment/demo-api           api=ghcr.io/acme/demo-api:${{ github.sha }}
        kubectl -n production rollout status deployment/demo-api --timeout=180s

#排障:发布失败后怎么查

CI 报错只是开始,接下来按顺序查:

bash
kubectl -n production get events --sort-by=.lastTimestamp | tail -30
kubectl -n production get pods -l app=demo-api
kubectl -n production describe pod <pod-name>
kubectl -n production logs <pod-name> --previous

先看 Events(调度失败、镜像拉取失败、探针失败都会出现在这里),再 describe 看具体状态,最后看日志。镜像 tag 拼错是最常见的坑:构建用 SHA、部署也用 SHA,一旦两边对不上就是 ImagePullBackOff,Events 里一眼就能看到。

#经验

一条稳的发布流水线 = 短期凭据 + 不可变镜像 + 环境审批 + rollout 验证。发布不是终点,验证才是。另外补一句:CI 里跑 go test 之类的单测当然好,但更值钱的是加一条「冒烟」——部署完打一个真实请求确认服务可用,这一步能拦住一半的「测试过了但线上挂」事故。

写于 2026 年 7 月 5 日

栏目
技术文章
约
3 分钟
字数
2.3K
阅读
247

本文为原创记录,转载请注明出处。如果这篇替你省了时间,欢迎留言说说你踩到的坑。

同题 · related

留言 · remarks

00 条

还没有留言,来说点什么吧。

Kubernetes CI/CD:GitHub Actions 构建并发布镜像 · LXH·BLOG