【转载】jenkins 容器环境中调用docker

转载来自https://juejin.cn/post/7219899306946199610

// 编辑jenkins 的docker-compose.yml 文件

// docker-compose.yml文件内容 ----------------
version: "3.1"
services:
  jenkins:
        image: jenkins/jenkins:2.361.4-lts
        // 因为下面/usr/bin/docker 是root创建的,所以也要用root来登录
        user: root
        container_name: jenkins
        ports:
          - 8080:8080
          - 50000:50000
        privileged: true
        volumes:
          // 这里是为了为jenkins容器能调用host主机的docker所做的映射
          - /usr/bin/docker:/usr/bin/docker
          // 此映射卷主要用于存储jenkins的配置文件到当前目录下
          - ./data/:/var/jenkins_home/
          // 此映射卷主要用于执行docker镜像内的docker命令执行 共享当前docker的状态
          - /var/run/docker.sock:/var/run/docker.sock

当前在jenkins 容器中调用docker的方式有三种

  1. 调用第三方容器算力运行,例如aws,阿里提供的容器算力
  2. DinD即dockerindocker,当前用法虽然可以运行,但是不建议在生产环境中使用,在Docker内部运行Docker可能会导致许多问题,包括安全风险和潜在的性能问题。
  3. 调用jenkins host中的中的docker

DinD方式

host方式

【转载】jenkins 容器环境中调用docker_第1张图片
所以我们可以将这两个关键点在启动时就传给jenkins容器

    - /usr/bin/docker:/usr/bin/docker
    // 此映射卷主要用于执行docker镜像内的docker命令执行 共享当前docker的状态
    - /var/run/docker.sock:/var/run/docker.sock

这样的话我们就能正常的调用host的docker进行命令的执行如下图

注意点:因为调用的是host的docker,它就有可以杀掉自己的风险需要注意

到此我们就做好了jenkins调用docker的基础准备

pipline 调用 docker

pipline 调用docker有两种方式
1.使用docker原生命令写法
2.使用jenkins docker 插件写法

docker原生命令写法示例
优点: 易于理解与平时操作docker无异
缺点: 中间的所有步骤都要进行考虑流程复杂就有点费劲

pipeline {
  agent any
  stages {
    stage('Build Docker Image') {
      steps {
        script {
          sh "docker build -t my-image ."
        }
      }
    }
    stage('Push Docker Image') {
      steps {
        script {
          withCredentials([usernamePassword(credentialsId: 'registry-credentials-id', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
            sh "docker login -u ${USERNAME} -p ${PASSWORD} https://my-docker-registry.com"
            sh "docker tag my-image my-docker-registry.com/my-image:latest"
            sh "docker push my-docker-registry.com/my-image:latest"
          }
        }
      }
    }
    stage('Deploy Docker Image') {
      steps {
        script {
          sh "docker pull my-docker-registry.com/my-image:latest"
          sh "docker stop my-container || true"
          sh "docker rm my-container || true"
          sh "docker run -d --name my-container -p 8080:8080 my-docker-registry.com/my-image:latest"
        }
      }
    }
  }
}

jenkins docker 插件写法
必须在jenkins上安装这个几个插件
【转载】jenkins 容器环境中调用docker_第2张图片

以下是一个使用Jenkins Declarative Pipeline语法的示例

pipeline {
    agent {
        docker {
            image 'node:14'
            args '-p 3000:3000' // 指定端口映射
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'npm install' // 在Docker容器中运行npm install命令
            }
        }
        stage('Test') {
            steps {
                sh 'npm test' // 在Docker容器中运行npm test命令
            }
        }
    }
        stage('build docker images') {
            steps {
                script {
                    sh 'docker run -itd --name ${DOCKER_CONTAINER_NAME} nginx:latest'
                    sh 'docker cp ./dist/js ${DOCKER_CONTAINER_NAME}:/usr/share/nginx/html/'
                    sh 'docker cp ./dist/css ${DOCKER_CONTAINER_NAME}:/usr/share/nginx/html/'
                    sh 'docker cp ./dist/favicon.ico ${DOCKER_CONTAINER_NAME}:/usr/share/nginx/html/'
                    sh 'docker cp ./dist/index.html ${DOCKER_CONTAINER_NAME}:/usr/share/nginx/html/'
                    sh 'docker commit -m "add content" ${DOCKER_CONTAINER_NAME} newnginx:${DOCKER_CONTAINER_NAME}'
                    sh 'docker kill ${DOCKER_CONTAINER_NAME}'
                }
            }
        }
        stage('push images') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: 'd2ccd81c-5244-43dc-9228-59067b2d1827', passwordVariable: 'DOCKER_HUB_PASSWORD', usernameVariable: 'DOCKER_HUB_USERNAME')]) {
                        sh 'docker login http://harbor.com -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD'
                        sh 'docker tag newnginx:${DOCKER_CONTAINER_NAME} harbor.com/web/newnginx:latest'
                        sh 'docker push harbor.com/web/newnginx:latest'
                    }
                }
            }
        }
        stage('update service') {
            steps {
                script {
                    sh 'ssh [email protected] "docker pull 192.168.31.44/web/newnginx:latest && docker run -d -p 80:80 192.168.31.44/web/newnginx:latest"'
                }
            }
        }
}

Jenkins Declarative Pipeline语法可以在每个stages都独立定义个agent,可以将每个步骤到放入到独立的docker中运行,防止造成相互的环境干扰,阶段docker所生产的产物都是放在jenkins创建的一个workspace的一个文件夹中每条流水线都有自己独立的文件夹名称

你可能感兴趣的:(jenkins,docker,运维)