Knative Serving 之路由管理和 Ingress

Knative 默認會爲每個 Service 生成一個域名,而且 Istio Gateway 要根據域名判斷當前的請求應該轉發給哪一個 Knative Service。Knative 默認使用的主域名是 example.com,這個域名是不能做爲線上服務的。本文我首先介紹一下如何修改 默認主域名,而後再深刻一層介紹如何添加自定義域名以及如何根據 path 關聯到不一樣的 Knative Service。web

Knative Serving 的默認域名 example.com

首先須要部署一個 Knative Service。若是你已經有了一個 Knative 集羣,那麼直接把下面的內容保存到 helloworld.yaml 文件中。而後執行一下 kubectl apply -f helloworld.yaml  便可把 hello 服務部署到 helloworld namespace 中。json

---
apiVersion: v1
kind: Namespace
metadata:
  name: helloworld

---
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: hello
  namespace: helloworld
spec:
  template:
    metadata:
      labels:
        app: hello
      annotations:
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/simple-app:132e07c14c49
          env:
            - name: TARGET
              value: "World!"

如今咱們來看一下 Knative Service 自動生成的域名配置:後端

└─# kubectl -n helloworld get ksvc
NAME    URL                                   LATESTCREATED   LATESTREADY   READY   REASON
hello   http://hello.helloworld.example.com   hello-wsnvc     hello-wsnvc   True

如今使用 curl 指定 Host 就能訪問服務了。api

  • 首先獲取到 Istio Gateway IP
└─# kubectl get svc istio-ingressgateway --namespace istio-system --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"
47.95.191.136
  • 訪問 hello 服務
└─# curl -H "Host: hello.helloworld.example.com" http://47.95.191.136/
Hello World!!

若是想要在瀏覽器中訪問 hello 服務須要先作 host 綁定,把域名 hello.helloworld.example.com 指向 47.95.191.136 才行。這種方式還不能對外提供服務。瀏覽器

使用自定義主域名

下面我來介紹一下如何把默認的 example.com 改爲咱們本身的域名,假設咱們本身的域名是:serverless.kuberun.com,如今執行 kubectl edit cm config-domain --namespace knative-serving 以下圖所示,添加 serverless.kuberun.com 到 ConfigMap 中,而後保存退出就完成了自定義主域名的配置。websocket

再來看一下 Knative Service 的域名, 以下所示已經生效了。app

└─# kubectl -n helloworld get ksvc
NAME    URL                                              LATESTCREATED   LATESTREADY   READY   REASON
hello   http://hello.helloworld.serverless.kuberun.com   hello-wsnvc     hello-wsnvc   True

泛域名解析
Knative Service 默認生成域名的規則是 servicename.namespace.use-domain 。因此不一樣的 namespace 會生成不一樣的子域名,每個 Knative Service 也會生成一個惟一的子域名。爲了保證全部的 Service 服務都能在公網上面訪問到,須要作一個泛域名解析。把 *.serverless.kuberun.com 解析到 Istio Gateway 47.95.191.136 上面去。若是你是在阿里雲(萬網)上面購買的域名,你能夠經過以下方式配置域名解析:less

如今直接經過瀏覽器訪問 http://hello.helloworld.serverless.kuberun.com/ 就能夠直接看到 helloworld 服務了:dom

## 自定義服務域名
剛纔咱們給 Knative 指定了一個主域名,使得 Service 基於主域名生成本身的惟一域名。但自動生成的域名不是很友好,好比剛纔部署的 helloworld 的域名 hello.helloworld.serverless.kuberun.com對於普通用戶來講意義不明顯、很差記憶。
若是能經過 hello.kuberun.com 訪問 hello world 服務那就完美了,接下來我來介紹實現方法:curl

  • 先在萬網上面修改域名解析,把 hello.kuberun.com 的 A 記錄指向 Istio Gateway 47.95.191.136 

  • hello.kuberun.com 解析到 Istio Gateway 之後 Istio Gateway 並不知道此應該轉發到哪一個服務,因此還須要配置 VirtualService 告知 Istio 如何轉發,把下面的內容保存到 hello-ingress-route.yaml 文件:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
    name: hello-ingress-route
    namespace: knative-serving
    spec:
    gateways:
    - knative-ingress-gateway
    hosts:
    - hello.helloworld.serverless.kuberun.com
    - hello.kuberun.com
    http:
    - match:
     - uri:
         prefix: "/"
     rewrite:
       authority: hello.helloworld.svc.cluster.local
     retries:
       attempts: 3
       perTryTimeout: 10m0s
     route:
     - destination:
         host: istio-ingressgateway.istio-system.svc.cluster.local
         port:
           number: 80
       weight: 100
     timeout: 10m0s
     websocketUpgrade: true

    如今打開 http://hello.kuberun.com/ 就能看到 helloworld 服務了:

基於路徑的服務轉發
真實線上服務的場景多是一個路徑後端對應着一個應用,如今咱們對剛纔的 hello.kuberun.com 進行一下擴展。讓 /blog 開頭的路徑映射到 blog service,其餘的路徑仍是原樣打到 hello service 上面。
把下面的內容保存到 blog.yaml 文件,而後執行:  kubectl apply -f blog.yaml 便可完成 blog 服務的部署。

---
apiVersion: v1
kind: Namespace
metadata:
 name: blog

---
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
 name: hello-blog
 namespace: blog
spec:
 template:
   metadata:
     labels:
       app: hello
     annotations:
       autoscaling.knative.dev/target: "10"
   spec:
     containers:
       - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/simple-app:132e07c14c49
         env:
           - name: TARGET
             value: "Blog!"

查看 blog 服務的默認域名:

└─# kubectl -n blog get ksvc
NAME    URL                                        LATESTCREATED   LATESTREADY   READY   REASON
hello   http://hello-blog.blog.serverless.kuberun.com   hello-zbm7q     hello-zbm7q   True

如今使用瀏覽器打開 http://hello-blog.blog.serverless.kuberun.com 就能夠訪問剛剛部署的服務了:

這是默認域名,咱們的需求是想要經過 http://hello.kuberun.com/blog 訪問, 因此還須要修改 Istio VirtualService 的配置。以下所示在 hello-ingress-route.yaml 增長 /blog 的配置:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-ingress-route
  namespace: knative-serving
spec:
  gateways:
  - knative-ingress-gateway
  hosts:
  - hello.helloworld.serverless.kuberun.com
  - hello.kuberun.com
  http:
  - match:
    - uri:
        prefix: "/blog"
    rewrite:
      authority: hello-blog.blog.svc.cluster.local
    retries:
      attempts: 3
      perTryTimeout: 10m0s
    route:
    - destination:
        host: istio-ingressgateway.istio-system.svc.cluster.local
        port:
          number: 80
      weight: 100
  - match:
    - uri:
        prefix: "/"
    rewrite:
      authority: hello.helloworld.svc.cluster.local
    retries:
      attempts: 3
      perTryTimeout: 10m0s
    route:
    - destination:
        host: istio-ingressgateway.istio-system.svc.cluster.local
        port:
          number: 80
      weight: 100
    timeout: 10m0s
    websocketUpgrade: true

如今就能在瀏覽器中打開 http://hello.kuberun.com/blog 以下所示:

小結

本文主要圍繞 Knative Service 域名展開介紹了 Knative Service 的路由管理。您應該瞭解到以下內容:

  • Knative Service 默認的主域名是 example.com, 全部 Knative Service 生成的獨立域名都是這個主域名的子域名
  • Knative Service 生成的域名規範
  • 如何配置 Knative Service 使用自定義的主域名,以及如何配置公網域名解析
  • 如何基於 Istio VirtualService 實現 Knative Service 的個性化 Ingress 配置,提供生產級別的服務路由


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索