Kubernetes 中的 Service (服務)
Kubernetes 中的「服務」(Services)主要目的是讓你不需要更改現有的應用程式,就能使用 Kubernetes 提供的服務發現機制。不論你的應用程式是為了雲端設計的新程式,還是你將舊應用程式轉成容器化的形式,你都可以透過「服務」來讓這些運行在 Pod 中的應用程式在網路上可供其他客戶端存取與互動。簡單來說,服務幫助你把應用程式在網路上公開,讓其他應用或用戶可以找到並使用它。
今天,我們將深入探討 Kubernetes 中五種類型的 Service:ClusterIP、NodePort、LoadBalancer、ExternalName 和 Headless,並介紹它們的功能和使用場景。
Service 的基本概念
Service 的定義
在 Kubernetes 中,「Service」是一種抽象方式,用來定義一組 Pod 以及如何與這些 Pod 進行網路通訊。雖然 Pod 是短暫的且會動態分配 IP 地址,但 Service 提供了一個穩定的網路端點(IP 和 DNS 名稱),讓其他應用程式可以與這組 Pod 進行通訊。換句話說,Service 充當了負載平衡器,將流量自動分配到匹配的 Pod 上,即使這些 Pod 的數量或 IP 地址發生變化。
Service 的功能
- 負載平衡:Service 透過將流量分配至後端的一組 Pod 上,實現自動的負載平衡。
- 服務發現:Service 透過 DNS 名稱進行服務發現,其他 Pod 可以通過這個名稱來存取對應的服務。
- 暴露服務:Service 可以將服務暴露在 Cluster 的內部或外部,使其可以被客戶端或其他服務存取。
Service 的類型
Kubernetes 提供了多種方式來暴露 Service,主要分為以下幾種類型:
1. ClusterIP
- 預設類型:這是 Kubernetes 中的預設 Service 類型。
- 內部存取:該類型的 Service 僅在 Cluster 內部存取,適合於服務之間的內部通訊。
- 應用場景:適用於需要內部流量管理的後端服務,如微服務架構中的內部 API 通訊。
2. NodePort
- 外部存取:該類型的 Service 會將服務暴露在每個 Node 的指定端口上。
- 存取方式:外部客戶端可以通過
<NodeIP>:<NodePort>的形式存取服務。 - 應用場景:適合開發和測試環境,或結合外部負載平衡器使用,以實現基本的外部存取功能。
3. LoadBalancer
- 雲端集成:此類型會使用雲端提供商的負載平衡器將服務直接暴露在外部。
- 高可用性與擴展性:適合於正式環境中,提供穩定的外部存取,並支援自動擴展。
- 應用場景:適合高流量的 Web 應用或 API 服務,確保服務可用性和性能。
4. ExternalName
- DNS 重定向:ExternalName 不創建 ClusterIP,也不涉及負載平衡,而是將服務名稱解析為外部的 DNS 名稱。
- 外部服務存取:適用於需要將Cluster內部的請求重定向到外部 API 或第三方服務的場景。
- 應用場景:適合簡化內部存取外部服務的設定,特別是在需要跨越網路邊界的情況下。
5. Headless Service
- 無 ClusterIP:Headless Service 與普通的 ClusterIP 不同,它不會分配 Cluster IP。這類型的 Service 主要用於不需要負載平衡且需要直接取得 Pod 地址的情境。
- 應用場景:當應用程式需要直接與特定 Pod 通訊(例如資料庫或需要自我負載平衡的分散式系統),Headless Service 是理想的選擇。
- Service 的定義:通過將
clusterIP設定為None,就可以創建一個 Headless Service。
實作範例
ClusterIP 範例
以下是一個 ClusterIP Service 的 YAML 定義:
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
創建並查看 ClusterIP Service:
kubectl apply -f nginx-clusterip.yaml
kubectl get services
此 ClusterIP Service 將流量負載平衡至所有標籤為 app=nginx 的 Pod,並通過 ClusterIP 在 Cluster 內部進行存取。
NodePort 範例
以下是一個 NodePort Service 的 YAML 定義:
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007
type: NodePort
創建並查看 NodePort Service:
kubectl apply -f nginx-nodeport.yaml
kubectl get services
此 NodePort Service 將流量暴露在每個 Node 的 30007 端口上,並可通過 <NodeIP>:30007 存取。
LoadBalancer 範例
以下是一個 LoadBalancer Service 的 YAML 定義:
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
創建並查看 LoadBalancer Service:
kubectl apply -f nginx-loadbalancer.yaml
kubectl get services
此 LoadBalancer Service 會使用雲端提供商的負載平衡器將服務直接暴露在外部,適合需要高可用性的應用場景。
ExternalName 範例
ExternalName 是一種將 Service 的查詢轉發到指定 DNS 名稱的 Service 類型。當一個 Pod 嘗試通過 Service 名稱存取資源時,Kubernetes 不會進行 IP 地址解析,而是直接返回設定的 DNS 名稱。這通常用於將Cluster內部的請求重定向到外部的 API 或第三方服務。
典型應用場景
ExternalName 最常見的使用場景包括:
- 重定向到外部服務:如果有一些外部服務(例如公司內部的 API 或第三方 API)需要在 Kubernetes Cluster內部進行統一存取,可以使用 ExternalName 將請求透明地轉發。
- 簡化 DNS 設定:可以透過 ExternalName 將複雜的外部域名抽象成更易記的內部 Service 名稱。
ExternalName 的 YAML 定義
以下是一個 ExternalName Service 的 YAML 設定範例:
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: example.com
在這個範例中,當Cluster內部的應用程式通過 external-service 存取時,Kubernetes 將自動將這些請求轉發到 example.com。
注意事項
- 不涉及流量轉發:ExternalName 不會創建 ClusterIP,也不會涉及負載平衡。它僅僅是在 DNS 層面進行名稱解析。
- 依賴 DNS 解析:ExternalName 依賴於外部 DNS 的穩定性,這在某些情況下可能會帶來延遲或故障風險。
- 僅支援 TCP 和 UDP 協議:ExternalName 主要用於 TCP 和 UDP 協議的流量,對於更高層的 HTTP 協議可能需要額外設定。
Headless範例
以下是一個 Headless Service 的 YAML 定義:
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
這樣的設定允許直接通過 DNS 解析得到各個 Pod 的 IP 地址,而不是透過負載平衡進行流量分配。
總結
今天我們學習了 Kubernetes 中的五種 Service 類型:ClusterIP、NodePort、LoadBalancer、ExternalName 和 Headless。這些 Service 提供了不同的方式來暴露應用,使其能夠在 Cluster 內部或外部被存取。通過這些學習,我們了解了如何創建和管理這些 Service,並熟悉了它們各自的使用場景。這些知識對於設計和部署 Kubernetes 應用至關重要,尤其是在不同的網路環境中保持服務的穩定運行。
接下來,我們將繼續探討 Kubernetes 中其他關鍵的概念與實踐,例如 ConfigMaps、Secrets 和 Volumes,這些內容將進一步豐富我們的 Kubernetes 技能,幫助我們更靈活地應對實際部署中的挑戰。
