Amazon ECS (Docker): contenitore vincolante per indirizzo IP specifico


24

Sto giocando con Amazon ECS (un reimballaggio di Docker) e sto scoprendo che esiste una funzionalità Docker che ECS non sembra fornire. Vale a dire, vorrei avere più contenitori in esecuzione in un'istanza e avere richieste che arrivano all'indirizzo IP 1 mappano al contenitore 1 e richieste che arrivano all'indirizzo IP 2 mappano al contenitore 2, ecc.

In Docker, l'associazione di un contenitore a un indirizzo IP specifico viene eseguita tramite:

docker run -p myHostIPAddr:80:8080 imageName command

Tuttavia, in Amazon ECS, non sembra esserci un modo per farlo.

Ho impostato un'istanza EC2 con più indirizzi IP elastici. Quando si configura un contenitore come parte della definizione di un'attività, è possibile mappare le porte host alle porte contenitore. Tuttavia, a differenza di Docker, ECS non fornisce un modo per specificare l'indirizzo IP dell'host come parte della mappatura.

Un'ulteriore svolta è che vorrei che le richieste in uscita dal contenitore N avessero l'indirizzo IP esterno del contenitore N.

C'è un modo per fare tutto quanto sopra?

Ho esaminato la documentazione della CLI di AWS e l'SDK di AWS per Java. Vedo che la CLI può restituire un array networkBindings contenente elementi come questo:

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

e Java SDK ha una classe denominata NetworkBinding che rappresenta le stesse informazioni. Tuttavia, queste informazioni sembrano essere solo di output, in risposta a una richiesta. Non riesco a trovare un modo per fornire queste informazioni vincolanti a ECS.

Il motivo per cui voglio fare questo è che voglio impostare macchine virtuali completamente diverse per diversi collegi elettorali, utilizzando contenitori diversi potenzialmente sulla stessa istanza EC2. Ogni VM avrebbe il proprio server Web (inclusi certificati SSL distinti), nonché il proprio servizio FTP e SSH.

Grazie.


Sto riscontrando lo stesso problema con il nostro flusso di lavoro. aws ecs describe-container-instancesnon sembra aiutare. Sembrano davvero voler spingerti a usare un ELB, che per il nostro caso è un po 'stupido.
quattro43,

Sembra che ci sia un modo per farlo ora (Q4 2017): stackoverflow.com/a/46577872/6309
VonC

Risposte:


4

Un'opzione: creare un ELB per ciascun client, quindi assegnare determinati contenitori a ciascun ELB.

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


13
Ca-ching! 18 dollari al mese per un ELB. Ora, chi desidera microservizi con ECS? aws.amazon.com/elasticloadbalancing/pricing
Knots,

1
@Knots abbiamo avuto lo stesso problema. Quindi siamo passati a Lambda + API Gateway e il nostro costo è sceso a 10 centesimi.
grepe,

Ora puoi utilizzare un singolo ALB (invece dei classici ELB) per tutti i tuoi servizi anziché 1 per servizio. Devono trovarsi su nomi host diversi o su percorsi diversi su un nome host.
AJ Brown,

4

Ecco un modo reale e logico per farlo. Sembra troppo complicato ma puoi effettivamente implementarlo in pochi minuti e funziona. In realtà lo sto implementando mentre parliamo.

Si crea un'attività per ciascun contenitore e si crea un servizio per ogni attività, associato a un gruppo target per ciascun servizio. E poi crei solo 1 bilanciamento del carico elastico.

I sistemi di bilanciamento del carico elastico basati sull'applicazione possono instradare le richieste in base al percorso richiesto. Utilizzando i gruppi target, è possibile instradare le richieste che arrivano elb-domain.com/1al contenitore 1, elb-domain.com/2al contenitore 2, ecc.

Ora sei solo ad un passo. Creare un server proxy inverso.

Nel mio caso stiamo usando nginx, quindi puoi creare un server nginx con tutti gli IP che desideri e, utilizzando la funzionalità di proxy inverso di nginx, puoi indirizzare i tuoi IP ai percorsi del tuo ELB, che di conseguenza li indirizzano al contenitore corretto (S). Ecco un esempio se stai usando domini.

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

Naturalmente, se stai effettivamente ascoltando gli IP, puoi omettere la server_namelinea e ascoltare le interfacce corrispondenti.

Questo in realtà è meglio dell'assegnazione di un IP statico per contenitore perché consente di avere cluster di macchine docker in cui le richieste sono bilanciate su quel cluster per ciascuno dei "IP". La ricostruzione di una macchina non influisce sull'IP statico e non è necessario ripetere molta configurazione.

Sebbene questo non risponda completamente alla tua domanda perché non ti consentirà di utilizzare FTP e SSH, direi che non dovresti mai usare Docker per farlo, e invece dovresti usare i server cloud. Se si utilizza Docker, quindi invece di aggiornare il server tramite FTP o SSH, è necessario aggiornare il contenitore stesso. Tuttavia, per HTTP e HTTPS, questo metodo funziona perfettamente.


1

Non è possibile al contenitore stesso, ma è possibile creare un'istanza EC2 dedicata a un contenitore specifico. Quindi, dove è necessario accedere a quel servizio, è possibile fare riferimento all'host EC2 che esegue il contenitore.

  • Crea un cluster dedicato per i tuoi servizi con questo requisito
  • Crea un'istanza EC2 ottimizzata AMI usando il tuo tipo di istanza preferito
    • Assicurarsi di assegnare tale istanza al cluster sopra usando l'opzione UserData come descritto in quella guida.
  • Crea una TaskDefinition con NetworkMode impostato su "bridge" (uguale al desktop)
  • Crea una definizione di servizio con:
    • LaunchType impostato su EC2
    • Cluster impostato sul cluster creato in precedenza
    • Definizione dell'attività impostata sulla definizione dell'attività creata in precedenza
  • Assegnare eventuali gruppi di sicurezza all'istanza EC2 come altrimenti.

Anche se stai ancora parlando direttamente con un'istanza EC2, puoi controllare l'IP del contenitore (indirettamente) come faresti con l'istanza EC2. Ciò consente di risparmiare il mal di testa nell'esecuzione dei servizi sul "bare metal" consentendo di gestire e configurare più facilmente il servizio e la configurazione in essi contenuti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.