我敢说本篇文章是网上为数不多的解决traefik暴露域名失败问题的正确文章。
我看了网上太多讲述traefik夸夸其谈的文章了,包含一大堆复制粘贴的水文和还有什么所谓“阿里技术专家”的文章,讲的全都是错的!基本没有一个能说到点子上去! 所以这些垃圾文章导致你最后配置ingress规则以后,访问域名还是会报错: Connection Refused
你所看到的这些水文就是把官方或者网上互相抄来抄去的文章,拿来复制粘贴一大片代码,不知所云,完全就是流水账!
我们要明白解决问题的关键,在于分析问题的思考模式和分析过程!这个非常重要!
然后回到开头,为什么会出现Connection Refused错误,我们不考虑什么所谓的k8s和traefik这些杂七杂八的东西,而是回归到网络的本质中去!
这种情况只有一种可能: 端口可能根本就没有监听!
对了,这就是问题的关键!
所以,因为k8s的部署是容器网络,容器的端口默认是不对外暴露的,所以即便deployment部署了,如果没有没有暴露端口,就等同于没有监听端口,此时访问域名就必然是Connection Refused!
有人说:那你配置service不就完了。service再搞个NodePort不就完了!
那我问你NodePort的端口是多少!是30000-32767! 这玩意能用吗?!
所以注意了:对于traefik来说:service不是对外提供服务的,它是被k8s集群内部所调用的,特别是为ingress服务!
我们始终要记住网络的基本原则:一个请求进来,服务器必须对它所请求的端口有监听,否则就会产生Connection Refused错误
这是第一个问题。
然后第二个问题: 域名怎么解析。或者说ingress规则中host中的域名应该解析到哪一台机器?
大家有没有想过这个问题? 给你10秒钟好好想一想
。。。。。。。。。。。。。
时间到了! 有没有一点idea。 作为一个常识,我们应该不会想到这个域名必须绑定到其中某一台机器吧,对不对,否则就失去了做集群的必要性了!
我们需要的是一种集群边缘触发方式,也就是说把访问域名解析到集群中的任意一台机器
所以,这里要严厉批判traefik官方文档! traefik官方文档简直就是胡说八道!竟然把deployment搞进来了! deployment是啥玩意? 说到底它就是一个动态的东西,通过deployment生成的pod,你根本没法知道:它会分配到哪一台机器。 这他妈不是坑爹吗? 那么我现在没法知道traefik controller pod具体在哪一台机器,我怎么做域名解析? 难道我通过kubectl get pods 命令获取到了traefik controller pod的信息,然后知道了它在哪台机器,然后把域名解析到这台机器。但是如果后来删除了deployment,又重新部署了分配了新的pod, 这种情况怎么办?
这样的运作规则跟集群边缘触发方式完全是互相矛盾的!
我们需要的是:每一台机器都能有traefik controller pod,这个只有DaemonSet能满足!因为DaemonSet可以确保在每个节点上都运行一个Pod的副本
好了,知道了原因,我来谈谈怎么解决这个问题:
1. traefik controller 的部署方式必须DaemonSet.
2. traefik controller的80端口必须通过hostPort暴露出来:
3. ingress规则中的域名执行k8s集群中任何一台机器就ok了
最后谈一点:ingress规则中的namespace必须跟它后面路由转发的service的namespace保持一致