NodePort,LoadBalancer還是Ingress?我該如何選擇 - kubernetes

2019-09-09     hello架構

當我們使用k8s集群部署好應用的Service時,默認的Service類型是ClusterIP,這種類型只有 Cluster 內的節點和 Pod 可以訪問。如何將應用的Service暴露給Cluster外部訪問呢,Kubernetes 提供了多種類型的 Service,如下:

ClusterIP


ClusterIP服務是Kuberntets的默認服務。它在集群內部生成一個服務,供集群內的其他應用訪問。外部無法訪問。

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

如果不能從網際網路訪問ClusterIP服務,那我們還介紹它幹啥?其實,我們可以使用Kubernetes proxy來訪問它!

開啟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來訪問服務:

  1. 調試服務,或者是因為某些原因需要從電腦直接連接服務;
  2. 允許內部流量,顯示內部儀錶盤等。

這個訪問需要你作為一個已驗證的用戶去運行kubectl,所以不要通過這種方式將服務發布到網際網路,或者是在生產環境下使用。

NodePort


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說的,關於能使用哪些埠,有很多注意事項。

使用場景

這種方式有一些不足:

  1. 一個埠只能供一個服務使用;
  2. 只能使用30000–32767的埠;
  3. 如果節點 / 虛擬機的IP位址發生變化,需要進行處理。

因此,我不推薦在生產環境使用這種方式來直接發布服務。如果不要求運行的服務實時可用,或者在意成本,這種方式適合你。例如用於演示的應用或是臨時運行就正好用這種方法。

LoadBalancer


LoadBalancer服務是發布服務到網際網路的標準方式。在GKE中,它會啟動一個Network Load Balancer,分配一個單獨的IP位址,將所有流量轉發到服務中。

使用場景

如果你想直接發布服務,這是默認方式。指定埠的所有流量都會轉發到服務中,沒有過濾,也沒有路由。這意味著你幾乎可以發送任意類型的流量到服務中,比如HTTP、TCP、UDP、Websockets、gRPC等等。

這裡最大的不足是,使用LoadBalancer發布的每個服務都會有一個自己的IP位址,你需要支付每個服務的LoadBalancer 費用,這是一筆不小的開支。

Ingress


Ingress實際上不是一種服務。相反,它在多個服務前面充當「智能路由」的角色,或者是集群的入口。

使用Ingress可以做很多事情,不同類型的Ingress控制器有不同的功能。

默認的GKE ingress控制器會啟動一個 HTTP(S) Load Balancer,可以通過基於路徑或者是基於子域名的方式路由到後端服務。例如,可以通過foo.yourdomain.com 發送任何東西到foo服務,或者是發送yourdomain.com/bar/路徑下的任何東西到bar服務。

對於使用第 7 層HTTP Load Balancer 的GKE上的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等等。還有一些Ingress控制器插件,比如證書管理器,可以自動為服務提供SSL認證。

如果想在同一個IP位址下發布多個服務,並且這些服務使用相同的第 7 層協議(通常是 HTTP),Ingress是最有用的。如果使用原生的GCP集成,只需要支付一個負載均衡器的費用。因為Ingress是「智能」的,你可以得到很多開箱即用的特性(比如SSL、認證、路由等)。

文章來源: https://twgreatdaily.com/qb3YPm0BJleJMoPMKA79.html