comment relier Docker container l'un à l'autre avec docker-composer

je dois configurer une réplique de mongo avec docker-composer. Pour le jeu de répliques, les containers doivent se connaître.

j'ai essayé docker-compose.yml

    dbreplicasetpart1:
      image: mongo:2.6.8
      expose:
        - '27018'
      links:
        - replicasetpart2
        - replicasetpart3
      cap_add:
        - NET_ADMIN

    dbreplicasetpart2:
      image: mongo:2.6.8
      links:
        - replicasetpart1
        - replicasetpart3
      expose:
        - '27019'
      cap_add:
        - NET_ADMIN
...

je reçois un message d'importation circulaire. Mais si je supprime le back-link à dbreplicasetpart1 Je ne peux pas ping de dbreplicasetpart2 à dbreplicasetpart1. Quelle est la solution?

23
demandé sur Golo Roden 2015-03-27 21:23:08

4 réponses

mise à Jour pour Docker 1.10

Panneau 1.10 permet la définition de réseaux dans le fichier composer. Voici le code mis à jour

version: "2"

services:
  replica1:
    image: mongo:2.6.8
    container_name: replica1
    networks:
      - my-net
    ports:
      - "27018"
    environment:
      REPLICA2_URL: "http://replica2:27019"
  replica2:
    image: mongo:2.6.8
    container_name: replica2
    networks:
      - my-net
    ports:
      - "27019"
    environment:
      REPLICA1_URL: "http://replica1:27018"

networks:
  my-net:
    driver: bridge

précédente réponse pour Docker 1.9

A partir du Docker 1.9, la solution est de créer un réseau personnalisé et de le passer au docker-compose up la commande.

  1. Créer un réseau docker network create --driver bridge my-net

  2. Référence du réseau variable d'environnement (${NETWORK}) dans la composition docker.fichiers yml. Par exemple:

``

replica1:
  image: mongo:2.6.8
  container_name: replica1
  net: ${NETWORK}
  ports:
    - "27018"
  environment:
    REPLICA2_URL: "http://replica2:27019"

replica2:
  image: mongo:2.6.8
  container_name: replica2
  net: ${NETWORK}
  ports:
    - "27019"
  environment:
    REPLICA1_URL: "http://replica1:27018"

``

Notez que replica1http://replica1:27018 résoudra à l'adresse ip du service replica1 (conteneur). Il n'est pas nécessaire de coder les adresses ip; une entrée pour replica1 est automatiquement ajoutée à /etc/host du conteneur replica2. Il en va de même pour le container replica1. Docker ajoutera une entrée pour replica2 dans son fichier/etc / host fichier.

  1. appeler docker-composer, passer le réseau que vous avez créé NETWORK=my-net docker-compose up -d -f docker-compose.yml

j'ai créé un réseau de ponts au-dessus de laquelle ne fonctionne qu'à l'intérieur d'un seul noeud (hôte). Bon pour les dev. Si vous avez besoin de deux noeuds pour se parler, vous devez créer un réseau de superposition. Même principe. Vous passez le nom du réseau à la commande docker-composer.

41
répondu Alkaline 2016-03-19 10:07:06

Vous devez utiliser l'ambassadeur modèle:

https://docs.docker.com/engine/admin/ambassador_pattern_linking/

fondamentalement, vous créez un composant intermédiaire qui les relie tous les deux ensemble. Vous pouvez voir un exemple que nous utilisons avec le service de découverte Eureka de Spring Cloud:

ambassador:
  image: cpuguy83/docker-grand-ambassador
  volumes:
    - "/var/run/docker.sock:/var/run/docker.sock"
  command: "-name eureka_1 -name eureka2_1 "

eureka:
  links:
    - "ambassador:eureka2"

eureka2:
  links:
    - "ambassador:eureka"

pour la simplicité, j'ai seulement copié les liens

14
répondu MiguelPuyol 2016-11-03 15:44:36

nous avons pensé à utiliser la solution avec l'ambassadeur. C'est en effet la solution la plus confortable. La configuration qui fonctionne pour nous:

amba1:
  image: cpuguy83/docker-grand-ambassador
  volumes:
    - "/var/run/docker.sock:/var/run/docker.sock"
  command: "-name cucumber_dbreplicasetpart1_1"

amba2:
  image: cpuguy83/docker-grand-ambassador
  volumes:
    - "/var/run/docker.sock:/var/run/docker.sock"
  command: "-name cucumber_dbreplicasetpart2_1"

amba3:
  image: cpuguy83/docker-grand-ambassador
  volumes:
    - "/var/run/docker.sock:/var/run/docker.sock"
  command: "-name cucumber_dbreplicasetpart3_1"

dbreplicasetpart1:
  image: 'mongo:2.6.8'
  hostname: dbreplicasetpart1
  command: >
    bash -c
    '
      mongod --fork --logpath mongo.log --smallfiles --replSet rs1
      echo "
        printjson(
          rs.initiate(
            {
              _id : \"rs1\",
              members : [
                {_id : 0, host : \"dbreplicasetpart1:27017\"},
                {_id : 1, host : \"dbreplicasetpart2:27017\"},
                {_id : 2, host : \"dbreplicasetpart3:27017\"},
              ]
            }
          )
        );
      " | mongo;
      tail -f mongo.log
    '
  links:
    - "amba2:dbreplicasetpart2"
    - "amba3:dbreplicasetpart3"

dbreplicasetpart2:
  image: 'mongo:2.6.8'
  hostname: dbreplicasetpart2
  command: >
    bash -c
    '
      mongod --fork --logpath mongo.log --smallfiles --replSet rs1
      echo "
        printjson(
          rs.initiate(
            {
              _id : \"rs1\",
              members : [
                {_id : 0, host : \"dbreplicasetpart1:27017\"},
                {_id : 1, host : \"dbreplicasetpart2:27017\"},
                {_id : 2, host : \"dbreplicasetpart3:27017\"},
              ]
            }
          )
        );
      " | mongo;
      tail -f mongo.log
    '
  links:
    - "amba1:dbreplicasetpart1"
    - "amba3:dbreplicasetpart3"

dbreplicasetpart3:
  image: 'mongo:2.6.8'
  hostname: dbreplicasetpart3
  command: >
    bash -c
    '
      mongod --fork --logpath mongo.log --smallfiles --replSet rs1
      echo "
        printjson(
          rs.initiate(
            {
              _id : \"rs1\",
              members : [
                {_id : 0, host : \"dbreplicasetpart1:27017\"},
                {_id : 1, host : \"dbreplicasetpart2:27017\"},
                {_id : 2, host : \"dbreplicasetpart3:27017\"},
              ]
            }
          )
        );
      " | mongo;
      tail -f mongo.log
    '
  links:
    - "amba1:dbreplicasetpart1"
    - "amba2:dbreplicasetpart2"
0
répondu Michael K. 2015-04-13 08:33:14

voici ce qui devrait encore fonctionner dans Docker 1.7.1 (dans le cas où vous avez collé avec CentOS 6):

etcd:
  image: elcolio/etcd:latest
skydns:
  image: outrider/skydns
  links:
    - etcd
  environment:
    ETCD_MACHINES: "http://etcd:4001"
    SKYDNS_DOMAIN: "docker"
    SKYDNS_PATH_PREFIX: my
    SKYDNS_NDOTS: 0
    SKYDNS_VERBOSE: "true"
    SKYDNS_ADDR: 0.0.0.0:53
  expose:
    - 53

my-service:
    image: alpine
    command: sh -c "dns_add my-service && ping my-service"
    links:
      - etcd
      - skydns

dns_add script:

#!/usr/bin/env sh

# This script configures resov.conf to use
# "skydns" name server with "docker" domain
# and adds a service name specified in the first argument
SERVICE_NAME=

waitforit () {
  HOST=
  PORT=
  TIME_OUT=${3:-30};
  END=$(($(date "+%s+$TIME_OUT")))
  while [ $(date "+%s") -lt $END ]
    do nc -z -w1 $HOST $PORT && break
  done
  return $END
}

# Use skydns to resolve names
echo "nameserver `resolveip -s skydns`" > /etc/resolv.conf
echo "search docker" >> /etc/resolv.conf

# Put yourself to DNS
ETCD_HOST=etcd
ETCD_PORT=4001
waitforit $ETCD_HOST $ETCD_PORT
HOST_IP=`resolveip -s $HOSTNAME`
apk update && apk add curl
curl -XPUT http://$ETCD_HOST:$ETCD_PORT/v2/keys/my/docker/$SERVICE_NAME -d value="{\"host\":\"$HOST_IP\"}"

Voici une explication:

  1. nous mettons en place notre propre serveur DNS dans un conteneur
  2. Nous configurons nos conteneurs pour utiliser ce serveur
  3. nous configurons ce serveur DNS en utilisant des requêtes HTTP spéciales
-1
répondu Vanuan 2016-10-14 02:52:36