2. K8s 发布流水线基础:CI/CD 概念、Jenkins/GitLab CI 与 K8s 集成方式

2.1 CI/CD 核心概念与在 K8s 场景下的价值

CI/CD(持续集成/持续交付)是现代云原生应用交付的基石。在 Kubernetes 环境中,CI/CD 流水线不仅负责代码的编译与测试,更承担着将应用容器化、推送镜像仓库、更新集群资源对象的全链路自动化任务。

阶段 核心活动 K8s 场景下的关键产出
持续集成 (CI) 代码合并、静态检查、单元测试、构建镜像 Docker Image + 标签(如 commit SHA)
持续交付 (CD) 自动部署到测试/预发环境、集成测试 K8s YAML 清单更新、Helm Chart 升级
持续部署 (CD) 自动发布到生产环境(需审批或门禁) Rolling Update / Blue-Green / Canary 策略执行
关键原则: 在 K8s 流水线中,不可变基础设施是核心思想——每次构建生成全新的镜像,而非对运行中的容器打补丁。镜像标签应具备唯一性(如 v1.2.3-b4c5d6e),避免使用 latest。

2.2 CI/CD 工具与 K8s 的集成模式

主流的 CI/CD 工具(Jenkins、GitLab CI)与 K8s 的集成通常采用以下三种模式之一:

  1. In-Cluster 模式: CI/CD 工具以 Pod 形式运行在 K8s 集群内部,通过 ServiceAccount 直接调用 K8s API。
  2. Out-of-Cluster 模式: CI/CD 工具运行在集群外部(如独立 VM),通过 kubeconfig 文件或 API Server 外部端点进行通信。
  3. Operator 模式: 使用自定义资源(CRD)声明流水线,由 K8s Operator 负责执行(如 Argo Workflows、Tekton)。
架构对比: In-Cluster 模式简化了权限管理(天然使用 Pod 身份),适合纯云原生团队;Out-of-Cluster 模式便于与现有企业 LDAP/AD 集成,适合混合架构。
CI/CD 工具与 K8s 集成架构 代码仓库 GitHub / GitLab CI/CD 引擎 Jenkins / GitLab CI Kubernetes 集群 API Server Worker Nodes In-Cluster 模式 Pod 运行在集群内 使用 ServiceAccount 鉴权 Out-of-Cluster 模式 工具运行在集群外 使用 kubeconfig 连接 Operator 模式 CRD 声明流水线 Argo / Tekton 执行

2.3 Jenkins 与 K8s 集成实践

Jenkins 通过 Kubernetes Plugin 实现动态 Agent 管理。每次构建任务启动时,Jenkins Master 向 K8s API 请求创建一个 Agent Pod,任务完成后自动销毁,实现资源弹性伸缩。

集成关键步骤

  1. 安装 Kubernetes Plugin: 在 Jenkins 插件管理中安装并配置 K8s 连接信息(API Server URL、凭证)。
  2. 定义 Pod Template: 在流水线中声明 Agent 容器镜像、资源限制、挂载卷。
  3. 编写 Jenkinsfile: 在 CI 阶段执行 docker build 并推送镜像;在 CD 阶段执行 kubectl set image 或 helm upgrade。
// Jenkinsfile 示例:动态 K8s Agent + 镜像构建与部署
pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: docker
    image: docker:20.10
    command: ['cat']
    tty: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.sock
  - name: kubectl
    image: bitnami/kubectl:1.28
    command: ['cat']
    tty: true
  volumes:
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
'''
        }
    }
    stages {
        stage('Build & Push Image') {
            steps {
                container('docker') {
                    sh 'docker build -t registry.example.com/app:${BUILD_NUMBER} .'
                    sh 'docker push registry.example.com/app:${BUILD_NUMBER}'
                }
            }
        }
        stage('Deploy to K8s') {
            steps {
                container('kubectl') {
                    sh 'kubectl set image deployment/app app=registry.example.com/app:${BUILD_NUMBER} -n production'
                }
            }
        }
    }
}
安全注意: Jenkins Agent Pod 应使用最小权限的 ServiceAccount,避免赋予 cluster-admin 权限。推荐使用 RBAC + 命名空间隔离,限制 Agent 仅能操作目标命名空间。

2.4 GitLab CI 与 K8s 集成实践

GitLab CI 通过 GitLab Agent for Kubernetes(或传统 kubeconfig 方式)实现与 K8s 集群的通信。Agent 以 Pod 形式运行在集群内,建立反向连接,避免暴露 API Server 端口。

集成关键步骤

  1. 注册 GitLab Agent: 在 GitLab 项目设置中创建 Agent 配置,生成注册令牌。
  2. 部署 Agent Pod: 在目标 K8s 集群中安装 gitlab-agent Helm Chart,配置令牌与 GitLab 项目 ID。
  3. 编写 .gitlab-ci.yml: 使用 kubectl 或 helm 命令执行部署,通过 Agent 的 CI/CD 隧道访问 K8s API。
# .gitlab-ci.yml 示例:使用 GitLab Agent 部署到 K8s
stages:
  - build
  - deploy

variables:
  IMAGE_TAG: $CI_COMMIT_SHORT_SHA

build:
  stage: build
  image: docker:20.10
  services:
    - docker:dind
  script:
    - docker build -t registry.example.com/app:$IMAGE_TAG .
    - docker push registry.example.com/app:$IMAGE_TAG

deploy:
  stage: deploy
  image: bitnami/kubectl:1.28
  script:
    - kubectl set image deployment/app app=registry.example.com/app:$IMAGE_TAG -n production
  environment:
    name: production
    kubernetes:
      namespace: production

2.5 两种集成方式对比

对比维度 Jenkins + K8s Plugin GitLab CI + Agent
Agent 生命周期 按需创建/销毁,资源弹性好 Agent 常驻 Pod,持续监听
网络连接 Jenkins Master 主动连接 K8s API Agent 反向连接 GitLab,无需开放 API
权限模型 ServiceAccount + RBAC Agent 令牌 + 项目级授权
多租户支持 需手动配置不同 Namespace 的 SA 原生支持项目级 K8s 命名空间映射
流水线语法 Groovy (Jenkinsfile) YAML (.gitlab-ci.yml)
Jenkins Agent vs GitLab Agent 连接模式对比 Jenkins 模式(主动连接) Jenkins Master K8s API Server 主动调用 Agent Pod 动态创建 任务完成后销毁 GitLab CI 模式(反向连接) GitLab Server GitLab Agent 反向连接 K8s API Server 通过 Agent 代理 Agent 常驻运行

2.6 流水线安全基线

无论选择哪种集成方式,以下安全实践必须纳入流水线设计:

  • 凭证管理: 使用 CI/CD 工具内置的凭证存储(Jenkins Credentials / GitLab CI Variables),禁止将 K8s 令牌硬编码在代码库中。
  • 镜像签名与扫描: 在 CI 阶段集成 cosign 签名和 trivy 漏洞扫描,阻断高危镜像进入部署流程。
  • 最小权限原则: 为每个流水线创建独立的 ServiceAccount,仅授予目标命名空间的 get、list、update 权限。
  • 审计日志: 启用 K8s 审计日志,记录所有通过 CI/CD 工具触发的 API 调用,便于事后追溯。
推荐实践: 在流水线中增加 人工审批门禁(Jenkins Input Step / GitLab Manual Job),确保生产环境部署前经过二次确认。结合 Policy-as-Code(如 OPA Gatekeeper)在部署前自动校验 YAML 合规性。