18.7.2 Jenkins与Docker构建与镜像管理

Jenkins与Docker构建与镜像管理#

Jenkins与Docker集成的目标是实现构建环境一致、镜像可追溯、交付流程自动化。以下包含原理草图、安装准备、流水线示例、命令解释、排错与练习。

原理与流程草图

文章图片

1. 环境安装与准备(Docker引擎 + Jenkins Agent)
- 目标:让Jenkins构建节点具备Docker能力,并可访问镜像仓库。

安装Docker(Ubuntu示例)

# 1) 安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 2) 添加Docker官方源
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 3) 安装Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# 4) 将Jenkins用户加入docker组
sudo usermod -aG docker jenkins
sudo systemctl restart docker

验证Docker权限

# 期望输出:Docker版本信息
sudo -u jenkins docker version

命令解释
- usermod -aG docker jenkins:把jenkins用户加入docker组,避免需要sudo。
- docker version:验证Docker客户端/服务端正常工作。


2. Jenkins Pipeline构建与推送镜像(完整示例)
以下示例包含构建、标签、推送与扫描,并说明关键参数。

Dockerfile(示例)

# ./Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["python", "app.py"]

Jenkinsfile(Pipeline示例)

// Jenkinsfile
pipeline {
  agent { label 'docker-agent' }

  environment {
    REGISTRY = "harbor.example.com"
    IMAGE_NAME = "ops/demo-app"
    IMAGE_TAG = "${env.BUILD_NUMBER}-${env.GIT_COMMIT[0..7]}"
    FULL_IMAGE = "${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
  }

  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }

    stage('Build Image') {
      steps {
        sh '''
          # 构建镜像,--pull 确保基础镜像最新
          docker build --pull -t ${FULL_IMAGE} .
        '''
      }
    }

    stage('Tag Latest') {
      steps {
        sh '''
          # 打latest标签,便于测试或回滚
          docker tag ${FULL_IMAGE} ${REGISTRY}/${IMAGE_NAME}:latest
        '''
      }
    }

    stage('Scan Image') {
      steps {
        sh '''
          # 使用Trivy扫描镜像漏洞,发现高危直接失败
          trivy image --exit-code 1 --severity HIGH,CRITICAL ${FULL_IMAGE}
        '''
      }
    }

    stage('Push Image') {
      steps {
        withCredentials([usernamePassword(credentialsId: 'harbor-cred',
          usernameVariable: 'HARBOR_USER',
          passwordVariable: 'HARBOR_PASS')]) {
          sh '''
            echo "${HARBOR_PASS}" | docker login ${REGISTRY} -u "${HARBOR_USER}" --password-stdin
            docker push ${FULL_IMAGE}
            docker push ${REGISTRY}/${IMAGE_NAME}:latest
          '''
        }
      }
    }
  }

  post {
    always {
      sh '''
        # 清理本地镜像,避免磁盘占满
        docker image rm ${FULL_IMAGE} ${REGISTRY}/${IMAGE_NAME}:latest || true
      '''
    }
  }
}

关键命令解释
- docker build --pull:强制拉取基础镜像,避免使用过期层。
- docker tag:为同一镜像添加不同标签。
- docker push:推送到仓库,便于部署环境拉取。
- trivy image --exit-code 1:高危漏洞存在时流水线直接失败。


3. 镜像命名与标签规范示例
建议格式:应用名:版本-构建号-提交哈希

harbor.example.com/ops/demo-app:1.2.3-105-a1b2c3d4
harbor.example.com/ops/demo-app:latest

4. 仓库配置与登录(Harbor示例)
手工登录(排障时验证)

docker login harbor.example.com -u opsuser -p '******'
# 预期输出:Login Succeeded

Harbor项目结构示例

harbor.example.com/
  ops/
    demo-app
    api-service

5. 常见问题与排错
- 权限报错:Got permission denied while trying to connect to the Docker daemon socket

# 解决:将jenkins用户加入docker组并重新登录
sudo usermod -aG docker jenkins
sudo systemctl restart docker
# 重新触发构建或重启agent
  • 磁盘占满:no space left on device
# 清理dangling镜像
docker image prune -f
# 清理未使用容器/网络/卷(谨慎使用)
docker system prune -f
  • 推送失败:denied: requested access to the resource is denied
# 验证仓库权限与项目存在
docker login harbor.example.com
# 检查镜像名是否含有正确namespace

6. 练习与实践任务
1. 构建练习:基于上面的Dockerfile与Jenkinsfile完成一次构建并推送到Harbor,提交构建日志截图。
2. 标签策略练习:为镜像同时打v1.0.0latest标签,验证拉取与运行。
3. 漏洞扫描练习:在Dockerfile中引入一个已知高危依赖,验证Trivy是否阻断发布。
4. 排错练习:手动移除docker组权限,观察构建报错并修复。

以上内容可直接落地为企业级构建与镜像管理基线,为后续Kubernetes部署提供可追溯的制品。