配置最佳實踐
本文件重點介紹並整合了使用者指南、入門文件和示例中介紹的配置最佳實踐。
這是一份不斷更新的文件。如果你想到一些不在列表上但可能對其他人有用的內容,請隨時提交一個 issue 或 Pull Request。
通用配置技巧
定義配置時,請指定最新的穩定 API 版本。
配置檔案在推送到叢集之前應儲存在版本控制中。這樣可以在必要時快速回滾配置更改。它還有助於叢集的重新建立和恢復。
使用 YAML 而不是 JSON 編寫配置檔案。儘管這些格式在幾乎所有情況下都可以互換使用,但 YAML 通常更易於使用者使用。
在合理的情況下,將相關物件分組到一個檔案中。一個檔案通常比多個檔案更容易管理。請參閱 guestbook-all-in-one.yaml 檔案,以獲取此語法的示例。
還要注意,許多
kubectl命令可以在目錄上呼叫。例如,你可以在包含配置檔案的目錄上呼叫kubectl apply。不要不必要地指定預設值:簡單、最小的配置可以減少出錯的可能性。
將物件描述放在註解中,以便更好地進行自省。
注意
YAML 1.2 布林值規範相對於 YAML 1.1 引入了一項重大更改。這是 Kubernetes 中的一個已知 問題。YAML 1.2 只識別 **true** 和 **false** 為有效布林值,而 YAML 1.1 還接受 **yes**、**no**、**on** 和 **off** 作為布林值。然而,Kubernetes 使用的 YAML 解析器 大部分與 YAML 1.1 相容,這意味著在 YAML 清單中使用 **yes** 或 **no** 而不是 **true** 或 **false** 可能會導致意外的錯誤或行為。為避免此問題,建議始終在 YAML 清單中使用 **true** 或 **false** 作為布林值,並引用可能與布林值混淆的任何字串,例如 **"yes"** 或 **"no"**。
除了布林值之外,YAML 版本之間還有額外的規範更改。請參閱 YAML 規範更改 文件以獲取完整列表。
"裸" Pod 與 ReplicaSet、Deployment 和 Job
如果可以避免,請不要使用裸 Pod(即,未繫結到 ReplicaSet 或 Deployment 的 Pod)。裸 Pod 在節點發生故障時不會被重新排程。
除了某些明確的
restartPolicy: Never場景外,Deployment 幾乎總是優於直接建立 Pod,因為它既建立 ReplicaSet 以確保所需數量的 Pod 始終可用,又指定了替換 Pod 的策略(例如 RollingUpdate)。Job 也可能適用。
服務
在其對應的後端工作負載(Deployment 或 ReplicaSet)之前,以及在任何需要訪問它的工作負載之前,建立 Service。當 Kubernetes 啟動容器時,它會提供指向在容器啟動時正在執行的所有 Service 的環境變數。例如,如果存在一個名為
foo的 Service,所有容器在其初始環境中都會獲得以下變數FOO_SERVICE_HOST=<the host the Service is running on> FOO_SERVICE_PORT=<the port the Service is running on>_這確實暗示了一個排序要求_ - Pod 想要訪問的任何
Service都必須在 Pod 本身之前建立,否則環境變數將不會被填充。DNS 沒有這個限制。一個可選的(但強烈推薦的)叢集附加元件 是一個 DNS 伺服器。DNS 伺服器監視 Kubernetes API 以獲取新的
Service,併為每個 Service 建立一組 DNS 記錄。如果整個叢集都啟用了 DNS,那麼所有Pod都應該能夠自動進行Service的名稱解析。除非絕對必要,否則不要為 Pod 指定
hostPort。當你將 Pod 繫結到hostPort時,它會限制 Pod 可以排程的地方的數量,因為每個 <hostIP,hostPort,protocol> 組合必須是唯一的。如果你不明確指定hostIP和protocol,Kubernetes 將使用0.0.0.0作為預設hostIP和TCP作為預設protocol。如果僅出於除錯目的需要訪問埠,可以使用 apiserver 代理 或
kubectl port-forward。如果需要顯式地在節點上暴露 Pod 的埠,請考慮使用 NodePort Service,然後再使用
hostPort。避免使用
hostNetwork,原因與hostPort相同。當不需要
kube-proxy負載均衡時,使用 無頭 Service(其ClusterIP為None)進行服務發現。
使用標籤
定義並使用標識應用程式或 Deployment 的 **語義屬性** 的 標籤,例如
{ app.kubernetes.io/name: MyApp, tier: frontend, phase: test, deployment: v3 }。你可以使用這些標籤為其他資源選擇合適的 Pod;例如,一個 Service 選擇所有tier: frontend的 Pod,或者app.kubernetes.io/name: MyApp的所有phase: test元件。請參閱 guestbook 應用程式以獲取此方法的示例。Service 可以透過從其選擇器中省略特定於釋出版本的標籤來跨越多個 Deployment。當需要在不中斷服務的情況下更新正在執行的服務時,請使用 Deployment。
物件的期望狀態由 Deployment 描述,如果對該規範的更改被_應用_,Deployment 控制器將以受控的速度將實際狀態更改為期望狀態。
對於常見用例,請使用 Kubernetes 常用標籤。這些標準化標籤以一種方式豐富元資料,允許工具(包括
kubectl和 dashboard)以可互操作的方式工作。你可以修改標籤進行除錯。由於 Kubernetes 控制器(如 ReplicaSet)和 Service 使用選擇器標籤來匹配 Pod,從 Pod 中刪除相關標籤將阻止控制器考慮它或 Service 為其提供流量。如果你刪除現有 Pod 的標籤,其控制器將建立一個新 Pod 來替換它。這是一種在"隔離"環境中除錯先前"活動"Pod 的有用方法。要互動式地刪除或新增標籤,請使用
kubectl label。
使用 kubectl
使用
kubectl apply -f <目錄>。這會在<目錄>中查詢所有.yaml、.yml和.json檔案中的 Kubernetes 配置,並將其傳遞給apply。對於
get和delete操作,請使用標籤選擇器而不是特定的物件名稱。請參閱有關 標籤選擇器 和 有效使用標籤 的部分。使用
kubectl create deployment和kubectl expose快速建立單容器 Deployment 和 Service。有關示例,請參閱 使用 Service 訪問叢集中的應用程式。