1. 项目背景与核心需求

在云原生技术栈中,Kubernetes已成为容器编排的事实标准,而完整的CI/CD流水线则是保障应用快速迭代的关键。传统方案中,Jenkins往往承担了从代码构建到部署的全流程工作,但随着系统复杂度提升,这种"大而全"的模式暴露出以下典型问题:

  • 构建与部署耦合度过高,任何环节故障都会阻断整个流程
  • 安全检测环节容易被忽视或简化,导致漏洞镜像流入生产环境
  • 多环境发布策略难以灵活配置,回滚机制不完善

本次实践的核心目标是在Kubernetes环境中构建分层式CI/CD流水线,通过以下技术组合实现安全左移:

  1. Jenkins :专注代码构建、单元测试等CI环节
  2. Spinnaker :负责多环境部署、金丝雀发布等CD环节
  3. 镜像扫描 :在制品入库前进行漏洞检测,建立安全门禁

2. 技术架构设计

2.1 整体工作流设计

graph LR
    A[代码提交] --> B(Jenkins构建)
    B --> C{镜像扫描}
    C -->|通过| D[推送Harbor]
    D --> E(Spinnaker部署)
    C -->|拒绝| F[失败通知]

2.2 关键组件选型对比

组件 职责范围 优势 局限性
Jenkins CI阶段 丰富的插件生态,灵活的Pipeline编排 复杂部署策略支持较弱
Spinnaker CD阶段 原生支持K8s,可视化发布策略 学习曲线陡峭
Trivy 基础扫描 集成简单,扫描速度快 规则库相对精简
Anchore 深度扫描 策略引擎灵活,支持自定义规则 资源消耗大,部署复杂

实际部署时采用混合扫描方案:Harbor内置Trivy做快速初筛,关键镜像使用Anchore进行深度分析

3. 镜像扫描实现细节

3.1 Harbor Trivy集成方案

3.1.1 API调用示例
stage('Trivy Scan') {
    steps {
        script {
            def scanAPI = "https://harbor.example.com/api/v2.0/projects/${project}/repositories/${repo}"
            sh """
                curl -X POST "${scanAPI}/artifacts/${tag}/scan" \
                -H "accept: application/json" \
                -u ${creds}
            """
            // 轮询扫描结果
            def retry = 0
            while(retry < 30) {
                def result = sh(returnStdout: true, 
                    script: """curl -s "${scanAPI}/artifacts/${tag}?page=1&page_size=10&with_scan_overview=true" \
                    -H "accept: application/json" \
                    -u ${creds} | jq -r '.scan_overview[].severity'""")
                if (result != 'null') break
                sleep 10
                retry++
            }
        }
    }
}
3.1.2 实践痛点
  • API返回结果需要二次解析,无法直接集成到Jenkins报告
  • 扫描日志与漏洞详情分离,审计追溯困难
  • 缺乏质量门禁自动拦截机制

3.2 Anchore深度集成方案

3.2.1 Helm部署优化
# values.yaml关键配置
postgresql:
  persistence:
    size: 50Gi

anchoreGlobal:
  defaultAdminPassword: "StrongPass!123"
  defaultAdminEmail: "admin@example.com"

anchoreApi:
  ingress:
    enabled: true
    hosts: ["anchore.example.com"]
  resources:
    requests:
      memory: 1Gi

anchoreEnterpriseUi:
  enabled: false  # 社区版禁用企业UI
3.2.2 Jenkins插件配置
  1. 安装Anchore Container Scanner插件
  2. 系统配置中添加Anchore服务端点:
    • Engine URL: http://anchore-engine.anchore.svc:8228
    • Engine Username: admin
    • Engine Password: StrongPass!123
  3. 配置扫描策略阈值(示例):
    • 阻断条件:高危漏洞数>0 或 总漏洞数>50
3.2.3 私有仓库认证
# 进入Anchore引擎容器执行
anchore-cli registry add harbor.internal.com registry-user registry-pass --insecure

4. 完整Pipeline实现

4.1 多阶段流水线结构

pipeline {
    agent { label 'build-slave' }
    environment {
        HARBOR_REG = 'harbor.example.com'
        PROJECT = 'devops'
    }
    stages {
        stage('Checkout') {
            steps { git branch: 'main', url: 'git@example.com:repo/app.git' }
        }
        
        stage('Build') {
            steps {
                sh 'docker build -t ${HARBOR_REG}/${PROJECT}/${JOB_NAME}:${BUILD_ID} .'
            }
        }
        
        stage('Trivy Quick Scan') {
            steps {
                harborScan(
                    harborUrl: 'https://${HARBOR_REG}',
                    credentialsId: 'harbor-creds',
                    project: PROJECT,
                    repository: JOB_NAME,
                    tag: BUILD_ID
                )
                // 结果校验逻辑...
            }
        }
        
        stage('Anchore Deep Scan') {
            steps {
                script {
                    def imageRef = "${HARBOR_REG}/${PROJECT}/${JOB_NAME}:${BUILD_ID}"
                    writeFile file: 'anchore_images', text: "${imageRef} ${WORKSPACE}/Dockerfile"
                    anchore name: 'anchore_images', 
                           engineRetries: 120,
                           bailOnFail: true
                }
            }
        }
        
        stage('Deploy') {
            when { expression { currentBuild.resultIsBetterOrEqualTo('SUCCESS') } }
            steps {
                sh """
                    echo "IMAGE=${HARBOR_REG}/${PROJECT}/${JOB_NAME}:${BUILD_ID}" > deploy.properties
                    echo "ENV=staging" >> deploy.properties
                """
                archiveArtifacts 'deploy.properties'
            }
        }
    }
}

4.2 安全门禁策略配置

在Anchore控制台创建自定义策略(示例):

{
  "action": "STOP",
  "gate": "vulnerabilities",
  "trigger": "package",
  "params": [
    {
      "name": "package_type",
      "value": "all"
    },
    {
      "name": "severity_comparison",
      "value": ">="
    },
    {
      "name": "severity",
      "value": "high"
    }
  ]
}

5. 生产环境调优建议

5.1 性能优化方案

  1. 扫描缓存 :配置Anchore的analyzer组件持久化存储

    analyzer:
      extraVolumeMounts:
        - name: analysis-cache
          mountPath: /analysis_scratch
      extraVolumes:
        - name: analysis-cache
          persistentVolumeClaim:
            claimName: anchore-cache-pvc
    
  2. 资源配额 (针对100节点集群):

    # Anchore引擎资源请求
    resources:
      requests:
        cpu: "2"
        memory: "4Gi"
      limits:
        cpu: "4"
        memory: "8Gi"
    

5.2 高可用部署

# values.yaml片段
anchoreApi:
  replicaCount: 3
  podDisruptionBudget:
    maxUnavailable: 1

anchoreCatalog:
  replicaCount: 2

postgresql:
  replication:
    enabled: true
    slaveReplicas: 2

6. 典型问题排查指南

6.1 常见错误与解决方案

现象 根本原因 解决方案
Anchore扫描超时 大镜像分析时间超过默认阈值 调整 engineRetries 参数(建议≥300)并增加analyzer资源
私有仓库镜像拉取失败 未正确配置registry认证 通过 anchore-cli registry add 添加凭证,注意使用 --insecure 跳过证书验证
策略评估结果不符合预期 默认策略规则过于宽松 在Anchore控制台创建自定义策略,明确漏洞级别和包类型过滤条件
Jenkins插件报SSL错误 自签名证书不被信任 将CA证书导入Java信任库: keytool -import -alias anchore -file ca.crt -keystore $JAVA_HOME/lib/security/cacerts

6.2 日志分析技巧

  1. Anchore引擎日志

    kubectl logs -n anchore deploy/anchore-engine-api -f | grep -E 'ERROR|WARN'
    
  2. Jenkins插件调试 : 在Pipeline开始前添加:

    anchore debug: true, bailOnFail: false
    

7. 安全基线建议

  1. 镜像扫描标准

    • 基础镜像必须来自受信任源(如官方仓库或内部基线镜像)
    • 禁止包含已知高危漏洞(CVSS≥7.0)
    • 非必要组件不包含调试工具(telnet/nc等)
  2. 运行时防护

    # PodSecurityPolicy示例
    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: restricted
    spec:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      requiredDropCapabilities:
        - ALL
    

通过这套方案的实施,某金融客户将高危镜像拦截率从32%提升至89%,部署失败率下降65%。关键经验是:扫描策略需要随威胁情报持续更新,建议每月review一次规则库。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐