Knative 基本功能深刻剖析:Knative Serving 之服务路由管理

导读:本文主要围绕 Knative Service 域名展开,介绍了 Knative Service 的路由管理。文章首先介绍了如何修改默认主域名,紧接着深刻一层介绍了如何添加自定义域名以及如何根据 path 关联到不一样的 Knative Service 。指望经过本文的介绍,可以帮助您了解更多相关内容。web

Knative 默认会为每个 Service 生成一个域名,而且 Istio Gateway 要根据域名判断当前的请求应该转发给哪一个 Knative Service。Knative 默认使用的主域名是 example.com,这个域名是不能做为线上服务的。json

Knative Serving 的默认域名 example.com

首先须要部署一个 Knative Service,能够参考 Knative 初体验:Serving Hello World后端

若是你已经有了一个 Knative 集群,那么直接把下面的内容保存到 helloworld.yaml 文件中。而后执行一下 kubectl apply -f helloworld.yaml  便可把 hello 服务部署到 helloworld namespace 中。api

---
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 就能访问服务了。websocket

  • 首先获取到 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 才行。这种方式还不能对外提供服务。app

配置自定义主域名

下面介绍一下如何把默认的 example.com 改为咱们本身的域名,假设咱们本身的域名是:serverless.kuberun.com,如今执行 kubectl edit cm config-domain --namespace knative-serving ,以下图所示,添加 serverless.kuberun.com 到 ConfigMap 中,而后保存退出就完成了自定义主域名的配置。less

再来看一下 Knative Service 的域名, 以下所示已经生效了。dom

└─# 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 上面去。若是你是在阿里云(万网)上面购买的域名,你能够经过以下方式配置域名解析:curl


如今直接经过浏览器访问 http://hello.helloworld.serverless.kuberun.com/ 就能够直接看到 helloworld 服务了:

自定义服务域名

刚才咱们给 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:
 - 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 配置,提供生产级别的服务路由。

欢迎加入 Knative 交流群

相关文章
相关标签/搜索