iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0

昨天已讓六個 Deployment 各自維持 Pod。現在 api-b 要呼叫 api-a,Gateway 也要把 request 轉送到兩個 API,該填哪個位址?今天將為這些 workload 建立穩定的 Service 名稱。

Service 與 EndpointSlice 如何連接後端 Pod

先看 api-a 的 ClusterIP Service:

apiVersion: v1
kind: Service
metadata:
  name: api-a
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: api-a
  ports:
    - name: http
      port: 80
      targetPort: http

selector 要選中 api-a Pod;port: 80 是呼叫端使用的 Service port;targetPort: http 則指向 Deployment 裡命名為 http 的 container port,也就是 8080。若 selector 拼錯,Service 物件仍可能建立成功,卻沒有對應的後端。

替六個 workload 建立 Service

以下將 api-a 以及其餘五個 Service 放在同一份 app-services.yaml。

  • 前端 Pod 監聽 80
  • Gateway 與兩個 API 的 Pod 監聽 8080
apiVersion: v1
kind: Service
metadata:
  name: api-a
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: api-a
  ports:
    - name: http
      port: 80
      targetPort: http
---
apiVersion: v1
kind: Service
metadata:
  name: api-b
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: api-b
  ports:
    - name: http
      port: 80
      targetPort: http
---
apiVersion: v1
kind: Service
metadata:
  name: api-gateway
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: api-gateway
  ports:
    - name: http
      port: 80
      targetPort: http
---
apiVersion: v1
kind: Service
metadata:
  name: portal-web
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: portal-web
  ports:
    - name: http
      port: 80
      targetPort: http
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-a
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: frontend-a
  ports:
    - name: http
      port: 80
      targetPort: http
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-b
  namespace: team-a
spec:
  type: ClusterIP
  selector:
    app: frontend-b
  ports:
    - name: http
      port: 80
      targetPort: http
kubectl apply -f app-services.yaml
kubectl -n team-a get services
kubectl -n team-a get endpointslices -l kubernetes.io/service-name=api-a

預期看到六個 ClusterIP Service,EndpointSlice 會列出 Service 對應的端點。

Service 名稱要被正確讀取

假設 api-b 原本就會讀取 API_A_BASE_URL 這個環境變數,可在它的 Deployment container 設定中加入:

env:
  - name: API_A_BASE_URL
    value: http://api-a

沿用 Day 14 的 other-deployments.yaml,就修改其中 api-b 的 container,再重新 kubectl apply -f other-deployments.yaml。

應用 Gateway 的兩條下游 route 也要指向 api-a、api-b 的 Service。

api-b 若與 api-a 同在 team-a,可用 http://api-a 呼叫 Service port 80。而跨 Namespace 時,使用 http://api-a.team-a.svc.cluster.local 才會呼叫成功,看起來的寫法也比較明確,不過叢集 DNS domain 未必是 cluster.local,需按實際配置核對。

在 Docker Compose 裡,同一 network 內的服務可以用 service name 互相找到。Kubernetes 由 Service 與叢集 DNS 提供類似的存取方式,而 Service 對應的 Pod 可以更換。

到目前為止,應已可以從 api-b Pod 發起真正的 request 給 api-a,經 api-a Service 得到預期回應,而且重建一顆 api-a Pod 後,呼叫仍能成功。

單純 DNS 解析成功還不算整條呼叫路徑驗證,若失敗,依序看 DNS、Service selector、EndpointSlice、Pod 監聽 port 與應用 log。

Gateway 路由及前端載入也應用各自的實際 request 測試,不能只靠六個 Service 存在就判定架構已連通。

參考資料


上一篇
Day 14 - 把服務交給 Deployment 管理
下一篇
Day 16 - NodePort,從電腦直接打到測試 API
系列文
初見 Kubernetes - 純網站後端開發踏入 K8s 世界的經驗分享 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言