Het opzetten van envoy als een front proxy op Docker met communicatie naar andere Docker containers

Ik heb al bestaande containers die ik wil gebruiken envoy als een proxy & https manager in de voorkant van. Ik ben aan het leren om envoy te gebruiken, en deel hier wat van mijn leerervaringen, aangezien de documentatie een beetje verwarrend is om mee te beginnen.

Mijn reeds bestaande container heet "taxgod" - het draait een Crystal applicatie op poort 3000 (http). Ik wil het proxyen naar poort 80 op de host voor http, en poort 443 voor https.

Ik zal een nep-certificaat gebruiken voor demonstratiedoeleinden. Het maken van certificaten valt buiten het bereik van dit artikel.

De envoy container gaat penvoyage heten (picockpit afgezant )

Gebouw van de reis

afbeelding

De penvoyage map gebruikt voor het bouwen bevat

  • Dockerfile
  • envoy.yaml
  • example.crt (certificaat)
  • example.key (sleutel voor het certificaat)

Dockerfile

FROM envoyproxy/envoy:latest
KOPIEer envoy.yaml /etc/envoy/envoy.yaml
COPY example.crt /etc/example-com.crt
COPY example.key /etc/example-com.key
#VOLUME /etc/envoy/envoy.yaml

80/tcp blootleggen
443/tcp blootleggen
#Educated gok dat dit TCP is
VERTELSTEM 9901/tcp

LABEL version="0.2.0″.
       description="penvoyage is een envoy proxy voor PiCockpit".
       maintainer=""

Pas op met de " tekens, WordPress zou ze kunnen verknoeien!

Ik zal binnenkort wat gedetailleerder ingaan op de envoy.yaml. Het volstaat te zeggen dat het in deze map staat en gekopieerd zal worden naar het nieuw aangemaakte container image.

Om de container te bouwen, start (vanuit de directory met de penvoyage directory):

docker build -t jasmine/penvoyage:0.2.0 -t jasmine/penvoyage:latest penvoyage

Uw uitvoer zou moeten eindigen met de regels

Met succes getagd jasmine/penvoyage:0.2.0
Succesvol getagd jasmine/penvoyage:latest

Maak het docker netwerk

docker network create -d bridge my-bridge-network

We zullen dit netwerk gebruiken om beide containers aan elkaar te koppelen, zodat ze elkaar kunnen zien.

Containers kunnen met elkaar praten door hun containernamen te gebruiken, als ze zich op hetzelfde containernetwerk bevinden.

B.v. u kunt doen

ping taxgod

waarbij taxgod de naam van de container is.

Om een container aan een netwerk toe te voegen nadat deze is uitgevoerd, doe je het volgende:

docker network connect my-bridge-network taxgod

In dit geval is my-bridge-network het netwerk, en taxgod is de container die ermee verbonden moet worden.

Om te zien hoe een draaiende container is verbonden met een bepaald netwerk, zie hieronder.

Om te zien welke containers zich op een bepaald Docker-netwerk bevinden, voert u het volgende commando uit:

docker network inspect my-bridge-network

Start de penvoyage container image

docker run -rm -it -p 80:80 -p 443:443 -p 9901:9901 -network=my-bridge-network jasmine/penvoyage

Dit zal:

  • -rm de container verwijderen nadat hij is afgesloten
  • -it aan de container hechten (zodat je envoy's uitvoer kunt zien)
  • -p 80:80 breng poort 80 in kaart op poort 80 binnen de container (in het Docker bestand heb ik dit gedefinieerd als de tcp poort)
  • herhaal voor poort 443 en poort 9901
  • koppel de container aan mijn-bruggen-netwerk
  • bouw de container van de jasmine/penvoyage:latest image (:latest is hier impliciet)

Wat gaat deze container doen?

Het zal verbindingen naar de host (in mijn geval op IP 192.168.1.2) proxy'en naar de taxgod container, op poort 3000.

Het zal fungeren als een https proxy met de voorbeeldcertificaten, en de verbindingen proxy-en naar dezelfde taxgod container, op poort 3000.

envoy.yaml

Let op: yaml gebruikt whitespace voor de structuur, waarschijnlijk zal WordPress dit verprutsen. Dus gebruik dit als een referentie, in plaats van een copy & paste ding!


static_resresources:
   luisteraars:
   - adres:
       socket_address:
         adres: 0.0.0.0
         port_value: 80
     filter_ketens:
     - filters:
       - naam: envoy.http_connection_manager
         config:
           codec_type: auto
           stat_prefix: ingress_http
           route_config:
             naam: local_route
             virtual_hosts:
             - naam: local_service
               domeinen: ["*"]
               routes:
               - match: { prefix: "/" }
                 route: { cluster: target_taxgod }
           http_filters:
           - naam: envoy.router
   - adres:
       socket_address:
         adres: 0.0.0.0
         port_value: 443
     filter_ketens:
     - tls_context:
         common_tls_context:
           tls_certificaten:
           - certificate_chain: { bestandsnaam: "/etc/example-com.crt" }
             private_key: { bestandsnaam: "/etc/voorbeeld-com.key" }
       filters:
       - naam: envoy.http_connection_manager
         config:
           stat_prefix: ingress_https
           route_config:
             virtual_hosts:
             - naam: standaard
               domeinen: ["*"]
               routes:
               - match: { prefix: "/" }
                 route: { cluster: target_taxgod }
           http_filters:
           - naam: envoy.router
   clusters:
   - naam: target_taxgod
     connect_timeout: 0.25s
     type: strict_dns
     lb_policy: round_robin
     gastheren:
     - socket_address:
         adres: taxgod
         port_value: 3000
admin:
   access_log_path: "/tmp/envoy.log"
   adres:
     socket_address:
       adres: 0.0.0.0
       port_value: 9901


Korte uitleg van het envoy yaml bestand:

Er zijn twee hoofdsecties, static_resources en admin

admin is voor het beheer van envoy en valt buiten het bereik van dit artikel. In een productieomgeving zul je het waarschijnlijk op de juiste manier moeten beveiligen. KOPIEER EN PLAK DAT DEEL NIET!!!

static_resources definieert een statische configuratie voor envoy (envoy kan ook worden ingesteld met behulp van zijn API)

in listeners definiëren we op welke poorten we willen luisteren, en wat er met de verbindingen moet gebeuren.

  • address - definieert adres en poort om op te luisteren
    • envoy.http_connection_manager - beheert http verbindingen, leest headers, enzovoort. het is een voorgedefinieerd filter
    • stat_prefix: definieert een menselijk leesbare naam voor logs / statistieken
    • domeinen: ["*"] - komt overeen met alle domeinen
    • route: { cluster: target_taxgod } - zal verkeer routeren naar onze cluster target_taxgod (zal overeenkomen voor /, dat is alles op de site)

het adres en de subconfiguratie worden twee keer herhaald, een voor poort 80, en een voor poort 443. Voor poort 443 voegen we ook de tls_context en common_tls_context toe in de filter_chains om de certificaten te injecteren.

Merk op dat het nog steeds envoy.http_connection_manager, NIET https_connection_manager voor poort 443.

in clusters definiëren we onze eindpunten waarnaar we willen kunnen verbinden / proxy verkeer naar toe.

  • het cluster heeft een naam
  • een time-out van de verbinding
  • lb_policy - het load balancing beleid. Er is maar één host, dus die krijgt al het verkeer (round_robin betekent dat elke host om de beurt verkeer krijgt)
  • in de hosts is het socket_address ingesteld als adres taxgod - dit is de Docker naam van de container, en de port als port_value 3000

De poort 3000 is de interne poort van de container taxgod, het is niet de poort waar je hem aan bindt op de externe host!

Ik hoop dat deze blog post mensen helpt die een https:// setup in envoy proberen op te zetten.

Foutmeldingen

afbeelding

Envoy geen gezonde stroomopwaarts foutmelding

de envoy container zich niet op hetzelfde Docker netwerk bevindt als je doelcontainer, omdat het die niet kan zien, kan het er ook geen verbinding mee maken.

afbeelding

Envoy upstream connect error of disconnect/reset before headers fout

Probeer verwijder

http2_protocol_options: {}

uit je envoy.yaml

Nuttige bronnen