在 jenkins 管道中升级 docker 容器

Upgrading a docker container in jenkins pipeline

我有以下管道:

pipeline {
    environment {
    registry = "my-docker"
    registryCredential = 'dockerhubcredentials'
    dockerImage = ''
    }

    agent any
    stages {
            stage('Cloning our Git') {
                steps {
                git 'my-git'
                }
            }

            stage('Building Docker Image') {
                steps {
                    script {
                        dockerImage = docker.build registry + ":$BUILD_NUMBER"
                    }
                }
            }

            stage('Deploying Docker Image to Dockerhub') {
                steps {
                    script {
                        docker.withRegistry('', registryCredential) {
                        dockerImage.push()
                        }
                    }
                }
            }

            stage('Cleaning Up') {
                steps{
                  sh "docker rmi --force $registry:$BUILD_NUMBER"
                }
            }
            
            stage('Upgrade docker') {
                steps{
                    // sh docker stop *Current CONTAINERID* (How do I get it?)
                    // sh docker run my-container:*NEW_BUILD_NUMBER*
                }
            }
        }
    }

现在我正在尝试添加升级 docker 阶段,所有其他步骤都运行良好。

  1. 如何获取我要查找的容器的当前容器 ID 以停止它?

  2. 停止后我想拉动并启动新的(我需要新的内部版本号,可能 $BUILD_NUMBER + 1,我想我可以做到 - 如果我想纠正我'我错了。

  3. 在 jenkins 中升级 docker 容器是个好习惯吗?没找到例子,感觉很普通的自动化流程。

如果我们解决您试图在管道中实现的两个步骤并实施它们,那么您的前两个文字问题将变得无关紧要,因为它们不会影响实施。

首先,停止容器:

// sh docker stop *Current CONTAINERID* (How do I get it?)

你的管道永远不会 运行 是容器,所以你没有容器可以停止,可以安全地跳过这一步方法。

其次,运行安装新容器:

// sh docker run my-container:*NEW_BUILD_NUMBER*

新容器将来自您的新图像,并且您的新图像是 return 对象的一部分,来自您的 docker.build 全局变量方法。因此,我们可以 运行 您的新容器,例如:

// three methods available here
dockerImage.run([args, command])
dockerImage.withRun[(args[, command])] {…}
dockerImage.inside[(args)] {…}

因为您将 return 分配给了 dockerImage

对于第三个问题,构建一个新的 Docker 图像和 运行 将一个新的容器作为管道的一部分是绝对常见的。如果需要,您可以向管道添加各种其他阶段,例如将新映像部署到 Kubernetes 集群。

如果您通过 Jenkins 管道部署它,您通常需要直接指定容器的名称:

sh "docker run -d --name my-container $registry:$BUILD_NUMBER"

获得该名称后,您可以使用该名称清理旧容器,而无需知道容器 ID

sh 'docker stop my-container'
sh 'docker rm my-container'

另一个重要的推论是,您可能不应该 docker rmidocker run 之前新建映像。 Docker 将拉取您刚刚推送的图像,但您一分钟前刚刚拥有该图像。您可能想要清理旧图像,也许可以使用 docker system prune 清理任何未使用的东西。

将它们放在一起,管道的末端将是:

environment {
  ...
  containerName = 'my-container'
}

stages {
  ...
  stage('Upgrade docker') {
    steps {
      sh script: "docker stop $containerName", returnStatus: true
      sh script: "docker rm $containerName", returnStatus: true
      sh "docker run -d --name $containerName $registry:$BUILD_NUMBER"
    }
  }
  stage('Cleaning up') {
    steps {
      sh "docker system prune --all --force"
    }
  }
}