在将docker部署到远程主机时传递环境变量

时间:2017-03-29 12:56:38

标签: docker jenkins yaml docker-compose

我的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获取环境变量并将它们放入我的容器中。所以我的容器中的主机的值为ENVAENVB。使用以下命令(在构建课程图像之后):docker-compose up some-service-acc

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

我可以通过Jenkins部署服务(Job-DSL,设置DOCKER_HOST =" tcp:// serverA:2375"临时)。因此它将从服务器B上的Jenkins容器运行ServerA上的所有docker(compose)命令。服务已启动并运行,但它没有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 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上。但如果这不可能,有人可以解释一下它是如何完成的吗? 是对compose文件中的值或源中任何其他位置进行硬编码的选项,因为它们包含敏感数据。

如果我在错误的地方询问,请将我重定向到我应该去的地方。

谢谢!

1 个答案:

答案 0 :(得分:2)

您需要在运行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"
}

编辑:从评论中,您还想传递秘密。

要做到这一点,有一些像Mask Password这样的插件可以让你传递变量,而不会在日志或作业配置中显示它们。 (我相当肯定一个坚定的入侵者仍然可以获得这些值,因为Jenkins自己知道它并以明文形式传递给你的脚本。)

更好的选择IMO是在docker中使用秘密管理工具。 Hashicorp has their Vault product实现了一个加密的K / V存储,其中使用时间限制令牌访问值,并提供了每个请求生成新密码并集成到目标系统的能力。在完全配置时,我认为这是最高级别的安全性,但您可以配置这些无数种方式以满足您自己的需求。您需要编写一些内容来提取秘密并将其注入您的容器环境(它是您可以添加到入口点的休息协议)。

Docker本身的最新选项是秘​​密管理,需要新的Swarm模式。您将秘密保存在swarm中,并使用entry in the docker-compose.yml version 3 format将其作为文件添加到您想要的容器中。如果您已经使用Swarm模式并且可以使用docker stack deploy而不是docker-compose启动容器,那么这是一个相当简单的实现方法。