在kubernetes中配置skydns

pmos 7年前發布 | 34K 次閱讀 Kubernetes

kubernetes中的集群發現有兩種方式,一種是 環境變量 ,還有一種就是 dns 服務。對于環境變量,在使用上有一些限制,它依賴于svc和rc的啟動順序: 如果rc先于svc啟動,那么pod里面就沒有相關svc的環境變量,這種方式違背了kubernetes的理念,即資源之間是解耦的。推薦的方式是使用dns的服務,這篇文章主要關于部署skydns的過程以及其中遇到的問題和采用的方式。

部署

關于skydns如何部署在已有的kubernetes集群中,網上有不少資料可以參考,想要部署一個toy版本可以參考一下。

問題 & 方案

在實際應用的過程中,我需要改變一些配置,其中遇到的坑就記錄在此。

http vs https

網絡上所有關于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上的,對于這個問題,有幾個可行的方案:

  1. 修改apiserver的配置,讓它監聽在某個內網ip上,skydns通過內網ip去訪問apiserver
  2. 通過外網ip訪問,建立iptables路由規則,將外網的流量轉發到127.0.0.1:8080
    這個方案需要注意添加ip白名單,防止外網惡意流量的入侵,由于事先并不知道調度器會把dns服務送往哪臺機器,需要預先對所有集群機器的ip加白名單。
  3. 將dns服務通過label綁定在apiserver所在的機器上,直接訪問本地外網ip
    (備注,不確定本地docker里面訪問 external_ip:8080 可不可以被轉發到 127.0.0.1:8080 ,需要試試。如果不行的話,這條方案直接槍斃。)

但我所遇到的情況更苛刻,kubernetes集群中的機器分布于不同的idc機房,運營商也不全是同一個。這個時候除了自己搭建V*N內網,就沒有辦法使用內網ip了。由于自己維護V*N內網的成本太大,因此這里就不考慮方案一了。

對于方案二,需要預先加很多白名單。之后如果集群有新機器進來,又要加一遍,維護成本也很大,暫時放棄。

對于方案三,即使可行,但我也不想把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,也非常感謝廣大讀者可以提出更好的做法,我也會即使更新在博客中,在此謝過了。

 

來自:http://xidui.github.io/2017/02/06/在kubernetes中配置skydns/

 

 本文由用戶 pmos 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!