将Docker部署到远程主机时传递环境variables

我有我的docker容器和环境variables的一些麻烦。

目前我有一个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获取环境variables并将其放入我的容器中。 所以我有我的容器中的主机ENVAENVB的值。 使用下面的命令(在build立课程的形象之后): docker-compose up some-service-acc

我们目前正在开发一个更好的基础架构,并希望通过Jenkins部署服务。 Jenkins启动并运行在服务器B上的docker容器中

我可以通过Jenkins部署服务(Job-DSL,设置DOCKER_HOST =“tcp:// serverA:2375”临时)。 因此,它将在服务器B上的Jenkins容器上运行ServerA上的所有docker(组合)命令。除了没有ENVAENVB值之外,该服务已启动并正在运行。

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检查来检查正在运行的容器时,我得到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=" ] 

我在哪里需要设置环境variables,以便将它们传递给容器? 我更喜欢将variables存储在服务器A上。但如果这是不可能的,有人可以解释我是如何做到的? 由于它们包含敏感数据,因此不能对撰写文件或源文件中的任何其他位置进行硬编码。

如果我在错误的地方问这个问题,请把我redirect到我应该去的地方。

谢谢!

您需要在运行docker-compose命令行的shell中设置环境variables。 在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" } 

编辑:从评论,你也想传递秘密。

为了做到这一点,有一些像Mask Password这样的插件可以让你在日志或作业configuration中不显示variables的情况下传递variables。 (我相当肯定,一个坚定的入侵者仍然可以获得价值,因为jenkins知道它并将其以明文forms传递给您的脚本。)

IMO更好的select是使用Docker中的秘密pipe理工具。 Hashicorp的Vault产品实现了一个encryption的K / V存储,其中的值是通过一个有时间限制的令牌来访问的,并且能够根据请求生成新的密码,并集成到目标系统中。 我认为这是完全configuration的最高级别的安全性,但您可以configuration这种无数的方式来满足您自己的需求。 你需要写一些东西来提取秘密,并将其注入到容器的环境中(这是一个可以添加到入口点的rest协议)。

Docker本身的最新选项是秘​​密pipe理,需要新的Swarm模式。 您将您的秘密保存在swarm中,并使用docker-compose.yml版本3格式的条目将其作为文件添加到您想要的容器中。 如果您已经使用Swarm模式,并且可以使用docker stack deploy而不是docker-compose来启动容器,那么这是一个相当容易实现的解决scheme。