Kubernetes Namespace 多租戶隔離

Kubernetes Namespace Multi-Tenancy Isolation

Namespace 概述

Kubernetes Namespace 是一種將叢集資源劃分為多個虛擬叢集的機制。它提供了一個範圍,用於隔離不同團隊、專案或環境的資源。Namespace 是實現多租戶架構的基礎,能夠有效地管理資源配額、存取控制和網路隔離。

Namespace 的主要用途

  • 資源隔離:將不同團隊或應用程式的資源分開管理
  • 存取控制:透過 RBAC 限制使用者只能存取特定 Namespace
  • 資源配額:為每個 Namespace 設定資源使用上限
  • 環境區分:區分開發、測試、生產環境

預設 Namespace

Kubernetes 叢集啟動時會自動建立以下預設 Namespace:

1
2
# 查看所有 Namespace
kubectl get namespaces
Namespace說明
default未指定 Namespace 時的預設空間
kube-systemKubernetes 系統元件所在的空間
kube-public公開可讀的資源空間
kube-node-lease節點租約資訊空間

建立與管理 Namespace

使用 YAML 建立 Namespace

1
2
3
4
5
6
7
apiVersion: v1
kind: Namespace
metadata:
  name: development
  labels:
    env: dev
    team: frontend

使用指令建立 Namespace

1
2
3
4
5
6
7
8
# 建立 Namespace
kubectl create namespace production

# 刪除 Namespace(會刪除其下所有資源)
kubectl delete namespace development

# 切換預設 Namespace
kubectl config set-context --current --namespace=production

資源配額(ResourceQuota)

ResourceQuota 用於限制 Namespace 中的資源使用量,避免單一 Namespace 佔用過多叢集資源。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: development
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "20"
    services: "10"
    persistentvolumeclaims: "5"
    secrets: "20"
    configmaps: "20"

查看配額使用狀況

1
kubectl describe resourcequota compute-quota -n development

限制範圍(LimitRange)

LimitRange 用於設定 Namespace 中 Pod 和 Container 的預設資源限制和請求。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: development
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    max:
      cpu: "2"
      memory: "2Gi"
    min:
      cpu: "50m"
      memory: "64Mi"
    type: Container

網路隔離

透過 NetworkPolicy 實現 Namespace 之間的網路隔離。

拒絕所有入站流量

1
2
3
4
5
6
7
8
9
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress

僅允許同 Namespace 的流量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: production

允許特定 Namespace 存取

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-monitoring
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring

RBAC 權限控制

使用 Role 和 RoleBinding 實現 Namespace 層級的存取控制。

建立 Role

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-role
  namespace: development
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "delete"]

建立 RoleBinding

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: development
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: developers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-role
  apiGroup: rbac.authorization.k8s.io

跨 Namespace 通訊

在 Kubernetes 中,不同 Namespace 的服務可以透過完整的 DNS 名稱互相通訊。

DNS 命名格式

1
<service-name>.<namespace>.svc.cluster.local

跨 Namespace 存取範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
  namespace: frontend
spec:
  containers:
  - name: app
    image: nginx
    env:
    - name: BACKEND_URL
      value: "http://api-service.backend.svc.cluster.local:8080"

使用 ExternalName 服務

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Service
metadata:
  name: backend-alias
  namespace: frontend
spec:
  type: ExternalName
  externalName: api-service.backend.svc.cluster.local

最佳實踐

1. Namespace 命名規範

建議採用一致的命名規範,例如:

  • <team>-<env>frontend-devbackend-prod
  • <project>-<env>ecommerce-staging

2. 標籤管理

為 Namespace 添加適當的標籤,便於管理和篩選:

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    env: production
    team: platform
    cost-center: "12345"

3. 資源配額規劃

根據團隊需求和叢集容量,合理分配資源配額:

環境CPU 請求記憶體請求Pod 數量
開發4 cores8 Gi50
測試8 cores16 Gi100
生產32 cores64 Gi500

4. 預設套用 NetworkPolicy

建議為每個 Namespace 套用預設的 NetworkPolicy,遵循最小權限原則。

5. 定期審計

定期檢視 Namespace 的資源使用狀況和存取權限:

1
2
3
4
5
# 查看 Namespace 資源使用
kubectl top pods -n production

# 查看 RBAC 設定
kubectl get rolebindings -n production

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy