Knative Serving 之路由管理和 Ingress

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

Knative Serving 的默認域名 example.com

首先須要部署一個 Knative Service,能夠參考 Knative 初體驗:Serving Hello World。若是你已經有了一個 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

泛域名解析less

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

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

自定義服務域名

剛纔咱們給 Knative 指定了一個主域名,使得 Service 基於主域名生成本身的惟一域名。但自動生成的域名不是很友好,好比剛纔部署的 helloworld 的域名 hello.helloworld.serverless.kuberun.com對於普通用戶來講意義不明顯、很差記憶。

若是能經過 hello.kuberun.com 訪問 hello world 服務那就完美了,接下來我來介紹實現方法:

  • 先在萬網上面修改域名解析,把 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:
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/](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fhello.kuberun.com%2F) 就能看到 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 配置,提供生產級別的服務路由



本文做者:冬島

閱讀原文

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

相關文章
相關標籤/搜索