如何在没有环境变量的情况下从该主机上的 docker 容器中获取 docker 主机的主机名
How to get the hostname of the docker host from inside a docker container on that host without env vars
除了使用环境变量之外,还有什么方法可以从主机上的容器 运行 中获取 docker 主机的主机名? 我知道我可以在创建容器时将主机名作为环境变量传递给容器。我想知道如何在 运行 时查找它。
foo.example.com (docker host)
bar (docker container)
docker主机foo.example.com
中的容器bar
运行是否有办法获得"foo.example.com"?
编辑以添加用例:
容器将为服务发现创建一个 SRV 记录
_service._proto.name. TTL class SRV priority weight port target.
-----------------------------------------------------------------
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo.example.com.
其中 20003 是 docker 主机上动态分配的端口,用于侦听 bar 中某个固定端口的服务(docker 处理从主机端口到容器端口的映射)。
我的容器将 运行 进行健康检查,以确保它已成功创建该 SRV 记录,因为其他 docker 主机上的许多其他 bar 容器也会创建自己的 SRV 记录。
_service._proto.name. TTL class SRV priority weight port target.
-----------------------------------------------------------------
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo.example.com. <--
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo2.example.com.
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo3.example.com.
运行状况检查将遍历 SRV 记录以查找上面的第一个记录,因此需要知道它的主机名。
一边
我正在使用 Helios and just found out it adds an env var for me,我可以从中获取主机名。但我只是好奇,如果我在没有 Helios 的情况下使用 docker。
您可以将主机名作为环境变量传入。您还可以挂载 /etc,这样您就可以 cat /etc/hostname。但我同意 Vitaly 的观点,这不是容器 IMO 的预期用例。
您可以轻松地将其作为环境变量传递
docker run .. -e HOST_HOSTNAME=`hostname` ..
使用
-e HOST_HOSTNAME=`hostname`
将调用主机名并将其return用作环境变量HOST_HOSTNAME
,当然您可以根据需要自定义密钥。
请注意,这适用于 bash shell,如果您使用不同的 shell,您可能需要查看 "backtick" 的替代方案,例如 fish
shell 备选方案是
docker run .. -e HOST_HOSTNAME=(hostname) ..
另一个对我有用的选项是将主机的网络名称空间绑定到 docker。
通过添加:
docker run --net host
我添加这个是因为它没有在任何其他答案中提到。您可以使用 -h 指令在 运行 时间给容器一个特定的主机名。
docker run -h=my.docker.container.example.com ubuntu:latest
您可以使用反引号(或您 shell 使用的任何等效物)将 hosthame 的输出放入 -h 参数。
docker run -h=`hostname` ubuntu:latest
需要注意的是,hostname 的值将从您 运行 命令所在的主机中获取,因此如果您想要 运行 正在 [=] 的虚拟机的主机名18=] 容器然后使用主机名作为参数可能不正确,如果您使用主机在虚拟机上执行 docker 命令。
我认为我遇到同样问题的原因是 bug in the latest Docker for Mac beta,但隐藏在评论中我能够找到适合我和我的团队的解决方案。我们正在将其用于本地开发,我们需要我们的容器化服务在我们努力替换它时与单体通信。这可能不是一个可行的生产解决方案。
在主机上,为环回接口指定一个已知可用 IP 地址的别名:
$ sudo ifconfig lo0 alias 10.200.10.1/24
然后将该 IP 和主机名添加到您的 docker 配置中。就我而言,我正在使用 docker-compose,所以我将其添加到我的 docker-compose.yml:
extra_hosts:
# configure your host to alias 10.200.10.1 to the loopback interface:
# sudo ifconfig lo0 alias 10.200.10.1/24
- "relevant_hostname:10.200.10.1"
然后我通过附加到 bash 会话并使用 wget
从主机的 Web 请求页面来验证所需的主机服务(Web 服务器)在容器内可用服务器:
$ docker exec -it container_name /bin/bash
$ wget relevant_hostname/index.html
$ cat index.html
我知道这是一个老问题,但我也需要这个解决方案,我想出了另一个解决方案。
我使用 entrypoint.sh 来执行以下行,并为该实例定义一个具有实际主机名的变量:
HOST=`hostname --fqdn`
然后,我在入口点脚本中使用了它:
echo "Value: $HOST"
希望对您有所帮助
您可以像这样将其作为环境变量传递。一般Node
就是它所在运行所在的主机。主机名默认为节点创建时的主机名。
docker service create -e 'FOO={{.Node.Hostname}}' nginx
然后你可以docker ps
获取进程ID并查看env
$ docker exec -it c81640b6d1f1 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c81640b6d1f1
TERM=xterm
FOO=docker-desktop
NGINX_VERSION=1.17.4
NJS_VERSION=0.3.5
PKG_RELEASE=1~buster
HOME=/root
使用 metricbeats 的一个例子,所以你知道哪个节点有系统问题,我在 https://github.com/trajano/elk-swarm:
metricbeat:
image: docker.elastic.co/beats/metricbeat:7.4.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /sys/fs/cgroup:/hostfs/sys/fs/cgroup:ro
- /proc:/hostfs/proc:ro
- /:/hostfs:ro
user: root
hostname: "{{.Node.Hostname}}"
command:
- -E
- |
metricbeat.modules=[
{
module:docker,
hosts:[unix:///var/run/docker.sock],
period:10s,
enabled:true
}
]
- -E
- processors={1:{add_docker_metadata:{host:unix:///var/run/docker.sock}}}
- -E
- output.elasticsearch.enabled=false
- -E
- output.logstash.enabled=true
- -E
- output.logstash.hosts=["logstash:5044"]
deploy:
mode: global
我运行
docker info | grep Name: | xargs | cut -d' ' -f2
在我的容器里。
HOSTIP=`ip -4 addr show scope global dev eth0 | grep inet | awk '{print }' | cut -d / -f 1 | sed -n 1p`
docker run --add-host=myhost:${HOSTIP} --rm -it debian
现在您可以使用别名“myhost”访问主机了
第一行在 cygwin 上不会 运行,但您可以想出一些其他方法来使用 ipconfig 获取本地 IP 地址。
除了使用环境变量之外,还有什么方法可以从主机上的容器 运行 中获取 docker 主机的主机名? 我知道我可以在创建容器时将主机名作为环境变量传递给容器。我想知道如何在 运行 时查找它。
foo.example.com (docker host)
bar (docker container)
docker主机foo.example.com
中的容器bar
运行是否有办法获得"foo.example.com"?
编辑以添加用例:
容器将为服务发现创建一个 SRV 记录
_service._proto.name. TTL class SRV priority weight port target.
-----------------------------------------------------------------
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo.example.com.
其中 20003 是 docker 主机上动态分配的端口,用于侦听 bar 中某个固定端口的服务(docker 处理从主机端口到容器端口的映射)。
我的容器将 运行 进行健康检查,以确保它已成功创建该 SRV 记录,因为其他 docker 主机上的许多其他 bar 容器也会创建自己的 SRV 记录。
_service._proto.name. TTL class SRV priority weight port target.
-----------------------------------------------------------------
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo.example.com. <--
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo2.example.com.
_bar._http.example.com 60 IN SRV 5000 5000 20003 foo3.example.com.
运行状况检查将遍历 SRV 记录以查找上面的第一个记录,因此需要知道它的主机名。
一边
我正在使用 Helios and just found out it adds an env var for me,我可以从中获取主机名。但我只是好奇,如果我在没有 Helios 的情况下使用 docker。
您可以将主机名作为环境变量传入。您还可以挂载 /etc,这样您就可以 cat /etc/hostname。但我同意 Vitaly 的观点,这不是容器 IMO 的预期用例。
您可以轻松地将其作为环境变量传递
docker run .. -e HOST_HOSTNAME=`hostname` ..
使用
-e HOST_HOSTNAME=`hostname`
将调用主机名并将其return用作环境变量HOST_HOSTNAME
,当然您可以根据需要自定义密钥。
请注意,这适用于 bash shell,如果您使用不同的 shell,您可能需要查看 "backtick" 的替代方案,例如 fish
shell 备选方案是
docker run .. -e HOST_HOSTNAME=(hostname) ..
另一个对我有用的选项是将主机的网络名称空间绑定到 docker。
通过添加:
docker run --net host
我添加这个是因为它没有在任何其他答案中提到。您可以使用 -h 指令在 运行 时间给容器一个特定的主机名。
docker run -h=my.docker.container.example.com ubuntu:latest
您可以使用反引号(或您 shell 使用的任何等效物)将 hosthame 的输出放入 -h 参数。
docker run -h=`hostname` ubuntu:latest
需要注意的是,hostname 的值将从您 运行 命令所在的主机中获取,因此如果您想要 运行 正在 [=] 的虚拟机的主机名18=] 容器然后使用主机名作为参数可能不正确,如果您使用主机在虚拟机上执行 docker 命令。
我认为我遇到同样问题的原因是 bug in the latest Docker for Mac beta,但隐藏在评论中我能够找到适合我和我的团队的解决方案。我们正在将其用于本地开发,我们需要我们的容器化服务在我们努力替换它时与单体通信。这可能不是一个可行的生产解决方案。
在主机上,为环回接口指定一个已知可用 IP 地址的别名:
$ sudo ifconfig lo0 alias 10.200.10.1/24
然后将该 IP 和主机名添加到您的 docker 配置中。就我而言,我正在使用 docker-compose,所以我将其添加到我的 docker-compose.yml:
extra_hosts:
# configure your host to alias 10.200.10.1 to the loopback interface:
# sudo ifconfig lo0 alias 10.200.10.1/24
- "relevant_hostname:10.200.10.1"
然后我通过附加到 bash 会话并使用 wget
从主机的 Web 请求页面来验证所需的主机服务(Web 服务器)在容器内可用服务器:
$ docker exec -it container_name /bin/bash
$ wget relevant_hostname/index.html
$ cat index.html
我知道这是一个老问题,但我也需要这个解决方案,我想出了另一个解决方案。
我使用 entrypoint.sh 来执行以下行,并为该实例定义一个具有实际主机名的变量:
HOST=`hostname --fqdn`
然后,我在入口点脚本中使用了它:
echo "Value: $HOST"
希望对您有所帮助
您可以像这样将其作为环境变量传递。一般Node
就是它所在运行所在的主机。主机名默认为节点创建时的主机名。
docker service create -e 'FOO={{.Node.Hostname}}' nginx
然后你可以docker ps
获取进程ID并查看env
$ docker exec -it c81640b6d1f1 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c81640b6d1f1
TERM=xterm
FOO=docker-desktop
NGINX_VERSION=1.17.4
NJS_VERSION=0.3.5
PKG_RELEASE=1~buster
HOME=/root
使用 metricbeats 的一个例子,所以你知道哪个节点有系统问题,我在 https://github.com/trajano/elk-swarm:
metricbeat:
image: docker.elastic.co/beats/metricbeat:7.4.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /sys/fs/cgroup:/hostfs/sys/fs/cgroup:ro
- /proc:/hostfs/proc:ro
- /:/hostfs:ro
user: root
hostname: "{{.Node.Hostname}}"
command:
- -E
- |
metricbeat.modules=[
{
module:docker,
hosts:[unix:///var/run/docker.sock],
period:10s,
enabled:true
}
]
- -E
- processors={1:{add_docker_metadata:{host:unix:///var/run/docker.sock}}}
- -E
- output.elasticsearch.enabled=false
- -E
- output.logstash.enabled=true
- -E
- output.logstash.hosts=["logstash:5044"]
deploy:
mode: global
我运行
docker info | grep Name: | xargs | cut -d' ' -f2
在我的容器里。
HOSTIP=`ip -4 addr show scope global dev eth0 | grep inet | awk '{print }' | cut -d / -f 1 | sed -n 1p`
docker run --add-host=myhost:${HOSTIP} --rm -it debian
现在您可以使用别名“myhost”访问主机了
第一行在 cygwin 上不会 运行,但您可以想出一些其他方法来使用 ipconfig 获取本地 IP 地址。