1. bash針對kubectl命令的自動補充
這可能是在使用Kubernetes過程中最容易做的事,但它也是其中一個最有用的。要添加自動補充功能,如果使用bash,只需執行以下命令:
echo "source <(kubectl completion bash)" >> ~/.bashrc
它將添加自動補全命令到你的.bashrc文件。因此每個你打開的shell窗口都支持該功能。我發現自動補全對一些長的參數,比如--all-namespaces特別有用。
2. 給每個namespace添加默認的內存和CPU限額
是人就會犯錯。我們假定某人寫了個應用,他每秒就會打開一個數據庫連接,但是不會關閉。這樣集群中就有了一個內存泄漏的應用。假定我們把該應用部署到了沒有限額設置的集群,那么該應用就會crash掉一個節點。
為了避免這種情況,Kubernetes允許為每個namespace設置默認的限額。要做到這很簡單,我們只需創建一個limit range 的 yaml 並應用到特定namespace。以下是一個例子:
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: 512Mi
defaultRequest:
memory: 256Mi
type: Container
將該內容創建一個yaml文件並將它應用到任何你想應用的namespace,例如namespace limit-example。使用了限額后,任何部署到該namespace的應用,假如沒有主動設置限額,都將得到一個默認的512Mi的內存限額。
3. kebelet可以幫我清理掉Docker鏡像嗎
這是kubelet默認已實現的功能。如果kubelet啟動時沒有設置flag,當/var/lib/docker目錄到達90%的容量時,它就會自動進行垃圾回收。這是極好的,但是針對inode閾值它沒有默認設置(Kubernetes 1.7之前)。
你可能會遇到/var/lib/docker只使用了50%磁盤空間,但是inode全部用光的情況。這可能會引起工作節點各種各樣的問題。如果你運行的kubelet版本在1.4到1.6之間,那你得給kubelet添加以下flag:
--eviction-hard
=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5%
如果kubelet版本是1.7或更高,它默認就有這個配置。1.6默認不會監控inode的使用率,所以得添加那個flag來解決這個問題。
4. minikube雖然是mini,但是本地使用功能強大
minikube絕對是本地啟動Kubernetes集群最容易的方式。你只需遵循這個[1]指南去下載所有東西。
一旦所有組件安裝完畢,你只需運行如下命令:
minikube start
待命令執行完畢,你本地就有一個運行的Kubernetes集群了。
當你想在本地構建一個應用並在本地運行時,有一個技巧。當你在本地構建一個Docker鏡像時,如果不運行其它命令,你的鏡像將被構建在你的本地計算機。
為了使你構建的Docker鏡像能夠直接push到本地Kubernetes集群,你需要使用如下命令告知Docker機器:
eval $(minikube docker-env)
這將使你能直接推送本地構建的應用到你的本地集群。
5. 不要將kubectl的權限開放給所有人
這可能是一個明擺着的事,但是當多個團隊部署應用到同一個集群時,而這種場景就是Kubernetes的目標,不要開放一個通用的kubectl給每個人。我的建議是基於namespace來隔離團隊,然后使用RBAC策略來限制能且僅能訪問那個namespace。
在權限被控制之后,你可能會變得瘋狂,比如只能基於Pod來讀取,創建和刪除Pod。但是其中一個最需要做的事是只能訪問管理員憑證,這樣可以隔離誰能管理集群,而誰只能在集群上部署應用。
這個話題我期待着后續單獨開一篇博客來進行更詳細的分析。
6. Pod中斷預算(Pod Disruption Budgets)是你的朋友
在Kubernetes集群中我們如何確保應用零宕機?
PodDisruptionBudgetPodDisruptionBudgetPodDisruptionBudget
集群會更新。節點會打上drain標簽且Pod會被移除,這沒法避免。所以我們應該針對每個deployment都設置一個PDB,保證至少有一個實例。我們可以使用一個簡單的yaml來創建一個PDB,應用到集群里,並使用標簽選擇器來確定這個PDB覆蓋了哪些資源。
注意:PDB只對自願中斷的資源負責,某些如硬件失敗這種錯誤,PDB無法起作用。
PDB例子如下:
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: app-a-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: app-a
兩個最需要關注的字段是matchLabels和minAvailable。
matchLabels字段用來確定是否一個deployment可以關聯到這個PDB。
例如,如果我有一個帶標簽app:app-a的deployment,和另一個帶標簽app:app-b的deployment,例子中的PDB將只對第一個deployment起作用。
minAvailable字段是Kubernetes在某些場景下,比如node被打上drain標簽時,進行操作的依據。假設app-a運行在node1上,如果node1被打上了drain標簽,那么kubernetes只會清除那些有至少2個實例的app-a。
這允許你在任何時候都可控制運行的實例數。
7. 你的APP還活着且可用嗎
Kubernetes允許我們定義探針,供kubelet確認我們的Pod和APP是否是健康的。
Kubernetes提供了兩種類型的探針,Readiness探針和Liveness探針。
Readiness探針用來確認容器是否可接受流量。
Liveness探針用來確認容器是否是健康的,或者需要被重啟。
這些配置可以很容易得追加到deployment的yaml,並且可以自定義超時時間,重試次數,延時時間等。需要更進一步得了解如何使用它們的,請閱讀此文[2]。
8. 給所有事物都打上標簽
標簽是Kubernetes的其中一個基石。它使得對象和對象之間保持松耦合,且允許我們根據標簽來查詢對象。你甚至可以使用go client根據標簽來監控事件。
你幾乎可以用標簽做任何事,其中一個極佳的例子是同一集群中的多個環境。
我們假定你在dev和qa環境使用了相同的集群。這說明你將在dev和qa環境同時運行一個app-a應用。
為了達到這個目的,最簡單的方式是使用service對象,其中一個選擇帶標簽app:app-a和environment:dev的Pod,而另一個,則選擇帶標簽app:app-a和environment:qa的Pod。
這樣做的好處是,兩個相同的APP,每一個有不同的endpoint,這樣就支持同時測試。
9. 主動清理
Kubernetes是一個非常非常強大的系統,但是和其它系統一樣,它最終也會陷入混亂。kubelet必須進行任何你告訴它的校驗,同時它也進行自己的校驗。
當然,Kubernetes有一個服務無法連接了,系統是不會掛掉的,因為它支持擴縮容。但是一個服務一旦擴大到成千上萬個endpoint,那么kubelet就會一下子陷入癱瘓。
簡單的說,不論你因為什么理由需要刪除一個deployment(或者其它東西),你都必須確保清理干凈和它相關的一切東西。
10. 你熱愛GO語言嗎
最后一點是我個人覺得最重要的:持續的學習GO語言。
Kubernetes是由GO編寫的,它的所有插件也是用GO寫的,他們甚至還編寫了一個GO語言的客戶端。client-go可用來做各種有趣的事。你可以用它根據自己的愛好擴展kubernetes。比如數據收集,部署引擎,或者一個簡單的清理應用。
學習這個GO 客戶端,並在Kubernetes中使用它,這是我給每個使用Kubernetes的用戶的最大建議。
原文鏈接:
-
https://kubernetes.io/docs/tasks/tools/install-minikube/
-
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
原文鏈接:https://hackernoon.com/top-10-kubernetes-tips-and-tricks-27528c2d0222