使用 docker 设置保护 Jenkins master

Setup secured Jenkins master with docker

我想使用 docker 在 ec2 上设置一个安全的 Jenkins 主服务器。 我正在使用这里的标准 jenkins docker 文件:https://registry.hub.docker.com/_/jenkins/

默认情况下,它会打开一个不安全的 8080 http 端口。但是我希望它使用带 https 的标准 443 端口(起初我想使用自签名 ssl 证书)。

我对这个话题进行了一些研究,找到了几种可能的解决方案。我对 docker 并没有真正的经验,所以我仍然找不到一个我可以使用或实施的简单方法。以下是我发现的一些选项:

有没有经验的可以推荐我最好的解决方案?

P.S。我不确定 ec2 会给我带来多少麻烦,但我认为它只是在安全组中打开 443。

我会在同一个容器中同时使用 nginx 和 jenkins,并使用 supervisord 来管理这两个进程。使用内置工具保护不同的服务是一件痛苦的事; nginx 对所有服务的工作方式相同,并且易于配置。使用 docker-compose(是无花果)创建两个不同的容器并将它们与 docker 提供的带有链接的漂亮内部网络挂钩是可能的,并且在某些方面更好。问题是 运行ning pairs of jobs together 在像 marathon 这样的集群管理器中仍然没有得到很好的支持。告诉大多数服务 运行 单个容器比 运行 两个容器要容易得多,但要确保它们在同一主机上。

在 Docker 上学习了几个教程后,我发现最容易遵循的选项是数字 2。Jenkins docker 图像以一种您可以轻松将参数传递给 jenkins 的方式声明入口点.

假设您在 ubuntu ec2 实例的主文件夹中有作为 jenkins_keystore.jks 的密钥库(例如本例中的自签名)。以下是如何生成一个的示例:

keytool -genkey -keyalg RSA -alias selfsigned -keystore jenkins_keystore.jks -storepass mypassword -keysize 2048

现在您可以轻松地将 jenkins 配置为仅在 https 上 运行,而无需创建您自己的 docker 图像:

docker run -v /home/ubuntu:/var/jenkins_home -p 443:8443 jenkins --httpPort=-1 --httpsPort=8443 --httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=mypassword
  • -v /home/ubuntu:/var/jenkins_home 将主机主文件夹公开给 jenkins docker 容器
  • -p 443:8443将容器中的8443 jenkins端口映射到宿主机的443端口
  • --httpPort=-1 --httpsPort=8443 阻止 jenkins http 并在容器内的端口 8443 上使用 https 公开它
  • --httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=mypassword 提供已从主机主文件夹映射到容器 /var/jenkins_home/ 文件夹的密钥库。

otognan一样,我也建议做#2,但他的回答似乎已经过时了。

首先,使用 jenkins/jenkins:lts 图像,因为 jenkins 图像已弃用(参见 https://hub.docker.com/_/jenkins/

现在,让我们开始设置吧。您需要停止当前的 jenkins 容器以释放端口。

首先,您需要一个证书密钥库。如果你没有,你可以用

创建一个自签名的
keytool -genkey -keyalg RSA -alias selfsigned -keystore jenkins_keystore.jks -storepass mypassword -keysize 4096

接下来,让我们将 SSL 参数传递到 jenkins 容器中。这是我用来执行此操作的脚本:

read -s -p "Keystore Password:" password
echo
sudo cp jenkins_keystore.jks /var/lib/docker/volumes/jenkins_home/_data
docker run -d -v jenkins_home:/var/jenkins_home -v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -p 443:8443 -p 50000:50000 jenkins/jenkins:lts --httpPort=-1 --httpsPort=8443 --httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=$password
  • 此脚本提示用户输入密钥库密码
  • -v jenkins_home:/var/jenkins_home 创建一个名为 jenkins_home 的命名卷,按照约定恰好存在于 /var/lib/docker/volumes/jenkins_home/_data
    • 如果 /var/lib/docker/volumes/jenkins_home/_data 处的目录尚不存在,您需要在复制密钥库之前使用 docker volume 创建命名卷。
  • -p 443:8443将容器中的8443 jenkins端口映射到宿主机的443端口
  • --httpPort=-1 --httpsPort=8443 在容器内的 8443 端口(容器外的 443 端口)屏蔽 http 并暴露 https。
  • --httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=$password 提供您的密钥库,它存在于容器内的 /var/jenkins_home/jenkins_keystore.jks(容器外的 /var/lib/docker/volumes/jenkins_home/_data/jenkins_keystore.jks)。
  • -v /var/run/docker.sock:/var/run/docker.sock 是可选的,但这是允许您的 jenkins 实例启动其他 docker 容器的推荐方法。
    • 警告:通过授予容器对 /var/run/docker.sock 的访问权限,很容易突破容器提供的限制,并获得对主机的访问权限。这显然是一个潜在的安全风险。
  • -v $(which docker):/usr/bin/docker 也是可选的,但允许您的 jenkins 容器能够 运行 docker 二进制文件。
    • 请注意,由于docker现在是动态链接的,它不再自带依赖项,因此您可能需要在容器中安装依赖项。
    • 另一种方法是省略 -v $(which docker):/usr/bin/docker 并在 jenkins 容器中安装 docker。您需要确保内部容器 docker 和外部主机 docker 的版本相同,以便支持通过 /var/run/docker.sock 进行通信。
    • 无论哪种情况,您都可能希望使用 Dockerfile 创建新的 Jenkins docker 映像。
    • 另一种选择是包含 -v $(which docker):/usr/bin/docker,但在主机上安装 docker 的静态链接二进制文件。

您现在应该可以通过没有端口说明符的 https 访问 jenkins 门户网站(因为 443 端口是 https 的默认端口)

感谢 otognan 让我参与其中。

我知道这是一个非常古老的话题,但我想分享一个博客 post,其中详细介绍了反向代理选项:https://itnext.io/setting-up-https-for-jenkins-with-nginx-everything-in-docker-4a118dc29127

Jenkins 建议在文档中设置反向代理。首先,这似乎是一项额外的工作,但它也是与 CI/CD 环境相关的其他服务(即 SonarQube)的通用解决方案。