Configuration d'envoy comme proxy frontal sur Docker avec communication vers d'autres conteneurs Docker
J'ai déjà des conteneurs existants pour lesquels je veux utiliser envoy comme proxy et gestionnaire https. J'apprends à utiliser envoy, et je partage ici certaines de mes connaissances, car la documentation est un peu confuse au départ.
Mon conteneur existant s'appelle "taxgod". Il exécute une application Crystal sur le port 3000 (http). Je veux le proxyer sur le port 80 de l'hôte pour http, et le port 443 pour https.
Je vais utiliser un faux certificat à des fins de démonstration. La création de certificats n'entre pas dans le cadre de cet article.
Le conteneur d'envoi va s'appeler penvoyage (picockpit envoyé )
Pénétration des bâtiments
Le dossier penvoyage utilisé pour la construction contient
- Dockerfile
- envoy.yaml
- example.crt (certificat)
- example.key (clé pour le certificat)
Dockerfile
FROM envoyproxy/envoy:latest
COPIE envoy.yaml /etc/envoy/envoy.yaml
COPIE exemple.crt /etc/example-com.crt
COPY exemple.key /etc/example-com.key
#VOLUME /etc/envoy/envoy.yamlEXPOSE 80/tcp
EXPOSE 443/tcp
#Educated devine que c'est TCP
EXPOSE 9901/tcpLABEL version="0.2.0″ \
description="penvoyage est un proxy d'envoi pour PiCockpit" ;)
maintainer=""
Faites attention aux caractères ", WordPress pourrait les abîmer !
J'entrerai bientôt dans le fichier envoy.yaml de manière un peu plus détaillée. Il suffit de dire qu'il se trouve dans ce dossier et qu'il sera copié dans l'image du conteneur nouvellement créé.
Pour construire le conteneur, exécutez (à partir du répertoire contenant le répertoire penvoyage) :
docker build -t jasmine/penvoyage:0.2.0 -t jasmine/penvoyage:latest penvoyage
Votre sortie devrait se terminer par les lignes
Successfully tagged jasmine/penvoyage:0.2.0
Vous avez réussi à étiqueter jasmine/penvoyage:latest
Créer le réseau docker
docker network create -d bridge my-bridge-network
Nous utiliserons ce réseau pour attacher les deux conteneurs l'un à l'autre, afin qu'ils se voient mutuellement.
Les conteneurs peuvent communiquer entre eux en utilisant leurs noms de conteneurs, lorsqu'ils se trouvent sur le même réseau de conteneurs.
Par exemple, vous pouvez faire
ping taxgod
où taxgod est le nom du conteneur.
Pour ajouter un conteneur à un réseau après son exécution, procédez comme suit :
docker network connect my-bridge-network taxgod
Dans ce cas, my-bridge-network est le réseau, et taxgod est le conteneur qui doit y être connecté.
Pour voir comment un conteneur qui est exécuté est connecté à un réseau particulier, voir ci-dessous.
Pour voir quels conteneurs se trouvent sur un réseau Docker particulier, exécutez la commande suivante :
docker network inspect my-bridge-network
Exécuter l'image du conteneur penvoyage
docker run -rm -it -p 80:80 -p 443:443 -p 9901:9901 -network=my-bridge-network jasmine/penvoyage
Ce sera :
- -rm retirer le conteneur après l'avoir éteint
- -it attacher au conteneur (pour que vous puissiez voir la sortie de envoy)
- -p 80:80 mappe le port 80 vers le port 80 à l'intérieur du conteneur (dans le fichier Docker, j'ai défini ce port comme étant le port tcp).
- répétez pour le port 443 et le port 9901
- attachez le conteneur à mon réseau de ponts
- construire le conteneur à partir de l'image jasmine/penvoyage:latest (:latest est implicite ici)
À quoi servira ce conteneur ?
Il va proxyer les connexions à l'hôte (dans mon cas sur l'IP 192.168.1.2) vers le conteneur taxgod, sur le port 3000.
Il agira comme un proxy https avec les exemples de certificats, et enverra les connexions au même conteneur taxgod, sur le port 3000.
envoy.yaml
Veuillez noter : yaml utilise les espaces pour la structure, il est fort probable que WordPress s'y prenne mal. Utilisez donc ceci comme une référence, plutôt qu'un copier-coller !
ressources_statiques :
des auditeurs :
- l'adresse :
adresse_socle :
adresse : 0.0.0.0
valeur_du_port : 80
chaînes de filtres :
- filtres :
- nom : envoy.http_connection_manager
config :
codec_type : auto
stat_prefix : ingress_http
route_config :
nom : local_route
virtual_hosts :
- nom : local_service
domaines : ["*"]
routes :
- match : { préfixe : "/" }
route : { cluster : target_taxgod }
http_filters :
- nom : envoy.router
- l'adresse :
adresse_socle :
adresse : 0.0.0.0
port_value : 443
chaînes de filtres :
- tls_context :
common_tls_context :
tls_certificats :
- certificate_chain : { filename : "/etc/example-com.crt" }
private_key : { filename : "/etc/example-com.key" }
filtres :
- nom : envoy.http_connection_manager
config :
stat_prefix : ingress_https
route_config :
virtual_hosts :
- nom : default
domaines : ["*"]
routes :
- match : { préfixe : "/" }
route : { cluster : target_taxgod }
http_filters :
- nom : envoy.router
clusters :
- nom : target_taxgod
connect_timeout : 0.25s
type : strict_dns
lb_policy : round_robin
hôtes :
- adresse_socle :
adresse : taxgod
valeur_du_port : 3000
admin :
access_log_path : "/tmp/envoy.log"
l'adresse :
adresse_socle :
adresse : 0.0.0.0
valeur_du_port : 9901
Brève explication du fichier yaml de l'envoyeur :
Il y a deux sections principales, static_resources et admin.
admin est pour l'administration d'envoy et en dehors de la portée de cet article. Dans un environnement de production, vous devrez probablement le sécuriser de manière appropriée. NE COPIEZ PAS ET COLLEZ CETTE PARTIE ! !!
static_resources définit une configuration statique pour envoy (envoy peut également être configuré en utilisant son API).
dans les listeners, nous définissons les ports sur lesquels nous voulons écouter, et ce qui doit arriver aux connexions.
- address - définit l'adresse et le port sur lesquels écouter
- envoy.http_connection_manager - gère les connexions http, lit les en-têtes, et ainsi de suite. c'est un filtre prédéfini
- stat_prefix : définit un nom lisible par l'homme pour les logs / statistiques
- domaines : ["*"] - correspond à tous les domaines
- route : { cluster : target_taxgod } - routera le trafic vers notre cluster target_taxgod (correspondra à /, c'est-à-dire tout ce qui se trouve sur le site)
l'adresse et sa sous-configuration sont répétées deux fois, une pour le port 80, et une pour le port 443. Pour le port 443, nous ajoutons également le tls_context et le common_tls_context dans les filter_chains pour injecter les certificats.
Notez que c'est toujours gestionnaire de connexions http envoyées, PAS https_connection_manager pour le port 443.
dans les clusters, nous définissons les points d'extrémité auxquels nous voulons pouvoir nous connecter ou vers lesquels le trafic doit être acheminé.
- le cluster a un nom
- un délai de connexion
- lb_policy - la politique d'équilibrage de la charge. Il n'y a qu'un seul hôte, il recevra donc tout le trafic (round_robin signifie que chaque hôte recevra le trafic à tour de rôle).
- dans les hôtes, la socket_address est définie comme address taxgod - c'est le nom Docker du conteneur, et le port comme port_value 3000
Le port 3000 est le port interne du conteneur taxgod, ce n'est pas le port auquel vous le liez sur l'hôte externe !
J'espère que ce billet de blog aidera les personnes qui essaient de mettre en place une installation https:// dans envoy.
Messages d'erreur
Envoyée pas d'amont sain message d'erreur
le conteneur de l'envoyé n'est pas sur le même réseau Docker comme votre conteneur cible, puisqu'il ne peut pas le voir, il ne peut pas s'y connecter.
Envoyée erreur de connexion en amont ou déconnexion/réinitialisation avant les en-têtes erreur
Essayez de supprimer
http2_protocol_options : {}
de votre envoy.yaml
Ressources utiles
- 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 semble intéressant - il permet de changer les URLs de l'application vers un chemin différent de celui exposé à la couche de reverse proxy
- 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
- il existe des filtres intégrés
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http_filters/router_filter#config-http-filters-router
- "Le filtre routeur implémente la redirection HTTP. Il sera utilisé dans presque tous les scénarios de proxy HTTP pour lesquels Envoy est déployé."
- https://blog.turbinelabs.io/setting-up-ssl-with-envoy-f7c5aa06a5ce
- a une section sur la redirection du trafic non sécurisé
- https://www.envoyproxy.io/try/migrating-from-nginx-to-envoy
- utile comme introduction à Envoy aussi bien
- https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries