iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0

昨天幫 todo-api、todo-frontend、MySQL 都加上了 Resource Request 和 Limit,今天要學 Namespace,看看怎麼用它隔離不同環境的資源。


為什麼需要 Namespace

目前所有資源都在 default Namespace 裡:todo-api、todo-frontend、mysql,全部混在一起。

這在單人開發的時候沒問題,但實際工作場景通常需要:

  • 隔離環境:開發、測試、生產環境跑在同一個 Cluster,但資源要分開,不能互相影響
  • 隔離團隊:不同團隊負責不同的服務,各自管理各自的資源
  • 資源配額:限制某個環境或團隊最多能用多少 CPU 和記憶體

Namespace 提供了一個邏輯上的隔離層,讓同一個 Cluster 可以跑多套環境或服務,互不干擾。


Namespace 是什麼

Namespace 是 K8s 資源的邏輯分組,同一個 Namespace 裡的資源名稱必須唯一,但不同 Namespace 可以有同名的資源。

K8s 預設有幾個 Namespace:

kubectl get namespaces
NAME              STATUS   AGE
default           Active   10d   ← 沒有指定 Namespace 的資源都在這裡
kube-node-lease   Active   10d   ← Node 心跳資訊
kube-public       Active   10d   ← 公開讀取的資源
kube-system       Active   10d   ← K8s 系統元件

哪些資源有 Namespace 隔離,哪些沒有:

  • 有隔離:Pod、Deployment、Service、ConfigMap、Secret、Ingress
  • 沒有隔離(叢集層級):Node、PersistentVolume、StorageClass、Namespace 本身

Namespace 只隔離邏輯資源(部署的應用)。Node 是實體機器、PV 是實體儲存空間,這類叢集基礎設施是所有 Namespace 共用的,無法隔離。


Namespace 的常見區分方式

Namespace 只是一個邏輯邊界,怎麼切都可以,實際上沒有唯一標準答案。常見的做法有三種:

1. 按環境分(本篇示範這個)

dev / staging / production

每個環境自帶完整的前端、後端、資料庫。最直觀,適合小型專案或剛開始導入 K8s 的團隊。

2. 按功能層分

frontend / backend / database

每層各自一個 Namespace,方便用 NetworkPolicy 限制存取(例如只允許 backend 連 database,frontend 不能直連 DB)。適合單一產品、職責邊界清楚的團隊。

3. 按服務分(微服務常見)

app-order / app-user / infra

每個業務服務自己的 Namespace,包含自己的 API 和 DB;infra 放 Ingress、監控等公用元件。一個 team 只管一個 Namespace,最小權限原則好執行。

實務上也常混用,例如先按環境分,再在各環境裡按功能或服務細分。(下面會用「按環境」示範,比較容易理解 Namespace 隔離的概念 !)


跨 Namespace 的 Service 連線

同一個 Namespace 內,Service 直接用名稱連線:

http://todo-api-service:80

跨 Namespace 則需要用完整的 DNS 名稱:

http://todo-api-service.production.svc.cluster.local:80

格式是:<service名稱>.<namespace名稱>.svc.cluster.local


實際操作

今天目標:建立 dev Namespace,把 Todo App 的所有資源部署到 dev Namespace,設定 ResourceQuota 限制資源上限,並將預設 Namespace 切換到 dev。

Step1: 建立 Namespace

kubectl create namespace dev

或是用 YAML:

apiVersion: v1
kind: Namespace
metadata:
  name: dev

確認建立成功:

kubectl get namespaces

https://ithelp.ithome.com.tw/upload/images/20260922/20183863i5EDDMMbuU.png

Step2: 把 Todo App 部署到 dev Namespace

  1. 有兩種方式指定 Namespace:

方式一:在 YAML 的 metadata 裡指定

apiVersion: apps/v1
kind: Deployment
metadata:
  name: todo-api
  namespace: dev          # 指定 Namespace
spec:
  ...

方式二:用 kubectl 指令時加 -n 參數

kubectl apply -f todo-api-deployment.yaml -n dev
  1. 把 ConfigMap 和 Secret 也部署到 dev Namespace(每個 Namespace 的資源是獨立的):

todo-api-configmap.yaml 的內容如下,DATABASE_URL 已移到 Secret,ConfigMap 只放非敏感設定:

apiVersion: v1
kind: ConfigMap
metadata:
  name: todo-api-config
  namespace: dev
data:
  APP_ENV: "development"
  LOG_LEVEL: "info"
kubectl apply -f todo-api-configmap.yaml
  1. 建立 todo-api 的 Secret,把含有密碼的 DATABASE_URL 放在這裡:
kubectl create secret generic todo-api-secret \
  --from-literal=DATABASE_URL=mysql+pymysql://user:password@mysql-service:3306/tododb \
  -n dev
  1. 建立 MySQL 的 Secret(MySQL StatefulSet 啟動時需要這個才能設定 root 密碼):
kubectl create secret generic mysql-secret \
  --from-literal=MYSQL_ROOT_PASSWORD=rootpassword \
  --from-literal=MYSQL_PASSWORD=password \
  -n dev
  1. 部署 MySQL:
kubectl apply -f mysql-statefulset.yaml -n dev
kubectl apply -f mysql-service.yaml -n dev
  1. 等待 MySQL 啟動完成:
kubectl get pod mysql-0 -n dev -w

看到 Running 後按 Ctrl+C 繼續下一步。

  1. 部署 todo-api:
kubectl apply -f todo-api-deployment.yaml -n dev
kubectl apply -f todo-api-service.yaml -n dev
  1. 部署 todo-frontend:
kubectl apply -f todo-frontend-deployment.yaml -n dev
kubectl apply -f todo-frontend-service.yaml -n dev
  1. 確認 dev Namespace 裡的資源都正常:
kubectl get pods -n dev

https://ithelp.ithome.com.tw/upload/images/20260922/201838635whQJR1SYc.png

Step3: 查看指定 Namespace 的資源

# 看 dev Namespace 的所有 Pod
kubectl get pods -n dev

# 看所有 Namespace 的 Pod
kubectl get pods --all-namespaces
# 或
kubectl get pods -A

Step4: 設定預設 Namespace

每次下指令都要加 -n dev 很麻煩,可以設定預設的 Namespace:

kubectl config set-context --current --namespace=dev

之後的指令就不需要加 -n dev 了。確認目前的設定:

kubectl config view --minify | grep namespace

設定完之後,後續所有指令預設都在 dev Namespace 執行。

Step5: 設定 ResourceQuota

Namespace 可以設定資源配額,限制這個 Namespace 最多能用多少資源。在 /Todo-app/k8s 目錄下,建立 dev-quota.yaml:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "2"          # 所有 Pod 的 CPU request 總和不超過 2 顆
    requests.memory: "2Gi"     # 所有 Pod 的 Memory request 總和不超過 2Gi
    limits.cpu: "4"
    limits.memory: "4Gi"
    pods: "20"                 # 最多 20 個 Pod
kubectl apply -f dev-quota.yaml

注意:設定 ResourceQuota 之後,Namespace 內所有 Pod 都必須明確指定 requests 和 limits,否則會被拒絕建立。請確認你的 Deployment YAML 都有設定,格式如下:

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "200m"
    memory: "256Mi"

確認配額使用狀況:

kubectl describe resourcequota dev-quota -n dev
Name:            dev-quota
Namespace:       dev
Resource         Used    Hard
--------         ----    ----
limits.cpu       500m    4
limits.memory    256Mi   4Gi
pods             4       20
requests.cpu     100m    2
requests.memory  128Mi   2Gi

小結

今天學了 Namespace,把資源做邏輯隔離:

  • Namespace 提供邏輯隔離,同一個 Cluster 可以跑多套環境或服務,區分方式沒有唯一標準,常見的有按環境、按功能層、按服務三種
  • 同一個 Namespace 內直接用 Service 短名稱連線,跨 Namespace 才需要完整 DNS
  • ConfigMap、Secret 不會共用,每個 Namespace 要各自建立,且內容要填入真實值
  • mysql-secret 要在部署 MySQL 之前建立,否則 MySQL Pod 無法啟動
  • ResourceQuota 可以限制 Namespace 的資源使用上限,設定後所有 Pod 都必須指定資源限制

從現在開始,後續所有操作都在 dev Namespace 進行,請確認預設 Namespace 已設定為 dev:

kubectl config view --minify | grep namespace
#應該看到 namespace: dev

明天會學 HPA,讓 K8s 根據負載自動調整 Pod 數量,不需要人工盯著手動 scale !


上一篇
Day 16|Resource Request & Limit
下一篇
Day 18|HPA
系列文
從零學 K8s|30 天核心概念 × 實作,新手也能真正掌握 Kubernetes 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言