切換語言為:簡體

記錄istio無法轉發服務的一次bug

  • 爱糖宝
  • 2024-08-23
  • 2052
  • 0
  • 0

現象說明

由於擴容需要,我把k8s的一臺伺服器重啟了。然後跑在k8s上的專案訪問不了了。

我做了如下的一些嘗試:

1. 確認k8s叢集是正常的。

  • 判斷節點狀態

kubectl get nodes -o wide

發現有的node 顯示 not ready。透過重啟節點上的kubelet服務等方式,使得節點狀態轉換為ready

# 不正常的node 上重啟服務
systemctl restart docker

systemctl restart kubelet

  • 檢視kubelet日誌,看有無錯誤

# 各個node上, 檢視狀態
systemctl status kubelet

# 檢視日誌
journalctl -u kubelet -f

如果有日誌錯誤,就查詢相應的解決方法

2. 判斷服務狀態

# 檢視pod狀態
kubectl get pods -n <namespace_name>

# 檢視pod描述
kubectl describe pod -n <namespace_name> <pod_name>

# 檢視pod日誌
kubectl logs -n <namespace_name> <pod_name>

確定所有的pod都啟動正常,沒有報錯

3. 確定是否是請求轉發的問題

由於istio不好定位問題,因為一方面我對它不熟,另一方面多了好多流量轉發的過程,不好定位問題所在。我直接把系統的埠透過k8s暴露出來。

暴露服務的配置檔案expose.yml 如下:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  # 這裏修改你自己的名稱空間
  namespace: my_namespace
spec:
  selector:
    # 這裏修改爲你自己的選擇器,選擇需要暴露的服務
    app: xxx
  type: NodePort
  ports:
  - name: http
    # 這裏修改爲你自己的服務埠和對外暴露的埠
    port: 80
    targetPort: 80
    protocol: TCP
    nodePort: 8080

執行命令,部署到k8s上

# 修改下面命令中的檔名為你自己的檔案
kubectl apply -f expose.yml

然後可以在外部訪問 8080埠,發現是能夠訪問該服務的。 那就確認了是istio的問題。

4. 確認 istio的服務正常。

istio 正常情況下也是需要部署一些pod、service、crd等,到k8s上的。最可能出問題的就是pod和service

  • 確認istio 的pod正常啟動 這裏都在istio-system名稱空間中

# 檢視pod狀態
kubectl get pods -n istio-system

# 檢視pod描述
kubectl describe pod -n istio-system <pod_name>

# 檢視pod日誌
kubectl logs -n istio-system <pod_name>

我這裏有兩個pod istio-ingressgatewway是負責進入的流量轉發的, istiod是控制平面的服務

記錄istio無法轉發服務的一次bug

開始的時候,我這兩個pod都啟動不了,一直是creating的狀態。描述中的報錯是

MountVolume.SetUp failed for volume "istio-token" : failed to fetch token: the server could not find the requested resource

找了好久,沒有好的解決方法。有的人說是和第一方和第三方認證啥的相關。感覺不是很靠譜的樣子,畢竟istio官網,也沒說這個事情。

後來靈光一閃,是不是istio版本的問題?

找到的問題1: istio版本問題

突然想到我之前有兩個版本的istio安裝過。經過確認是istio版本和k8s版本不匹配的問題。我解除安裝了istio,然後安裝了正確的版本,istio的兩個pod啟動起來了。

為什麼會這樣?

我就重啟了一下伺服器,沒有重新安裝istio,為什麼之前可以,現在istio啟動不了?

我印象中我用過 1.4 和1.5兩個版本的istio。

  • 最開始安裝的1.4版本是正確的,正常啟動的。

  • 然後爲了專案能夠一鍵啟動,專案的啟動檔案裡,配置了istio的安裝指令碼,這裏配置了1.5的版本

  • 後來也根據安裝指令碼使用kubectl apply -f xxx.yaml 更新過專案,istio 也更新了,沒事

  • 伺服器重啟了,istio啟動失敗

我認為這可能是k8s的一個bug,就是1.4 版本安裝好之後,

kubectl apply -f install-1.4.yml

再安裝1.5

kubectl apply -f install-1.5.yml

並不會殺掉舊版本istio的pod,istio正常提供轉發服務。伺服器重新啟動後,會根據install-1.5.yml啟動1.5 版本的istio,版本不匹配這個時候就出錯了。

之前也遇到過類似的事情。

給我的啓發是,k8s中的服務yml配置有更新的時候,最好kubectl delete 之後,再 kubectl apply -f xxx

找到的問題2:

istio的pod都啟動了,但是還是無法訪問我們的專案。 我又重新確認了一下istio的gateway、 virtual service、service的配置情況,沒有問題。

之前是使用指令碼批次執行kubectl apply 的。爲了好定位問題,我手動一條一條執行,發現gateway.yml部署的時候,報錯,

Error from server: error when creating "gateway.yaml": admission webhook "validation.istio.io" denied the request: configuration is invalid: port name must be set: number:80  protocol:"HTTP" Error from server: error when creating "gateway.yaml": admission webhook "validation.istio.io" denied the request: configuration is invalid: port name must be set: number:8080  protocol:"HTTP"

這個報錯資訊很明確了,就是配置檔案錯了,少了一個name沒有配置。其實這個name無所謂,隨便寫個名字就行。

修改儲存,然後執行

kubectl apply -f gateway.yml

部署成功。

這個問題,我就沒想明白是怎麼回事了,之前的配置檔案都是正常部署的,istio也沒更新,k8s也沒更新,咋就不行了呢? 奇怪。。。。。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.