服務之間的連線與對外連接埠
用私有位址連到同叢集的服務,把資料庫這類不走 HTTP 的連接埠開放到網際網路,並用連線規則限制誰能連進來。
服務的 網路 分頁管三件事:私有網路 列出叢集裡其他服務連到它的位址,對外連接埠 讓叢集外的用戶端不經網域直接連進來,連線規則 決定哪些服務能連進來、它能連到哪裡。公開網域和 HTTPS 見加上公開網域與 HTTPS。
- 有權修改專案裡的服務。由 Helm、Argo CD 或 Flux 管理的服務不能從這裡開放連接埠或加規則,要回到那個工具修改。
- 連線規則要靠叢集的網路外掛(CNI)執行。K3s 內建的控制器支援,外掛不支援時規則建得起來,但不會擋任何連線。
- 開放連接埠要有負載平衡器。K3s 內建的 ServiceLB 和 Zeabur 安裝程式裝的 RKE2 都有。
用私有位址連到其他服務
Section titled “用私有位址連到其他服務”私有網路 的每一列是一個 Kubernetes Service,例如 web:8080。同專案的服務直接用這個位址連線,例如 http://web:8080。
從其他專案連線時,用 從其他專案連線 後面的完整位址,例如 web.demo.svc.cluster.local:8080。專案 隔離 了的話,對方專案要先在專案 設定 的 網路 加進 允許其他專案連入,見隔離其他專案。
這些位址只在叢集裡有效,網際網路連不到。
服務沒有私有位址時
Section titled “服務沒有私有位址時”只會主動往外連的背景服務不需要私有位址。要讓其他服務或公開網域連到它,先建立 Service。私有網路 會寫出可以複製的指令,例如:
kubectl -n demo expose deployment web --port=8080就緒檢查用的是數字連接埠時,指令會直接帶上那個連接埠。否則指令會寫 --port=<port>,執行前把 <port> 換成應用程式監聽的連接埠。
開放連接埠到網際網路
Section titled “開放連接埠到網際網路”資料庫、遊戲伺服器、MQTT 這類不走 HTTP 的服務,用對外連接埠讓叢集外的用戶端連進來。
到服務 網路 的 對外連接埠,按 開放連接埠,在 連接埠 選要開放的連接埠。只有私有位址上的連接埠可以選。
按 檢查變更,確認後套用。
列表會出現每個節點的位址和連接埠,例如 203.0.113.7:5432,旁邊有複製按鈕。顯示 連接埠 5432 正在等負載平衡器分配位址。 時,負載平衡器還在處理,或節點上這個連接埠已經有別的服務在用。
ServiceLB 會在每個節點監聽同一個連接埠號碼,所以整個叢集裡同一個連接埠號碼只能開放一次。同專案已經有服務開放了同一個連接埠時,Zeabur 會拒絕。
要關閉,在那一列按 關閉,檢查後套用。
用連線規則限制連入和連出
Section titled “用連線規則限制連入和連出”連線規則 的上方寫出目前誰能連進來,例如 web 只接受 1 個服務連入,下面分成 連入 和 連出 兩欄列出允許、部分允許或封鎖的對象。專案沒有任何規則時,所有連線都允許。
按 新增規則,選一種:
| 規則 | 效果 |
|---|---|
| 隔離這個服務 | 只有同專案的副本能連進來。它只能連到同專案的服務和 DNS,連不到網際網路。 |
| 允許來自公開網域的流量 | 讓 Traefik 把公開網域的請求送進來。 |
| 允許某個服務連入… | 選一個同專案的服務,讓它連進來。 |
規則可以疊加。常見的組合是先 隔離這個服務,再加 允許來自公開網域的流量 和需要連進來的服務。
要讓隔離的服務連到外部 API,到同一頁的 IP 限制 把位址加進 能連到哪裡,見限制能連入和連出的 IP。
要刪除規則,點規則名稱進入 物件 頁,在 YAML 檢視按 刪除。
用 kubectl 做同樣的事
Section titled “用 kubectl 做同樣的事”私有位址是一般的 ClusterIP Service,對外連接埠是 LoadBalancer Service,連線規則是一般的 NetworkPolicy。以下以專案 demo 為例。
apiVersion: v1kind: Servicemetadata: name: web namespace: demo labels: app.kubernetes.io/name: webspec: selector: app.kubernetes.io/name: web ports: - name: http port: 8080 targetPort: 8080selector 要和 Deployment 的 Pod 標籤相同。
Zeabur 開放連接埠時建立 <Service 名稱>-public-<連接埠>,複製來源 Service 的 selector 和那個連接埠,類型改成 LoadBalancer。標籤 app.kubernetes.io/name 是服務名稱,刪除服務時會一起刪掉。開放 db 的 5432:
apiVersion: v1kind: Servicemetadata: name: db-public-5432 namespace: demo labels: app.kubernetes.io/name: dbspec: type: LoadBalancer selector: app.kubernetes.io/name: db ports: - name: postgres port: 5432 targetPort: 5432 protocol: TCP關閉就刪除這個 Service:
kubectl -n demo delete service db-public-5432Zeabur 建立的規則都帶 app.kubernetes.io/managed-by: zeabur 標籤,名稱是 zeabur-<規則>-<服務>,超過 63 個字元會截斷。以下以服務 api 為例。
隔離這個服務:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: zeabur-isolate-api namespace: demo labels: app.kubernetes.io/managed-by: zeaburspec: podSelector: matchLabels: app.kubernetes.io/name: api policyTypes: [Ingress, Egress] ingress: - from: - podSelector: {} egress: - to: - podSelector: {} - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53允許某個服務連入,這裡讓 web 連到 api:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: zeabur-allow-web-api namespace: demo labels: app.kubernetes.io/managed-by: zeaburspec: podSelector: matchLabels: app.kubernetes.io/name: api policyTypes: [Ingress] ingress: - from: - podSelector: matchLabels: app.kubernetes.io/name: web允許來自公開網域的流量。規則允許兩個地方的 Traefik:K3s 內建的在 kube-system,Zeabur 安裝程式裝的在有 zeabur.com/platform: "true" 標籤的 Namespace:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: zeabur-allow-ingress-api namespace: demo labels: app.kubernetes.io/managed-by: zeaburspec: podSelector: matchLabels: app.kubernetes.io/name: api policyTypes: [Ingress] ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: app.kubernetes.io/name: traefik - namespaceSelector: matchLabels: zeabur.com/platform: "true" podSelector: matchLabels: app.kubernetes.io/name: traefik刪除規則:
kubectl -n demo delete networkpolicy zeabur-isolate-api私有網路 列出每個 Service 和它的連接埠。對外連接埠 列出每個節點的位址,資料庫會標 資料庫對外開放。連線規則 列出套用到這個服務的規則名稱,以及 連入 和 連出 各自允許誰。
kubectl -n demo get servicekubectl -n demo get networkpolicy -l app.kubernetes.io/managed-by=zeaburkubectl -n demo run probe --rm -it --restart=Never --image=busybox:1.37 -- wget -qO- -T 3 http://api:8080get service 的 TYPE 欄,私有位址是 ClusterIP,對外連接埠是 LoadBalancer,EXTERNAL-IP 是節點的位址。最後一行從同專案一個臨時的副本連到 api。api 隔離了而且沒有允許 probe 時,會在 3 秒後逾時。從叢集外用 nc -vz 203.0.113.7 5432 確認對外連接埠連得上。
| 畫面或結果 | 接著處理 |
|---|---|
| web 沒有私有位址 | 執行畫面上的 kubectl expose 指令,或套用上面的 Service。 |
kubectl expose 回覆 couldn't find port via --port flag or introspection | 容器沒有宣告連接埠。在 --port= 後面填應用程式監聽的連接埠。 |
| 一直顯示 正在等負載平衡器分配位址 | 節點上這個連接埠已經有別的服務在用,或叢集沒有負載平衡器。換一個連接埠,或請管理員確認 ServiceLB。 |
| 開放連接埠時回覆已有服務開放同一個連接埠 | 同專案已經開放了這個連接埠號碼,先關閉那一個。 |
| 隔離後公開網域逾時 | 加上 允許來自公開網域的流量。 |
| 隔離後服務連不到外部 API | 隔離只允許連到同專案和 DNS。在 IP 限制 的 能連到哪裡 加上外部 API 的位址。 |
| 加了規則,連線卻照樣通 | 叢集的網路外掛不支援 NetworkPolicy。 |