具有docker堆栈部署的主机环境变量

具有docker堆栈部署的主机环境变量,docker,docker-swarm,docker-swarm-mode,Docker,Docker Swarm,Docker Swarm Mode,我想知道是否有一种方法可以使用从部署容器的主机获取的环境变量,而不是从执行docker stack deploy命令的主机获取的环境变量。例如,设想在三节点docker Swarm集群上启动以下docker compose.yml: version: '3.2' services: kafka: image: wurstmeister/kafka ports: - target: 9094 published: 9094 proto

我想知道是否有一种方法可以使用从部署容器的主机获取的环境变量,而不是从执行
docker stack deploy
命令的主机获取的环境变量。例如,设想在三节点docker Swarm集群上启动以下
docker compose.yml

version: '3.2'
services:
  kafka:
    image: wurstmeister/kafka
    ports:
      - target: 9094
        published: 9094
        protocol: tcp
        mode: host
    deploy:
      mode: global
    environment:
      KAFKA_JMX_OPTS: "-Djava.rmi.server.hostname=${JMX_HOSTNAME} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.rmi.port=1099"
JMX_主机名
应取自实际部署容器的主机,并且每个容器的值不应相同。
有没有正确的方法可以做到这一点?

是的,当您将两个概念结合在一起时,这种方法会起作用:

  • Swarm,其中主机名是内置的
  • Swarm,也可以在堆栈文件中工作
  • 这会将主机名拉入到每个容器的ENV值DUDE中,使其成为运行该容器的主机:

    version: '3.4'
    
    services:
      nginx:
        image: nginx
        environment:
          DUDE: "{{.Node.Hostname}}"
        deploy:
          replicas: 3
    

    如果您通过运行docker命令,它将起作用


    这为我指明了正确的方向。

    当你有很多环境变量时,我找到了另一种方法。同样的方法也适用于docker compose up

    sudo -E docker stack deploy -c docker-compose.yml mystack
    
    而不是

    env foo="${foo}" bar="${bar}" docker stack deploy -c docker-compose.yml mystack
    

    sudo-E
    man描述

       -E, --preserve-env
                   Indicates to the security policy that the user wishes to
                   preserve their existing environment variables.  The
                   security policy may return an error if the user does not
                   have permission to preserve the environment.
    

    你的解决方案实际上是可行的,但它并不完全符合我的答案。假设我有一个非内置变量要读取?这可能吗?当然,您应该了解Swarm节点标签或主机标签。主机标签在/etc/docker/daemon.json中设置,但在Swarm中不经常使用。群集标签是通过<代码> DOCKER节点更新< /代码>使用<代码>标签添加< /代码>和代码>标签RM< /代码>,并设置您想要的任何键/值:)您可以以相同的方式访问它,但是在“中间代码”中使用“标签”。节点。标签。我试过这个方法,但不起作用。这就是我所做的:sudocker节点更新——标签addip='192.168.121.59'q687wox1uet33k4ubfvfa6p74。然后,我在环境部分的compose文件中使用了这个标签:environment:-KAFKA_HOST_IP:“{{{.Node.Labels.IP}”。已启动堆栈:sudo-E docker stack deploy-c docker-compose.yml服务。获取错误->desc=扩展环境失败:扩展环境“KAFKA_HOST_IP={{.Node.Labels.IP}”:模板:扩展:1:7:在:无法计算类型struct中的字段标签{ID string;主机名string;Platform template.Platform}这是替换堆栈yml文件中变量的正确答案。这是一个不同的问题,然后添加到容器环境中这在世界上是如何工作的
    env JMX_HOSTNAME=“${JMX_HOSTNAME}”
    将在docker看到它之前由shell插入。因此,docker将看到
    env JMX\u HOSTNAME=master\u host\u env\u value docker…
    。我是不是遗漏了什么?
       -E, --preserve-env
                   Indicates to the security policy that the user wishes to
                   preserve their existing environment variables.  The
                   security policy may return an error if the user does not
                   have permission to preserve the environment.