10個Kubernetes實用技巧——助你打造高可用集羣

【本文專欄於[頭條號]、[知乎]同步發佈,可關注同名賬號訂閱相關文章,每週固定更新】

Hi everybody~

這篇文章將給予各位十條簡單但非常實用的技巧,目前本人也在擁有十萬級qps的集羣中踐行着這些技巧。如果你想讓你的集羣更好用,那麼一起來試試下面這十條技巧吧。


 

1 使用Bash完成kubectl命令

這可能是最簡單也是使用Kubernetes時最有幫助的方法之一。要添加自動完成(如果使用bash),只需運行以下命令:

echo “source <(kubectl completion bash)” >> ~/.bashrc

這將在.bashrc中添加自動完成功能,這樣無論何時打開shell,它都會啓用它。你將會發現使用自動補全功能對於輸入長指令來說是尤爲方便的,尤其是當需要指定命名空間時。

2 向命名空間添加默認內存限制和cpu限制

人們總會犯錯,這是常有的事。如果有人編寫了一個應用程序,比方說,每秒打開一個數據庫的連接,但是從來沒有關閉它,這時就會導致在集羣上的應用程序中出現內存泄漏。如果將它們部署到沒有設置限制的集羣中,則可能導致節點崩潰。

爲了防止這種情況,Kubernetes允許根據每個命名空間設置默認限制。要做到這一點,只需創建一個yaml來限制範圍並將其應用於這個命名空間。下面是yaml的一個例子:

apiVersion: v1 
 kind: LimitRange 
 metadata: 
 name: mem-limit-range 
 spec: 
 limits: 
 - default: 
 memory: 512Mi 
 defaultRequest: 
 memory: 256Mi 
 type: Container

3 用Kubelet輔助清理docker鏡像

kubelet默認情況下已經做到了這一點。如果在啓動kubelet時沒有設置任何標誌,那麼當var/lib/docker達到90%的容量時,它將啓動垃圾收集。這一功能非常貼心,但請注意,kubelet並沒有爲node節點設置默認閾值(在Kubernetes 1.7之前)。

試想這種情況,你的/var/lib/docker可能只佔用了50%的磁盤空間,但此時全部的物理機磁盤空間已經被佔滿。這會給你的容器服務帶來很多問題。如果您目前正在使用的kubelet版本是1.4-1.6,那麼你必須顯式爲kubelet添加如下標誌。

--eviction-hard=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5%

這些配置在1.7或更高版本時是默認配置項。1.6版本默認情況下不監視node節點的資源利用率,因此添加該標誌將解決這個問題。

4 Minikube ——迷你但功能強大

Minikube絕對是本地運行Kubernetes集羣最簡單的方法了。一旦一切都安裝好了,簡單的命令就能運行它。

minikube start

這時我們將在本地運行一個kubernetes集羣。

當你想要在本地構建一個應用程序並在本地運行它時,這是有個技巧需要注意。如果你沒有運行其他命令,當你執行docker build時,仍然會在物理機上構建一個映像。

要讓你的docker build將鏡像push到本地kubernetes集羣,你需要使用以下命令:

eval $(minikube docker-env)

這能讓你在本地kubernetes集羣上構建應用程序。

5 不要把kubectl權限開放給所有人

這可能說起來很簡單,但是當多個團隊部署應用到一個kubernetes集羣時,情況就可能變得很複雜。切記不要把kubectl權限開放給每個人。個人建議是,根據命名空間來區分隔離每個團隊,然後使用RBAC策略只允許各自團隊訪問各自的命名空間。

如果我們把kubectl權限開放給每個人,那麼在pod級上進行讀取、創建和刪除訪問時,可能讓人抓狂,因爲誤操作的情況會經常發生。爲此,我們應該只允許管理員有權訪問,從而將管理集羣和部署集羣的人員權限區分開。

6 充分利用PodDisruptionBudget控制器

如何保證在kubernetes集羣中的應用程序總能正常運行?答案是使用PodDisruptionBudget控制器。

在進行kubectl drain操作時,kubernetes會根據PodDisruptionBudget控制器判斷應用POD集羣數量,進而保證在業務不中斷或業務SLA不降級的情況下進行應用POD銷燬。PDB(PodDisruptionBudget)應該放在每個擁有一個以上實例的deployment上。我們可以使用簡單yaml爲集羣創建PDB,並使用標籤選擇器確定PDB應該作用在哪些帶有標籤的資源上。注意:PDB只考慮主動中斷,硬件故障之類的情況不在PDB考慮範圍內。

PDB可以參考如下例子:

apiVersion: policy/v1beta1 
 kind: PodDisruptionBudget 
 metadata: 
 name: app-a-pdb 
 spec: 
 minAvailable: 2 
 selector: 
 matchLabels: 
 app: app-a

在衆多配置中,我們最需要關注兩個選項是matchlabel和minAvailable部分。匹配標籤是kubernetes查看部署是否附加到PDB。例如:如果我有一個帶有標籤app: app-a的部署和一個帶有標籤app: app-b的部署,那麼示例PDB將只應用於第一個部署。

minAvailable會在kubernetes在執行類似kubectl drain的操作時起作用。假設app-a正在節點1上運行,如果在節點1上執行drain,那麼它將只驅逐app-a,即當前至少有2個app在運行。

這讓你可以控制在給定時間需要運行多少實例。

7 使用探針來檢測應用的狀態

在Kubernetes中支持配置探針。kubelet使用探針來確定pod和應用程序是否健康。

這裏提供了兩種類型來實現這一功能,Readiness探針和Liveiness探針。

Readiness探針用於確定容器何時準備好接收流量。

Liveiness探針用於確定容器是健康的還是需要重新啓動。

在deployment 的yaml中,可以直接定義Readiness探針和Liveiness探針,還可以設置超時、重試和延遲等參數。

8 充分利用Label標籤

標籤是Kubernetes的基礎配置之一。它允許進羣內資源與資源之間鬆散耦合,還允許基於標籤進行查詢。你甚至可以使用Kubernetes go客戶端,根據標籤查看事件。

你幾乎可以使用標籤做任何事情,一個典型的例子是是同一個集羣中存在多個環境。假設開發和QA使用相同的集羣。這意味着你的集羣可能同時進行QA和開發。要以一種簡單的方式實現這一點,你必須使用服務對象,一個服務對象在app上執行標籤select: app-a以及environment: dev,另一個服務對象在app上打上:app-a標籤,但將環境從dev切換到QA。

這將爲您提供兩個相同的應用程序,每個應用程序具有不同的端點,允許同時進行測試。

9 隨時記得回收廢棄的資源

Kubernetes是一個非常強大的系統,但是就像任何系統一樣,它也會出現阻塞。只有一個不連接其他任何服務的服務纔不會讓系統陷入停滯。

當kubernetes規模較小時,幾臺或者幾十臺,可能不會有任何問題。但如果把服務擴大到上萬,kubelet就會可是出現阻塞。因爲Kubelet不僅會對你發出的指令進行校驗,同時還要做內部檢查。

因此,切記,從現在開始,養成習慣。如果你需要刪除deployment(或相關的任何內容),請確保用它清理了所有其他內容,比如service,volume等等,避免日後影響kubelet的查詢效率。

10 下決心學GO語言吧

[想來想去還是把這條寫在最後,只有真正實踐纔會知道其重要性]

Kubernetes是基於GO編寫的,所有的組件都是基於GO編寫的,kubernetes甚至使用GO編寫了一個客戶端。

client-go可以用於實現很多有趣的事情。你可以用它來擴展kubernetes,實現數據收集、部署引擎或簡單的清理應用程序。

學習使用GO語言編寫的Kubernetes客戶端並在Kubernetes中使用它,這是我對所以使用Kubernetes集羣的朋友提出的最大的建議。

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