如何处理特定主机名,如 Dockerfile 中的 -h 选项
How to handle specific hostname like -h option in Dockerfile
我使用 CentOS 7 作为 docker 守护程序主机和 centos:6 Docker 映像。
我想安装一些需要可解析的主机名作为非环回地址的软件。如果我 运行 带有 -h 选项的 docker 图像
docker run -i -t -h myhost centos:6 /bin/bash
然后我就可以安装软件了,因为/etc/hosts在容器里自动配置了like
[root@myhost /]# cat /etc/hosts
172.17.0.7 myhost
127.0.0.1 localhost
[root@myhost /]# ping myhost
PING myhost (172.17.0.7) 56(84) bytes of data.
64 bytes from myhost (172.17.0.7): icmp_seq=1 ttl=64 time=0.033 ms
但是如果我从 Docker 文件创建图像,我不能使用相同的方法。我测试了使用以下 Dockerfile
创建图像
FROM centos:6
ENV HOSTNAME myhost
RUN ping myhost
在 docker 构建过程中,分配的主机名无法解析为动态 ip 地址,如下所示:
$ docker build -t testimage .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM centos:6
---> a30bc9f3097e
Step 1 : ENV HOSTNAME myhost
---> Using cache
---> e73bf592389e
Step 2 : RUN ping myhost
---> Running in ca54c8eac073
ping: unknown host myhost
INFO[0000] The command [/bin/sh -c ping myhost] returned a non-zero code: 2
如何使用解析为动态容器 IP 地址的特定主机名?
这在 Docker 文件中通常是不可能的。
根据软件的不同,您或许可以进行某种变通。例如,您可以尝试
RUN echo $(grep $(hostname) /etc/hosts | cut -f1) my.host.name >> /etc/hosts && install-software
通过在与安装软件相同的 运行 命令中设置主机名,它会发生在容器的同一层内。 Docker 稍后会覆盖主机名,您必须在 运行 时重新设置它,但您的软件可能没问题。
如果您必须做很多这样的事情,您可以尝试 Packer 构建容器。它可以构建 Docker 个容器,但不使用多层。这使得重建更慢,下载构建的图像更快,并且在将图像冻结到容器中之前对图像进行多项操作更方便。
我认为下面的更好,因为 docker 容器通常没有安装 'hostname',因此我会使用 head 命令:
echo $(head -1 /etc/hosts | cut -f1) $HOST_NAME >> /etc/hosts
如果 /etc/hosts
没有帮助,我会替换 hostname
二进制文件。
RUN mv /usr/bin/hostname{,.bkp}; \
echo "echo myhost.local" > /usr/bin/hostname; \
chmod +x /usr/bin/hostname
...
RUN mv /usr/bin/hostname{.bkp,}
至于解决方法,您可以使用 docker-compose
或 docker stack
来构建具有特定 hostname
的容器,例如
version: '3'
services:
all:
image: testimage
container_name: myname
hostname: myhost
build:
context: .
然后 运行 为:
docker-compose --build up
或使用Docker stacks:
docker stack deploy -c docker-compose.yml mystack
如果你想在构建时指定主机名,现在它在这个 pull request 下实现了:
https://github.com/moby/buildkit/pull/1339
您可以投票支持它尽快合并。
我使用 CentOS 7 作为 docker 守护程序主机和 centos:6 Docker 映像。
我想安装一些需要可解析的主机名作为非环回地址的软件。如果我 运行 带有 -h 选项的 docker 图像
docker run -i -t -h myhost centos:6 /bin/bash
然后我就可以安装软件了,因为/etc/hosts在容器里自动配置了like
[root@myhost /]# cat /etc/hosts
172.17.0.7 myhost
127.0.0.1 localhost
[root@myhost /]# ping myhost
PING myhost (172.17.0.7) 56(84) bytes of data.
64 bytes from myhost (172.17.0.7): icmp_seq=1 ttl=64 time=0.033 ms
但是如果我从 Docker 文件创建图像,我不能使用相同的方法。我测试了使用以下 Dockerfile
创建图像FROM centos:6
ENV HOSTNAME myhost
RUN ping myhost
在 docker 构建过程中,分配的主机名无法解析为动态 ip 地址,如下所示:
$ docker build -t testimage .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM centos:6
---> a30bc9f3097e
Step 1 : ENV HOSTNAME myhost
---> Using cache
---> e73bf592389e
Step 2 : RUN ping myhost
---> Running in ca54c8eac073
ping: unknown host myhost
INFO[0000] The command [/bin/sh -c ping myhost] returned a non-zero code: 2
如何使用解析为动态容器 IP 地址的特定主机名?
这在 Docker 文件中通常是不可能的。
根据软件的不同,您或许可以进行某种变通。例如,您可以尝试
RUN echo $(grep $(hostname) /etc/hosts | cut -f1) my.host.name >> /etc/hosts && install-software
通过在与安装软件相同的 运行 命令中设置主机名,它会发生在容器的同一层内。 Docker 稍后会覆盖主机名,您必须在 运行 时重新设置它,但您的软件可能没问题。
如果您必须做很多这样的事情,您可以尝试 Packer 构建容器。它可以构建 Docker 个容器,但不使用多层。这使得重建更慢,下载构建的图像更快,并且在将图像冻结到容器中之前对图像进行多项操作更方便。
我认为下面的更好,因为 docker 容器通常没有安装 'hostname',因此我会使用 head 命令:
echo $(head -1 /etc/hosts | cut -f1) $HOST_NAME >> /etc/hosts
如果 /etc/hosts
没有帮助,我会替换 hostname
二进制文件。
RUN mv /usr/bin/hostname{,.bkp}; \
echo "echo myhost.local" > /usr/bin/hostname; \
chmod +x /usr/bin/hostname
...
RUN mv /usr/bin/hostname{.bkp,}
至于解决方法,您可以使用 docker-compose
或 docker stack
来构建具有特定 hostname
的容器,例如
version: '3'
services:
all:
image: testimage
container_name: myname
hostname: myhost
build:
context: .
然后 运行 为:
docker-compose --build up
或使用Docker stacks:
docker stack deploy -c docker-compose.yml mystack
如果你想在构建时指定主机名,现在它在这个 pull request 下实现了: https://github.com/moby/buildkit/pull/1339 您可以投票支持它尽快合并。