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
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.yaml80/tcp blootleggen
443/tcp blootleggen
#Educated gok dat dit TCP is
VERTELSTEM 9901/tcpLABEL 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
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.
Envoy upstream connect error of disconnect/reset before headers fout
Probeer verwijder
http2_protocol_options: {}
uit je envoy.yaml
Nuttige bronnen
- https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http_connection_management
- https://runnable.com/docker/basic-docker-networking
- https://docs.docker.com/engine/reference/commandline/network_create/
- https://docs.docker.com/v17.09/engine/userguide/networking/
- https://github.com/envoyproxy/envoy/tree/master/examples/front-proxy
- https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http_routing
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http_conn_man/header_sanitizing
- https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route.proto#envoy-api-field-route-routeaction-host-rewrite
- prefix_rewrite ziet er interessant uit - het maakt het mogelijk om applicatie URLs te veranderen naar een ander pad dan blootgesteld aan de reverse proxy laag
- https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto#envoy-api-enum-config-filter-network-http-connection-manager-v2-httpconnectionmanager-codectype
- er zijn ingebouwde filters
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http_filters/router_filter#config-http-filters-router
- "Het router filter implementeert HTTP forwarding. Het zal worden gebruikt in bijna alle HTTP proxy scenario's waar Envoy voor wordt ingezet."
- https://blog.turbinelabs.io/setting-up-ssl-with-envoy-f7c5aa06a5ce
- heeft een sectie over het omleiden van onveilig verkeer
- https://www.envoyproxy.io/try/migrating-from-nginx-to-envoy
- ook nuttig als een inleiding tot Envoy
- https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries