最近有些同學問我 NodePort,LoadBalancer 和 Ingress 之間的區別。它們都是將叢集外部流量匯入到叢集內的方式,只是實現方式不同。讓我們看一下它們分別是如何工作的,以及你該如何選擇它們。
註意:這裡說的每一點都基於Google Kubernetes Engine。如果你用 minikube 或其它工具,以預置型樣式(om prem)執行在其它雲上,對應的操作可能有點區別。我不會太深入技術細節,如果你有興趣瞭解更多,官方檔案[1]是一個非常棒的資源。
ClusterIP 服務是 Kubernetes 的預設服務。它給你一個叢集內的服務,叢集內的其它應用都可以訪問該服務。叢集外部無法訪問它。
ClusterIP 服務的 YAML 檔案類似如下:
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
selector:
app: my-app
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
如果 從Internet 沒法訪問 ClusterIP 服務,那麼我們為什麼要討論它呢?那是因為我們可以透過 Kubernetes 的 proxy 樣式來訪問該服務!
$ kubectl proxy --port=8080
這樣你可以透過Kubernetes API,使用如下樣式來訪問這個服務:
http://localhost:8080/api/v1/proxy/namespaces//services/:/
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
有一些場景下,你得使用 Kubernetes 的 proxy 樣式來訪問你的服務:
這種方式要求我們執行 kubectl 作為一個未認證的使用者,因此我們不能用這種方式把服務暴露到 internet 或者在生產環境使用。
NodePort 服務是引導外部流量到你的服務的最原始方式。NodePort,正如這個名字所示,在所有節點(虛擬機器)上開放一個特定埠,任何傳送到該埠的流量都被轉發到對應服務。
NodePort 服務的 YAML 檔案類似如下:
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
selector:
app: my-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP
NodePort 服務主要有兩點區別於普通的“ClusterIP”服務。第一,它的型別是“NodePort”。有一個額外的埠,稱為 nodePort,它指定節點上開放的埠值 。如果你不指定這個埠,系統將選擇一個隨機埠。大多數時候我們應該讓 Kubernetes 來選擇埠,因為如評論中 thockin 所說,使用者自己來選擇可用埠代價太大。
-
每個埠只能是一種服務
-
埠範圍只能是 30000-32767
-
如果節點/VM 的 IP 地址發生變化,你需要能處理這種情況
基於以上原因,我不建議在生產環境上用這種方式暴露服務。如果你執行的服務不要求一直可用,或者對成本比較敏感,你可以使用這種方法。這樣的應用的最佳例子是 demo 應用,或者某些臨時應用。
LoadBalancer 服務是暴露服務到 internet 的標準方式。在 GKE 上,這種方式會啟動一個 Network Load Balancer[2],它將給你一個單獨的 IP 地址,轉發所有流量到你的服務。
如果你想要直接暴露服務,這就是預設方式。所有通往你指定的埠的流量都會被轉發到對應的服務。它沒有過濾條件,沒有路由等。這意味著你幾乎可以傳送任何種類的流量到該服務,像 HTTP,TCP,UDP,Websocket,gRPC 或其它任意種類。
這個方式的最大缺點是每一個用 LoadBalancer 暴露的服務都會有它自己的 IP 地址,每個用到的 LoadBalancer 都需要付費,這將是非常昂貴的。
有別於以上所有例子,Ingress 事實上不是一種服務型別。相反,它處於多個服務的前端,扮演著“智慧路由”或者叢集入口的角色。
你可以用 Ingress 來做許多不同的事情,各種不同型別的 Ingress 控制器也有不同的能力。
GKE 上的預設 ingress 控制器是啟動一個 HTTP(S) Load Balancer[3]。它允許你基於路徑或者子域名來路由流量到後端服務。例如,你可以將任何發往域名 foo.yourdomain.com 的流量轉到 foo 服務,將路徑 yourdomain.com/bar/path 的流量轉到 bar 服務。
GKE 上用 L7 HTTP Load Balancer[4]生成的 Ingress 物件的 YAML 檔案類似如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: other
servicePort: 8080
rules:
- host: foo.mydomain.com
http:
paths:
- backend:
serviceName: foo
servicePort: 8080
- host: mydomain.com
http:
paths:
- path: /bar/*
backend:
serviceName: bar
servicePort: 8080
Ingress 可能是暴露服務的最強大方式,但同時也是最複雜的。Ingress 控制器有各種型別,包括 Google Cloud Load Balancer, Nginx,Contour,Istio,等等。它還有各種外掛,比如 cert-manager[5],它可以為你的服務自動提供 SSL 證書。
如果你想要使用同一個 IP 暴露多個服務,這些服務都是使用相同的七層協議(典型如 HTTP),那麼Ingress 就是最有用的。如果你使用本地的 GCP 整合,你只需要為一個負載均衡器付費,且由於 Ingress是“智慧”的,你還可以獲取各種開箱即用的特性(比如 SSL、認證、路由等等)。
-
https://kubernetes.io/docs/concepts/services-networking/service/
-
https://cloud.google.com/compute/docs/load-balancing/network/
-
https://cloud.google.com/compute/docs/load-balancing/http/
-
https://cloud.google.com/compute/docs/load-balancing/http/
-
https://github.com/jetstack/cert-manager
原文連結:https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0
本次培訓內容包括:容器原理、Docker架構及工作原理、Docker網路與儲存方案、Harbor、Kubernetes架構、元件、核心機制、外掛、核心模組、Kubernetes網路與儲存、監控、日誌、二次開發以及實踐經驗等,點選瞭解具體培訓內容。
長按二維碼向我轉賬
受蘋果公司新規定影響,微信 iOS 版的贊賞功能被關閉,可透過二維碼轉賬支援公眾號。