您好,登錄后才能下訂單哦!
這篇文章主要講解了“Kubernetes應用部署問題怎么處理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Kubernetes應用部署問題怎么處理”吧!
在將容器化的應用部署到Kubernetes集群中,可能會出現各種問題。根據Kubernetes的架構設計原理,容器化應用對外提供服務出現的主要問題在三個點上:
1)應用本身的問題:此問題為應用本身的問題,不在此文中進行詳細的闡述;
2)作為容器化應用邏輯主機的Pod的問題:此部分的問題主要涉及到容器化應用是否在容器云中正常部署和運行,這里會涉及到CPU、內存、存儲資源等問題;
3)代理容器化應用服務的問題:第三方服務或用戶會通過代理服務訪問容器化應用,如果代理服務存在問題,則容器云應用將無法對外提供服務能力,這里會涉及到服務是否存在、DNS解析是否正確等問題。
在本文中,以部署的高可用MySQL為例展示如何進行問題定位和處理。另外為了能夠在Kubernetes集群外訪問MySQL數據庫,對外暴露了MySQL master的NodePort類型服務,服務名稱為mysql-0-svc。
在調試Pod之前,通過kubectl get pods命令查看一下Pod的運行狀態。
$ kubectl get pods --namespace=kube-public
對于特定的Pod,可以通過kubectl describe pods命令查看詳細的信息。
$ kubectl describe pods/mysql-0 --namespace=kube-public
在Pod的生命周期中,有如下的幾個狀態:
Pending: Pod已經被Kubernetes系統接受,但是還有一個或者多個容器鏡像未被創建。這包括Pod正在被調度和從網絡上下載鏡像的時間。
Running: Pod已經被綁定到了一個Node,所有的容器也已經被創建。至少有一個容器已經在運行,或者在啟動或者重新啟動的過程中。
Succeeded: 在Pod中的所有的容器都已經被成功的終止,并且不會再重啟。
Failed: 在Pod中所有容器都已經被終止,并且至少有一個容器是非正常終止的。即,容器以非零狀態退出或者被系統強行終止的。
Unknown: 由于某些原因,Pod不能被獲取,典型的情況是在與Pod的主機進行通信中發生了失敗。
Waiting:由于某些原因,Pod已被調度到了Node節點上,但無法正常運行。
Crashing:由于某些原因,Pod處于崩潰狀態。
根據Pod所處的狀態,相應的處理方式不同。
如果Pod被卡在待命(Pending)狀態,則意味著它無法被安排到Node節點上。造成這種情況通常因為某種類型的資源不足,從而導致Pod無法被調度。通過查看kubectl describe …命令的輸出內容,應該有為什么Pod無法被調度的原因。這些原因包括:
沒有足夠的資源:集群中的CPU或內存可能已經耗盡了,在這種情況下,需要刪除Pod,調整資源請求或向集群中添加新的Node節點。
正在使用hostPort
:將Pod綁定到了數量有限的hostPort。在大多數情況下,沒有必要使用hostPort,可以嘗試使用服務來暴露Pod。如果確實需要hostPort,那么只能調度與Kubernetes集群中的節點一樣多的Pod。
如果Pod處于等待(Waiting)狀態,則它已被調度到一個工作Node上,但它無法在該Node上運行。同樣,通過kubectl describe …應該是能夠獲取有用的信息。處于等待(Waiting)狀態的最常見的原因是無法拉取鏡像。有三件事需要檢查:
確保鏡像名稱正確無誤。
確認鏡像倉庫中是否存在此鏡像?
在機器上,運行docker pull <image>命令,查看是否可以拉取鏡像。
首先,通過執行kubectl logs ${POD_NAME} ${CONTAINER_NAME}查看當前容器的日志:
$ kubectl logs mysql-0 mysql --namespace=kube-public
如果容器之前已崩潰,可以使用以下命令訪問上一個容器的崩潰日志:
$ kubectl logs --previous mysql-0 mysql --namespace=kube-public
或者,也可以使用kubectl exec在該容器內運行命令:
$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
請注意,這-c ${CONTAINER_NAME}是可選的,對于僅包含單個容器的Pod,可以省略。
如果這些方法都不起作用,可以找到運行該pod的主機,并通過SSH連接到該主機。
如果Pod沒有按預期運行,可能是Pod描述中存在錯誤,并且在創建Pod時忽略了該錯誤。通常可能是,Pod描述的一部分嵌套不正確,或鍵名不正確,因此鍵被忽略。例如,如果拼寫錯誤command,commnd則將創建Pod,但不會按照希望使用命令行。
首先,要做的第一件事是刪除此Pod,并嘗試使用–validate選項再次創建它。例如,運行kubectl create –validate -f mypod.yaml。如果拼寫錯誤command,commnd那么會出現如下錯誤:
I0805 10:43:25.129850 46757 schema.go:126] unknown field: commnd I0805 10:43:25.129973 46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842pods/mypod
接下來,要檢查的是apiserver上的Pod是否與要創建的Pod相匹配。例如,運行kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml,然后將原始的Pod描述mypod.yaml與從apiserver返回的描述文件mypod-on-apiserver.yaml進行比較。“apiserver”版本通常會有一些不在原始版本上的內容,這不影響。但是,如果原始版本上有不在apiserver版本上的行,則可能意味著原始版本Pod描述規范存在問題。
根據Kubernetes的架構設計,用戶或其它應用通過代理服務訪問容器化應用。因此需要通過調試確認代理服務是否正常,需要做的工作包括:
1)檢查代理服務本身是否存在;
2)檢查代理服務是否能夠正常通過DNS進行解析;
3)檢查代理服務本身是否正確。
在調試服務時,第一步要做的就是檢查服務是否存在。在本文的前面說明了,在Kubernetes中通過NodePort類型對外暴露了MySQL master。通過執行kubectl get svc命令,可以獲取是否存在相應服務:
$ kubectl get svc/mysql-0-svc --namespace=kube-public
通過返回的結果可以看出,在Kubernetes集群中存在此服務。
對于處于同一個命名空間的容器化應用,可以直接通過代理服務的名稱(mysql-0-svc)訪問MySQL master。
$ kubectl exec -it redis-ha-redis-ha-sentinel-5947b9569-r2b56 --namespace=kube-public -- nslookup mysql-0-svc
對Kubernetes集群中不同命名空間的容器化應用,則需要通過添加命名空間名稱后(mysql-0-svc.kube-public)訪問MySQL master:
$ kubectl exec -it gf1-6497d5df45-98g8v -- nslookup mysql-0-svc.kube-public
根據返回的可以看出,通過DNS能夠正確的解析代理服務。
如果通過上述的操作都無法正常解析服務,通過kubectl exec -it ${POD_NAME} — nslookup命令檢查一下Kubernetes master是否正常工作:
$ kubectl exec -it gf1-6497d5df45-98g8v -- nslookup kubernetes.default
如果此操作也失敗,則需要檢查Kubernetes集群中的DNS服務是否正常運行。
如果代理服務也存在,DNS解析也沒有問題。則需要檢查一下代理服務本身是否有問題:
$ kubectl get service mysql-0-svc -o yaml --namespace=kube-public
例如訪問的端口是否正確?targetPort是否指向了正確的Pods端口?這里的端口協議是否與Pod暴露出來的端口協議一致等。
感謝各位的閱讀,以上就是“Kubernetes應用部署問題怎么處理”的內容了,經過本文的學習后,相信大家對Kubernetes應用部署問題怎么處理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。