我正在尝试在docker swarm集群上运行traefik容器。因为我们使用的是TLS加密通信,所以我希望traefik仪表板可以通过https使用。
在我的浏览器中,我尝试通过https://my.docker.manager通过docker swarm manager主机名访问traefik,因此我将主机证书和密钥安装到traefik服务中。
当我尝试在浏览器中打开https://my.docker.manager时,出现超时。
当我尝试直接在主机(my.docker.manager)上curl https://my.docker.manager
时,我得到HTTP代码403作为响应
我的traefik配置:
debug=true
logLevel = "DEBUG"
defaultEntryPoints = ["http","https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "/etc/traefik/certs/my.docker.manager.crt"
keyFile = "/etc/traefik/certs/my.docker.manager.key"
[entryPoints.https.tls.defaultCertificate]
certFile = "/etc/traefik/certs/my.docker.manager.crt"
keyFile = "/etc/traefik/certs/my.docker.manager.key"
[api]
address = ":8080"
[docker]
watch = true
swarmMode = true
我的traefik撰写文件:
version: "3.7"
services:
traefik:
image: traefik
ports:
- 80:80
- 443:443
networks:
- devops-net
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /mnt/docker-data/secrets/certs/:/etc/traefik/certs/
configs:
- source: traefik.conf
target: /etc/traefik/traefik.toml
deploy:
placement:
constraints:
- node.role == manager
labels:
- "traefik.docker.network=devops-net"
- "traefik.frontend.rule=Host:my.docker.manager"
- "traefik.port=8080"
networks:
devops-net:
driver: overlay
external: true
configs:
traefik.conf:
external: true
如本文(https://www.digitalocean.com/community/tutorials/how-to-use-traefik-as-a-reverse-proxy-for-docker-containers-on-ubuntu-16-04)所述,我希望在浏览器中调用https://my.docker.manager时看到traefik仪表板。但是我只会超时。使用curl https://my.docker.manager
时,我得到HTTP代码403。我遵循上述文章,但有两个区别:
1)我没有配置凭据
2)我使用主机拥有的证书而不是letsencrypt
答案 0 :(得分:0)
同时,我找到了问题的原因(不确定什么是最佳解决方案)。对于有人感兴趣的情况,我会尽力解释。
在网络prod.company.de中,我有一个包含三个节点的Swarm
我的客户端位于另一个网络intranet.comnpany.de
我的集群管理器地址为docker-manager.prod.company.de。在此主机上,我已经部署了traefik服务,该服务我想通过https://docker-manager.prod.company.de访问(这是端口443,并且由于traefik配置转发到了容器内8080上的traefik仪表板)。
如果跟踪网络流量,可以看到来自客户端浏览器的https请求(https://docker-manager.prod.company.de)到达服务器,然后流量被转发到docker_gwbridge地址17.18.0.2。但是由于docker NAT配置,答案没有找到回到我客户端的方法。
iptables -t nat -L -v
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 8 504 MASQUERADE all -- any docker_gwbridge anywhere anywhere ADDRTYPE match src-type LOCAL 0 0 MASQUERADE all -- any !docker0 172.17.0.0/16 anywhere 0 0 MASQUERADE all -- any !docker_gwbridge 172.18.0.0/16 anywhere
MASQERADE表示,请求的源IP应该用网桥IP(在我的情况下为172.18.0.1)替换,以便将答案路由回该IP。在上述情况下,规则8 504 MASQUERADE all -- any docker_gwbridge anywhere anywhere
可以做到这一点,但是它仅限于ADDRTYPE match src-type LOCAL
发出的来自本地的请求,这意味着可以在docker主机上使用浏览器,但是我与客户端的连接可以不起作用,因为答案无法找到返回我的客户地址的方式。
当前,我在iptables中又添加了一个NAT规则:
iptables -t nat -A POSTROUTING -o docker_gwbridge -j MASQUERADE
结果
1 52 MASQUERADE all -- any docker_gwbridge anywhere anywhere
之后,在客户端的浏览器中打开https://docker-manager.prod.company.de时,我可以看到traefik仪表板。
但是我不明白,为什么我必须这样做,因为我在任何文档中都没有找到关于此的任何东西,而且我认为用例真的很少。因此,如果有人可以看一下这篇文章,并检查我是否做错了其他事情或向我解释,我为什么会感到高兴,为什么我必须做这些事情才能使标准用例正常工作。
亲切的问候