k8s服務暴露之ingress與負載均衡


k8s 對外暴露服務的方法

向 k8s 集群外部暴露服務的方式有三種: nodePort,LoadBalancer 和本文要介紹的 Ingress。每種方式都有各自的優缺點,nodePort 方式在服務變多的情況下會導致節點要開的端口越來越多,不好管理。而 LoadBalancer 更適合結合雲提供商的 LB 來使用,但是在 LB 越來越多的情況下對成本的花費也是不可小覷。Ingress 是 k8s 官方提供的用於對外暴露服務的方式,也是在生產環境用的比較多的方式,一般在雲環境下是 LB + Ingress Ctroller 方式對外提供服務,這樣就可以在一個 LB 的情況下根據域名路由到對應后端的 Service,有點類似於 Nginx 反向代理,只不過在 k8s 集群中,這個反向代理是集群外部流量的統一入口。
 
Service 雖然解決了服務發現和負載均衡的問題,但對外訪問的時候,NodePort類型需要在外部搭建額外的負載均衡,而LoadBalancer需要Kubernetes必須跑在支持的cloud provider上面。 Ingress就是為了解決這些限制的。

Ingress 是一個規則的集合,它允許集群外的流量通過一定的規則到達集群內的 Service 。 request--->ingress--->service.

Ingress由三個組件組成:

1.反向代理負載均衡器:即常見的負載均衡軟件,如 nginx、Haproxy 等

2.Ingress Controller: kubernetes API 進行交互,實時的感知后端 service、pod 等變化, Ingress Controller 再結合下文的 Ingress 生成配置,然后更新反向代理負載均衡器,並刷新其配置,實現動態服務發現與更新

3.Ingress:規則集合;定義了域名與Kubernetes的service的對應關系;這個規則將與 Ingress Controller 結合, Ingress Controller 將其動態寫入到負載均衡器配置中,從而實現整體的服務發現和負載均衡。

四:Service Load Balancer
在Ingress出現以前,Service Load Balancer誰推薦的解決Service局限性的方式。Service Load Balancer將haproxy跑在容器中,並監控service和endpoint的變化,通過容器IP對外提供4層和7層負載均衡服務。

五:Custom Load Balancer
自定義組件,代替kube-proxy來做負載均衡。如nginx plus, kube2haproxy等。

六:Endpoints
有幾種情況需要用到沒有selector的service
1.使用kubernetes集群外部的數據庫時。
2.service中用到了其它namespace或kubernetes集群中的service
3.在kubernetes的工作負載與集群外的后端之間互相遷移。

 

1. kube-proxy 只允許本地訪問

2. NodePort 使用物理機端口和k8s service虛擬ip:端口 映射

3. LoadBalancer 使用NodeIp+Nodeport的方式實現, 配合雲環境GCE、aws提供的負載地址

4. ingress  使用開源的反向代理負載均衡器來實現對外暴漏服務,比如 Nginx、Apache、Haproxy

作者:莫逐
鏈接: https://www.jianshu.com/p/b02dd40a16da
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

7層負載均衡

負載均衡(LB)在微服務架構演進中具有非常重要的意義,可以說的內容有很多,這里僅僅討論四層和七層負載均衡的一些要點和區別,以便於對ingress的理解。所謂四層和七層負載均衡是按照網絡層次OSI來划分的負載均衡類型(也可以按照其他的規則來分類,比如:應用的地理結構),簡單來說:四層負載均衡表示負載均衡器用ip+port接收請求,再直接轉發到后端對應的服務上,工作在傳輸層( transport layer );七層負載均衡表示負載均衡器根據虛擬的url或主機名來接收請求,經過處理后再轉向相應的后端服務上,工作在應用層( application layer )。

下圖表示了4層和7層負載均衡在建立TCP連接上的區別,從圖中可以看出,四層負載均衡需要建立的TCP連接其實之有一個,它只做一次轉發,client直接和server連接;而7層負載均衡則需要建立兩次TCP連接,client到LB,LB根據消息中的內容( 比如URL或者cookie中的信息 )來做出負載均衡的決定,接着建立LB到server的連接。

 

layer4VSlayer7_LB.png

7層負載均衡有什么好處呢?

  • 因為存在解包/封包的過程,比4層LB更加CPUintensive,但是卻極少降低性能;
  • 可以編寫更加智能的負載均衡策略,比如根據URL、cookie中的信息等,甚至對接收到的內容做一些優化和修改,比如加密、壓縮;
  • 使用buffer的方式來緩解服務器連接慢的問題,從而提高性能
  • 具有7層負載均衡功能的設備通常也被稱為反向代理服務器(reverseproxy server)

反向代理

舉個例子:
正向代理:在使用VPS訪問的時候,通常會使用一個本地的代理服務器,瀏覽器的網絡包會先經過本地的代理服務器,代理服務器會通過遠在異國它鄉的電腦來訪問並返回消息;這就好比去附近的咖啡店要先問一下手機咖啡店在哪里一樣,手機就是一個正向代理服務器。
反向代理:當訪問的請求到達時,那邊也設置了一個代理服務器,它通過查看請求的URL,發現是想查找視頻內容,於時把消息轉給了視頻搜索服務器(過程是我亂說的),這就好比你去朋友家做客,開門的卻是個管家,問你找誰?這時候管家就是一個反向代理了。

其他OSI層也可以做反向代理

ingress

k8s 對外暴露服務(service)主要有兩種方式:NotePort, LoadBalance, 此外externalIPs也可以使各類service對外提供服務,但是當集群服務很多的時候,NodePort方式最大的缺點是會占用很多集群機器的端口;LB方式最大的缺點則是每個service一個LB又有點浪費和麻煩,並且需要k8s之外的支持; 而ingress則只需要一個NodePort或者一個LB就可以滿足所有service對外服務的需求。工作機制大致可以用下圖表示:

 

 

實際上,ingress相當於一個7層的負載均衡器,是k8s對反向代理的一個抽象。大概的工作原理也確實類似於Nginx,可以理解成在 Ingress 里建立一個個映射規則 , ingress Controller 通過監聽 Ingress這個api對象里的配置規則並轉化成 Nginx 的配置(kubernetes聲明式API和控制循環) , 然后對外部提供服務。ingress包括:ingress controller和ingress resources

ingress controller:核心是一個deployment,實現方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要編寫的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的類型可以是NodePort或者LoadBalancer。

ingress resources:這個就是一個類型為Ingress的k8s api對象了,這部分則是面向開發人員。

 

 使用 Ingress 對外暴露服務

為了快速體驗 Ingress,下面部署一個 nginx 服務,然后通過 Ingress 對外暴露 nginx service 進行訪問。
首先部署 nginx 服務:
Deployment + Service:nginx.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

kubectl create -f nginx.yml

接下來創建 Ingress 對外暴露 nginx service 80 端口:
ingress.yml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    # use the shared ingress-nginx
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.kube.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80

說明:
    kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根據該注解自動發現 Ingress;
    host: nginx.kube.com:對外訪問的域名;
    serviceName: nginx:對外暴露的 Service 名稱;
    servicePort: 80:nginx service 監聽的端口;

注意:創建的 Ingress 必須要和對外暴露的 Service 在同一命名空間下!
將域名 nginx.kube.com 綁定到 k8s 任意節點 ip 即可訪問:http://nginx.kube.com
上面的示例不支持 https 訪問,下面舉一個支持 https 的 Ingress 例子:通過 Ingress 訪問 kubernetes dashboard 服務。
通過 Ingress 訪問 kubernetes dashboard(支持 HTTPS 訪問)
之前我們使用 helm 以 nodePort 的方式部署了 kubernetes dashboard:「helm 部署 kubernetes-dashboard」,從集群外部只能通過 nodeIP:nodePort 端口號 訪問,接下來基於之前部署的 kubernetes-dashboard 配置如何通過 Ingress 訪問,並且支持 HTTPS 訪問,HTTP 自動跳轉到 HTTPS。 :
首先,練習使用,先用自簽名證書來代替吧:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout kube-dashboard.key -out kube-dashboard.crt -subj "/CN=dashboard.kube.com/O=dashboard.kube.com"

使用生成的證書創建 k8s Secret 資源,下一步創建的 Ingress 會引用這個 Secret:
kubectl create secret tls kube-dasboard-ssl --key kube-dashboard.key --cert kube-dashboard.crt -n kube-system
創建 Ingress 資源對象(支持 HTTPS 訪問):
kube-dashboard-ingress.yml


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-kube-dashboard
  annotations:
    # use the shared ingress-nginx
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  tls:
  - hosts:
    - dashboard.kube.com
    secretName: kube-dasboard-ssl
  rules:
  - host: dashboard.kube.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
kubectl create -f kube-dashboard-ingress.yml -n kube-system


說明:
    kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根據該注解自動發現 Ingress;
    nginx.ingress.kubernetes.io/backend-protocol: Controller 向后端 Service 轉發時使用 HTTPS 協議,這個注解必須添加,否則訪問會報錯,可以看到 Ingress Controller 報錯日志:kubectl logs -f nginx-ingress-controller-mg8df

    2019/08/12 06:40:00 [error] 557#557: *56049 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: 192.168.26.10, server: dashboard.kube.com, request: “GET / HTTP/1.1”, upstream: “http://10.244.1.8:8443/”, host: “dashboard.kube.com”

報錯原因主要是 dashboard 服務后端只支持 https,但是 Ingress Controller 接到客戶端的請求時往后端 dashboard 服務轉發時使用的是 http 協議,解決辦法就是給 創建的 Ingress 設置:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 注解。解決方法參考自 StackOverflow:https://stackoverflow.com/questions/48324760/ingress-configuration-for-dashboard

    secretName: kube-dasboard-ssl:https 證書 Secret;
    host: dashboard.kube.com:對外訪問的域名;
    serviceName: kubernetes-dashboard:集群對外暴露的 Service 名稱;
    servicePort: 443:service 監聽的端口;

    注意:創建的 Ingress 必須要和對外暴露的 Service 在同一命名空間下!
將域名 dashboard.kube.com 綁定到 k8s 任意節點 ip 即可訪問:https://dashboard.kube.com

7層負載均衡

負載均衡(LB)在微服務架構演進中具有非常重要的意義,可以說的內容有很多,這里僅僅討論四層和七層負載均衡的一些要點和區別,以便於對ingress的理解。所謂四層和七層負載均衡是按照網絡層次OSI來划分的負載均衡類型(也可以按照其他的規則來分類,比如:應用的地理結構),簡單來說:四層負載均衡表示負載均衡器用ip+port接收請求,再直接轉發到后端對應的服務上,工作在傳輸層( transport layer );七層負載均衡表示負載均衡器根據虛擬的url或主機名來接收請求,經過處理后再轉向相應的后端服務上,工作在應用層( application layer )。

下圖表示了4層和7層負載均衡在建立TCP連接上的區別,從圖中可以看出,四層負載均衡需要建立的TCP連接其實之有一個,它只做一次轉發,client直接和server連接;而7層負載均衡則需要建立兩次TCP連接,client到LB,LB根據消息中的內容( 比如URL或者cookie中的信息 )來做出負載均衡的決定,接着建立LB到server的連接。

layer4VSlayer7_LB.png

7層負載均衡有什么好處呢?

  • 因為存在解包/封包的過程,比4層LB更加CPU‑intensive,但是卻極少降低性能;
  • 可以編寫更加智能的負載均衡策略,比如根據URL、cookie中的信息等,甚至對接收到的內容做一些優化和修改,比如加密、壓縮;
  • 使用buffer的方式來緩解服務器連接慢的問題,從而提高性能
  • 具有7層負載均衡功能的設備通常也被稱為反向代理服務器(reverse‑proxy server)

反向代理

舉個例子:
正向代理:在使用VPS訪問Google的時候,通常會使用一個本地的代理服務器,瀏覽器的網絡包會先經過本地的代理服務器,代理服務器會通過遠在異國它鄉的電腦來訪問Google並返回消息;這就好比去附近的咖啡店要先問一下手機咖啡店在哪里一樣,手機就是一個正向代理服務器。
反向代理:當訪問的請求到達Google時,Google那邊也設置了一個代理服務器,它通過查看請求的URL,發現是想查找視頻內容,於時把消息轉給了視頻搜索服務器(過程是我亂說的),這就好比你去朋友家做客,開門的卻是個管家,問你找誰?這時候管家就是一個反向代理了。
關於反向代理的好處這里就不多介紹,感興趣可以看這里

其他OSI層也可以做反向代理

ingress

k8s 對外暴露服務(service)主要有兩種方式:NotePort, LoadBalance, 此外externalIPs也可以使各類service對外提供服務,但是當集群服務很多的時候,NodePort方式最大的缺點是會占用很多集群機器的端口;LB方式最大的缺點則是每個service一個LB又有點浪費和麻煩,並且需要k8s之外的支持; 而ingress則只需要一個NodePort或者一個LB就可以滿足所有service對外服務的需求。工作機制大致可以用下圖表示:

ingress.png

實際上,ingress相當於一個7層的負載均衡器,是k8s對反向代理的一個抽象。大概的工作原理也確實類似於Nginx,可以理解成在 Ingress 里建立一個個映射規則 , ingress Controller 通過監聽 Ingress這個api對象里的配置規則並轉化成 Nginx 的配置(kubernetes聲明式API和控制循環) , 然后對外部提供服務。ingress包括:ingress controller和ingress resources

ingress controller:核心是一個deployment,實現方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要編寫的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的類型可以是NodePort或者LoadBalancer。

ingress resources:這個就是一個類型為Ingress的k8s api對象了,這部分則是面向開發人員。

假設已經有兩個服務部署在了k8s集群內部:

$ kubectl get svc,deploy NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/coffee-svc ClusterIP <none> <none> 80/TCP 1m svc/tea-svc ClusterIP <none> <none> 80/TCP 1m NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deploy/coffee 2 2 2 2 1m deploy/tea 1 1 1 1 1m 
作者:MunCN
鏈接:https://www.jianshu.com/p/97dd4d59ac5a
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

對外服務方式

1. kube-proxy 只允許本地訪問

2. NodePort 使用物理機端口和k8s service虛擬ip:端口 映射

3. LoadBalancer 使用NodeIp+Nodeport的方式實現, 配合雲環境GCE、aws提供的負載地址

4. ingress  使用開源的反向代理負載均衡器來實現對外暴漏服務,比如 Nginx、Apache、Haproxy等

作者:莫逐
鏈接:https://www.jianshu.com/p/b02dd40a16da
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

對外服務方式

1. kube-proxy 只允許本地訪問

2. NodePort 使用物理機端口和k8s service虛擬ip:端口 映射

3. LoadBalancer 使用NodeIp+Nodeport的方式實現, 配合雲環境GCE、aws提供的負載地址

4. ingress  使用開源的反向代理負載均衡器來實現對外暴漏服務,比如 Nginx、Apache、Haproxy等

作者:莫逐
鏈接:https://www.jianshu.com/p/b02dd40a16da
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM