需求概述

之前家里Kubernetes上托管的一些服务,如portal, emby, weave scope等等,是使用的service ip来访问的,访问起来稍微有点麻烦,主要是ip要记。

Kubernetes为了解决load balancer类型service的问题(vip消耗,L7负载特性等),提供了Ingress来解决这个问题。

针对这个需求,可以在godaddy上设置泛域名,type为A,例如 *.lab.ieevee.com,将其解析到ingress的service ip;新增的web站点,只要创建ingress,并设置其host从 *.lab.ieevee.com中选择,就可以直接在家里解析到对应的服务了。

下面以emby为例说明。

部署ingress controller

这次采用的ingress controller是traefik,使用helm部署,很简单。

$ git clone https://github.com/containous/traefik-helm-chart
$ helm install --namespace=traefik-v2 ./traefik-helm-chart/traefik

部署后:traefik并没有ingress controller能力,还需要修改deployment,增加参数 --providers.kubernetesingress=true

创建ingress

为emby创建ingress:host为emby.lab.ieevee.com;serviceName是emby的service,不要求是load balancer类型。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: emby
  namespace: default
spec:
  rules:
  - host: emby.lab.ieevee.com
    http:
      paths:
      - backend:
          serviceName: emby
          servicePort: 80
        path: /

本地hosts测试

本地配置hosts文件,测试应该正常了。

配置泛域名

我有自己的域名,不需要hosts这样比较原始的东西。

Godaddy支持配置泛域名,考虑到后面还有其他的ingress需求,所以不为emby单独创建一条A记录,而是在Godaddy上配置泛域名*.lab.ieevee.com,emby只是其中一个,真正分流是在ingress controller上实现的。

ingress-1

这样,不管是a.lab.ieevee.com还是b.lab.ieevee.com,都会解析到192.168.9.1,而这个ip,就是service traefix的load balancer ip了。

$ kubectl get svc
NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
virtuous-gibbon-traefik   LoadBalancer   10.100.135.27   192.168.9.1   80:30182/TCP,443:31831/TCP   7h29m

openwrt配置DNS Rebinding白名单

配置后,我发现在aws的主机上、家里其他网络的主机,都可以解析 emby.lab.ieevee.com,但是在openwrt下挂的主机都解析不了。

查了下openwrt的日志,看到下面一行:

Fri Jan 31 23:38:01 2020 daemon.warn dnsmasq[11062]: possible DNS-rebind attack detected: emby.lab.ieevee.com

原来是openwrt检测到了DNS Rebinding,给过滤掉了。按照openwrt的检测机制,如果开启了Rebind protection,只要返回的ip地址是局域网ip,openwrt就会过滤掉该请求的返回结果。

DNS Rebinding是一种攻击手段,目的是通过DNS重新请求解析IP地址,绕开浏览器对跨域攻击的检测。详细可以参考Ref-1/Ref-2。

我这里的做法是给lab.ieevee.com添加白名单。

ingress-2

总结

通过在Godaddy上配置泛域名,将*.lab.ieevee.com的域名请求,解析到ingress traefik的vip上;traefik作为ingress controller,将http请求按照vhost,转发给对应的pod,这样,在家里就可以通过域名来使用各种服务了,不用再去记IP地址。

Ref:

https://blog.deimos.fr/2017/08/20/kubernetes-with-traefik-and-lets-encrypt/

https://github.com/acmesh-official/acme.sh https://medium.com/@acidumirae/wildcard-letsencrypt-certificate-and-godaddy-acme-challenge-record-3ec74be6bd62