本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

使用 Kubernetes 命名空間來管理環境

Kubernetes 提供的一項優勢是,它能夠比傳統的部署策略更輕鬆、更好地管理各種環境。對於大多數重要的應用程式,您都會有測試、預演和生產環境。您可以使用與預演和生產環境相同的配置來啟動獨立的資源叢集 (例如 VM),但這樣做可能成本高昂,而且管理環境之間的差異可能很困難。
Kubernetes 包含一個很棒的功能,稱為[命名空間][4],可讓您在同一個叢集中管理不同的環境。例如,您可以在同一個機器叢集中擁有不同的測試和預演環境,從而可能節省資源。您也可以在同一個叢集中執行不同類型的伺服器、批次或其他作業,而無需擔心它們會互相影響。

預設命名空間

在 Kubernetes 中,指定命名空間是可選的,因為 Kubernetes 預設使用「default」命名空間。如果您剛建立叢集,可以使用以下命令檢查預設命名空間是否存在

$ kubectl get namespaces
NAME          LABELS    STATUS
default                  Active
kube-system              Active

您可以在此處看到預設命名空間存在且處於活動狀態。命名空間的狀態稍後將用於關閉和刪除命名空間。

建立新的命名空間

您可以使用與建立任何其他資源相同的方式來建立命名空間。建立一個 my-namespace.yaml 檔案並新增以下內容

kind: Namespace  
apiVersion: v1  
metadata:  
 name: my-namespace  
 labels:  
   name: my-namespace  

然後您可以執行以下命令來建立它

$ kubectl create -f my-namespace.yaml

服務名稱

透過命名空間,您可以讓您的應用程式指向靜態服務端點,這些端點不會根據環境而變更。例如,您的 MySQL 資料庫服務在生產和預演環境中都可以命名為 mysql,即使它在相同的基礎架構上執行。

這樣做之所以有效,是因為叢集中的每個資源預設只會「看到」同一個命名空間中的其他資源。這表示您可以透過建立具有相同名稱的 Pod、服務和複製控制器來避免命名衝突,前提是它們位於不同的命名空間中。在命名空間內,服務的簡短 DNS 名稱會解析為該命名空間內服務的 IP。因此,例如,您可能有一個 Elasticsearch 服務可以透過 DNS 名稱 elasticsearch 存取,只要存取它的容器位於同一個命名空間中即可。

您仍然可以透過完整的 DNS 名稱來查找其他命名空間中的服務,其形式為 SERVICE-NAME.NAMESPACE-NAME。因此,例如,生產和 Canary 環境分別為 elasticsearch.prod 或 elasticsearch.canary。

範例

讓我們看一個範例應用程式。假設您想要在 Kubernetes 中部署您的音樂商店服務 MyTunes。您可以執行應用程式生產和預演環境,以及在同一個叢集中執行的一些一次性應用程式。您可以透過執行一些命令來更了解情況

~$ kubectl get namespaces  
NAME                    LABELS    STATUS  
default                     Active  
mytunes-prod                Active  
mytunes-staging             Active  
my-other-app                Active  

您可以在此處看到一些命名空間正在執行。接下來,讓我們列出預演環境中的服務

~$ kubectl get services --namespace=mytunes-staging
NAME          LABELS                    SELECTOR        IP(S)             PORT(S)  
mytunes       name=mytunes,version=1    name=mytunes    10.43.250.14      80/TCP  
                                                        104.185.824.125     
mysql         name=mysql                name=mysql      10.43.250.63      3306/TCP  

接下來檢查生產環境

~$ kubectl get services --namespace=mytunes-prod  
NAME          LABELS                    SELECTOR        IP(S)             PORT(S)  
mytunes       name=mytunes,version=1    name=mytunes    10.43.241.145     80/TCP  
                                                        104.199.132.213     
mysql         name=mysql                name=mysql      10.43.245.77      3306/TCP  

請注意,即使服務本身的名稱相同,IP 位址也會因使用的命名空間而異。此功能讓設定您的應用程式變得非常容易 (因為您只需要將您的應用程式指向服務名稱),並且有可能讓您在預演或測試環境中設定您的應用程式與在生產環境中完全相同。

注意事項

雖然您可以在同一個叢集中執行預演和生產環境,並透過這樣做來節省資源和金錢,但您需要小心設定資源限制,以避免您的預演環境讓生產環境在 CPU、記憶體或磁碟資源方面匱乏。正確設定資源限制並測試它們是否運作需要大量的時間和精力,因此除非您可以透過在與預演或測試環境相同的叢集中執行生產環境來顯著節省金錢,否則您可能真的不想這樣做。

無論您是否在同一個叢集中執行預演和生產環境,命名空間都是在同一個叢集中分割不同應用程式的好方法。命名空間也將作為您可以套用資源限制的層級,因此請期待未來在命名空間層級提供更多資源管理功能。