【问题标题】:Setup secured Jenkins master with docker使用 docker 设置安全的 Jenkins master
【发布时间】:2015-06-27 14:22:59
【问题描述】:
我想使用 docker 在 ec2 上设置一个安全的 Jenkins 主服务器。
我在这里使用标准的 jenkins docker 文件:https://registry.hub.docker.com/_/jenkins/
默认情况下,它会打开一个不安全的 8080 http 端口。但是我希望它使用带有 https 的标准 443 端口(起初我想使用自签名 ssl 证书)。
我对该主题进行了一些研究,并找到了几种可能的解决方案。我对 docker 并没有真正的经验,所以我仍然找不到一个我可以使用或实现的简单的。以下是我找到的一些选项:
有经验的人可以推荐我最好的解决方案吗?
附:我不确定 ec2 会给我带来多少麻烦,但我认为它只是在安全组中打开 443。
【问题讨论】:
标签:
ssl
jenkins
https
amazon-ec2
docker
【解决方案1】:
在通过一些关于 Docker 的教程后,我发现最容易遵循的选项是第 2 项。Jenkins docker image 以一种您可以轻松将参数传递给 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/ 文件夹的密钥库。
【解决方案2】:
和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 阻止 http 并在容器内的端口 8443 上公开 https(容器外的端口 443)。
-
--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 让我参与其中。
【解决方案4】:
我会在同一个容器中使用 nginx 和 jenkins,并使用 supervisord 来管理这两个进程。使用内置工具保护不同的服务是一件痛苦的事; nginx 适用于所有服务,并且易于配置。使用 docker-compose (was fig) 创建两个不同的容器并将它们与 docker 提供的带有链接的漂亮内部网络连接起来是可能的,并且在某些方面更好。问题是,像马拉松这样的集群管理器仍然不能很好地支持同时运行成对的作业。告诉大多数服务运行单个容器比运行两个容器要容易得多,但要确保它们位于同一主机上。