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

Использование хоста ip в docker-compose

Я хочу создать файл docker-compose, который может работать на разных серверах.

Для этого я должен иметь возможность указать host-ip или имя хоста сервера (где все контейнеры запущены) в нескольких местах в docker-compose.yml.

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

consul:
  image: progrium/consul
  command: -server -advertise 192.168.1.125 -bootstrap

Я не хочу явно указывать 192.168.1.125.

Я мог бы использовать env_file:, чтобы указать имя хоста или ip и принять его на каждом сервере, поэтому у меня есть эта информация в одном месте и используйте ее в файле docker-compose.yml. Но это можно использовать только для спецификаций среды, а не для параметра рекламы.

Есть ли лучшее решение?

4b9b3361

Ответ 1

Есть ли лучшее решение?

Абсолютно! Вам не нужен IP-адрес хоста для связи между контейнерами. Если вы link контейнеры в вашем файле docker-compose.yaml, у вас будет доступ к ряду переменных среды, которые вы можете использовать для обнаружения IP-адресов ваших служб.

Рассмотрим, например, конфигурацию с помощью докеры с двумя контейнерами: одну с помощью consul, а одну - с некоторой службой, с которой нужно поговорить с консулом.

consul:
  image: progrium/consul
  command: -server -bootstrap
webserver:
  image: larsks/mini-httpd
  links:
    - consul

Во-первых, начиная с consul только с -server -bootstrap, consul определяет свой собственный рекламный адрес, например:

consul_1    | ==> Consul agent running!
consul_1    |          Node name: 'f39ba7ef38ef'
consul_1    |         Datacenter: 'dc1'
consul_1    |             Server: true (bootstrap: true)
consul_1    |        Client Addr: 0.0.0.0 (HTTP: 8500, HTTPS: -1, DNS: 53, RPC: 8400)
consul_1    |       Cluster Addr: 172.17.0.4 (LAN: 8301, WAN: 8302)
consul_1    |     Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
consul_1    |              Atlas: <disabled>

В контейнере webserver мы находим следующие переменные среды, доступные для pid 1:

CONSUL_PORT=udp://172.17.0.4:53
CONSUL_PORT_8300_TCP_START=tcp://172.17.0.4:8300
CONSUL_PORT_8300_TCP_ADDR=172.17.0.4
CONSUL_PORT_8300_TCP_PROTO=tcp
CONSUL_PORT_8300_TCP_PORT_START=8300
CONSUL_PORT_8300_UDP_END=udp://172.17.0.4:8302
CONSUL_PORT_8300_UDP_PORT_END=8302
CONSUL_PORT_53_UDP=udp://172.17.0.4:53
CONSUL_PORT_53_UDP_ADDR=172.17.0.4
CONSUL_PORT_53_UDP_PORT=53
CONSUL_PORT_53_UDP_PROTO=udp
CONSUL_PORT_8300_TCP=tcp://172.17.0.4:8300
CONSUL_PORT_8300_TCP_PORT=8300
CONSUL_PORT_8301_TCP=tcp://172.17.0.4:8301
CONSUL_PORT_8301_TCP_ADDR=172.17.0.4
CONSUL_PORT_8301_TCP_PORT=8301
CONSUL_PORT_8301_TCP_PROTO=tcp
CONSUL_PORT_8301_UDP=udp://172.17.0.4:8301
CONSUL_PORT_8301_UDP_ADDR=172.17.0.4
CONSUL_PORT_8301_UDP_PORT=8301
CONSUL_PORT_8301_UDP_PROTO=udp
CONSUL_PORT_8302_TCP=tcp://172.17.0.4:8302
CONSUL_PORT_8302_TCP_ADDR=172.17.0.4
CONSUL_PORT_8302_TCP_PORT=8302
CONSUL_PORT_8302_TCP_PROTO=tcp
CONSUL_PORT_8302_UDP=udp://172.17.0.4:8302
CONSUL_PORT_8302_UDP_ADDR=172.17.0.4
CONSUL_PORT_8302_UDP_PORT=8302
CONSUL_PORT_8302_UDP_PROTO=udp
CONSUL_PORT_8400_TCP=tcp://172.17.0.4:8400
CONSUL_PORT_8400_TCP_ADDR=172.17.0.4
CONSUL_PORT_8400_TCP_PORT=8400
CONSUL_PORT_8400_TCP_PROTO=tcp
CONSUL_PORT_8500_TCP=tcp://172.17.0.4:8500
CONSUL_PORT_8500_TCP_ADDR=172.17.0.4
CONSUL_PORT_8500_TCP_PORT=8500
CONSUL_PORT_8500_TCP_PROTO=tcp

Существует набор переменных для каждого порта EXPOSE d с помощью consul образ. Например, во втором изображении мы могли бы взаимодействовать с API-интерфейсом консула, подключаясь к:

http://${CONSUL_PORT_8500_TCP_ADDR}:8500/

Ответ 2

С новой версией Docker Compose (1.4.0) вы сможете сделать что-то вроде этого:

Докер-compose.yml

consul:
  image: progrium/consul
  command: -server -advertise HOSTIP -bootstrap

bash

$ sed -e "s/HOSTIP/${HOSTIP}/g" docker-compose.yml | docker-compose --file - up

Это благодаря новой функции:

  • Compose теперь может читать конфигурацию YAML со стандартного ввода, а не из файла, указывая - как имя файла. Это упрощает динамическое создание конфигурации:

    $ echo 'redis: {"image": "redis"}' | docker-compose --file - up
    

Ответ 3

docker-compose позволяет использовать переменные среды из среды, выполняющей команду compose.

См. документацию на https://docs.docker.com/compose/compose-file/#variable-substitution

Предполагая, что вы можете создать оболочку script, например, предложенную @balver, вы можете установить переменную среды с именем EXTERNAL_IP, которая будет включать значение $(docker-machine ip).

Пример:

#!/bin/sh
export EXTERNAL_IP=$(docker-machine ip)
exec docker-compose [email protected]

и

# docker-compose.yml
version: "2"
services:
  consul:
    image: consul
    environment:
      - "EXTERNAL_IP=${EXTERNAL_IP}"
    command: agent -server -advertise ${EXTERNAL_IP} -bootstrap

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

PS: Что-то очень похожее включено по умолчанию в HashiCorp Nomad, также включает отображенные порты. Doc: https://www.nomadproject.io/docs/jobspec/interpreted.html#interpreted_env_vars

Ответ 4

Переменные среды, как это предложено в более раннем решении, создаются Docker, когда контейнеры связаны. Но env vars не обновляются автоматически, если контейнер перезагружен. Таким образом, не рекомендуется использовать переменные среды в процессе производства.

Docker, помимо создания переменных среды, также обновляет записи хоста в файле /etc/hosts. Фактически, документация Docker рекомендует использовать записи хоста из etc/hosts вместо переменных среды.

Ссылка: https://docs.docker.com/userguide/dockerlinks/

В отличие от записей хоста в файле /etc/hosts, IP-адреса, хранящиеся в переменных среды, не обновляются автоматически, если исходный контейнер перезагружен. Мы рекомендуем использовать записи хоста в /etc/hosts для разрешения IP-адреса связанных контейнеров.

Ответ 5

Я использовал внутренний IP-адрес докере, который кажется статическим: 172.17.0.1