将envoy设置为Docker上的前台代理,并与其他Docker容器通信
我已经有了一些容器,我想用envoy作为前面的代理和https管理器。我正在学习使用envoy,并在此分享我的一些学习成果,因为文档在开始时有点混乱。
我已经存在的容器叫做 "taxgod" - 它在3000端口(http)上运行一个Crystal应用程序。我想把它代理到主机上的80端口用于http,443端口用于https。
我将使用一个假的证书进行演示。证书的创建不在本文的范围之内。
特使的容器将被称为penvoyage (皮座 特使 )
建设笔架山
用于建造的penvoyage文件夹包括
- 码头文件(Dockerfile
- envoy.yaml
- example.crt(证书)。
- example.key(证书的密钥)。
码头文件(Dockerfile
FROM envoyproxy/envoy:latest
COPY 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
曝光443/tcp
1TP3教育网猜测,这是TCP
曝光9901/tcpLABEL version="0.2.0"/LABEL version="0.2.0"。
description="penvoyage是PiCockpit的envoy代理" \"penvoyage是PiCockpit的envoy代理。
维护者=""
小心使用""字符,WordPress可能会把它们搞乱。
我很快会更详细地介绍envoy.yaml。我只想说,它在这个文件夹中,并将被复制到新创建的容器镜像中。
为了构建容器,运行(从包含penvoyage目录的目录)。
docker build -t jasmine/penvoyage:0.2.0 -t jasmine/penvoyage:latest penvoyage
你的输出应该以以下几行结束
成功地标记了jasmine/penvoyage:0.2.0
成功地标记了jasmine/penvoyage:最新的。
创建docker网络
docker network create -d bridge my-bridge-network
我们将使用这个网络将两个容器连接起来,这样它们就能看到对方。
当容器在同一个容器网络中时,它们可以使用它们的容器名称互相交谈。
例如,你可以做
ping taxgod
其中taxgod是容器的名称。
要在一个容器运行后将其添加到网络中,请执行以下操作。
docker network connect my-bridge-network taxgod
在这种情况下,my-bridge-network是网络,taxgod是要连接到网络的容器。
要看一个正在运行的容器是如何连接到一个特定的网络的,见下文。
要查看哪些容器在某个特定的Docker网络上,请运行以下命令。
docker network inspect my-bridge-network
运行penvoyage容器镜像
docker run -rm -it -p 80:80 -p 443:443 -p 9901:9901 -network=my-bridge-network jasmine/penvoyage
这将。
- -rm在容器关闭后将其删除
- -it attach to the container (so you can see envoy's output)
- -p 80:80 将端口80映射到容器内的端口80(在Docker文件中,我将其定义为tcp端口)。
- 重复端口443和端口9901的内容
- 将容器连接到我的桥梁网络
- 从jasmine/penvoyage:最新的镜像构建容器(这里隐含了:最新的)。
这个容器将做什么?
它将代理连接到主机(在我的例子中,IP为192.168.1.2)到taxgod容器,端口为3000。
它将作为一个带有样本证书的https代理,并将连接代理到同一个taxgod容器,端口为3000。
envoy.yaml
请注意:YAML使用空格作为结构,很可能WordPress会把它弄乱。所以,请把它作为一个参考,而不是复制和粘贴的东西。
静态_资源。
听众。
- 地址。
socket_address:
地址。0.0.0.0
port_value: 80
filter_chains。
- 滤波器。
- 名称: envoy.http_connection_manager
配置。
codec_type: auto
stat_prefix: ingress_http
route_config。
姓名:Local_route
virtual_hosts。
- 名称: local_service
域。["*"]
航线。
- 匹配。{前缀。"/" }
路线。{ 集群: target_taxgod }
http_filters。
- 名称: envoy.router
- 地址。
socket_address:
地址。0.0.0.0
port_value:443
filter_chains。
- tls_context。
common_tls_context。
tls_certificates。
- certificate_chain: { 文件名: "/etc/example-com.crt" }
private_key: { filename: "/etc/example-com.key" }
滤波器。
- 名称: envoy.http_connection_manager
配置。
stat_prefix: ingress_https
route_config。
virtual_hosts。
- 名称:默认
域。["*"]
航线。
- 匹配。{前缀。"/" }
路线。{ 集群: target_taxgod }
http_filters。
- 名称: envoy.router
集群。
- 名称: target_taxgod
connect_timeout:0.25s
类型:strict_dns
lb_policy: round_robin
主持人。
- socket_address:
地址: taxgod
port_value:3000
管理员。
access_log_path:"/tmp/envoy.log"
地址。
socket_address:
地址。0.0.0.0
端口_值: 9901
对envoy yaml文件的简短解释。
有两个主要部分,static_resources和admin
admin是用来管理envoy的,不在本文的讨论范围之内。在生产环境中,你可能需要适当地保护它。不要复制和粘贴这部分内容!!。
static_resources为envoy定义了一个静态配置(envoy也可以用它的API进行设置)。
在监听器中,我们定义了我们想要监听的端口,以及应该如何处理这些连接。
- address - 定义了要监听的地址和端口
- envoy.http_connection_manager - 管理http连接,读取头信息,等等。它是一个预定义的过滤器。
- stat_prefix: 为日志/统计数据定义一个人类可读的名称。
- 域名。["*"] - 匹配所有域名
- 路线。{ 集群: target_taxgod }- 将流量路由到我们的集群target_taxgod(将匹配/,也就是网站上的一切)。
这个地址和它的子配置重复了两次,一次用于80端口,另一次用于443端口。对于端口443,我们还在filter_chains中添加tls_context和common_tls_context,以注入证书。
请注意,它仍然是 envoy.http_connection_manager, 不是用于443端口的https_connection_manager。
在集群中,我们定义我们希望能够连接到/代理流量的端点。
- 该集群有一个名称
- 一个连接超时
- lb_policy - 负载平衡策略。只有一台主机,所以它将获得所有的流量(round_robin意味着每台主机将依次获得流量)。
- 在主机中,socket_address被设置为地址taxgod - 这是容器的Docker名称,端口为port_value。 3000
3000端口是容器taxgod的内部端口,而不是你在外部主机上绑定的端口。
我希望这篇博文能帮助试图在envoy中设置https:// 的人。
错误信息
特使 没有健康的上游 错误信息
特使集装箱 不在同一个Docker网络上 作为你的目标容器,因为它不能看到它,所以它不能连接到它。
特使 上游连接错误或断开连接/复位后才有头绪 错误
尝试 移除
http2_protocol_options:{}
从你的envoy.yaml中
有用的资源
- 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看起来很有趣--它允许将应用程序的URLs改为与反向代理层暴露的不同路径
- 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
- 有内置的过滤器
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http_filters/router_filter#config-http-filters-router
- "路由器过滤器实现了HTTP转发。它将被用于Envoy部署的几乎所有的HTTP代理场景。"
- https://blog.turbinelabs.io/setting-up-ssl-with-envoy-f7c5aa06a5ce
- 有一个关于重定向不安全流量的章节
- https://www.envoyproxy.io/try/migrating-from-nginx-to-envoy
- 作为特使的介绍,也很有用
- https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries