Amazon ECS (Docker): powiązanie kontenera z określonym adresem IP

24

Gram z Amazon ECS (przepakowywanie Dockera) i stwierdzam, że istnieje jedna funkcja Dockera, której ECS nie wydaje się zapewniać. Mianowicie, chciałbym, aby w jednej instancji działało wiele kontenerów, a żądania przychodzące do adresu IP 1 były mapowane do kontenera 1, a żądania przychodzące do adresu IP 2 mapowały do ​​kontenera 2 itd.

W Docker powiązanie kontenera z określonym adresem IP odbywa się poprzez:

docker run -p myHostIPAddr:80:8080 imageName command

Jednak w Amazon ECS wydaje się, że nie ma na to sposobu.

Skonfigurowałem instancję EC2 z wieloma elastycznymi adresami IP. Podczas konfigurowania kontenera jako części definicji zadania można mapować porty hosta na porty kontenera. Jednak w przeciwieństwie do Dockera, ECS nie zapewnia sposobu określenia adresu IP hosta jako części mapowania.

Dodatkowym zwrotem jest to, że chciałbym, aby żądania wychodzące z kontenera N miały zewnętrzny adres IP kontenera N.

Czy istnieje sposób na wykonanie powyższych czynności?

Przejrzałem dokumentację AWS CLI, a także AWS SDK dla Java. Widzę, że CLI może zwrócić tablicę networkBindings zawierającą takie elementy:

{
  "bindIP": "0.0.0.0", 
  "containerPort": 8021, 
  "hostPort": 8021
},

a Java SDK ma klasę o nazwie NetworkBinding, która reprezentuje te same informacje. Jednak wydaje się, że te informacje są tylko danymi wyjściowymi w odpowiedzi na żądanie. Nie mogę znaleźć sposobu na przekazanie tych wiążących informacji do ECS.

Powodem, dla którego chcę to zrobić, jest to, że chcę skonfigurować całkowicie różne maszyny wirtualne dla różnych okręgów, używając różnych kontenerów potencjalnie w tej samej instancji EC2. Każda maszyna wirtualna miałaby swój własny serwer WWW (w tym odrębne certyfikaty SSL), a także własną usługę FTP i SSH.

Dzięki.

Mark R.
źródło
Mam ten sam problem z przepływem pracy. aws ecs describe-container-instancesnie wydaje się pomagać. Wydaje się, że naprawdę chcą zmusić cię do użycia ELB, co w naszym przypadku jest trochę głupie.
four43
Wydaje się, że jednym ze sposobów, aby to zrobić teraz (Q4 2017): stackoverflow.com/a/46577872/6309
VonC

Odpowiedzi:

4

Jedna opcja: utwórz ELB dla każdego klienta, a następnie przypisz określone kontenery do każdego ELB.

[1] http://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html

Adam Keck
źródło
13
Ca-ching! 18 dolców miesięcznie za jednego ELB. Teraz, kto chce mikrousług z ECS? aws.amazon.com/elasticloadbalancing/pricing
Knots
1
@ Węzły mieliśmy ten sam problem. Następnie przeszliśmy na Lambda + API Gateway i nasz koszt spadł do 10 centów.
grepe,
Możesz teraz używać jednego ALB (zamiast klasycznych ELB) dla wszystkich swoich usług zamiast jednego na usługę. Muszą znajdować się na różnych nazwach hostów lub różnych ścieżkach na nazwie hosta.
AJ Brown,
4

Oto rzeczywisty, logiczny sposób na zrobienie tego. Brzmi to zbyt skomplikowanie, ale można go zaimplementować w ciągu kilku minut i działa. Właściwie to wdrażam, gdy mówimy.

Tworzysz zadanie dla każdego kontenera i tworzysz usługę dla każdego zadania w połączeniu z grupą docelową dla każdej usługi. A następnie tworzysz tylko 1 moduł równoważenia obciążenia elastycznego.

Elastyczne moduły równoważące obciążenie oparte na aplikacji mogą kierować żądania na podstawie żądanej ścieżki. Korzystając z grup docelowych, możesz kierować żądania przychodzące elb-domain.com/1do kontenera 1, elb-domain.com/2do kontenera 2 itp.

Teraz jesteś tylko o krok. Utwórz odwrotny serwer proxy.

W moim przypadku używamy nginx, więc możesz stworzyć serwer nginx z dowolną liczbą adresów IP, a korzystając z funkcji odwrotnego proxy nginx możesz przekierować swoje adresy IP na ścieżki twojego ELB, które odpowiednio skierują je do odpowiedniego kontenera (s). Oto przykład, jeśli używasz domen.

server {
    server_name domain1.com;
    listen 80;
    access_log /var/log/nginx/access.log vhost;
    location / {
        proxy_pass http://elb-domain.com/1;
    }
}

Oczywiście, jeśli faktycznie słuchasz adresów IP, możesz pominąć server_namelinię i po prostu odsłuchać odpowiednie interfejsy.

Jest to w rzeczywistości lepsze niż przypisywanie statycznego adresu IP do kontenera, ponieważ pozwala mieć klastry maszyn dokujących, w których żądania są równoważone w tym klastrze dla każdego z „adresów IP”. Ponowne uruchomienie komputera nie ma wpływu na statyczny adres IP i nie trzeba dużo przerabiać konfiguracji.

Chociaż to nie w pełni odpowiada na twoje pytanie, ponieważ nie pozwoli ci na korzystanie z FTP i SSH, twierdzę, że nigdy nie powinieneś używać Dockera do tego, a zamiast tego powinieneś używać serwerów w chmurze. Jeśli używasz Dockera, zamiast aktualizować serwer za pomocą FTP lub SSH, powinieneś zaktualizować sam kontener. Jednak w przypadku HTTP i HTTPS ta metoda działa idealnie.

TheNavigat
źródło
1

Nie możesz do samego kontenera, ale możesz utworzyć instancję EC2 dedykowaną do konkretnego kontenera. Następnie, tam gdzie musisz uzyskać dostęp do tej usługi, możesz odwołać się do hosta EC2 obsługującego kontener.

  • Utwórz dedykowany klaster dla swoich usług z tym wymogiem
  • Utwórz instancję EC2 zoptymalizowaną pod kątem AMI, używając preferowanego typu instancji
    • Pamiętaj, aby przypisać to wystąpienie do powyższego klastra za pomocą opcji UserData zgodnie z opisem w tym przewodniku.
  • Utwórz TaskDefinition z NetworkMode ustawionym na „bridge” (tak samo jak na pulpicie)
  • Utwórz definicję usługi za pomocą:
    • Typ uruchamiania ustawiony na EC2
    • Klaster ustawiony na klaster utworzony powyżej
    • Definicja zadania ustawiona na definicję zadania utworzoną powyżej
  • Przypisz dowolne grupy zabezpieczeń do instancji EC2, jak w innym przypadku.

Chociaż nadal rozmawiasz bezpośrednio z instancją EC2, możesz kontrolować adres IP kontenera (pośrednio), tak jak instancję EC2. To oszczędza ci bólu głowy związanego z uruchamianiem usług na „czystym metalu”, umożliwiając łatwiejsze zarządzanie usługami i ich konfigurację oraz konfigurację.

Patrick Twohig
źródło