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 只容許本地訪問node

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

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 )。api

下圖表示了4層和7層負載均衡在創建TCP鏈接上的區別,從圖中能夠看出,四層負載均衡須要創建的TCP鏈接其實之有一個,它只作一次轉發,client直接和server鏈接;而7層負載均衡則須要創建兩次TCP鏈接,client到LB,LB根據消息中的內容( 好比URL或者cookie中的信息 )來作出負載均衡的決定,接着創建LB到server的鏈接。瀏覽器

 

layer4VSlayer7_LB.pngbash

7層負載均衡有什麼好處呢?服務器

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

反向代理

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

其餘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
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索