不是就服務嗎?有什麼好講的? (´・ω・`)
要把服務提供出去才能讓外部使用喔 (⁎⁍̴̛ᴗ⁍̴̛⁎)
Kubernetes 中的 Service
是專有名詞,專指用來為 Pod
提供單一對外入口的功能元件。
將服務部署完之後,不外乎需要用以下幾種形式將服務提供出去:
以上皆是喔!
因為在 Kubernetes 中,Pod 是動態的、短暫的,可能會隨時重啟、移動或失效,這些行為都會使 Pod 的IP
位置產生變動。為了避免這種不穩定性,Kubernetes 不會直接暴露 Pod 的 IP。
也因此,需要透過Service
來穩定地訪問 Pod。
Service 是 Kubernetes 中的抽象層,會自動將流量轉發到正確的 Pod中。這樣即使 Pod 的 IP 發生變化,外部系統可以使用 Service 來穩定地與應用程序互動,而不會 Pod 動態變化影響導致服務不穩定。
在不同的業務場景,Service
也有不同的類型做應對:
對內服務:ClusterIP(預設)
透過ClusterIP
公開的服務,只能由 Cluster 內部呼叫,而不能被外部訪問。
只有同一個 Cluster 中的其他 Pod 可以透過 ClusterIP
訪問到對應的服務。
為什麼 Web Pod 沒有對應的 Service?
有的!但不是ClusterIP。
而是後面幾種類型:
提供外部呼叫:NodePort
指派一個port
,NodePort
就會透過這個 port 將外部流量轉到對應的 Pod 上。
(port
範圍介於30000-32767之間)
提供外部呼叫:LoadBalancer
只適用於有支援的雲平台。
功能基本上和NodePort
相同,雲平台供應商會透過建立一個Load Balancer
,將外部流量轉發到對應的 Pod 上。
ExternalName
這個類型比較特殊,它是把 Service 導向指定的 DNS name,而非指定的 pod。
相當於這個設定能將外部服務當作 Cluster
內部服務來使用,而不需要知道具體的外部地址。一旦外部服務的地址變更,只需要修改 ExternalName Service
的配置,就不需要更動使用到該服務的 Pod 了。
另外,使用 ExternalName Service
的流量是在 DNS level 轉發,而不是透過代理(proxying) 或 轉發(forwarding)完成的。
特別注意:
ExternalName Service
純粹是 DNS 重新定向,不提供負載均衡或代理功能喔!
直接呼叫 Pod 不行嗎?
不行,從 Cluster 外部是無法呼叫到 Pod 的。
必須使用Service
。那 Cluster 內部的其他服務,可以不透過 Service 直接呼叫 Pod 嗎?
可以,但不建議。
如果要不透過Service
呼叫 Pod,需使用建立 Pod 時隨機指派的內部IP
。也就是說,一旦 Pod 因損壞重啟,就會因為IP
異動導致外部呼叫失敗,Service
可以避免這個問題。
另外,誠如架構圖所示,當功能本身啟動多個 Pod 去分擔工作(絕大部分實務上都是這樣做的),就必須要有單一的對外窗口作分流才能達到工作負載平衡的效益。
只談 Service
的類型好像有點無聊,分享一個小小的 GKE 應用經驗。
雖說可以用 Service 的方式直接將服務提供出去非常簡便,但還是有些小缺點的。
Service 無法提供流量控制和安全性服務
那誰可以?
Load Balance可以!
架構會是這個樣子:
在 GKE 上,可以使用 Ingress 或 Istio Gateway 之類的服務來處理外部流量。這樣既可以在保持 Cluster 內部架構不變的同時將服務對外,還可以透過 Load Balancer 處理來自外部的流量並設定各項安全性措施喔 \ (^o^)/
當然也不是說 NodePort 跟 ExternalName 就沒用了。
畢竟每個系統的規格和需求都不相同,雲服務價格也不便宜,架構還是要因應需求而設計才是最適方案。
Service
是 Kubernetes
用以管理和訪問 Pod 的重要組件,能確保即使 Pod 動態增減,無論從內部或是外部呼叫都依然能保持穩定可用。