traefik v2 无法通过域从内部卷曲到我的 docker 的其他容器

问题描述 投票:0回答:1

我尝试完成以下事情: 从 服务 B 我想致电 服务 A

工作:

  • 从外部(不在服务器上)通过以下方式连接到服务 A:sub.example.org/route
  • 从服务 B 通过以下方式连接:服务名称:端口/路由

不起作用(curl没有反馈,没有错误):

  • 从服务 B 调用相同的 url,就像从外部调用时一样:sub.example.org/route

所以我确实尝试对此进行调试,但是curl和traefik不显示日志,这就是问题所在。 CURL 刚刚挂起。

sub.example.org 的 nslookup => ok
sub.example.org 的 ping => ok
sub.example.org 的curl => 挂起而不输出:连接到ip


所有外部域/路由均经过 SSL 加密


enter image description here

docker networking routes traefik
1个回答
0
投票

鉴于 DNS 和

ping
正常工作,这很可能是防火墙问题。 DNS 可能不会解析为 docker 分配的容器的私有 ip,而是解析为主机 ip。防火墙必须允许从 docker 桥接网络到端口 443 上的主机 IP 的流量。但是在映射容器端口 (
443:443
) 时,docker 只会将防火墙配置为允许从外部桥接网络到私有容器 ip 的流量 在桥接网络中 - 这不足以支持所需的用例。那么,让我们再次了解防火墙并修复它! :)

TL;博士

允许从

Service B
ip/network 到主机 ip 的 https 流量,例如使用
ufw
:

sudo ufw allow from <service-B-ip or traefik-subnet> to <host-ip> port 443

您可以使用

docker network inspect <network-name> | grep Subnet
找到 docker 桥接网络的子网,例如
172.18.0.0/16
。假设主机 IP 为
10.0.0.4
,这将允许桥接网络上的所有服务与 443 (traefik) 进行通信:

sudo ufw allow from 172.18.0.0/16 to 10.0.0.4 port 443

另请确保已启用

ufw
sudo ufw enable

了解 docker 网络和防火墙

防火墙测试请求的去向(网络接口、目标 IP、端口)以及请求来自何处(网络接口、IP)以及其他一些内容。因此,让我们检查一下需要哪些规则来允许用例中所需的流量,然后检查防火墙是否进行了相应配置。

运行

docker network ls
,您将找到一个 bridge 类型的网络,其中包含您的网络的一些 id,例如
cd0af4596aee
。你还可以检查
ifconfig
,会发现这个网络接口是在你创建网络后由docker创建的(
br-cd0af4596aee
)。

将容器的端口映射到主机端口时(例如 traefik 的

443:443
),docker 设置一些防火墙规则。 Docker 通过在基于 Linux 的系统上操作
iptables
来实现这一点,让我们看看 docker 做了什么:

$ sudo iptables -L -v -n | grep 443
pkts bytes target     prot opt in               out              source               destination
  13   780 ACCEPT     tcp  --  !br-cd0af4596aee br-cd0af4596aee  0.0.0.0/0            172.18.0.4           tcp dpt:443

该规则允许任何源,但只能通过不是网络桥接接口 (

!br-cd0af4596aee
) 的接口,并且只能访问私有 IP
172.18.0.4
。但是我们想要允许的流量源自网络
br-cd0af4596aee
,并以 DNS 解析的主机 ip 为目标(这可能不是 docker 分配的容器的私有 ip)。

理解了这一点,您现在可能了解解决方案是什么样的:我们需要允许从网络本身到主机 IP 的流量。因为处理网络接口很麻烦,我们还可以添加一条规则,只允许所有

in
out
接口,但仅允许特定的 ip/网络。为此,我们可以使用
ufw
,它在大多数 ubuntu 发行版上都可用。
ufw
iptables
的前端,比
iptables
更容易使用。请注意,iptables 中的 docker 规则先于
ufw
规则存在 - 有效地使 docker 绕过尝试阻止特定流量的 ufw 规则。 请参阅此处了解更多信息

假设

172.18.0.0/16
是网络的IP范围,
10.0.0.4
是主机IP:

# sudo ufw allow from <service-B-ip or network-of-the-service> to <host-ip> port 443
sudo ufw allow from 172.18.0.0/16 to 10.0.0.4 port 443

再次检查

iptables

$ sudo iptables -L -v -n | grep 443
13   780 ACCEPT     tcp  --  !br-cd0af4596aee br-cd0af4596aee  0.0.0.0/0            172.18.0.4           tcp dpt:443
1    60 ACCEPT     tcp  --  *      *       172.18.0.0/16        0.0.0.0/0            tcp dpt:443
0     0 ACCEPT     udp  --  *      *       172.18.0.0/16        0.0.0.0/0            udp dpt:443

这应该可以解决问题。

但是为什么 DNS 和 ping 有效?

  • DNS:默认情况下,容器可以访问互联网(即防火墙允许容器与外部主机通信),因此 DNS 解析工作正常。 DNS 只是一个请求,说 “该域的 ip 是什么?”.

  • ping:Ping 使用互联网控制消息协议 (ICMP)。让我们检查一下

    iptables

      $ iptables -L -v -n | grep icmp
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 3
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 11
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 12
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 3
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 11
      0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 12
      3   252 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8
      0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    

    防火墙配置为允许 icmp(AFAIK 在启用时由

    ufw
    完成;如果
    ufw
    被禁用,
    REJECT
    规则也将被删除)。

© www.soinside.com 2019 - 2024. All rights reserved.