我的 docker 容器和环境变量有一些问题。
目前我有一个 docker-compose.yml 定义如下:
version: '2.1'
services:
some-service:
build:
context: .
image: image/replacedvalues
ports:
- 8080
environment:
- PROFILE=acc
- ENVA
- ENVB
- TZ=Europe/Berlin
some-service-acc:
extends:
service: some-service
environment:
- SERVICE_NAME=some-service-acc
现在,当我在服务器 A 上手动部署(直接通过 SSH 命令行)时,它将从服务器 A 获取环境变量并将它们放入我的容器中。所以我有
ENVA
的值和 ENVB
来自我容器中的主机。使用以下命令(当然在构建镜像之后):docker-compose up some-service-acc
.我们目前正在开发更好的基础设施,并希望通过 Jenkins 部署服务。 Jenkins 在服务器 B 上的 docker 容器中启动并运行。
我可以通过 Jenkins 部署服务(Job-DSL,设置 DOCKER_HOST="tcp://serverA:2375"temporary)。因此,它将从服务器 B 上的 Jenkins 容器在服务器 A 上运行所有 docker (compose) 命令。该服务已启动并正在运行,只是它没有
ENVA
的值。和 ENVB
.Jenkins 使用 Job-DSL groovy 脚本运行以下命令:
withEnv(["DOCKER_HOST=tcp://serverA:2375"]) {
sh "docker-compose pull some-service-acc"
sh "docker-compose -p some-service-acc up -d some-service-acc"
}
我尝试将它们设置在我的 Jenkins 容器和服务器 B 本身上,但都没有成功。只有当我直接在服务器 A 上手动部署时它才能工作。
当我使用 docker inspect 来检查正在运行的容器时,我得到了
env
的以下输出堵塞:"Env": [
"PROFILE=acc",
"affinity:container==JADFG09gtq340iggIN0jg53ij0gokngfs",
"TZ=Europe/Berlin",
"SERVICE_NAME=some-service-acc",
"ENVA",
"ENVB",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"JAVA_VERSION=8",
"JAVA_UPDATE=121",
"JAVA_BUILD=13",
"JAVA_PATH=e9e7ea248e2c4826b92b3f075a80e441",
"JAVA_HOME=/usr/lib/jvm/default-jvm",
"JAVA_OPTS="
]
我需要在哪里设置环境变量以便将它们传递给容器?我更喜欢将变量存储在服务器 A 上。但如果这不可能,有人可以解释一下如何做到吗?是不是 对撰写文件或源中其他任何位置的值进行硬编码的选项,因为它们包含敏感数据。
如果我在错误的地方问这个问题,请将我重定向到我应该去的地方。
谢谢!
最佳答案
您需要在运行 docker-compose 命令行的 shell 中设置环境变量。在 Jenkins 中,最好在您的 groovy 脚本中完成(Jenkins 不使用构建从站中的主机环境):
withEnv(["DOCKER_HOST=tcp://serverA:2375", "ENVA=hello", "ENVB=world"]) {
sh "docker-compose pull some-service-acc"
sh "docker-compose -p some-service-acc up -d some-service-acc"
}
编辑:从评论中,您还想传递 secret 。
要做到这一点,有像 Mask Password 这样的插件。这将允许您传递变量而不会出现在日志或作业配置中。 (我相当确定一个坚定的入侵者仍然可以获取这些值,因为 Jenkins 自己知道它并以明文形式将它传递给您的脚本。)
IMO 更好的选择是使用 docker 内部的 secret 管理工具。 Hashicorp has their Vault product它实现了一个加密的 K/V 存储,其中使用时间限制 token 访问值,并提供了为每个请求生成新密码并集成到目标系统的能力。完全配置后,我认为这是最高级别的安全性,但您可以配置无数种方式以满足您自己的需求。您需要编写一些东西来提取 secret 并将其注入(inject)到容器的环境中(这是一个可以添加到入口点的休息协议(protocol))。
Docker 本身的最新选项是需要新的 Swarm 模式的 secret 管理。您将您的 secret 保存在 swarm 中,并使用 entry in the docker-compose.yml version 3 format 将其作为文件添加到您想要的容器中。 .如果您已经使用 Swarm 模式并且可以使用
docker stack deploy
启动您的容器而不是 docker-compose
,这是一个相当容易实现的解决方案。
关于docker - 将 docker 部署到远程主机时传递环境变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43094191/