Kubernetes中的Pod無法訪問外網-Ubuntu16.04 LTS

Kubernetes中的Pod無法訪問外網-Ubuntu16.04 LTS

安裝完Kubernetes後,在Pod中使用wget無法訪問外網URL地址,但是使用IP地址是可以訪問,應該是

Pod內無法解析DNS導致的。

1、解決方法

嘗試了將DNS換爲CoreDNS,問題仍然存在。經過多次測試,發現下面的方法是可行的:

編輯主機的/etc/resolv.conf文件:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN #nameserver 127.0.1.1 nameserver 192.168.199.1 nameserver 8.8.8.8 nameserver 9.9.9.9 search lan

如果/etc/resolv.conf爲鏈接,則需要修改/etc/resolvconf/resolv.conf.d/base或head文件,然後運行resolvconf -u進行更新/etc/resolv.conf裏的內容。

2、原因分析

Ubuntu16.04 LTS安裝的resolvconf有一些問題,/etc/resolv.conf並非鏈接(有的安裝同一個版本是鏈接,很奇怪的),resolvconf -u等方法都會執行失敗。原則上,是鏈接的到/etc/resolvconf/resolv.conf.d裏面去改,不是鏈接的,直接修改/etc/resolv.conf文件。

可能Kubernetes啓動Pod時,要把/etc/resolv.conf裏的dns信息帶到pod中,而resolv.conf解析不到外面的地址。聯想到之前kube-dns經常出錯,估計也是這個原因。配置完後,kube-dns就很少出錯了。

3、其它

下面是從網上看到的方法,做過嘗試的一些方法。

經過測試,加入外部DNS後可以訪問外部網址,/etc/resolv.conf裏的nameserver的IP地址無法ping通,肯定也無法做域名解析了。因此,主要原因在於service的clusterip可以傳遞外部請求到pod,但是pod卻無法訪問service的ip,在多個技術網站搜索,基本上都出現此問題。

解決方法包括:

  • 修改iptables的配置,在sysctl.conf。查看iptable配置,iptable -L -v。
  • 使用Service Mesh,不知道是否有助於該問題。
  • 使用weavenet的網絡驅動,有人說可以。有人說flannel可以,calico不行,但我用的flannel也是不行,可能跟操作系統也有關係,我的是ubuntu 16.04。
  • sudo gedit sysctl.conf,插入:
###################################### # For K8s pod access service  # by openthings,2018.06.30. #======================================
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1 #######################################

按照這些方法搞過,還是不行。 ping 10.96.0.10不通。

變通的方法:

  • 設一個代理,使用IP地址去訪問。如https_proxy=192.168.199.99:9999 wget example.org,經測試,可行。也證明了網絡是通的,主要是DNS服務地址訪問不到。
  • 嘗試通過修改/etc/resolvconf/resolv.conf.d/base,然後運行resolvconf不成功。
  • 在POD裏添加新的DNS服務器,如在/etc/resolv.conf加上 nameserver=8.8.8.8,沒效果。進到pod裏,檢查/etc/resolv.conf,並沒有將主機的nameserver配置參數帶進來。

但是,這兩個方法雖然可以訪問外部地址了,但仍然不能訪問Kubernetes的Service產生的ClusterIP。不過,集羣內部訪問其它服務(包括POD自己的服務),可以通過服務名進行。

嘗試設置Kubernetes的Kube-dns的外部dns,將下面內容保存爲extdns.yaml。

apiVersion: v1 kind: ConfigMap metadata:
 name: kube-dns
 namespace: kube-system
 labels:
 addonmanager.kubernetes.io/mode: EnsureExists
data:
 upstreamNameservers: /
 ["8.8.8.8", "9.9.9.9"]

其它:

如果 Node 上安裝的 Docker 版本大於 1.12,那麼 Docker 會把默認的 iptables FORWARD 策略改爲 DROP。這會引發 Pod 網絡訪問的問題。解決方法則在每個 Node 上面運行 iptables -P FORWARD ACCEPT,比如

如果使用了 flannel/weave 網絡插件,更新爲最新版本也可以解決這個問題。

DNS 無法解析也有可能是 kube-dns 服務異常導致的,可以通過下面的命令來檢查 kube-dns 是否處於正常運行狀態

如果 kube-dns 處於 CrashLoopBackOff 狀態,那麼需要查看 kube-dns Pod 的日誌,根據日誌來修復 DNS 服務。

如果 kube-dns Pod 處於正常 Running 狀態,則需要進一步檢查是否正確配置了 kube-dns 服務:

如果 kube-dns service 不存在,或者 endpoints 列表爲空,則說明 kube-dns service 配置錯誤,可以重新部署 kube-dns service。

本文轉自開源中國-Kubernetes中的Pod無法訪問外網-Ubuntu16.04 LTS

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章