Serverless之Knative部署应用示例(二)

1.什么是Knative?

  1. Knative是Google2018的Google Cloud Next大会上发布的一款基于kubernetes的Serverless框架。Knative 最初由 Google 打造,现在有 50 多家不同公司向其贡献过代码。它提供了一组必备组件,用于在 Kubernetes 上构建和运行无服务器应用。Knative 为 Kubernetes 上的云原生应用提供缩减至零、自动扩缩、集群内构建以及事件框架等功能。无论是在本地、云端还是第三方数据中心,Knative 都可以应用来源于实践中基于 Kubernetes 的成功框架的标准化最佳实践。最重要的是,Knative 使开发者能够专注于编写代码,而无需担心构建、部署和管理应用等“单调而棘手”的工作。
  2. knative的目的是在kubernetes之上提供一个简单、一致的层,以解决在开发人员和平台之间创建更牢固的边界,使得开发人员可以专注他们的业务逻辑。knative是建立在kubernetes和Istio平台之上的,使用了kubernetes提供的容器管理组件(deployment、service、Pod、ConfigMap等)以及Istio提供的网络管理组件(Ingress、LB);
  3. Knative中有两个重要的组件,分别是为其提供流量的Serving(服务)组件以及确保应用程序能够轻松消费事件的Eventing组件;
  4. 部署、升级和路由。
    应用部署应该是全部部署或者全部不部署吗?knative支持渐进式交付,并不是所有的HTTP请求都会到达生产环境系统中的一个软件版本上,而是所有的HTTP请求都会到达整个分布式系统上,由该软件的多个版本共同响应,在系统中可以同时运行多个版本,并在这些版本之间分配流量,这意味着部署可以按请求而不是实例的粒度进行;
  5. 自动扩/缩容
    系统中的流量是不固定的,有时没有流量,有时候流量过大,当没有流量时,系统的部分资源是浪费的,当流量过大时,系统就会承受过大的压力。Knative使用Knative Pod自动缩放器(KPA)进行扩/缩容,它是一种基于请求指标的自动缩放器,已与Knative的路由、缓冲和指标组件深度集成。自动缩放器无法解决所有问题,但是可以解决大部分流量的问题。
  6. 对开发者友好的软件
    Knative 提供了一组可重用的组件,专用于解决许多单调而棘手的任务,例如构建应用(从源代码到容器映像)、部署期间的流量路由和管理、自动扩缩工作负载,或者将正在运行的服务绑定到不断扩大的事件来源生态系统等工作流。Knative 将容器映像视为部署单元。因此,开发者可以使用他们熟悉的任何语言、框架或风格。
  7. 支持的开发模式
    Knative 遵循开发者习惯。它支持常见的开发模式,如 GitOps、DockerOps、ManualOps,以及 Django、Ruby on Rails、Spring 等各种工具和框架。
    Knative 旨在供您轻松嵌入现有构建工具链和持续集成/持续交付工具链。利用以 Kubernetes 为基石且可在任何位置、任何云和任何基础架构上运行的开源优先技术,企业可以自由地将工作负载转移到最适合的地方。这为客户提供了调整系统以适应其独特需求的灵活性和可控性。
    Knative 提供了一种开放式 API 和运行时环境,可让您选择在以下任何位置运行无服务器工作负载:Google Cloud 上的全托管式环境中、Google Kubernetes Engine (GKE) 上的 Anthos 中或者您自己的 Kubernetes 集群中。Knative 可让您先从 Cloud Run 轻松起步,然后迁移到 Cloud Run for Anthos;或者先在您自己的 Kubernetes 集群中运行,并在将来迁移到 Cloud Run。通过将 Knative 用作底层平台,您可以跨平台自由转移工作负载,同时显著降低转换费用。
    image

2.什么是Serving?

2.1Serving服务

  1. Serving模块提供了一组特定的对象,包括Service(服务)、Configuration(配置)、Revision(修订版本)、Route(路由)。Knative通过kubernetes CRD(自定义资源)的方式实现了这些对象。
    image
  2. 在kubernetes创建一个应用的时候需要定义什么?
    APP->Deployment->Service->ConfigMap->Secrets甚至我们还需要定义一个Ingress;但是在Knative当中,一个Service就可以搞定。这里的Service不是kubernetes的Service,而是Knative中的service,可以简写为kvc,在资源规范里可以看见;
[root@knative-k8s-master-139 ~]# kubectl api-resources | grep "knative"
services                          kservice,ksvc   serving.knative.dev/v1                      true         Service
  1. 创建一个Service(kservice)的时候会自动生成一个Configuration,基于Configuration创建Revision,再创建Route,客户端请求的流量也是由Route发给Revision;

2.2Serving组件;

  1. Configuration: 配置是待运行软件的期望状态,包含所需的容器镜像、环境变量等详细信息。Knative将此信息转换为底层的Kubernetes概念,例如部署。实际上,那些熟悉kubernetes的人可能知道Knative到底在做什么。即使没有Knative,开发人员也可以自己创建和提交一个部署;

  2. Revision: 修订版本是配置的快照,每次更改配置时,Knative都会创建一个修订版本,实际上修订版本还会转换为底层Kubernetes资源。如果单纯只是保存修订版本,则有些浪费资源,毕竟Git就可以进行版本控制,为什么用Knative?因为Knative并不只是支持蓝/绿部署,实际上,Knative还支持多版本之间更详细的流量配置规则;

  3. Route: Knative中的Route提供了一种将流量路由到正在运行代码的机制,它将一个HTTP可寻端点映射到一个或者多个Revision。可以做流量的切割和金丝雀发布;

3.部署一个应用;

3.1安装Knative的CLI

  1. 这里已经确保安装了kn,kn是Knative的"官方"客户端,但它不是官方的第一个客户端。在kn出现之前,Knative已经有了很多可选的客户端,比如knctl。这些工具有助于探索Knative客户端的不同使用体验;
  2. kn有两个作用。(1)客户端本身是专门给Knative设计的,你不需要详细了解kubectl;kn淘汰了Knative的Golang API,让knative的Golang API尽在其他使用Go语言编写的和Knative交互的工具使用;
  3. Knative CLI官方文档:https://knative.dev/docs/client/
  4. 我的上一篇博文有部署文档Knative Serving安装

3.2部署一个简单的应用

在这里你必须有一个kubernetes集群并且安装了Knative;安装部署文档在我上篇博客有说明;

3.2.1使用kn创建服务;

  1. 部署hello world实例;
# 可以使用--help来查看如何部署;
[root@knative-k8s-master-139 ~]# kn service --help
[root@knative-k8s-master-139 ~]# kn service  create --help


# 
[root@knative-k8s-master-139 ~]# kn service create helloworld-example \  # name就叫做hello-example; 
--image gcr.io/knative-samples/helloworld-go \  # 引用的容器镜像,使用knative提供的简单应用;
--env TRAGET="First"    # 注入示例应用需要的环境变量;
Creating service 'helloworld-example' in namespace 'default':  # 未指定namespace,在默认的default名称空间下;

  0.042s The Route is still working to reflect the latest desired specification.
  0.050s ...
  0.090s Configuration "helloworld-example" is waiting for a Revision to become ready.
575.648s ...
575.679s Ingress has not yet been reconciled.
575.748s Waiting for load balancer to be ready
575.951s Ready to serve.

Service 'helloworld-example' created to latest revision 'helloworld-example-00001' is available at URL:
http://helloworld-example.default.example.com
  1. 通过kn service list来查看;
[root@knative-k8s-master-139 ~]# kn service list
NAME                 URL                                             LATEST                     AGE   CONDITIONS   READY   REASON

helloworld-example   http://helloworld-example.default.example.com   helloworld-example-00001   12h   3 OK / 3     True 

3.2.2观察knative到底做了什么?

1.首先它给我们创建了一个deployment,我们可以看到此时的Pod Ready是处于0的,这是Knative独有的冷启动,在后续会说明;

[root@knative-k8s-master-139 ~]# kubectl get deploy
NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
helloworld-example-00001-deployment   0/0     0            0           12h
tools-test                            1/1     1            1           12h

2.为我们创建了一个Service,所有的SVC都是要注册到isto-ingressgateway上面的。它提供了一个外部访问入口和一个集群内部的访问入口;Knative只需要某种入口网关的功能,而不需要网格功能;
路由流量始终是无法避免的事物之一,在系统的边界处的某个地方会遇到流量,在knative中,这个地方就是流量入口。
流量入口控制器(ingress controller)是整个knative系统的唯一入口,这些控制器会把knative抽象的路由信息转换为为其所需的路由结构的特定配置,例如,默认的network-istio控制器会把knative流量入口配置转换为istio网关;

[root@knative-k8s-master-139 ~]# kubectl get svc
helloworld-example                 ExternalName   <none>          knative-local-gateway.istio-system.svc.cluster.local   80/TCP

3.我们为什么看不见创建的Pod呢?因为在没有人访问的情况下,Pod是无法启动会被置为0的状态;这就是Knative的KPA,Pod缩放至0;

[root@knative-k8s-master-139 ~]# kubectl get pods
NAME                          READY   STATUS      RESTARTS   AGE
tools-test-8444596cb5-rvpf9   1/1     Running     0          12h

3.2.3应用测试访问;

1.我们启动一个终端访问这个Service是没有问题的;

[root@tools-test-8444596cb5-rvpf9 /]# curl helloworld-example.default.svc
Hello World!
[root@tools-test-8444596cb5-rvpf9 /]#  while true; do curl --connect-timeout 1 helloworld-example.default; sleep .2; done
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!

2.我们观察Pod的状态与deploy的状态,当我们持续访问的时候,Pod是会被拉起的;

[root@knative-k8s-master-139 ~]# kubectl get deploy
NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
helloworld-example-00001-deployment   1/1     1            1           12h
tools-test                            1/1     1            1           12h

[root@knative-k8s-master-139 ~]# kubectl get pods
helloworld-example-00001-deployment-7787f5cf4f-rfwhb   2/2     Running     0          12s
tools-test-8444596cb5-rvpf9                            1/1     Running     0          12h
posted @ 2022-08-05 11:44  梨花海棠  阅读(292)  评论(0编辑  收藏  举报