Подтвердить что ты не робот

Как получить имя хоста узла докера изнутри контейнера докеров на этом хосте без env vars

Каким образом можно получить имя хоста хост-докера внутри контейнера, запущенного на этом хосте, кроме использования переменных среды? Я знаю, что могу передать имя хоста в качестве переменной среды в контейнер во время создания контейнера. Мне интересно, как я могу найти его во время выполнения.

foo.example.com (docker host)
  bar (docker container)

Есть ли способ для контейнера bar, запущенного в хосте docker foo.example.com, чтобы получить "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 для службы, прослушивающей какой-либо фиксированный порт в строке (докер обрабатывает сопоставление от порта хоста до порта контейнера).

В моем контейнере будет выполняться проверка работоспособности, чтобы убедиться, что она успешно создала эту запись SRV, поскольку на других докере-хостах будет также много других контейнеров-баров, которые также создают свои собственные записи 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 и только что узнал, что добавляет env var для меня, из которого я могу получить имя хоста. Но мне было просто любопытно, если бы я использовал докер без Гелиоса.

4b9b3361

Ответ 1

Вы можете передать имя хоста в качестве переменной среды. Вы также можете установить /etc, чтобы вы могли cat/etc/hostname. Но я согласен с Виталием, это не предполагаемый прецедент для контейнеров IMO.

Ответ 2

Вы можете легко передать его как переменную среды

docker run .. -e HOST_HOSTNAME=`hostname` ..

используя

-e HOST_HOSTNAME=`hostname`

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

обратите внимание, что это работает в оболочке bash, если вы используете другую оболочку, вам может потребоваться увидеть альтернативу для "обратного хода", например, альтернатива оболочки fish будет

docker run .. -e HOST_HOSTNAME=(hostname) ..

Ответ 3

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

docker run -h=my.docker.container.example.com ubuntu:latest

Вы можете использовать backticks (или что бы то ни было эквивалентно вашей оболочке), чтобы получить вывод hosthame в аргумент -h.

docker run -h=`hostname` ubuntu:latest

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

Ответ 4

Другим вариантом, который работал у меня, было привязать пространство имен сети к докере.

Добавив:

docker run --net host

Ответ 5

Я думаю, что причина, по которой у меня возникла та же проблема, связана с ошибкой в последней бета-версии Docker для Mac, но там, в комментариях, я смог найти решение, которое помогло бы мне & моя команда. Мы используем это для локальной разработки, где нам нужны наши контейнерные сервисы для общения с монолитом, когда мы работаем над его заменой. Вероятно, это не жизнеспособное решение.

На хост-компьютере псевдоним известного доступного IP-адреса для интерфейса обратной связи:

$ sudo ifconfig lo0 alias 10.200.10.1/24

Затем добавьте этот IP-адрес с именем хоста в конфигурацию вашего докера. В моем случае я использую 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 для запроса страницы с хост-веб-сервера:

$ docker exec -it container_name /bin/bash
$ wget relevant_hostname/index.html
$ cat index.html

Ответ 6

Вы можете передать его как переменную среды, подобную этой. Обычно Node - это хост, на котором он запущен. По умолчанию имя хоста задается по имени хоста узла.

docker service create -e 'FOO={{.Node.Hostname}}' nginx  

Затем вы можете сделать docker ps, чтобы получить идентификатор процесса и посмотреть на 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

В качестве примера использования можно привести метрические биты, чтобы вы знали, на каком узле возникают системные проблемы, которые я добавил в 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

Ответ 7

Я знаю, это старый вопрос, но мне тоже нужно было это решение, и я нашел другое решение.

Я использовал entrypoint.sh, чтобы выполнить следующую строку и определить переменную с фактическим именем хоста для этого экземпляра:

HOST='hostname --fqdn'

Затем я использовал его в своем сценарии точки входа:

echo "Value: $HOST"

Надеюсь, это поможет