編排文件技巧
- 使用資源時指定最新穩定版的API version
- 編排文件應該納入版本控制,這樣可以在必要的時候快速回滾,同樣也有利於資源恢復和重建
- 使用YAML格式而不是JSON格式,盡管兩種格式的文件可以相互轉換,但是YAML格式更易讀
- 使用單一的文件組織相關資源,單文件比多文件更好組織管理,可以參考guestbook-all-in-one.yaml
- 很多kubectl命令可以作用於整個文件夾,比如kubectl create somedir,可以對somedir目錄中所有的配置文件執行create指令
- 對資源的描述可以寫到annotations中,便於自省
裸Pod
不受任何控制器(Deployment,ReplicaSets,Jobs)控制的Pod稱之為裸Pod
- 盡量避免使用裸Pod,因為在發生節點錯誤的時候沒有任何策略保證Pod的重調度,死掉就徹底死掉了。
- 相反,Deployment會啟動相應的ReplicaSet來保證Pod的可用數量,同時有更新策略提供對Pod的更新比如Rolling Update。
- 有些特殊只需要執行一次的場景可用Job替代
Service
- service優先創建,理解為2點:service在它所依賴的資源創建出來之前創建;service在訪問它的資源創建之前創建。k8s創建容器的時候會在容器中寫入當前存在的service地址的環境變量,比如有個名稱為foo的service,所有k8s創建出來的容器中都會有如下的環境變量
FOO_SERVICE_HOST=<the host the Service is running on>
FOO_SERVICE_PORT=<the port the Service is running on>
如果代碼中要訪問Service,不要使用上述環境變量,最好使用Service的dns名稱,上述環境變量只是為了解決有些老的系統無法使用DNS查找問題的臨時方案
- 如非必要,不要給Pod指定
hostPort
,因為會限制Pod被調度的可能
如果只是想訪問某個端口進行debug,可以使用apiserver proxy或kubectl port-forward
如果確實需要暴露某個Pod的端口到主機端口,建議使用Service中的NodePort
使用標簽(labels)
- 定義和使用語義明確的標簽。比如
{ app: myapp, tier: frontend, phase: test, deployment: v3 }
,
Service可以通過Selector實現跨Deployment組織資源;Deployment可以通過標簽實現無中斷更新
- 巧用標簽進行調試。因為k8s資源控制器和Service都是通過標簽來組織和管理資源的。移除Pod上的標簽會導致控制器和Service不再將該Pod列為自己的資源,不再會有流量分配到該Pod。此時控制器會創建新的Pod來代替被移除的Pod,這是一種“隔離調試”技術。
容器鏡像
- 默認的 imagePullPolicy是
IfNotPresent
,kubelet只有在本地不存在的情況下才會去拉取鏡像。如果想每次執行都拉取鏡像可以指定策略:imagePullPolicy: Always
還有一種方法是指定:latest
tag,也會每次都拉取鏡像
生產環境避免使用這種方式
使用kubectl
- 使用
kubectl apply -f <directory>
或kubectl create -f <directory>
,會匹配目錄中的.yaml .yml .json 文件 - get/delete命令建議搭配使用標簽選擇器而不是資源名,參考label selectors和using labels effectively
- 使用
kubectl run
和kubectl expose
命令快速創建Deployment和Service,參考Use a Service to Access an Application in a Cluster