docker-compose: почему происходит сбой службы агента и приложения из-за имени хоста? - PullRequest
1 голос
/ 30 октября 2019

Ниже приведен рабочий файл docker-compose в спецификации v2:

version: '2'

volumes:
  webroot:
    driver: local


services:
  app: # Launch uwsgi application server
    build:
      context: ../../
      dockerfile: docker/release/Dockerfile
    links:
      - dbc
    volumes:
      - webroot:/var/www/someapp
    environment:
      DJANGO_SETTINGS_MODULE: someapp.settings.release
      MYSQL_HOST: dbc
      MYSQL_USER: todo
      MYSQL_PASSWORD: passwd
    command:
      - uwsgi
      - "--socket /var/www/someapp/someapp.sock"
      - "--chmod-socket=666"
      - "--module someapp.wsgi"
      - "--master"
      - "--die-on-term"

  test: # Run acceptance test cases
    image: shamdockerhub/someapp-specs
    links:
      - nginx
    environment:
      URL: http://nginx:8000/todos
      JUNIT_REPORT_PATH: /reports/acceptance.xml
      JUNIT_REPORT_STACK: 1
    command: --reporter mocha-jenkins-reporter

  nginx: # Start nginx web server that forwards https packets to uwsgi server
    build:
      context: .
      dockerfile: Dockerfile.nginx
    ports:
      - "8000:8000"
    links:
      - app
    volumes:
      - webroot:/var/www/someapp

  dbc: # Launch MySQL server
    image: mysql:5.6
    hostname: dbr
    expose:
      - "3306"
    environment:
      MYSQL_DATABASE: someapp
      MYSQL_USER: todo
      MYSQL_PASSWORD: passwd
      MYSQL_ROOT_PASSWORD: passwd

  agent: # Ensure DB server is runnin
    image: shamdockerhub/ansible
    links:
      - dbc
    environment:
      PROBE_HOST: "dbc"
      PROBE_PORT: "3306"
    command: ["probe.yml"]

, где записи

  MYSQL_HOST: dbc

  PROBE_HOST: "dbc"

не выглядят интуитивно понятными, поскольку установлен hostnameв dbr в dbc службе


1)

app служба завершается с ошибкой ниже при использовании MYSQL_HOST: dbr

   django.db.utils.OperationalError: (2005, "Unknown MySQL server host 'dbr' (0)")

2)

agent служба также не работает в приведенном ниже коде, когда PROBE_HOST: "dbr"

set_fact:
      probe_host: "{{ lookup('env', 'PROBE_HOST') }}"
local_action: >
      wait_for host={{ probe_host }}

1)

Почему эти две службы отказывают со значением dbr?

2)

Как заставить эти две службы работать с MYSQL_HOST: dbr и PROBE_HOST: "dbr"?

Ответы [ 3 ]

1 голос
/ 30 октября 2019

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

1 голос
/ 30 октября 2019

Установка hostname: эквивалентна команде hostname (8) в обычном Linux: она изменяет то, что контейнер считает своим собственным именем хоста, но не влияет на что-либо вне контейнера, которое может попытатьсядобраться до него. Например, в обычном Linux, работающем с hostname dbr, внешний DNS-сервер или файлы /etc/hosts других компьютеров не будут изменены. Установка имени хоста может повлиять на приглашение оболочки, в необычном случае получения интерактивной оболочки внутри контейнера;это не влияет на работу сети.

В пределах одного файла Docker Compose, если у вас нет специальной конфигурации для networks:, любой контейнер может достичь любого другого контейнера, используя имя своего блока в файле YAML. В вашем файле app, nginx, test, dbc и agent являются действительными именами хостов. Если вы вручную укажете container_name:, я считаю, что это также будет достижимо;псевдонимы сети, предложенные в ответе @ asolanki, дают еще одно имя;и устаревший вариант links: даст еще один вариант. Все это в дополнение к , которое дает вам стандартное имя Compose.

Сеть в Compose содержит некоторые разумные объяснения всего этого.

В вашем примере dbr не является допустимым именем хоста. dbc - это имя службы Compose контейнера, но ничто из предыдущего списка не приводит к существованию имени хоста dbr. Это имя, которое вы увидите в приглашении, если вы docker-compose exec dlc sh, но никто больше не думает, что у контейнера есть это имя.

Как конкретное следствие "links: устарело", формаlinks: у вас нет абсолютно ничего. links: [dbc] делает контейнер, который в противном случае был бы виден под именем dbc, видимым для этого конкретного контейнера с тем же именемВы можете использовать его для присвоения альтернативного имени контейнеру с точки зрения клиента, но я бы не стал.

Ваш файл docker-compose.yml не имеет блоков networks:, и поэтомуCompose создаст сеть default и подключит к ней все контейнеры. Это совершенно нормально, и я бы не рекомендовал менять его. Если вы объявляете несколько сетей, другое требование здесь заключается в том, что клиент и сервер должны находиться в одной сети, чтобы связаться друг с другом. (Контейнеры без блока networks: неявно имеют networks: [default].)

0 голосов
/ 30 октября 2019

Если вы хотите сослаться на службу под другим именем, вы можете использовать сетевой псевдоним . Измененный составной файл для использования сетевого псевдонима

version: '2'

volumes:
  webroot:
    driver: local


services:
  app: # Launch uwsgi application server
    build:
      context: ../../
      dockerfile: docker/release/Dockerfile
    links:
      - dbc
    volumes:
      - webroot:/var/www/someapp
    environment:
      DJANGO_SETTINGS_MODULE: someapp.settings.release
      MYSQL_HOST: dbc
      MYSQL_USER: todo
      MYSQL_PASSWORD: passwd
    command:
      - uwsgi
      - "--socket /var/www/someapp/someapp.sock"
      - "--chmod-socket=666"
      - "--module someapp.wsgi"
      - "--master"
      - "--die-on-term"
    networks:
      new:
        aliases:
          - myapp  

  test: # Run acceptance test cases
    image: shamdockerhub/someapp-specs
    links:
      - nginx
    environment:
      URL: http://nginx:8000/todos
      JUNIT_REPORT_PATH: /reports/acceptance.xml
      JUNIT_REPORT_STACK: 1
    command: --reporter mocha-jenkins-reporter
    networks:
      - new


  nginx: # Start nginx web server that forwards https packets to uwsgi server
    build:
      context: .
      dockerfile: Dockerfile.nginx
    ports:
      - "8000:8000"
    links:
      - app
    volumes:
      - webroot:/var/www/someapp
    networks:
      - new 

  dbc: # Launch MySQL server
    image: mysql:5.6
    hostname: dbr
    expose:
      - "3306"
    environment:
      MYSQL_DATABASE: someapp
      MYSQL_USER: todo
      MYSQL_PASSWORD: passwd
      MYSQL_ROOT_PASSWORD: passwd
    networks:
      new:
        aliases:
          - dbr  

  agent: # Ensure DB server is runnin
    image: shamdockerhub/ansible
    links:
      - dbc
    environment:
      PROBE_HOST: "dbc"
      PROBE_PORT: "3306"
    command: ["probe.yml"]
    networks:
      - new

networks:
  new:
...