使用 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 并没有真正的经验,所以我仍然找不到一个我可以使用或实施的简单方法。以下是我发现的一些选项:
- 在 8080 上使用标准 jenkins docker,但在我的 ec2 实例上配置一个安全的 apache 或 nginx 服务器,它将重定向流量。我不喜欢这个,因为服务器将在 docker 之外,所以我不能将它保留在版本控制中
- 以某种方式修改 jenkins docker 文件以使用根据 https://wiki.jenkins-ci.org/display/JENKINS/Starting+and+Accessing+Jenkins 配置的 https 启动 jenkins。我不确定该怎么做。我需要创建自己的 docker 容器吗?
- 像这样 https://registry.hub.docker.com/u/marvambass/nginx-ssl-secure/ 使用带有安全 nginx 的 docker 文件并以某种方式组合两个 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)的通用解决方案。
我想使用 docker 在 ec2 上设置一个安全的 Jenkins 主服务器。 我正在使用这里的标准 jenkins docker 文件:https://registry.hub.docker.com/_/jenkins/
默认情况下,它会打开一个不安全的 8080 http 端口。但是我希望它使用带 https 的标准 443 端口(起初我想使用自签名 ssl 证书)。
我对这个话题进行了一些研究,找到了几种可能的解决方案。我对 docker 并没有真正的经验,所以我仍然找不到一个我可以使用或实施的简单方法。以下是我发现的一些选项:
- 在 8080 上使用标准 jenkins docker,但在我的 ec2 实例上配置一个安全的 apache 或 nginx 服务器,它将重定向流量。我不喜欢这个,因为服务器将在 docker 之外,所以我不能将它保留在版本控制中
- 以某种方式修改 jenkins docker 文件以使用根据 https://wiki.jenkins-ci.org/display/JENKINS/Starting+and+Accessing+Jenkins 配置的 https 启动 jenkins。我不确定该怎么做。我需要创建自己的 docker 容器吗?
- 像这样 https://registry.hub.docker.com/u/marvambass/nginx-ssl-secure/ 使用带有安全 nginx 的 docker 文件并以某种方式组合两个 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)的通用解决方案。