Как обрабатывать определенное имя хоста, например, -h в Dockerfile

Я использую CentOS 7 в качестве хоста docker daemon и centos: 6 изображений Docker.

Я хочу установить какое-то программное обеспечение, которое требует разрешимого имени хоста как не-loopback-адрес. Если я запустил изображение докера с параметром -h, например

docker run -i -t -h myhost centos:6 /bin/bash

Затем я могу установить программное обеспечение, потому что /etc/hosts в контейнере автоматически настроены как

[[email protected] /]# cat /etc/hosts
172.17.0.7  myhost
127.0.0.1   localhost    

[[email protected] /]# 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

Но я не могу использовать тот же путь, если создам образ из Dockerfile. Я протестировал создание образа, используя следующий Dockerfile

FROM centos:6

ENV HOSTNAME myhost
RUN ping myhost

В процессе сборки docker назначенное имя хоста не может быть разрешено как динамическое ip addr, как показано ниже:

$ 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-адрес?

Ответ 1

Обычно это невозможно в файле Docker.

В зависимости от программного обеспечения вы можете выполнять какую-то работу. Например, вы можете попробовать что-то вроде

RUN echo $(grep $(hostname) /etc/hosts | cut -f1) my.host.name >> /etc/hosts && install-software

Установив имя хоста в пределах той же команды RUN, что и при установке программного обеспечения, это произойдет внутри одного и того же слоя контейнера. Docker позже перезапишет имя хоста, и вам придется устанавливать его заново при запуске, но ваше программное обеспечение может быть в порядке с этим.

Если вам нужно сделать это много, вы можете попробовать Packer для создания контейнеров. Он может создавать контейнеры Docker, но не использует несколько слоев. Это замедляет восстановление, ускоряет загрузку встроенных изображений и упрощает выполнение нескольких операций над изображением, прежде чем замораживать его в контейнере.

Ответ 2

Я думаю, что следующее лучше, потому что контейнеры докеров обычно не имеют "hostname", поэтому я бы использовал команду head:

echo $(head -1 /etc/hosts | cut -f1) $HOST_NAME >> /etc/hosts

Ответ 3

В случае, когда /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,}

Ответ 4

Недавно я начал проект по маршрутизации контейнеров по имени хоста, проект находится на очень ранней альфа-стадии, но, возможно, он может помочь кому-то, кто ищет некоторые более простые решения маршрутизации, которые не используют более тяжелые или медленные решения, такие как dns resolvers или consul keyval resolver через ассоциацию рой.

Для тех, кто заинтересован или хочет помочь репо, здесь.

https://github.com/Markcial/yacht

Ответ 5

Что касается обходного пути, вы можете использовать docker-compose или docker stack для построения вашего контейнера с определенным hostname, например

version: '3'
services:
  all:
    image: testimage
    container_name: myname
    hostname: myhost
    build:
      context: .

Затем запустите как:

docker-compose --build up

или используя стеки Docker:

docker stack deploy -c docker-compose.yml mystack