Docker este uimitor. Îmi place. De fapt, îmi place foarte mult. Cu toate acestea, atunci când lucrați cu peste 10 micro-servicii în orice zi, poate fi dificil să gestionați relațiile dintre aceste servicii în timp ce vă dezvoltați la nivel local.

În producție, avem domenii de încredere pe care le putem folosi pentru a căuta alte servicii. Când lucrăm la nivel local, suntem la voința variabilelor de mediu Docker Compose și a legăturilor complexe pentru a realiza conducte locale. Acest lucru duce la setări confuze și complexe, care necesită mult timp pentru a 1) învățare și 2) predare noilor dezvoltatori.

Din câte știu, acesta este încă cel mai susținut mod de a căuta informații despre alte containere Docker atunci când lucrezi local cu Docker.

Știu bine, pare prea frumos pentru a fi adevărat... Ei bine, nu este. DNSDock este un instrument care permite această caracteristică. DNSDock este citat ca „Descoperirea serviciului DNS pentru containerele Docker”, eu prefer să-l numesc „Sânta vitală a dezvoltării locale Docker”.

„Descoperirea serviciului DNS pentru containerele Docker”

Cool zici. Ce înseamnă mai exact asta? Ei bine, înseamnă că puteți atribui domenii containerelor dvs. din fișierul docker-compose și aceste domenii nu vor fi disponibile numai pentru alte containere care rulează în VM, ci și pentru mașina dvs. gazdă.

Vă întrebați ce date sunt în containerul dvs. Redis? Conectați-l direct la RDM. Rulați PostgresSQL sau MySQL? Porniți Sequel Pro și aruncați o privire. Deși toate acestea sunt destul de posibile fără DNDock, este, de asemenea, un PITA uriaș!

Dulce, așa că acum că știm ce și de ce, să aruncăm o privire la cum.

Scopul final

Mai întâi, să aruncăm o privire la rezultatul așteptat. În esență, vrem un fișier Docker Compose care să arate așa...

# myapp/docker-compose.yml
redis:
  image: redis
  environment:
    DNSDOCK_NAME: cache
    DNSDOCK_IMAGE: myapp
  ports:
    - "6379":"6379"
mysql:
 image: mysql:5.6
  environment:
    DNSDOCK_NAME: db
    DNSDOCK_IMAGE: myapp
    MYSQL_ALLOW_EMPTY_PASSWORD: yes
  ports:
    — “3306:3306”
myapp:
  build: .
  environment:
    REDIS_HOST: cache.myapp.docker
    DB_HOST: db.myapp.docker
    HOST: api.myapp.docker
    DNSDOCK_NAME: api
    DNSDOCK_IMAGE: myapp
  ports:
    - "8001":"8001"

Cu această configurație, clientul nostru Redis este disponibil la cache.myapp.docker, mysql db este disponibil la db.myapp.docker, iar API-ul nostru este disponibil la api.myapp.docker.

Acum, de pe mașina noastră gazdă, putem să ne uităm cu ușurință la datele Redis sau MySQL, precum și să accesăm API-ul prin numele nostru de domeniu normalizat. Dacă trebuia să creați alte servicii în amonte sau în aval, puteți seta pur și simplu un API_HOST env var și nu ar fi nevoie să adăugați link-uri Docker și link-uri externe complicate.

Acest lucru ne permite să avem variabile de mediu curate, non-docker, pe care le putem folosi în toate mediile, atât în ​​interiorul, cât și în afara VM-ului Docker. Puteți înlocui cu ușurință REDIS_HOST și MYSQL_HOST în mediile dvs. de testare și producție, fără a fi nevoie ca aplicația dvs. să știe unde este rulată.

După cum vă puteți imagina, acest lucru reduce foarte mult efortul necesar pentru a porni sisteme complexe și pentru a obține paritatea mediului.

Cum să ajungem acolo

Deci, de ce este nevoie pentru ca această magie să se întâmple? Configurarea DNSDock este puțin complicată, dar odată ce l-ați configurat corect, prietenii și colegii vă vor lăuda ca fiind eroul care a simplificat procesul de dezvoltare local.

Mai întâi, să aruncăm o privire la modul în care funcționează DNSDock. (Notă laterală: documentele din depozitul DNSDock sunt mult mai bune decât orice aș putea oferi. Scopul acestui articol este mai mult despre conștientizare decât instrucțiuni.)

Dnsdock se conectează la API-ul Docker Remote și păstrează o listă actualizată a containerelor care rulează. Dacă o solicitare DNS se potrivește cu unele dintre containere, adresele IP locale ale acestora sunt returnate.

Asta e, direct din documente. Cu toate acestea, pentru ca acest lucru să funcționeze pe VM și pe mașina gazdă (acest articol se concentrează pe Mac OSX), trebuie să lucrăm puțin.

Configurarea mașinii dvs

Primul lucru pe care trebuie să-l facem este să configurați câteva informații de rutare pentru mașina noastră gazdă. Rularea următoarelor comenzi va configura mașina dvs. gazdă să direcționeze orice solicitare către *.docker către IP-ul mașinii Docker.

# make resolver dir if it does not exist
sudo mkdir -p /etc/resolver >/dev/null 2>&1
# add nameserver entry for *.docker URLs
echo "nameserver 172.17.42.1" | sudo tee /etc/resolver/docker > /dev/null
# remove previous entry for DNSDocker in case docker machine has different IP
sudo route -n delete -net 172.17.0.0
# add entries to route table for docker machine
sudo route -n add 172.17.0.0/16 $(docker-machine ip <your_docker_machine_name>)
sudo route -n add 172.17.42.1/32 $(docker-machine ip <your_docker_machine_name>)

Configurarea containerului DNDock

Acum că mașina gazdă este configurată să accepte redirecționarea domeniilor *.docker către mașina Docker, putem pune în funcțiune un container DNSDock și putem încerca noua noastră funcționalitate.

În primul rând, să punem containerul în funcțiune...

docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -p 172.17.42.1:53:53/udp tonistiigi/dnsdock

Acum să aruncăm o privire la ce face asta de fapt...

# share the docker socket to the container so that DNSDock can connect to the Docker API
-v /var/run/docker.sock:/var/run/docker.sock
# expose the default DNS port to the docker0 bridge interface
-p 172.17.42.1:53:53/udp

Și asta este! Creați unele servicii cu docker-compose și ar trebui să le puteți accesa de pe mașina dvs. gazdă și din interiorul VM-ului dvs., indiferent de numele de domeniu pe care le-ați atribuit!

Sper că acest lucru vă va aduce la fel de multă bucurie și eficiență pe cât mi-a adus mie!

SFATURI!

De asemenea, puteți seta DNSDOCK_ALIAS env var în fișierul dvs. de compunere docker, permițându-vă să configurați aliasuri și pentru containerele dvs....

myapp:
  build: .
  environment:
    REDIS_HOST: cache.myapp.docker
    DB_HOST: db.myapp.docker
    HOST: api.myapp.docker
    DNSDOCK_NAME: api
    DNSDOCK_IMAGE: myapp
    DNSDOCK_ALIAS: api.v2.myapp.docker, m.api.myapp.docker, etc...
  ports:
    - "8001":"8001"

De asemenea, puteți seta sufixul de domeniu dorit dacă nu preferați .docker implicit...

docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -domain container -p 172.17.42.1:53:53/udp tonistiigi/dnsdock

Dacă folosim exemplul nostru de myapp, acum vom obține adrese URL precum api.myapp.container. (Dacă modificați domeniul, va trebui să creați un server de nume pentru acel sufix de domeniu, consultați informațiile de rutare de mai sus.)

Mulțumiri

Aș dori să-i strig pe @steven.merrill de la https://www.phase2technology.com/. Vă mulțumesc că ați revizuit postarea și m-ați ajutat cu chestiile tehnice!

O altă notă

Tehnologia Faza 2 mi-a permis accesul beta la unele instrumente docker fantastice care fac toate acestea pentru tine! Reveniți aici pentru o actualizare după ce va fi lansat oficial open source!