1.二进制部署:
这里代理的DNS server作为一个虚拟IP,通过每个租户Node节点配置iptables创建DNAT规则来分发DNS请求。
这种二进制的部署需要完全手动的维护。
2.容器化部署:
通过kubernetes中的RC/RSet 来进行部署。Kube-DNS作为一个特殊的租户,通过RC/RSet配置文件来部署整个Kube-DNS。建立三个副本,分布到三个未被其他租户使用的Node中,并与之绑定。这里需要注意的是RC/RSet来部署会在Pod出现故障的时候重新调度,这时如果需要保证还是调度到原来的Node上,需要在Node上设置相应的label,以此来让RC创建Pod的时候通过nodeSelector来调度到。如果不需要保证Pod的IP不变,那么可以不设置。最后创建DNS的service来select这三个副本,建立代理关系。
在普通的租户Node中,每个租户的Pod都会被注入DNS service IP(kubelet启动参数cluster-dns)到每个container的resolv.conf(这个根据不同的系统在kubelet启动参数中修改).
Pod需要根据域名访问同一个租户下的不同service时,就会向DNS service发送域名请求。这个时候有两种做法到达DNS 服务器:
1) 动态配置Iptables:
利用kube-proxy,针对这个特殊的Kube-DNS来动态生成DNS service对应的Iptables。这样省去了在每个Node中手动添加的麻烦。不过这个需要最终Kube-Proxy实现方案的确定。(已和娄超沟通,可以在后续的kube-proxy上加入这个特殊租户)
2) 手动配置Iptables
针对每个租户Node,需要配置如下Iptables 规则(实际上线部署需要完整模拟kube-proxy创建的chain):
以下以两个副本为例,service IP为192.254.0.2,副本IP为10.180.156.75, 10.180.156.78.
分别创建三条Nat Chain
iptables -t nat -N KUBE-DNS-SVC
iptables -t nat -N KUBE_DNS-SVC-TCP
iptables -t nat -N KUBE_DNS-SVC-UDP
根据目的IP 创建 Nat Chain到KUBE-DNS-SVC中
iptables -t nat -A PREROUTING -d 192.254.0.2 -j KUBE-DNS-SVC
根据不同的协议创建不同的Nat Chain到KUBE_DNS-SVC-TCP/UDP中
iptables -t nat -A KUBE-DNS-SVC -p tcp --dport 53 -j KUBE_DNS-SVC-TCP
iptables -t nat -A KUBE-DNS-SVC -p udp --dport 53 -j KUBE_DNS-SVC-UDP
分别创建不同协议的DNAT chain
TCP:
iptables -t nat -A KUBE_DNS-SVC-TCP -p tcp -j DNAT --to-destination 10.180.156.75:53
iptables -t nat -A KUBE_DNS-SVC-TCP -p tcp -j DNAT --to-destination 10.180.156.78:53
UDP:
iptables -t nat -A KUBE_DNS-SVC-UDP -p udp -j DNAT --to-destination 10.180.156.75:53
iptables -t nat -A KUBE_DNS-SVC-UDP -p udp -j DNAT --to-destination 10.180.156.78:53
这里需要注意的是,针对同一个协议有两个endpoint,可以根据实际的需要给任意的endpoint配置-m statistic --mode random –probability 匹配率,即这样可以避免同时向两个endpoint发送相同的请求。(Kube-DNS相当于无状态的服务,而且在直接访问skydns server的前面还有一个dnsmasq,所以可以不配置丢包率,这个后续如果是动态部署的需要和kube-proxy协商也做成这样)
静态部署主要的区别:POD的创建是通过kubelet启动Node的时候来部署。启动node的时候通过参数--config加入Kube-DNS的Pod配置yaml文件即可由kubelet来动态生成Pod,并维护Pod。并且设置Node不可调度。(这里不会遇上上述动态部署过程中Pod的IP变化问题,因为这里Pod是绑定在固定Node上的)