多個web服務接入共享ingressgateway

吳德寶AllenWu發表於2018-10-19

[TOC]

多個web服務接入共享ingressgateway

背景

共享ingressgateway

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

因此,一個ingressgateway就需要支撐不同的業務接入,對於ingressgateway來說,Gateway資源配置為同一個埠,同一種協議,然後只要對應的VirtualService中配置不同的hosts,最後通過VirtualService的hosts路由到不同的服務就能解決。

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

統一域名訪問

另外一塊在於統一的域名姿勢訪問,在K8S內部,建立Service的時候會預設給kube-DNS裡面新增一條記錄,然後可以通過服務名在Pod裡面訪問其他服務。

但是如果希望能夠自定義域名,保持接入容器、接入istio和沒有接入istio都有著同樣的訪問姿勢的話,就需要能夠自定義域名,當然,這個自定義域名必須首先能夠解析,kube-DNS可以配置私有DNS和上游域名伺服器,並且我們自己在K8S叢集中針對這塊DNS有做相關優化

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

如果是其他特殊的自定義域名,那麼需要運維手動配置,也是通過dnsPod和bind9,然後最後還是解析LVS上,然後進行7層路由

接入Istio後,要想還是保持原有統一域名的訪問方式,那麼這個自定義域名,同樣需要解析,並且解析到LVS,LVS下面就是istio的ingress gateway,然後通過host進行路由。因此client請求http處理的時候,需要攜帶Host用來進行路由。

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

然後再一點就是在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路由到了不同的後端服務

相關文章