rationale behind docker compose “links” order

2019-09-15 16:02发布

问题:

I have a Redis - Elasticsearch - Logstash - Kibana stack in docker which I am orchestrating using docker compose. Redis will receive the logs from a remote location, will forward them to Logstash, and then the customary Elasticsearch, Kibana.

In the docker-compose.yml, I am confused about the order of "links"

Elasticsearch links to no one while logstash links to both redis and elasticsearch

elasticsearch:

redis:

logstash:
    links:
    - elasticsearch
    - redis

kibana:
    links:
    - elasticsearch

Is this order correct? What is the rational behind choosing the "link" direction. Why don't we say, elasticsearch is linked to logstash?

回答1:

Instead of using the Legacy container linking method, you could instead use Docker user defined networks. Basically you can define a network for your services and then indicate in the docker-compose file that you want the container to run on that network. If your containers all run on the same network they can access each other via their container name (DNS records are added automatically).

1) : Create User Defined Network

docker network create pocnet

2) : Update docker-compose file

You want to add your containers to the network you just created. Your docker-compose file would look something along the lines of this :

version: '2'

services:
  elasticsearch:
    image: elasticsearch
    container_name: elasticsearch
    ports:
      - "{your:ports}"
    networks:
      - pocnet

  redis:
    image: redis
    container_name: redis
    ports:
       - "{your:ports}"
    networks:
      - pocnet

  logstash:
    image: logstash
    container_name: logstash
    ports:
      - "{your:ports}"
    networks:
      - pocnet

  kibana:
    image: kibana
    container_name: kibana
    ports:
      - "5601:5601"
    networks:
      - pocnet

networks:
  pocnet:
    external: true

3) : Start Services

docker-compose up

note : you might want to open a new shell window to run step 4.

4) : Test

Go into the Kibana container and see if you can ping the elasticsearch container.

your__Machine:/ docker exec -it kibana bash
kibana@123456:/# ping elasticsearch



回答2:

First of all Links in docker are Unidirectional.

More info on links: there are legacy links, and links in user-defined networks.

The legacy link provided 4 major functionalities to the default bridge network.

  • name resolution
  • name alias for the linked container using --link=CONTAINER-NAME:ALIAS
  • secured container connectivity (in isolation via --icc=false)
  • environment variable injection

Comparing the above 4 functionalities with the non-default user-defined networks , without any additional config, docker network provides

  • automatic name resolution using DNS
  • automatic secured isolated environment for the containers in a network
  • ability to dynamically attach and detach to multiple networks
  • supports the --link option to provide name alias for the linked container

In your case: Automatic dns will help you on user-defined network. first create a new network:

docker network create ELK -d bridge

With this approach you dont need to link containers on the same user-defined network. you just have to put your elk stack + redis containers in ELK network and remove link directives from composer file.

Your order looks fine to me. If you have any problem regarding the order, or waiting for services to get up in dependent containers, you can use something like the following:

version: "2"
services:
  web:
    build: .
    ports:
      - "80:8000"
    depends_on:
      - "db"
    entrypoint: ./wait-for-it.sh db:5432
  db:
    image: postgres

This will make the web container wait until it can connect to the db. You can get wait-for-it script from here.



标签: docker