Aktualizacja II
Jest teraz 16 lipca 2015 roku i wszystko się zmieniło. Odkryłem ten automagiczny pojemnik od Jasona Wildera :
https://github.com/jwilder/nginx-proxy
i rozwiązuje ten problem w tak długim czasie, jak zajmujedocker run
to pojemnik. To jest teraz rozwiązanie, którego używam do rozwiązania tego problemu.
Aktualizacja
Teraz jest lipiec 2015 r. I sytuacja uległa drastycznej zmianie w odniesieniu do sieci kontenerów Docker. Obecnie istnieje wiele różnych ofert, które rozwiązują ten problem (na różne sposoby).
Powinieneś użyć tego posta, aby uzyskać podstawową wiedzę na temat
docker --link
podejścia do odkrywania usług, które jest tak podstawowe, jak to tylko możliwe, działa bardzo dobrze i faktycznie wymaga mniej wymyślnego tańca niż większość innych rozwiązań. Jest ograniczony, ponieważ dość trudno jest połączyć w sieć kontenery na oddzielnych hostach w dowolnym klastrze, a kontenerów nie można ponownie uruchomić po podłączeniu do sieci, ale oferuje szybki i stosunkowo łatwy sposób na sieciowe kontenery na tym samym hoście. To dobry sposób, aby zorientować się, jakie oprogramowanie, którego będziesz prawdopodobnie używać do rozwiązania tego problemu, faktycznie robi pod maską.Ponadto prawdopodobnie będziesz chciał również sprawdzić powstające Docker
network
, Hashicorp'sconsul
, Weaveworksweave
, Jeff Lindsay'sprogrium/consul
&gliderlabs/registrator
i GoogleKubernetes
.Istnieje również CoreOS ofiary, które wykorzystują
etcd
,fleet
orazflannel
.A jeśli naprawdę chcesz zorganizować imprezę, możesz uruchomić klaster
Mesosphere
, lubDeis
, lubFlynn
.Jeśli jesteś nowy w sieci (tak jak ja), powinieneś wyjąć okulary do czytania, pop „Paint The Sky With Stars - The Best of Enya” na Wi-Hi-Fi i wypić piwo - to będzie chwilę, zanim naprawdę dokładnie zrozumiesz, co próbujesz zrobić. Podpowiedź: próbujesz zaimplementować
Service Discovery Layer
w swoimCluster Control Plane
. To bardzo fajny sposób na spędzenie sobotniej nocy.To świetna zabawa, ale żałuję, że nie poświęciłem czasu na lepszą edukację w zakresie sieciowania w ogóle, zanim zacząłem od razu nurkować. W końcu znalazłem kilka postów od życzliwych bogów Digital Ocean Tutorial:
Introduction to Networking Terminology
iUnderstanding ... Networking
. Proponuję najpierw przeczytać je kilka razy przed zanurzeniem się.Baw się dobrze!
Oryginalny post
Nie mogę pojąć mapowania portów dla Docker
kontenerów. W szczególności, jak przekazywać żądania z Nginx do innego kontenera, nasłuchując na innym porcie, na tym samym serwerze.
Mam plik Dockerfile dla kontenera Nginx w następujący sposób:
FROM ubuntu:14.04
MAINTAINER Me <[email protected]>
RUN apt-get update && apt-get install -y htop git nginx
ADD sites-enabled/api.myapp.com /etc/nginx/sites-enabled/api.myapp.com
ADD sites-enabled/app.myapp.com /etc/nginx/sites-enabled/app.myapp.com
ADD nginx.conf /etc/nginx/nginx.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["service", "nginx", "start"]
A potem api.myapp.com
plik konfiguracyjny wygląda tak:
upstream api_upstream{
server 0.0.0.0:3333;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.mypp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
A potem jeszcze jeden dla app.myapp.com
.
A potem biegnę:
sudo docker run -p 80:80 -p 443:443 -d --name Nginx myusername/nginx
I wszystko działa dobrze, ale żądania nie są przekazywane do innych kontenerów / portów. A kiedy ssh do kontenera Nginx i sprawdzam logi, nie widzę żadnych błędów.
Jakaś pomoc?
Odpowiedzi:
Odpowiedź @ T0xicCode jest prawidłowa, ale pomyślałem, że omówię szczegóły, ponieważ w końcu wdrożenie działającego rozwiązania zajęło mi około 20 godzin.
Jeśli chcesz uruchomić Nginx we własnym kontenerze i używać go jako odwrotnego serwera proxy do równoważenia obciążenia wielu aplikacji na tej samej instancji serwera, kroki, które musisz wykonać, są następujące:
Połącz swoje pojemniki
Kiedy używasz
docker run
kontenerów, zazwyczaj wprowadzając do nich skrypt powłokiUser Data
, możesz zadeklarować linki do innych działających kontenerów. Oznacza to, że musisz uruchomić swoje kontenery w odpowiedniej kolejności i tylko te ostatnie mogą łączyć się z pierwszymi. Tak jak to:Tak więc w tym przykładzie,
API
pojemnik nie jest związana z żadnym innym, aleApp
pojemnik jest powiązanaAPI
iNginx
jest powiązana zarównoAPI
iApp
.Wynikiem tego są zmiany w
env
zmiennych i/etc/hosts
plikach, które znajdują się w kontenerachAPI
iApp
. Wyniki wyglądają tak:/ etc / hosts
Uruchomienie
cat /etc/hosts
w TwoimNginx
kontenerze spowoduje:ENV Vars
Uruchomienie
env
w TwoimNginx
kontenerze spowoduje:Obcięłem wiele rzeczywistych zmiennych, ale powyższe są kluczowymi wartościami potrzebnymi do proxy ruchu do kontenerów.
Aby uzyskać powłokę do uruchamiania powyższych poleceń w działającym kontenerze, użyj następującego:
sudo docker exec -i -t Nginx bash
Możesz zobaczyć, że masz teraz zarówno
/etc/hosts
wpisy w plikach, jak ienv
zmienne, które zawierają lokalny adres IP dowolnego z połączonych kontenerów. O ile wiem, to wszystko, co dzieje się, gdy uruchamiasz kontenery z zadeklarowanymi opcjami linków. Ale teraz możesz użyć tych informacji do konfiguracjinginx
w swoimNginx
kontenerze.Konfigurowanie Nginx
To jest trochę trudne i jest kilka opcji. Możesz skonfigurować swoje witryny tak, aby wskazywały wpis w utworzonym
/etc/hosts
plikudocker
, lub możesz użyćENV
vars i uruchomić zamianę ciągu (użyłemsed
) na swoimnginx.conf
i wszelkich innych plikach conf, które mogą znajdować się w twoim/etc/nginx/sites-enabled
folderze, aby wstawić adres IP wartości.OPCJA A: Skonfiguruj Nginx przy użyciu zmiennych ENV
Kluczową różnicą między tą opcją a użyciem
/etc/hosts
opcji file jest sposób, w jaki piszesz,Dockerfile
aby używał skryptu powłoki jakoCMD
argumentu, który z kolei obsługuje zamianę ciągu w celu skopiowania wartości IP zENV
do pliku (ów) conf.Oto zestaw plików konfiguracyjnych, z którymi skończyłem:
Dockerfile
nginx.conf
api.myapp.conf
Nginx-Startup.sh
Zostawię ci zadanie domowe z większością treści
nginx.conf
iapi.myapp.conf
.Magia dzieje się wtedy,
Nginx-Startup.sh
gdy używamysed
do zamiany ciągu znaków wAPP_IP
symbolu zastępczym, który zapisaliśmy wupstream
bloku naszychapi.myapp.conf
iapp.myapp.conf
plików.To pytanie ask.ubuntu.com bardzo ładnie to wyjaśnia: znajdź i zamień tekst w pliku za pomocą poleceń
Dlatego docker uruchomił nasz kontener i uruchomił
Nginx-Startup.sh
skrypt, którysed
zmienił wartośćAPP_IP
na odpowiedniąENV
zmienną, którą podaliśmy wsed
poleceniu. Mamy teraz pliki conf w naszym/etc/nginx/sites-enabled
katalogu, które mają adresy IP zeENV
zmiennych ustawionych przez docker podczas uruchamiania kontenera. Wapi.myapp.conf
pliku zobaczysz, żeupstream
blok zmienił się na ten:Adres IP, który widzisz, może być inny, ale zauważyłem, że zwykle
172.0.0.x
.Powinieneś teraz mieć wszystko poprawnie routowane.
OPCJA B: Użyj
/etc/hosts
wpisów plikuTo powinien być szybszy i łatwiejszy sposób na zrobienie tego, ale nie mogłem zmusić go do pracy. Pozornie po prostu wprowadzasz wartość
/etc/hosts
wpisu do swoich plikówapi.myapp.conf
iapp.myapp.conf
, ale nie mogłem uruchomić tej metody.Oto próba, którą podjąłem
api.myapp.conf
:Biorąc pod uwagę, że w moim
/etc/hosts
pliku jest taki wpis:172.0.0.2 API
pomyślałem, że po prostu ściągnie wartość, ale wygląda na to, że tak nie jest.Miałem również kilka dodatkowych problemów z
Elastic Load Balancer
pozyskiwaniem ze wszystkich AZ, więc mógł to być problem, gdy próbowałem tej trasy. Zamiast tego musiałem nauczyć się radzić sobie z zastępowaniem ciągów w Linuksie, więc to było zabawne. Spróbuję za chwilę i zobaczę, jak to działa.źródło
Próbowałem użyć popularnego odwrotnego proxy Jasona Wildera, który magicznie działa dla każdego, i dowiedziałem się, że nie działa dla wszystkich (tj. Dla mnie). Jestem zupełnie nowy w NGINX i nie podobało mi się, że nie rozumiem technologii, których próbowałem użyć.
Chciałem dodać moje 2 centy, ponieważ powyższa dyskusja na temat
linking
kontenerów jest teraz przestarzała, ponieważ jest to przestarzała funkcja. Oto wyjaśnienie, jak to zrobić za pomocąnetworks
. Ta odpowiedź jest pełnym przykładem konfigurowania nginx jako zwrotnego serwera proxy do statycznie stronicowanej witryny internetowej przy użyciuDocker Compose
i konfiguracji nginx.TL; DR;
Dodaj usługi, które muszą komunikować się ze sobą, do predefiniowanej sieci. Aby omówić krok po kroku sieci Dockera, dowiedziałem się tutaj kilku rzeczy: https://technologyconversations.com/2016/04/25/docker-networking-and-dns-the-good-the-bad-and- brzydki /
Zdefiniuj sieć
Przede wszystkim potrzebujemy sieci, w której mogą rozmawiać wszystkie Twoje usługi backendu. Zadzwoniłem do mnie,
web
ale to może być cokolwiek zechcesz.Zbuduj aplikację
Zrobimy po prostu prostą aplikację internetową. Witryna jest prostą stroną index.html obsługiwaną przez kontener nginx. Zawartość jest woluminem zamontowanym na hoście w folderze
content
DockerFile:
default.conf
docker-compose.yml
Zauważ, że nie potrzebujemy już tutaj mapowania portów. Po prostu eksponujemy port 80. Jest to przydatne, aby uniknąć kolizji portów.
Uruchom aplikację
Uruchom tę witrynę za pomocą
Kilka zabawnych sprawdzeń dotyczących mapowania DNS dla twojego kontenera:
Ten ping powinien działać wewnątrz kontenera.
Zbuduj proxy
Odwrotny serwer proxy Nginx:
Dockerfile
Zresetowaliśmy całą konfigurację hosta wirtualnego, ponieważ zamierzamy ją dostosować.
docker-compose.yml
Uruchom serwer proxy
Uruchom proxy za pomocą naszego zaufanego
Zakładając, że nie ma żadnych problemów, masz uruchomione dwa kontenery, które mogą rozmawiać ze sobą, używając swoich nazw. Przetestujmy to.
Skonfiguruj wirtualnego hosta
Ostatnim szczegółem jest skonfigurowanie wirtualnego pliku hostingu, aby serwer proxy mógł kierować ruch w zależności od tego, jak chcesz skonfigurować dopasowanie:
sample-site.conf dla naszej konfiguracji wirtualnego hostingu:
W zależności od tego, jak skonfigurowano serwer proxy, będziesz potrzebować tego pliku przechowywanego w
conf.d
folderze lokalnym, który zamontowaliśmy za pomocąvolumes
deklaracji wdocker-compose
pliku.Wreszcie, powiedz nginx, aby przeładował swoją konfigurację.
Ta sekwencja kroków jest kulminacją godzin pełnych bólu głowy, kiedy zmagałem się z zawsze bolesnym błędem 502 Bad Gateway i uczyłem się nginx po raz pierwszy, ponieważ większość mojego doświadczenia dotyczyła Apache.
Ta odpowiedź ma na celu zademonstrowanie, jak usunąć błąd złej bramy 502, który wynika z braku możliwości komunikacji między kontenerami.
Mam nadzieję, że ta odpowiedź zaoszczędzi komuś wiele godzin bólu, ponieważ z jakiegoś powodu trudno było znaleźć pojemniki do rozmowy, mimo że spodziewałem się, że będzie to oczywisty przypadek użycia. Ale z drugiej strony, ja głupi. Daj mi znać, jak mogę ulepszyć to podejście.
źródło
502 Gateway Error
, obecnie niesławny klasyk. Dzięki @gdbj za poświęcenie czasu na pogłębienie rozmowy i przedstawienie tak szczegółowego rozwiązania.Korzystając z linków docker , możesz połączyć kontener nadrzędny z kontenerem nginx. Dodatkową funkcją jest to, że docker zarządza plikiem hosta, co oznacza, że będziesz mógł odwoływać się do połączonego kontenera za pomocą nazwy, a nie potencjalnie losowego adresu IP.
źródło
„Opcja B” AJB może zostać uruchomiona przy użyciu podstawowego obrazu Ubuntu i samodzielnego skonfigurowania nginx. (To nie zadziałało, gdy użyłem obrazu Nginx z Docker Hub.)
Oto plik Docker, którego użyłem:
Moja konfiguracja nginx (aka: conf / mysite.com):
I wreszcie, jak zaczynam moje kontenery:
To sprawiło, że zacząłem działać, więc mój nginx skierował w górę do drugiego kontenera docker, który ujawnił port 3000.
źródło
upstream website {
określa wartość witryny internetowej dla nginx. To jest to, czego następnie używasz w swoimproxy_pass
. Część dockerowa tego po prostu używa tej samej nazwy dla spójności, ale nie ma nic wspólnego z konfiguracją nginx. Aby było to trochę jaśniejsze, przepustka proxy powinna brzmieć:upstream website { server localhost:3000; }
Odpowiedź @ gdbj to świetne wyjaśnienie i najbardziej aktualna odpowiedź. Oto jednak prostsze podejście.
Więc jeśli chcesz przekierować cały ruch z nasłuchiwania nginx
80
do innego ujawniającego kontenera8080
, minimalna konfiguracja może wynosić tylko:nginx.conf:
docker-compose.yml
Docker docs
źródło
Właśnie znalazłem artykuł od Ananda Mani Sankara, który pokazuje prosty sposób korzystania z serwera proxy Nginx w połączeniu z docker composer.
Zasadniczo należy skonfigurować łączenie instancji i porty w pliku docker-compose i odpowiednio zaktualizować nadrzędne w nginx.conf.
źródło
links
przestarzałych. Korzystaj z sieci teraz: docs.docker.com/engine/userguide/networking