Docker jest niesamowity. Kocham to. Prawdę mówiąc, naprawdę to kocham. Jeśli jednak każdego dnia pracujesz z ponad 10 mikrousługami, zarządzanie relacjami między tymi usługami podczas lokalnego rozwoju może być trudne.
W fazie produkcyjnej dysponujemy niezawodnymi domenami, za pomocą których możemy wyszukiwać inne usługi. Kiedy pracujemy lokalnie, jesteśmy zdani na zmienne środowiskowe Docker Compose i złożone połączenia w celu osiągnięcia lokalnych potoków. Prowadzi to do mylących i skomplikowanych konfiguracji, których nauczenie się 1) i 2) zajmuje dużo czasu nowym programistom.
O ile mi wiadomo, jest to nadal najpopularniejsza metoda wyszukiwania informacji o innych kontenerach Dockera podczas lokalnej pracy z Dockerem.
Wiem dobrze, wydaje się to zbyt piękne, aby mogło być prawdziwe… Cóż, tak nie jest. DNSDock to narzędzie, które umożliwia tę właśnie funkcję. DNSDock jest cytowany jako „wykrywanie usług DNS dla kontenerów Docker”, ja wolę to nazywać „siłą napędową lokalnego rozwoju Dockera”.
„Wykrywanie usług DNS dla kontenerów Docker”
Fajnie mówisz. Co to dokładnie oznacza? Oznacza to, że możesz przypisywać domeny do swoich kontenerów w pliku tworzenia dokera, a domeny te będą dostępne nie tylko dla innych kontenerów działających na Twojej maszynie wirtualnej, ale także dostępne dla Twojego komputera hosta.
Zastanawiasz się, jakie dane znajdują się w Twoim kontenerze Redis? Podłącz go bezpośrednio do RDM. Uruchamiasz PostgresSQL lub MySQL? Po prostu odpal Sequel Pro i spójrz. Chociaż wszystko to jest całkiem możliwe bez DNSDock, jest to także ogromna PITA!
Sweet, skoro już wiemy co i dlaczego, przyjrzyjmy się jak.
Cel końcowy
Najpierw przyjrzyjmy się oczekiwanemu wynikowi. Zasadniczo chcemy pliku Docker Compose, który wygląda tak…
# 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"
W tej konfiguracji nasz klient Redis jest dostępny pod adresem cache.myapp.docker, nasza baza danych mysql jest dostępna pod adresem db.myapp.docker, a nasze API jest dostępne pod adresem api.myapp.docker.
Teraz z naszego komputera hosta możemy łatwo przeglądać nasze dane Redis lub MySQL, a także uzyskiwać dostęp do interfejsu API za pośrednictwem naszej znormalizowanej nazwy domeny. Jeśli chcesz uruchomić inne usługi nadrzędne lub podrzędne, możesz po prostu ustawić zmienną środowiska API_HOST i nie będzie potrzeby dodawania skomplikowanych łączy Dockera i linków zewnętrznych.
Dzięki temu możemy mieć czyste zmienne środowiskowe inne niż Docker, których możemy używać we wszystkich środowiskach, zarówno wewnątrz, jak i na zewnątrz maszyny wirtualnej Docker. Możesz łatwo zastąpić REDIS_HOST i MYSQL_HOST w swoich środowiskach testowych i produkcyjnych, bez konieczności informowania aplikacji o tym, gdzie jest uruchamiana.
Jak można sobie wyobrazić, znacznie zmniejsza to wysiłek wymagany do uruchomienia złożonych systemów i uzyskania parytetu środowiskowego.
Jak się tam dostać
Co więc dokładnie jest potrzebne, aby zadziałała ta magia? Konfiguracja DNSDock jest nieco skomplikowana, ale gdy już ją poprawnie skonfigurujesz, Twoi przyjaciele i współpracownicy będą Cię chwalić jako bohatera, który uprościł proces lokalnego programowania.
Najpierw przyjrzyjmy się, jak działa DNSDock. (Uwaga dodatkowa: dokumentacja w repozytorium DNSDock jest znacznie lepsza niż cokolwiek, co mogłem udostępnić. Celem tego artykułu jest bardziej świadomość niż instrukcje.)
Dnsdock łączy się z Docker Remote API i utrzymuje aktualną listę uruchomionych kontenerów. Jeśli żądanie DNS pasuje do niektórych kontenerów, zwracane są ich lokalne adresy IP.
To wszystko, prosto z dokumentów. Jednak aby to działało na maszynie wirtualnej i komputerze hosta (ten artykuł skupia się na Mac OSX), musimy włożyć trochę pracy.
Konfigurowanie maszyny
Pierwszą rzeczą, którą musimy zrobić, to skonfigurować pewne informacje o routingu dla naszego komputera-hosta. Uruchomienie poniższych poleceń skonfiguruje komputer hosta tak, aby kierował wszelkie żądania do *.docker na adres IP komputera 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>)
Konfigurowanie kontenera DNSDock
Teraz, gdy maszyna hosta jest skonfigurowana do obsługi przekazywania domen *.docker na maszynę Docker, możemy uruchomić kontener DNSDock i wypróbować naszą nową funkcjonalność.
Najpierw uruchommy kontener…
docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -p 172.17.42.1:53:53/udp tonistiigi/dnsdock
Przyjrzyjmy się teraz, co to właściwie robi…
# 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 to wszystko! Uruchom niektóre usługi za pomocą docker-compose, a powinieneś być w stanie uzyskać do nich dostęp z komputera hosta i z poziomu maszyny wirtualnej, niezależnie od przypisanej im nazwy domeny!
Mam nadzieję, że przyniesie Ci to tyle samo radości i wydajności, co mnie!
WSKAZÓWKI!
Możesz także ustawić zmienną DNSDOCK_ALIAS env env w pliku tworzenia okna dokowanego, co umożliwi Ci także skonfigurowanie aliasów dla kontenerów…
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"
Możesz także ustawić żądany sufiks domeny, jeśli nie wolisz domyślnego ustawienia .docker…
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
Jeśli użyjemy naszego przykładu myapp, otrzymamy teraz adresy URL takie jak api.myapp.container. (Jeśli zmienisz domenę, będziesz musiał utworzyć serwer nazw dla tego sufiksu domeny, zobacz informacje o routingu powyżej.)
Podziękowanie
Chciałbym gorąco pozdrowić @steven.merrill z https://www.phase2technology.com/. Dziękuję za zapoznanie się z moim postem i pomoc w kwestiach technicznych!
Kolejna uwaga
Technologia Phase 2 umożliwiła mi dostęp w wersji beta do fantastycznych narzędzi dokowanych, które robią to wszystko za Ciebie! Zaglądaj tutaj, aby uzyskać aktualizację, gdy zostanie oficjalnie udostępniona jako oprogramowanie typu open source!