CI 集成

CI(持续集成)是现代软件开发流程中的关键环节,它与 Kubernetes 集成可以实现应用程序的自动化构建、测试和部署。本章节将介绍如何将 Jenkins、GitLab CI 和 GitHub Actions 与 Kubernetes 集成,实现从代码提交到容器化部署的完整自动化流水线。

CI/CD 与 Kubernetes 集成架构
graph TB
    subgraph "代码仓库"
        GIT[Git Repository]
    end
    
    subgraph "CI/CD 系统"
        JENKINS[Jenkins
GitLab CI
GitHub Actions] DOCKER[容器化构建] TEST[自动化测试] end subgraph "Kubernetes 集群" REGISTRY[镜像仓库] DEPLOY[自动部署] MONITOR[监控系统] end GIT --> JENKINS JENKINS --> DOCKER DOCKER --> REGISTRY REGISTRY --> DEPLOY DEPLOY --> MONITOR TEST --> REGISTRY
CI 工具对比
工具优点缺点适用场景
Jenkins 功能强大,插件丰富,社区支持好 配置复杂,资源消耗大,升级困难 大型企业,复杂流水线
GitLab CI 与 GitLab 集成度高,配置简单 仅限于 GitLab 平台 GitLab 用户,中型企业
GitHub Actions 与 GitHub 深度集成,易上手 依赖于 GitHub 平台,成本可能较高 GitHub 用户,开源项目
Jenkins 与 Kubernetes 集成

Jenkins 是最流行的 CI/CD 工具之一,通过 Kubernetes 插件可以实现在 Kubernetes 集群中动态创建 Jenkins 构建节点。

1. Jenkins K8s 插件配置
# Jenkins K8s 插件配置示例
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: jenkins
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: ["", "extensions", "apps"]
  resources: ["configmaps", "services"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins
  namespace: jenkins
2. Jenkins Pod 模板配置
# Jenkins Pod 模板配置
apiVersion: v1
kind: Pod
spec:
  serviceAccount: jenkins
  containers:
  - name: jnlp
    image: jenkins/inbound-agent:4.11-1-jdk11
    args: ['$(JENKINS_SECRET)', '$(JENKINS_NAME)']
  - name: docker
    image: docker:20.10.16-dind
    securityContext:
      privileged: true
    volumeMounts:
      - name: docker-sock
        mountPath: /var/run/docker.sock
  volumes:
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
      type: Socket
3. Jenkins Pipeline 示例
# Jenkinsfile 示例
pipeline {
  agent {
    kubernetes {
      yaml """
      apiVersion: v1
      kind: Pod
      spec:
        containers:
        - name: docker
          image: docker:20.10.16-dind
          securityContext:
            privileged: true
          volumeMounts:
            - name: docker-sock
              mountPath: /var/run/docker.sock
        command:
        - sleep
        - 3600
      volumes:
        - name: docker-sock
          hostPath:
            path: /var/run/docker.sock
            type: Socket
      """
    }
  }
  stages {
    stage('构建') {
      steps {
        container('docker') {
          script {
            docker.build("myapp:${env.BUILD_NUMBER}")
          }
        }
      }
    }
    stage('部署到K8s') {
      steps {
        sh '''
          echo "apiVersion: apps/v1" > deployment.yaml
          echo "kind: Deployment" >> deployment.yaml
          echo "metadata:" >> deployment.yaml
          echo " name: myapp" >> deployment.yaml
          echo "spec:" >> deployment.yaml
          echo " replicas: 2" >> deployment.yaml
          echo " selector:" >> deployment.yaml
          echo " matchLabels:" >> deployment.yaml
          echo " app: myapp" >> deployment.yaml
          echo " template:" >> deployment.yaml
          echo " metadata:" >> deployment.yaml
          echo " labels:" >> deployment.yaml
          echo " app: myapp" >> deployment.yaml
          echo " spec:" >> deployment.yaml
          echo " containers:" >> deployment.yaml
          echo " - name: myapp" >> deployment.yaml
          echo " image: myapp:${env.BUILD_NUMBER}" >> deployment.yaml
          kubectl apply -f deployment.yaml
        '''
      }
    }
  }
}
GitLab CI 与 Kubernetes 集成

GitLab CI 是 GitLab 内置的 CI/CD 工具,与 GitLab 代码仓库深度集成,可以通过 Runner 实现在 Kubernetes 集群中的构建和部署。

1. GitLab Runner 部署
# GitLab Runner 部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-runner
  namespace: gitlab-runner
spec:
  replicas: 1
  selector:
    matchLabels:
      name: gitlab-runner
  template:
    metadata:
      labels:
        name: gitlab-runner
    spec:
      serviceAccountName: gitlab-runner
      containers:
      - name: gitlab-runner
        image: gitlab/gitlab-runner:alpine-v14.10.1
        imagePullPolicy: Always
        volumeMounts:
        - name: config
          mountPath: /etc/gitlab-runner
        - name: docker-sock
          mountPath: /var/run/docker.sock
    volumes:
    - name: config
      emptyDir: {}
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
        type: Socket
2. .gitlab-ci.yml 示例
# .gitlab-ci.yml 示例
stages:
  - build
  - test
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

build-image:
  stage: build
  script:
    - echo "构建 Docker 镜像"
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main

test-app:
  stage: test
  script:
    - echo "运行单元测试"
    - docker run --rm $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA npm test
  dependencies:
    - build-image

deploy-to-k8s:
  stage: deploy
  script:
    - echo "部署到 K8s"
    - export KUBECONFIG=$KUBECONFIG_FILE
    - kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  only:
    - main
  when: manual
  environment:
    name: production
    url: https://myapp.example.com
GitHub Actions 与 Kubernetes 集成

GitHub Actions 是 GitHub 提供的 CI/CD 服务,可以通过工作流文件定义自动化构建和部署流程。

1. GitHub Actions 工作流示例
# .github/workflows/deploy.yml 示例
name: 构建和部署到 K8s

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      id-token: write

    steps:
    - name: 检出代码
      uses: actions/checkout@v3

    - name: 设置 Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: 登录到容器注册表
      uses: docker/login-action@v2
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    - name: 提取 Docker 镜像元数据
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

    - name: 构建并推送 Docker 镜像
      id: build-and-push
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}

    - name: 设置 kubectl
      uses: azure/setup-kubectl@v3
      with:
        version: 'v1.24.0'

    - name: 配置 K8s 集群访问
      uses: azure/k8s-set-context@v1
      with:
        kubeconfig: ${{ secrets.KUBE_CONFIG_DATA }}

    - name: 部署到 K8s
      run: |
          cat <          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: myapp-deployment
          spec:
            replicas: 2
            selector:
              matchLabels:
                app: myapp
            template:
              metadata:
                labels:
                app: myapp
              spec:
                containers:
                - name: myapp
                  image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
                  ports:
                  - containerPort: 80
          EOF

    - name: 验证部署
      run: |
        kubectl rollout status deployment/myapp-deployment
        kubectl get services -o wide
CI/CD 最佳实践
安全最佳实践
  • 使用服务账户和 RBAC 授权
  • 将敏感信息存储在 Secret 中
  • 启用镜像扫描和安全审计
  • 使用多阶段构建减少攻击面
性能最佳实践
  • 使用缓存加速构建过程
  • 并行执行测试任务
  • 优化 Docker 镜像大小
  • 使用资源限制避免资源争用
CI/CD 故障排除
常见问题可能原因解决方案
构建权限不足 服务账户权限配置不当 配置正确的 RBAC 权限
镜像推送失败 镜像仓库认证问题 检查认证凭据和网络连接
部署失败 Kubernetes API 访问问题 验证 kubeconfig 和网络策略
资源不足 集群资源分配不足 调整资源请求和限制
网络连接问题 网络策略或防火墙限制 配置正确的网络策略
常用命令
# 验证 Jenkins Pod 模板
kubectl apply -f jenkins-pod-template.yaml
# 检查 GitLab Runner 状态
kubectl get pods -n gitlab-runner
# 查看 GitHub Actions 日志
kubectl logs -f deployment/myapp-deployment
# 测试部署状态
kubectl rollout status deployment/myapp-deployment