iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0

到目前為止,我們的 cloud-native-search 系統在 Kubernetes 裡能跑能擴,但有個問題:

現在任何 Pod 幾乎都能連任何 Pod。

例如:

  • 一個無關的測試 Pod 可以直接打 ES 叢集。
  • 一個開發者若拿到 kubectl 權限,就能 kubectl exec 進生產服務。

在現實世界裡,這叫「防火牆全開」。
所以今天的目標是讓叢集從「通用網路」變成「分區網路」,
讓每個服務都只能接觸它應該接觸的東西。


Step 1 — 先建立命名空間分區(Namespace)

Kubernetes 的 Namespace 就像 apartment 的樓層,不同應用最好不要混在同一層。

kubectl create namespace search-system
kubectl create namespace elasticsearch

接著修改前面的 Deployment / Service YAML:

metadata:
  name: search-deploy
  namespace: search-system
metadata:
  name: es01
  namespace: elasticsearch

這樣我們就能分清楚:

  • search-service → 在 search-system
  • Elasticsearch → 在 elasticsearch

Step 2 — NetworkPolicy

NetworkPolicy 是 Kubernetes 的 L3/L4 層流量防火牆。
一旦某 namespace 啟用 NetworkPolicy,預設就會「拒絕所有入站流量」,
除非明確放行。

下面這份 policy 限定:
只有 search-system namespace 裡的 Pod 可以打 ES。

# k8s/networkpolicy-es.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-search-to-es
  namespace: elasticsearch
spec:
  podSelector: {}  # 所有 Pod in this namespace (ES)
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: search-system
    ports:
    - protocol: TCP
      port: 9200

應用這份規則後:

kubectl apply -f k8s/networkpolicy-es.yaml

再試著在別的 namespace 執行:

kubectl run curl --rm -it --image=curlimages/curl --restart=Never \
  -n default -- curl -s http://es01.elasticsearch:9200

會發現請求被拒(timeout)。
search-system 的 Pod 仍可正常存取。

💡 小訣竅:
在 namespace metadata 加上 label

metadata:
  name: search-system
  labels:
    name: search-system

才能被上面的 namespaceSelector 匹配。


Step 3 — RBAC:控制「人」的權限

NetworkPolicy 控「流量」,RBAC 控「操作權」。

我們希望:

  • 一般開發者能看 Pod 狀態,但不能刪除。
  • CI/CD 帳號可以部署,但不能改權限。

建立角色 (Role)

# k8s/role-dev.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: search-system
  name: developer-view
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list", "watch"]

建立角色綁定 (RoleBinding)

# k8s/rolebinding-dev.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-view-binding
  namespace: search-system
subjects:
- kind: User
  name: shirley
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-view
  apiGroup: rbac.authorization.k8s.io

套用後:

kubectl apply -f k8s/role-dev.yaml
kubectl apply -f k8s/rolebinding-dev.yaml

現在,使用者 shirley 登入後,只能 get/list/watch
無法 deleteexec


小結:權限的層次化設計

類型 功能 關聯任務
Namespace 邏輯隔離 資源歸類與分權
NetworkPolicy 控制 Pod 之間的網路流量 零信任架構
RBAC 控制人與 ServiceAccount 的操作範圍 最小權限原則

這一層,讓系統不只是穩定可擴,而是「安全地運行」。
當專案進入多人協作階段,這些設定會防止「一個錯誤的 kubectl delete」毀掉整個環境。


上一篇
Day 27 - HPA 自動擴縮:讓系統自己呼吸
下一篇
Day 29 - 觀測 & 小故障演練 — 看見系統、擁抱未知
系列文
用 Golang + Elasticsearch + Kubernetes 打造雲原生搜尋服務29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言