1. 程式人生 > >Kubernetes NodePort、LoadBalancer和Ingress介紹

Kubernetes NodePort、LoadBalancer和Ingress介紹

最近,有人問我NodePorts,LoadBalancers和Ingress之間有什麼區別。 它們都是將外部流量引入群集的方式,但是分別以不同的方式完成。 讓我們來具體看看它們是如何工作的,以及何時使用它們。
注意:此處的所有內容均適用於Google Kubernetes Engine。 如果您在另一個雲上執行,使用minikube或其他東西,這些將略有不同。 我也沒有深入瞭解技術細節。 如果您有興趣瞭解更多資訊,官方文件[1]是一個很好的資源!
ClusterIP

640?wx_fmt=png

ClusterIP服務是預設的Kubernetes服務。 它為您提供叢集內的其他應用程式可以訪問的服務。 沒有外部訪問許可權。
ClusterIP服務的YAML如下所示:
apiVersion: v1
kind: Service
metadata:  
  name: my-internal-service
spec:
  selector:    
    app: my-app
  type: ClusterIP
  ports:  
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP

如果您無法從網際網路訪問ClusterIP服務,我為什麼要談論它呢? 事實證明,您可以使用Kubernetes代理訪問它!
640?wx_fmt=png
啟動Kubernetes代理:
$ kubectl proxy --port=8080

現在,您可以使用Kubernetes API以訪問此服務:
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/

因此,要訪問我們上面定義的服務,您可以使用以下地址:
http://localhost:8080/api/v1/proxy/namespaces/default
/services/my-internal-service:http/
什麼時候使用Kubernetes Proxy訪問服務?
在某些情況下,您可以使用Kubernetes代理來訪問您的服務。
  1. 除錯您的服務或出於某種原因直接從您的膝上型電腦連線它們

  2. 允許內部流量,顯示內部dashboard等


因為此方法要求您作為經過身份驗證的使用者執行kubectl,所以不應使用此方法將服務公開給Internet或將其用於生產服務。
NodePort

640?wx_fmt=png

NodePort服務是將外部流量直接傳送給您的服務的最原始方式。 顧名思義,NodePort在所有節點(VM)上開啟一個特定埠,並且傳送到該埠的任何流量都將轉發到該服務。
640?wx_fmt=png
注意:上圖並不是技術上最精確的圖示,但我認為它說明了NodePort的工作原理。
NodePort服務的YAML如下所示:
apiVersion: v1

kind: Service
metadata:  
  name: my-nodeport-service
spec:
  selector:    
    app: my-app
  type: NodePort
  ports:  
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30036
    protocol: TCP

基本上,NodePort服務與普通的“ClusterIP”服務有兩點不同。 首先,型別是“NodePort”。還有一個名為nodePort的附加埠,用於指定在節點上開啟的埠。 如果您不指定此埠,它將選擇一個隨機埠。 大多數時候你應該讓Kubernetes選擇埠;正如thockin所說,對於你可以使用的埠有很多必要的說明。
什麼時候使用這種方法?
這種方法有許多缺點:
  1. 每個埠只能有一個服務

  2. 您只能使用埠30000-32767

  3. 如果您的Node/VM的IP地址發生變化,您需要處理好


出於這些原因,我不建議在生產中使用此方法直接公開您的服務。 如果您執行的服務不必始終可用,或者您的成本非常敏感,則此方法適合您。 比如演示應用程式或臨時的東西。
LoadBalancer

640?wx_fmt=png

LoadBalancer服務是將服務公開給Internet的標準方法。 在GKE上,這將啟動Network Load Balancer[2],它將為您提供單個IP地址,以便將所有流量轉發到您的服務。
640?wx_fmt=png
什麼時候使用?
如果要直接公開服務,這是預設方法。 您指定的埠上的所有流量都將轉發到該服務。 沒有過濾,沒有路由等。這意味著您可以向其傳送幾乎任何型別的流量,如HTTP、TCP、UDP、Websockets、gRPC等等。
最大的缺點是您使用LoadBalancer公開的每個服務都將獲得自己的IP地址,並且您必須為每個公開的服務支付LoadBalancer,這可能會變得昂貴!
Ingress

640?wx_fmt=png

與上述所有示例不同,Ingress實際上不是一種服務。 相反,它位於多個服務的前面,充當叢集中的“智慧路由器”或入口點。
您可以使用Ingress執行許多不同的操作,並且有許多型別的Ingress控制器,都具有不同的功能。
預設的GKE ingress controller將為您啟動HTTP(S)負載均衡器。這將允許您執行基於路徑和子域的路由到後端服務。 例如,您可以將foo.yourdomain.com上的所有內容傳送到foo服務,並將youdomain.com/bar/下的所有內容傳送到bar服務。
640?wx_fmt=png
使用L7 HTTP負載均衡器的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控制器的外掛,如cert-manager[3],可以為您的服務自動配置SSL證書。
如果要在同一IP地址下公開多個服務,Ingress是最有用的,並且這些服務都使用相同的L7協議(通常是HTTP)。 如果您使用GCP整合,您只需支付一個負載均衡器,並且因為Ingress是“智慧”的,您可以獲得大量開箱即用的功能(如SSL、身份驗證、路由等)。相關連結:
  1. https://kubernetes.io/docs/concepts/services-networking/service/

  2. https://cloud.google.com/compute/docs/load-balancing/network/

  3. https://github.com/jetstack/cert-manager