iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
Kubernetes

從零開始的雲端實戰:30 天 Kubernetes 核心觀念與部署指南系列 第 10

【Day 10】Pod 之間的溝通橋樑:Service(ClusterIP)概念與內部網路

  • 分享至 

  • xImage
  •  

今日目標

  • 理解為什麼不能直接依賴 Pod IP 進行通訊(Pod 的短暫性與動態 IP 痛點)。
  • 搞懂 Kubernetes Service 的角色定位與 Endpoints 的運作機制。
  • 掌握預設的 Service 類型:ClusterIP
  • 實戰操作:建立 ClusterIP Service,並透過 K8s 內部 DNS 進行跨 Pod 服務發現。

痛點場景:為什麼我們不能直接連 Pod IP?

在前面幾天,我們知道 Deployment 可以隨時建立、刪除、擴縮容或滾動更新 Pod。但這衍生出一個嚴重的網路通訊問題:

  1. Pod 是短暫且易逝的(Ephemeral):每個 Pod 在建立時都會分到一個內部 IP(例如 10.244.0.15),但只要 Pod 重啟或更新,IP 就會立刻改變
  2. 多副本負載平衡問題:如果前端有 3 個後端 API 副本(Pod),前端到底該把請求發給哪一個 IP?

如果讓應用程式直接寫死 Pod IP,整個系統會變得極度脆弱。

這正是 Service 出現的原因:Service 為一群功能相同的 Pod 提供了一個「單一、固定、永久不變的入口(IP 與 DNS 名稱)」,並自動在後端的 Pod 之間進行負載平衡。


Service 如何找到對應的 Pod?

答案依然是我們在 Day 08 學到的 Label Selector(標籤選擇器)

  • Service 透過 spec.selector 去尋找帶有特定標籤的 Pod。
  • Kubernetes 會自動建立一個同名的 Endpoints(或 EndpointSlice) 物件,即時動態追蹤符合標籤且處於健康狀態(Running)的 Pod IP 列表。
  • 當某個 Pod 掛掉或新增時,Endpoints 列表會自動更新,客戶端完全無感。

預設類型:ClusterIP 是什麼?

Kubernetes 的 Service 有多種型態(Type),最基本也是預設的型態就是 ClusterIP

  • 作用範圍:僅限在 Kubernetes 集群內部 存取。
  • 特性:K8s 會分配一個虛擬的內部 IP 給這個 Service(外部網路無法直接存取)。
  • 適用場景:資料庫(MySQL / Redis)、後端內部微服務等不需要直接對公網開放的元件。

實戰演練:建立 ClusterIP Service 與內部 DNS 解析

步驟 1:建立 nginx-service.yaml

我們為前兩天建立的 nginx-deployment(標籤為 app: nginx-app)配置一個 ClusterIP Service:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  selector:
    app: nginx-app
  ports:
    - protocol: TCP
      port: 80        # Service 對外暴露的 Port
      targetPort: 80  # 轉發到後端 Pod 容器的 Port

步驟 2:套用配置並檢查狀態

kubectl apply -f nginx-service.yaml

查看已建立的 Service:

kubectl get svc nginx-service

輸出預期:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   10.105.120.45   <none>        80/TCP    10s

你會拿到一個固定的 CLUSTER-IP,只要 Service 不刪除,這個 IP 永遠不會改變。

檢查背後的 Endpoints(確認是否有成功抓到 3 個 Nginx Pod 的 IP):

kubectl get endpoints nginx-service

步驟 3:透過內部 DNS 測試連線

Kubernetes 內建 CoreDNS 服務,在集群內部的任何 Pod 都可以直接用 Service 名稱 作為網域名稱進行訪問!

我們臨時起一個帶有 curl 工具的測試 Pod 來驗證:

kubectl run test-client --image=curlimages/curl --rm -it -- restart=Never -- sh

進入測試容器後,直接用 Service 名稱發送請求:

# 1. 透過 Service 名稱連線 (K8s 內部自動解析)
curl http://nginx-service

# 2. 透過完整 FQDN (Fully Qualified Domain Name) 連線
curl [http://nginx-service.default.svc.cluster.local](http://nginx-service.default.svc.cluster.local)

若成功輸出 Nginx 的 HTML 歡迎頁面,代表內部 Service 發現與負載平衡機制完全運作正常!
(測試完成後輸入 exit 退出並自動銷毀測試 Pod)


本日小結

今天我們搞懂了 Service 的核心價值:

  • 解決了 Pod IP 動態變動的痛點,提供永久固定的虛擬 IP 與 DNS 名稱。
  • 掌握了預設的 ClusterIP 模式,適合內部微服務之間的穩定調用。

但 ClusterIP 只能在集群內部存取,如果我們要讓外面的使用者或本機瀏覽器真正連進我們的網站,該怎麼辦?

明天 Day 11,我們將把服務對外開放:「對外開門營運:Service NodePort 與 LoadBalancer 存取測試」


上一篇
【Day 09】零停機更新:Rolling Update 滾動升級與 Rollback 退回舊版
系列文
從零開始的雲端實戰:30 天 Kubernetes 核心觀念與部署指南10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言