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

使用 Kubernetes 名字空間管理環境

Kubernetes 的優勢之一是它能夠比傳統部署策略更輕鬆、更好地管理各種環境。對於大多數非簡單應用程式,您擁有測試、暫存和生產環境。您可以在暫存和生產環境中配置相同資源的獨立叢集(例如虛擬機器),但這可能成本高昂,並且管理環境之間的差異可能很困難。
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、Service 和 Replication Controller 來避免命名衝突,前提是它們位於不同的名稱空間中。在名稱空間內,服務的短 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、記憶體或磁碟資源。正確設定資源限制並測試其是否有效需要大量時間和精力,因此除非您可以透過在與暫存或測試相同的叢集中執行生產環境來顯著節省金錢,否則您可能不希望這樣做。

無論您是否在同一個叢集中執行暫存和生產環境,名稱空間都是在同一個叢集中劃分不同應用程式的好方法。名稱空間還將作為未來可以應用資源限制的級別,因此請期待未來名稱空間級別的更多資源管理功能。