Build/push 图片来自 jenkins 运行 docker

Build/push image from jenkins running in docker

我有两个 docker 容器 - 一个 运行 jenkins 和一个 运行 docker 注册表。我想从 jenkins build/push 图像到 docker 注册表。我如何以简单安全的方式实现这一点(意味着没有黑客攻击)?

最简单的方法是确保 jenkins 容器和 registry 容器在同一台主机上。然后,您可以将 docker 套接字挂载到 jenkins 容器上,并使用主机中的 dockerd 将映像推送到注册表。 /var/run/docker.sockdockerd 正在监听的 unix 套接字。

通过挂载 docker 套接字,任何 docker 命令你 运行 从那个容器中执行,就好像它是主机一样。

$ docker run -dti --name jenkins -v /var/run/docker.sock:/var/run/docker.sock jenkins:latest

我在 Jenkins docker 容器中使用这种类型的工作流,好消息是它不需要任何黑客技术即可完成。有些人使用 "docker in docker" 来完成此操作,但如果这是你想要的路线,我无法帮助你,因为我没有这样做的经验。我将在这里概述的是如何使用现有的 docker 服务(运行ning jenkins 容器)来进行构建。

我会做一些假设,因为你没有指定你的设置是什么样的:

  • 您运行将两个容器安装在同一台主机上
  • 您没有使用 docker-compose
  • 你不是运行宁docker群(或群模式)
  • 您正在 Linux
  • 使用 docker

如果上述任何条件不成立,这可以很容易地修改,但我需要一个基线作为起点。

您将需要以下内容:

  • 从 Jenkins 容器访问 docker 运行在主机上
  • 从 Jenkins 容器访问 registry 容器

Prerequisites/Setup

设置起来非常简单。在让 Jenkins 访问主机上的 运行ning docker 服务的情况下,您可以使用以下两种方法之一。 1) 通过 TCP 和 2) 通过 docker unix 套接字。如果您已经 docker 侦听 TCP,您只需记下主机的 IP 地址和默认 docker TCP 端口号(2375 或 2376,取决于您是否使用 TLS)以及 TLS您可能拥有的配置。

如果您不想启用 docker TCP 服务,它会稍微复杂一些,但您可以在 /var/run/docker.sock 处使用 UNIX 套接字。这需要您将套接字绑定挂载到 Jenkins 容器。您可以通过在 运行 jenkins:

时将以下内容添加到 运行 命令来实现

-v /var/run/docker.sock:/var/run/docker.sock

您还需要在主机系统上创建一个与容器中的 jenkins 用户具有相同 UID 的 jenkins 用户,然后将该用户添加到 docker 组。

詹金斯

您现在需要 Docker build/publish 插件,例如 CloudBees Docker Build and Publish plugin 或其他一些插件,具体取决于您的需要。您需要注意以下配置项:

  • Docker URI/URL 将类似于 tcp://<HOST_IP>:2375unix:///var/run/docker.sock,具体取决于我们如何进行上述设置。如果您将 TCP 和 TLS 用于 docker 服务,您需要将 Jenkins 实例的 TLS 客户端证书作为 "Docker Host Certificate Authentication" 上传到 Jenkins 中您常用的凭据部分。
  • Docker 注册表 URL 将是注册表容器的 URL,而不是本地主机。它可能类似于 http://<HOST_IP>:32768 或类似内容,具体取决于您的配置。您也可以 link 容器,但如果您稍后将容器移动到单独的主机,则这不容易扩展。您还需要在相应的凭据部分中以 username/password 对的形式添加用于登录注册表的凭据。

我已经完成了这个确切的设置,所以我会给你一个 "tl;dr" 的版本,因为这里的深入已经超出了 Whosebug 的范围:

  • 在容器中安装 PID1 处理程序文件(即 tini)。您需要它来处理信号和处理收割。这将是您的入口点。
  • 安装一些过程控制服务(即supervisord)包。通常 运行 容器中的多个服务 推荐,但在这种特殊情况下,您的选择 非常 有限。
  • 安装 Java/Jenkins 软件包或基于他们的 DockerHub 图像构建您的图像。
  • 添加 dind (Docker-in-Docker) 包装器脚本。 This 是我的配置依据。
  • 为进程控制服务创建配置以启动 Jenkins(作为 jenkins 用户)和 dind 包装器(作为 root)。
  • 将 jenkins 用户添加到 Docker 文件中的 docker 组
  • 运行 docker 带有 --privileged 标志的容器(DinD 需要它)。
  • 大功告成!

感谢您的意见!经过一些实验,我想到了这个。

docker 运行 -d \ -p 8080:8080 \ -p 50000:50000 \ --名字詹金斯\ -v <code>pwd/data/jenkins:/var/jenkins_home \ -v /用户/.../.docker/machine/machines/docker:/用户/.../.docker/machine/machines/docker \ -e DOCKER_TLS_VERIFY="1" \ -e DOCKER_HOST="tcp://192.168.99.100:2376" \ -e DOCKER_CERT_PATH="/用户/.../.docker/machine/machines/docker" \ -e DOCKER_MACHINE_NAME="docker" \ johannesw/jenkins-docker-cli

如果你使用管道,你可以安装这个Docker插件https://plugins.jenkins.io/docker-workflow, 在 Jenkins 上创建凭证资源,以访问 Docker 注册表,并在您的管道中执行此操作:

    stage("Build Docker image") {
        steps {
            script {
                docker_image = docker.build("myregistry/mynode:latest")
            }
        }
    }

    stage("Push images") {
        steps {
            script {

                withDockerRegistry(credentialsId: 'registrycredentials', url: "https://myregistry") {
                    docker_image.push("latest")
                }
            }
        }
    }

完整示例位于:https://pillsfromtheweb.blogspot.com/2020/06/build-and-push-docker-images-with.html