昨天我們體驗了 Deployment,看到它如何在 ReplicaSet 之上提供更高層次的抽象,幫我們解決應用程式更新時的痛點。不管是 Rolling Update (滾動更新) 確保不中斷服務,還是 Roll Back (快速回滾) 應對突發 bug,都讓我們更好的去管理應用的生命週期。
不過,隨著叢集裡的服務和資源越來越多,新的問題也開始浮現:
這時候,我們需要一個「分門別類」的機制,幫忙把叢集裡的資源整理好。
👉 這就是 Namespace 的登場時機。
在 Kubernetes Cluster 中,會有很多 Deployment
在運行,特別是當我們要區分 dev、stage、prod 環境時,很容易發生資源混在一起的狀況。
Namespace 就像「不同的房子」,同名的人在不同房子裡不會混淆,每個Namespace擁有獨立運行環境及資源限制。
mysql.connect("db.prod.svc.cluster.local")
⚠️ 重要‼️
刪除 Namespace 時,該 Namespace 裡的所有資源物件也會一併刪除。 因此需要特別注意!管理者需要控制 RBAC 權限設定 (之後會聊到),避免誤刪或越權操作。
先來看看 Kubernetes 預設有哪些 Namespace:
kubectl get namespace
下圖我們可以看到這些都是 KinD 系統預設會建立的 Namespace
:
Namespace | 主要用途 |
---|---|
default | 使用者的預設工作區,當我們建立 Pod、Deployment 沒有指定 Namespace 的話預設都是存在這邊。 |
kube-system | 存放 K8s 核心系統元件,所有負責管理和運作整個 Cluster 的核心元件 (Control Plane Components) 都會被放在這裡。 |
kube-public | 主要用來存放一些需要被公開存取的叢集資訊,例如用來加入節點的 cluster-info、ConfigMap 。一般使用者很少會直接用到它。 |
kube-node-lease | 這是系統內部用來確認所有 Node 是否健康運作的地方。 |
local-path-storage | 這是 KinD 特有的,用來提供儲存功能。簡單來說是為了讓 KinD 叢集可以使用本機硬碟作為儲存空間。 |
來看看這些 Namespace 裡面都有什麼 Pod。
kubectl get pods -A
下圖可以看到:
default
Namespacekube-system
包含我們在 【Day02】搞懂 K8s 架構:Master Node 和 Worker Node 的分工合作 提及的 Kubernetes 核心元件:etcd
、api-server
、kube-proxy
、kube-controller-manager
、kube-scheduler
# 建立 Namespace
kubectl create namespace dev
# 在 dev Namespace 中建立 Deployment
kubectl -n dev apply -f deployment-def.yaml
# 查看 dev Namespace 中的 Pod
kubectl get pods -n dev
kubectl get pods --namespace=dev
可以看到不同 Namespace 中可以使用相同名字:
apiVersion: v1
kind: Namespace
metadata:
name: dev
前面提到 Kubernetes 預設使用 default
Namespace,可以用以下指令切換到指定的 Namespace:
kubectl config set-context $(kubectl config current-context) --namespace=dev
透過上述指令,就可以讓我們把預設的從 default
的 Namespace 變成我指定的 Namespace。
但是這樣切換在實際開發的時候其實很不直覺,用 Imperative (命令式) 切換 Namespace 再建立 Deployment 並不是最佳實務。應該是建立好 Namespace 之後,在 YAML 檔中直接指定 Namespace:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
namespace: dev # 指定 dev Namespace
spec:
replicas: 3
selector:
matchLabels:
type: front-end
template:
metadata:
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
這樣就可以透過聲明式方式,把 Deployment 建立在指定的 Namespace 了!
今天我們看了 Namespace 如何解決 Kubernetes 叢集的資源管理問題。透過邏輯隔離,不同環境和團隊可以安全共用同一個叢集,避免資源名稱衝突。待後續到 RBAC (Role Based Access Control)
的部分,也能針對不同 Namespace 設定存取權限。
我們也實際操作了如何建立和管理 Namespace,並掌握了用聲明式方式在 YAML 檔中直接指定 Namespace 的最佳實務。
不過,Namespace 的功能不只是邏輯隔離這麼簡單。在實際的生產環境中,我們還會需要控制每個 Namespace 可以使用多少 CPU、記憶體、儲存空間,甚至限制可以建立多少個 Pod。
明天我們要來看看 ResourceQuota
和 LimitRange
,看看如何為不同的 Namespace 設定資源限制,確保一個團隊的應用程式不會消耗掉整個叢集的資源。