Docker 安装

Docker 是一个在称为 "容器"(或 Docker 容器)的隔离环境中运行应用程序的平台。像Jenkins 这样的应用程序可以作为只读 "镜像"(或 Docker 镜像)被下载,每个镜像都作为一个容器在 Docker 中运行。一个 Docker 容器实际上是一个 Docker 镜像的 "运行实例"。从这个角度来看,镜像或多或少是永久存储的(就镜像更新发布而言),而容器则是临时存储的。请在 Docker 文档的 Get Started, Part 1: Orientation and Setup 中阅读更多关于这些概念。

Docker 的基础平台和容器设计意味着单个的 Docker 镜像(对于任何特定的应用程序,如 Jenkins)可以运行在任何支持的操作系统(macOS、Linux 和 Windows)或同样运行着 Docker 的云服务(AWS 和 Azure)。

安装 Docker

要在你的操作系统上安装Docker,请遵循 Guided Tour page 的 "先决条件 "部分。

作为替代解决方案,你可以访问 Dockerhub 并选择适合咱们操作系统或云服务的 Docker 社区版。按照他们网站上的安装说明进行操作。

如果你在基于 Linux 的操作系统上安装 Docker,请确保你对 Docker 进行配置,使其可以作为非 root 用户进行管理。请在 Docker 文档的 Linux 安装后步骤 页面阅读更多相关信息。该页面还包含了关于如何配置 Docker 在系统引导时启动的信息。

先决条件

最低硬件要求:

  • 256MB 运行内存 RAM;
  • 1GB 的磁盘空间(但如果作为Docker容器运行Jenkins,建议最小为10GB)。

为小团队推荐的硬件配置:

  • 4GB 以上的运行内存 RAM;
  • 50GB 以上的磁盘空间。

软件要求:

下载和运行 Docker 中的 Jenkins

有好几个 Jenkins 的 Docker 镜像可以使用。

推荐使用的 Docker 镜像是官方的 jenkins/jenkins 镜像(来自 Docker Hub 资源库)。这个镜像包含 Jenkins 当前的长期支持(LTS)版本(可用于生产)。但是这个镜像里面没有 docker CLI,也没有捆绑常用的 Blue Ocean 插件和功能。这意味着,如果你想使用 Jenkins 和 Docker 的全部功能,你或许要通过下面描述的安装过程。

每次发布新的 Jenkins Docker 版本时,都会发布一个新的 jenkins/jenkins 镜像。你可以在 标签页 上看到以前发布的 jenkins/jenkins 镜像的版本列表。

在 macOS 和 Linux 上

  1. 打开一个终端窗口;

  2. 使用以下的 docker network create 命令在 Docker 中创建一个 桥接网络

docker network create jenkins
  1. 为了在 Jenkins 节点内执行 Docker 命令,使用以下的 docker run 命令下载并运行 docker:dind Docker 镜像:
docker run \
  --name jenkins-docker \
  --rm \
  --detach \
  --privileged \
  --network jenkins \
  --network-alias docker \
  --env DOCKER_TLS_CERTDIR=/certs \
  --volume jenkins-docker-certs:/certs/client \
  --volume jenkins-data:/var/jenkins_home \
  --publish 2376:2376 \
  docker:dind \
  --storage-driver overlay2
  • (可选的)--name jenkins-docer 命令行标志,指定运行镜像时要使用的 Docker 容器名称。默认情况下,Docker 将为该容器生成一个唯一的名称;

  • (可选的)--rm 命令行开关,关闭时自动删除 Docker 容器(Docker 镜像的实例);

  • (可选的) --detach 命令行开关,在后台运行 Docker 容器。稍后可以通过运行 docker stop jenkins-docker 停止此实例;

  • --privileged 命令行开关,在 Docker 中运行 Docker 目前需要特权访问才能正常运行。较新的 Linux 内核版本可能会放宽此要求;

  • --network jenkins 命令行参数,这与前面步骤中创建的网络相对应;

  • --network alias docker 命令行参数,使 Docker 容器中的 Docker 在 jenkins 网络中作为主机名 docker 可用;

  • --env DOCKER_TLS_CERTDIR=/certs 命令行参数,在 Docker 服务器中启用 TLS。由于使用了特权容器,因此建议这样做,尽管他需要使用下面会描述的共享卷。此环境变量控制管理 Docker TLS 证书的根目录;

  • --volume jenkins-docker-certs:/certs/client 命令行参数,将容器内的 /certs/client 目录映射到上面创建的名为 jenkins-docker-certs 的 Docker 卷;

  • --volume jenkins-data:/var/jenkins_home 命令行参数,将容器内的 /var/jenkins_home 目录映射到名为 jenkins-data 的 Docker 卷。这将允许由该 Docker 容器的 Docker 守护进程控制的其他 Docker 容器从 Jenkins 挂载数据;

  • (可选的)--publish 2376:2376 命令行参数,在主机上暴露 Docker 守护程序端口。这对于在主机上执行 docker 命令以控制此内部 Docker 守护进程很有用;

  • docker:dind 命令行参数,docker:dind 镜像本身。这个镜像可以在运行前通过以下命令下载:docker image pull docker:dind

  • Docker 卷的存储驱动。参见 "Docker存储驱动",了解支持的选项。

注意:如果复制和粘贴上面的命令片段不起作用,请尝试复制和粘贴下面的无注释版本:

docker run --name jenkins-docker --rm --detach \
  --privileged --network jenkins --network-alias docker \
  --env DOCKER_TLS_CERTDIR=/certs \
  --volume jenkins-docker-certs:/certs/client \
  --volume jenkins-data:/var/jenkins_home \
  --publish 2376:2376 \
  docker:dind --storage-driver overlay2
  1. 通过执行以下两个步骤,定制官方 Jenkins Docker 镜像:

a. 使用以下内容创建 Dockerfile:

FROM jenkins/jenkins:2.387.3
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
  https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"

b. 从这个 Docker 文件构建一个新的 docker 镜像,并给这个镜像起一个有意义的名字,例如 "myjenkins-blueocean:2.387.3-1":

docker build -t myjenkins-blueocean:2.387.3-1 .

请记住,如果以前没有做过,上述过程将自动下载官方的 Jenkins Docker 镜像。

  1. 使用以下 docker run 命令在 Docker 中作为容器运行咱们自己的 myjenkins-blueocean:2.387.3-1 镜像:
docker run \
  --name jenkins-blueocean \
  --restart=on-failure \
  --detach \
  --network jenkins \
  --env DOCKER_HOST=tcp://docker:2376 \
  --env DOCKER_CERT_PATH=/certs/client \
  --env DOCKER_TLS_VERIFY=1 \
  --publish 8080:8080 \
  --publish 50000:50000 \
  --volume jenkins-data:/var/jenkins_home \
  --volume jenkins-docker-certs:/certs/client:ro \
  myjenkins-blueocean:2.387.3-1
  • (可选的) --name jenkins-blueocean 命令行参数,指定 Docker 镜像的这个实例的 Docker 容器名称;

  • --restart=on-failure 命令行开关,如果容器停止了,总是要重新启动他。如果他被手动停止,则只有当 Docker 守护进程重新启动或容器本身被手动重新启动时,他才会被重新启动;

  • (可选的) --detach 命令行开关,在后台运行当前的容器(即 "detached" 模式)并输出容器的 ID。如果你不指定这个选项,那么这个容器的运行 Docker 日志会在终端窗口中输出;

  • --network jenkins 命令行参数,将这个容器连接到前面步骤中定义的 jenkins 网络。这使得上一步骤中的Docker 守护程序通过主机名 docker 对这个 Jenkins 容器可用;

  • --env DOCKER_HOST=tcp://docker:2376 --env DOCKER_CERT_PAT=/certs/client --env DOCKER_TLS_VERIFY=1 命令行参数,指定由 dockerdocker-compose 和其他 Docker 工具使用的环境变量,以连接到上一步的 Docker 守护进程;

  • --publish 8080:8080 命令行参数,将当前容器的 8080 端口映射(即 "发布")到主机上的 8080 端口。第一个数字代表主机上的端口,而最后一个数字代表容器的端口。因此,如果你为这个选项指定了 -p 49000:8080,那么咱们将通过 49000 端口访问主机上的 Jenkins;

  • (可选的) --publish 50000:50000 命令行参数,将当前容器的 50000 端口映射到主机上的 50000 端口。只有当你在其他机器上设置了一个或多个入站的 Jenkins 代理,而这些代理又与你的 jenkins-blueocean 容器(Jenkins "控制器")交互时,这才是必要的。入站的 Jenkins 代理默认通过 TCP 50000 端口与 Jenkins 控制器通信。你可以通过 安全,Security 页面在你的 Jenkins 控制器上改变这个端口号。如果你想把你的 Jenkins 控制器的 入站 Jenkins 代理的 TCP 端口 改为51000(比如),那么你需要重新运行 Jenkins (通过这个 docker run ... 命令)并以类似 --publish 52000:51000 的命令行参数,指定这个 "发布" 选项,其中最后一个值与 Jenkins 控制器上的这个变化值一致,第一个值是承载 Jenkins 控制器的机器上的端口号。入站的 Jenkins 代理在该端口(本例中为 52000)与 Jenkins 控制器通信。注意,WebSocket 代理 不需要这种配置;

  • --volume jenkins-data:/var/jenkins_home 命令行参数,将容器中的 /var/jenkins_home 目录映射到名为 jenkins-dataDocker 卷。除了将 /var/jenkins_home 目录映射到 Docker 卷之外,咱们还可以将此目录映射到计算机本地文件系统上的一个目录。例如,指定选项 --volume $HOME/jenkins:/var/jenkins_home 会将容器的 /var/jenkins_home 目录映射到本地计算机上 $HOME 目录中的 jenkins 子目录,通常是 /Users/<your-username>/jenkins/home/<你的用户名>/jenkins。注意,如果你改变了这个源卷或目录,上面的 docker:dind 容器的卷需要更新以与之匹配;

  • myjenkins-blueocean:2.387.3-1 命令行参数,咱们在上一步中构建的 Docker 映像的名称。

注意:如果复制和粘贴上面的命令片段不起作用,请尝试复制和粘贴这里的无注释版本:

docker run --name jenkins-blueocean --restart=on-failure --detach \
  --network jenkins --env DOCKER_HOST=tcp://docker:2376 \
  --env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 \
  --publish 8080:8080 --publish 50000:50000 \
  --volume jenkins-data:/var/jenkins_home \
  --volume jenkins-docker-certs:/certs/client:ro \
  myjenkins-blueocean:2.387.3-1
  1. 继续进行 安装后的设置向导

在 Windows 系统上

Jenkins 项目提供的是 Linux 容器镜像,而不是 Windows 容器镜像。请确保您的 Docker for Windows 安装配置为运行 Linux 容器而不是 Windows 容器。有关 切换到 Linux 容器 的说明,请参阅 Docker 文档。一旦配置为运行 Linux 容器,步骤如下:

  1. 打开一个命令提示符窗口,与上面的 macOS 和 Linux 指示类似,做以下工作:

  2. 在 Docker 中创建一个桥接网络;

docker network create jenkins
  1. 运行一个 docker:dind Docker 镜像;
docker run --name jenkins-docker --rm --detach ^
  --privileged --network jenkins --network-alias docker ^
  --env DOCKER_TLS_CERTDIR=/certs ^
  --volume jenkins-docker-certs:/certs/client ^
  --volume jenkins-data:/var/jenkins_home ^
  --publish 2376:2376 ^
  docker:dind
  1. 通过执行以下两个步骤,定制官方 Jenkins Docker 镜像:

a. 使用以下内容创建 Dockerfile:

FROM jenkins/jenkins:2.387.3
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
  https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"

b. 从这个 Docker 文件建立一个新的 docker 镜像,并给这个镜像起一个有意义的名字,例如 "myjenkins-blueocean:2.387.3-1":

docker build -t myjenkins-blueocean:2.387.3-1 .

请记住,如果以前没有做过,上述过程将自动下载官方的 Jenkins Docker 镜像。

  1. 使用以下 docker run 命令在 Docker 中作为容器运行你自己的 myjenkins-blueocean:2.387.3-1 镜像:
docker run --name jenkins-blueocean --restart=on-failure --detach ^
  --network jenkins --env DOCKER_HOST=tcp://docker:2376 ^
  --env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 ^
  --volume jenkins-data:/var/jenkins_home ^
  --volume jenkins-docker-certs:/certs/client:ro ^
  --publish 8080:8080 --publish 50000:50000 myjenkins-blueocean:2.387.3-1
  1. 继续进行 安装后的设置向导

访问 Docker 容器

如果你有一些 Docker 方面的经验,并且你希望或需要通过终端/命令提示符使用 docker exec 命令来访问你的 Docker 容器,你可以在 docker exec 命令中添加一个选项,如 --name jenkins-tutorial。这将访问名为 "jenkins-tutorial" 的 Jenkins Docker 容器。

这意味着咱们可以使用 docker exec 命令访问咱们的 docker 容器(通过单独的终端/命令提示符窗口):

docker exec -it jenkins-blueocean bash

访问 Docker 日志

咱们可能需要访问 Jenkins 控制台日志,例如,在作为 安装后设置向导 一部分的 解锁 Jenkins 时。

Jenkins 控制台日志可以通过执行 docker run ... 命令的终端/命令提示窗口轻松访问。如果需要的话,咱们也可以通过咱们容器的 Docker 日志,使用以下命令访问 Jenkins 控制台日志:

docker logs <docker-container-name>

<docker-container-name> 可以通过 docker ps 命令获取。

访问 Jenkins 主目录

咱们可能需要访问 Jenkins 主目录,例如,检查 workspage 子目录中 Jenkins 构建的详细信息。

如果咱们把 Jenkins 主目录(/var/jenkins_home)映射到咱们机器的本地文件系统上(即在 上面docker run ... 命令中),那么咱们就可以通过咱们机器的常规终端/命令提示符访问该目录的内容。

否则,如果咱们在 docker run ... 命令中指定了 --volume jenkins-data:/var/jenkins_home 选项,咱们可以通过容器的终端/命令提示符使用 docker container exec 命令访问 Jenkins 主目录的内容:

docker container exec -it <docker-container-name> bash

如上 所述,<docker-container-name> 可以通过 docker container ls 命令获得。如果你在上面的 docker container run ... 命令中指定了 --name jenkins-blueocean 选项(参见 访问 Jenkins/Blue Ocean Docker容器),咱们可以简单地使用 docker container exec 命令:

docker container exec -it jenkins-blueocean bash

安装后设置向导

在使用上述程序之一(使用 Jenkins Operator 的安装除外)下载、安装和运行 Jenkins 后,安装后的设置向导开始。

这个设置向导带咱们完成几个快速的 "一次性" 步骤,以解锁 Jenkins、使用插件对其进行定制,并创建第一个管理员用户,咱们可以通过他继续访问 Jenkins。

解锁 Jenkins

当咱们首次访问新的 Jenkins 实例时,系统会要求咱们使用自动生成的密码解锁他。

  1. 浏览到 http://localhost:8080(或咱们在安装 Jenkins 时为其配置的那个端口),然后等待 Unlock Jenkins 页面出现。

解锁 Jenkins

  1. 从 Jenkins 控制台的日志输出,复制自动生成的字母数字密码(在两组星号之间)。

Jenkins 控制台的日志输出

注意

  • 命令:sudo cat /var/lib/jenkins/secrets/initialAdminPassword 将在控制台打印密码;

  • 如果你在 Docker 中使用官方的jenkins/jenkins 镜像运行 Jenkins,你可以使用 sudo docker exec ${CONTAINER_ID 或 CONTAINER_NAME} cat /var/jenkins_home/secrets/initialAdminPassword 来在控制台中打印密码,而不必进入容器。

  1. Unlock Jenkins 页面上,将此密码粘贴到 Administrator password 字段中,然后单击 Continue

注意

  • Jenkins 控制台日志指出了还可以获得该密码的位置(在 Jenkins 主目录中)。在新安装的 Jenkins 上必须在设置向导中输入这个密码,然后才能访问 Jenkins 的主用户界面。如果你碰巧跳过了安装向导中的后续用户创建步骤,这个密码也可以作为默认的管理员账户密码(用户名为 "admin")。

使用插件定制 Jenkins

解锁 Jenkins 后,会出现 Customize Jenkins 页面。作为初始设置的一部分,咱们可以在此处安装任意数量的有用插件。

点击给出的两个选项之一:

  • Install suggested plugins - 安装建议的插件集,这些插件是基于最常见的使用情况;
  • Select plugins to install - 选择最初要安装哪一组插件。当你第一次访问插件选择页面时,建议的插件被默认选择。

如果咱们不确定需要什么插件,就选择 Install suggested plugins。咱们可以在以后的时间点,通过 Jenkins 中的 Manage Jenkins > Plugins 页面安装(或删除)额外的 Jenkins 插件。

安装向导会显示正在配置的 Jenkins 及咱们选择的一组正在安装的 Jenkins 插件的进度。此过程可能需要几分钟时间。

创建首个管理员用户

最后,在 使用插件自定义 Jenkins 后,Jenkins 会要求您创建第一个管理员用户。

  1. Create First Admin User 页面出现时,请在相应字段中指定管理员用户的详细信息,然后单击 Save and Finish

  2. 当出现 Jenkins is ready 的页面时,点击 Start using Jenkins

注意

  • 此页面可能表明 Jenkins 几乎准备就绪! 相反,如果是这样,请单击 Restart
  • 如果一分钟后页面没有自动刷新,请使用你的网络浏览器手动刷新页面。
  1. 如果需要,使用咱们刚刚创建的用户的凭据登录到 Jenkins,咱们就可以开始使用 Jenkins 了!

更新 Jenkins

参考:New Jenkins Container And Update Jenkins (Docker)

  1. 得到新版 Jenkins WAR 文件的具体下载地址;

比如:https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.407/jenkins.war

  1. 登入 Jenkins 所在的 Docker 容器;
# 以 `-u 0` 来使用主机的 root 账号
docker container exec -u 0 -it jenkins-blueocean bash
  1. 使用第 1 步中所拷贝的 URI 地址,下载更新;
curl https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.407/jenkins.war -o jenkins.war
  1. 将其移动到正确位置;
mv ./jenkins.war /usr/share/jenkins

注意:可以先 cp /usr/share/jenkins/jenkins.war /usr/share/jenkins/jenkins.war.bakup 备份一下。

  1. 修改 jenkins.war 的权限;
chown jenkins:jenkins /usr/share/jenkins/jenkins.war
  1. 退出容器并重启该容器。
# 退出容器(在容器里)
exit

# 重启该容器(从咱们的服务器)
docker container restart jenkins-blueocean

大功告成!