多個web服務接入共享ingressgateway

[TOC]web

多個web服務接入共享ingressgateway

背景

共享ingressgateway

首先,對ingressgateway而言,目前業界一致的作法就是共享ingressgateway,這個對於前期來看,也是足夠了,只是須要保證ingressgateway不能單點,而且ingressgateway能夠部署多個進行負載均衡。後端

所以,一個ingressgateway就須要支撐不一樣的業務接入,對於ingressgateway來講,Gateway資源配置爲同一個端口,同一種協議,而後只要對應的VirtualService中配置不一樣的hosts,最後經過VirtualService的hosts路由到不一樣的服務就能解決。api

外部統一的入口訪問,指定不一樣hosts,而後VirtualService會有不一樣的路由規則,不衝突~bash

統一域名訪問

另一塊在於統一的域名姿式訪問,在K8S內部,建立Service的時候會默認給kube-DNS裏面添加一條記錄,而後能夠經過服務名在Pod裏面訪問其餘服務。服務器

可是若是但願可以自定義域名,保持接入容器、接入istio和沒有接入istio都有着一樣的訪問姿式的話,就須要可以自定義域名,固然,這個自定義域名必須首先可以解析,kube-DNS能夠配置私有DNS和上游域名服務器,而且咱們本身在K8S集羣中針對這塊DNS有作相關優化微信

現有K8S集羣中,建立service的時候給定的這個默認的自定義域名,會寫到機房的bind9中,也同時會寫到咱們外部的DNS解析服務器中,這樣,這個域名就能夠在集羣內和集羣外都可以解析訪問。這個域最終會解析到LVS上,而後LVX下面就是ingress,也就是七層的負載均衡器,而後經過七層進行路由。app

若是是其餘特殊的自定義域名,那麼須要運維手動配置,也是經過dnsPod和bind9,而後最後仍是解析LVS上,而後進行7層路由負載均衡

接入Istio後,要想仍是保持原有統一域名的訪問方式,那麼這個自定義域名,一樣須要解析,而且解析到LVS,LVS下面就是istio的ingress gateway,而後經過host進行路由。所以client請求http處理的時候,須要攜帶Host用來進行路由。運維

這一點上,和K8S現有的域名管理姿式保持一致,只是自定義域名解析的LVS不一樣,一個LB的LVS,一個istio ingressgateway的LVS。curl

而後再一點就是在istio中,須要經過是VirtualService來配置路由,路由的區分是要經過hosts來區分

方案&實操

在MAC 本機上進行驗證

ingressgateway

kubectl get svc -n istio-system  |grep istio-ingressgateway 

istio-ingressgateway       NodePort    10.233.13.102   <none>        80:31380/TCP,443:31390/TCP,8081:31381/TCP,31499:31499/TCP,31400:31400/TCP,15011:32636/TCP,8060:32041/TCP,15030:31210/TCP,15031:32538/TCP   25d
複製代碼

對於服務一:

hello-web 服務

1,服務一的部署配置以下:

apiVersion: v1
kind: Service
metadata:
  name: hello-web
  labels:
    app: hello-web
spec:
  ports:
  - name: http-web
    port: 12345
  selector:
    app: hello-web
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-web-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-web
        version: v1
    spec:
      containers:
      - name: hello-web
        image: wudebao5220150/webserver:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 12345
---
複製代碼

kubectl apply -f <(istioctl kube-inject -f hello-web.yaml)

2,網關和路由的配置以下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: hello-web-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*.hello-web.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-web
spec:
  hosts:
  - "www.hello-web.com"
  gateways:
  - hello-web-gateway
  http:
  - match:
    - uri:
        exact: /hello
    route:
    - destination:
        port:
          number: 12345
        host: hello-web
複製代碼

kubectl apply -f hello-web-gateway.yaml

hosts爲www.hello-web.com的請求,會路由到指定的http的match上。這裏是入口,入口以後的路由,經過hosts進行區分,而後具體到下游Cluster的詳盡規則由http的match去實現

對於服務二:

wudebao-web 服務

1,服務二的部署配置以下:

apiVersion: v1
kind: Service
metadata:
  name: wudebao-web
  labels:
    app: wudebao-web
spec:
  ports:
  - name: http-web
    port: 54321
  selector:
    app: wudebao-web
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wudebao-web
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: wudebao-web
        version: v1
    spec:
      containers:
      - name: wudebao-web
        image: wudebao5220150/webserver-v2:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 54321
複製代碼

kubectl apply -f <(istioctl kube-inject -f wudebao-web.yaml)

2,網關和路由的配置以下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: wudebao-web-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*.wudebao-web.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: wudebao-web
spec:
  hosts:
  - "www.wudebao-web.com"
  gateways:
  - wudebao-web-gateway
  http:
  - match:
    - uri:
        exact: /wudebao
    route:
    - destination:
        port:
          number: 54321
        host: wudebao-web
複製代碼

kubectl apply -f wudebao-web-gateway.yaml

hosts爲www.wwudebao-web.com的請求,會路由到指定的http的match上。這裏是入口,入口以後的路由,經過hosts進行區分,而後具體到下游Cluster的詳盡規則由http的match去實現

關鍵點說明:

  1. Gateway的servers的port要特別注意處理好,number和name不能隨便定義,name有固定格式,number是要在ingressgateway真實配置好的

  2. VirtualService的spec下的hosts,須要指定,能夠任意指定就好比能夠是真實域名

    • 這個host設置爲和訪問的域名同樣,而後client進行http請求的時候帶上host,而後就能夠經過host路由
    • 同時須要可以保證k8s可以解析這個自定義域名
  3. VirtualService的route的destination的host,是真正要路由到cluster的服務

    • 通常能夠直接採用服務名,若是是同一個namespace下
    • 最好FQDN,寫上徹底限定域名
  4. 若是隻是ingressgateway,服務能夠不用Sidecar,外部請求可以訪問,可是不能應用到istio的一些針對服務的路由策略和規則

    • 所以,部署的時候,仍是得Sidecar注入envoy代理才行

最終訪問:

IP:Port同樣,Host和URI不一樣,經過Host路由到不一樣的Service上:

curl 172.31.36.68:31380/hello -H "Host: www.hello-web.com"  -v

curl 172.31.36.68:31380/wudebao -H "Host: www.wudebao-web.com"  -v

複製代碼

這樣同時知足多個web服務的接入請求,不一樣host路由到了不一樣的後端服務

【"歡迎關注個人微信公衆號:Linux 服務端系統研發,後面會大力經過微信公衆號發送優質文章"】

個人微信公衆號
相關文章
相關標籤/搜索