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 的集成通常采用以下三种模式之一:
- In-Cluster 模式: CI/CD 工具以 Pod 形式运行在 K8s 集群内部,通过 ServiceAccount 直接调用 K8s API。
- Out-of-Cluster 模式: CI/CD 工具运行在集群外部(如独立 VM),通过 kubeconfig 文件或 API Server 外部端点进行通信。
- Operator 模式: 使用自定义资源(CRD)声明流水线,由 K8s Operator 负责执行(如 Argo Workflows、Tekton)。
架构对比: In-Cluster 模式简化了权限管理(天然使用 Pod 身份),适合纯云原生团队;Out-of-Cluster 模式便于与现有企业 LDAP/AD 集成,适合混合架构。
2.3 Jenkins 与 K8s 集成实践
Jenkins 通过 Kubernetes Plugin 实现动态 Agent 管理。每次构建任务启动时,Jenkins Master 向 K8s API 请求创建一个 Agent Pod,任务完成后自动销毁,实现资源弹性伸缩。
集成关键步骤
- 安装 Kubernetes Plugin: 在 Jenkins 插件管理中安装并配置 K8s 连接信息(API Server URL、凭证)。
- 定义 Pod Template: 在流水线中声明 Agent 容器镜像、资源限制、挂载卷。
- 编写 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 端口。
集成关键步骤
- 注册 GitLab Agent: 在 GitLab 项目设置中创建 Agent 配置,生成注册令牌。
- 部署 Agent Pod: 在目标 K8s 集群中安装
gitlab-agentHelm Chart,配置令牌与 GitLab 项目 ID。 - 编写 .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) |
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 合规性。