Ответ 1
Вы можете передать имя хоста в качестве переменной среды. Вы также можете установить /etc, чтобы вы могли cat/etc/hostname. Но я согласен с Виталием, это не предполагаемый прецедент для контейнеров IMO.
Каким образом можно получить имя хоста хост-докера внутри контейнера, запущенного на этом хосте, кроме использования переменных среды? Я знаю, что могу передать имя хоста в качестве переменной среды в контейнер во время создания контейнера. Мне интересно, как я могу найти его во время выполнения.
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 для меня, из которого я могу получить имя хоста. Но мне было просто любопытно, если бы я использовал докер без Гелиоса.
Вы можете передать имя хоста в качестве переменной среды. Вы также можете установить /etc, чтобы вы могли cat/etc/hostname. Но я согласен с Виталием, это не предполагаемый прецедент для контейнеров IMO.
Вы можете легко передать его как переменную среды
docker run .. -e HOST_HOSTNAME=`hostname` ..
используя
-e HOST_HOSTNAME=`hostname`
будет вызывать имя хоста и использовать его как переменную среды под названием HOST_HOSTNAME
, конечно вы можете настроить ключ по своему усмотрению.
обратите внимание, что это работает в оболочке bash, если вы используете другую оболочку, вам может потребоваться увидеть альтернативу для "обратного хода", например, альтернатива оболочки fish
будет
docker run .. -e HOST_HOSTNAME=(hostname) ..
Я добавляю это, потому что он не упоминается ни в одном из других ответов. Вы можете указать контейнеру определенное имя хоста во время выполнения с помощью директивы -h.
docker run -h=my.docker.container.example.com ubuntu:latest
Вы можете использовать backticks (или что бы то ни было эквивалентно вашей оболочке), чтобы получить вывод hosthame в аргумент -h.
docker run -h=`hostname` ubuntu:latest
Существует предостережение, значение имени хоста будет взято с хоста, на котором вы запускаете команду, поэтому, если вы хотите, чтобы имя хоста виртуальной машины, на которой запущен ваш контейнер докеров, с использованием имени хоста в качестве аргумента может быть неверным, если вы используете хост-компьютер для выполнения команд докеров на виртуальной машине.
Другим вариантом, который работал у меня, было привязать пространство имен сети к докере.
Добавив:
docker run --net host
Я думаю, что причина, по которой у меня возникла та же проблема, связана с ошибкой в последней бета-версии 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
Вы можете передать его как переменную среды, подобную этой. Обычно 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
Я знаю, это старый вопрос, но мне тоже нужно было это решение, и я нашел другое решение.
Я использовал entrypoint.sh, чтобы выполнить следующую строку и определить переменную с фактическим именем хоста для этого экземпляра:
HOST='hostname --fqdn'
Затем я использовал его в своем сценарии точки входа:
echo "Value: $HOST"
Надеюсь, это поможет