kubernetes中的集群发现有两种方式,一种是 环境变量
,还有一种就是 dns
服务。对于环境变量,在使用上有一些限制,它依赖于svc和rc的启动顺序: 如果rc先于svc启动,那么pod里面就没有相关svc的环境变量,这种方式违背了kubernetes的理念,即资源之间是解耦的。推荐的方式是使用dns的服务,这篇文章主要关于部署skydns的过程以及其中遇到的问题和采用的方式。
关于skydns如何部署在已有的kubernetes集群中,网上有不少资料可以参考,这里贴上一篇文章: kubernetes入门之skydns 。想要部署一个toy版本可以参考一下。
在实际应用的过程中,我需要改变一些配置,其中遇到的坑就记录在此。
网络上所有关于skydns的配置,全都是基于http的。比如下面这一条:
command: - /kube2sky - --kube_master_url=http://10.8.65.48:8080 - -domain=kube.local
kube-apiserver监听了两个端口,一个是对外的https,一个是对内的http,两者提供的服务是一样的。
默认的http端口是监听在127.0.0.1:8080上的,对于这个问题,有几个可行的方案:
external_ip:8080
可不可以被转发到 127.0.0.1:8080
,需要试试。如果不行的话,这条方案直接枪毙。) 但我所遇到的情况更苛刻,kubernetes集群中的机器分布于不同的idc机房,运营商也不全是同一个。这个时候除了自己搭建vpn内网,就没有办法使用内网ip了。由于自己维护vpn内网的成本太大,因此这里就不考虑方案一了。
对于方案二,需要预先加很多白名单。之后如果集群有新机器进来,又要加一遍,维护成本也很大,暂时放弃。
对于方案三,即使可行,但我也不想把dns服务绑死在某一台机器上,集群调度本身就应该有足够的自由度。
想了又想,要不试试使用https的端口吧。但让我失望的是,google到处搜,也没有搜到skydns用https的方案。最后还是在kube2sky的 github主页 找到了某个可能可用的配置选项:
--kube-master-url: URL of kubernetes master. Required if --kubecfg_file is not set. --kubecfg-file: Path to kubecfg file that contains the master URL and tokens to authenticate with the master.
在skydns-rc.yaml中去掉 --kube_master_url
,然后使用 --kubecfg_file
,指向kubeconfig文件,这里我偷个懒使用的是kubelet的配置文件(kubelet.kubeconfig):
apiVersion: v1 kind: Config current-context: kubelet-to-cluster.local preferences: {} clusters: - cluster: certificate-authority: /etc/kubernetes/certs/ca.crt server: https://node-1-master: name: cluster.local contexts: - context: cluster: cluster.local user: kubelet name: kubelet-to-cluster.local users: - name: kubelet user: token: J1j0EhcoCBZBAP20xDR72ta79vPr7j3J
在上一部中指定了 --kubecfg_file=/etc/kubernetes/kubelet.kubeconfig
还是不够的,启动的时候会报错,说找不到配置文件。原因是这个路径只是作为一个字符串传进了pod中,pod中并没有这个路径对应的文件,我们还需要做目录的挂载:
# 省略很多配置 volumeMounts: - name: kubernetes-etc mountPath: /etc/kubernetes readOnly: true
# 省略很多配置 volumes: - name: kubernetes-etc hostPath: path: /etc/kubernetes
在我以为大功告成的时候,结果还是给了我最后一个坑。这个时候kube2sky报了一个错,说无法解析node-1-master。
因为集群中所有机器都是以这种短名字命名的,它们对应的ip都配在所有机器的 /etc/hosts
里。而pod中的 /etc/hosts
并不是继承于宿主机的,所以自然就无法解析这些短名字了。最后解决的方法也跟上面一样,把 /etc/hosts
这个文件挂载到skydns的pod中就可以了。
我的方案可能并不是best practice,也非常感谢广大读者可以提出更好的做法,我也会即使更新在博客中,在此谢过了。