Knative是什么?

Knative是一个开源的Kubernetes扩展平台,用于简化构建和运行现代云原生应用程序,特别是无服务器应用。它基于Kubernetes和Istio,提供了用于处理容器化应用的管理、部署、自动伸缩等功能。

能做什么?

Knative能够自动进行无服务器部署,支持事件驱动的编程模型,提供自动伸缩、自动负载均衡、按需扩展等功能。此外,它还能帮助开发者在Kubernetes上运行容器应用,无论是短生命周期的服务、微服务,还是传统的持久化应用。

相关组件

Knative Serving: 它的主要功能是自动管理容器化应用的部署、扩展和路由。当你部署一个 Web 服务或 API 时,Serving 会根据流量自动扩缩容(可以缩到零),并通过自动生成的 URL 将请求路由到你的应用。它解决的问题是"我想运行一个应用,但不想手动管理它的扩缩容和网络配置"。

Knative Eventing: 它提供了一套机制来产生、消费和路由事件。Eventing 允许不同的服务通过事件进行解耦通信——一个服务可以发送事件(比如"用户上传了文件"),其他服务可以订阅这个事件并做出反应。它支持多种事件源(如 Kafka、RabbitMQ、Webhook 等)和事件处理方式(如 Trigger 规则、Channel 等)。它解决的问题是"我有多个微服务需要通过事件进行异步协作,但不想自己构建复杂的事件管理基础设施"。

安装knative-serving

如果你的无服务函数是独立的、只需要处理 HTTP 请求,不需要与其他函数进行异步通信或事件交互,那么只安装 Serving 就足够了

本文介绍如何在三节点的kubernetes集群上部署knative-serving

集群配置
节点名称角色CPU内存Kubernetes版本
masterMaster2核4GB1.31.12
node1Worker2核4GB1.31.12
node2Worker2核4GB1.31.12

kubernetes版本与knative版本兼容性:本文kubernetes版本为1.31.12,最新的knative1.19.x版本要求kubernetes版本至少为1.32。故本文安装knative1.18.2版本。

下载YAML文件并部署

下载knative相关的crds和core文件:

https://github.com/knative/serving/releases/download/knative-v1.18.2/serving-crds.yaml
https://github.com/knative/serving/releases/download/knative-v1.18.2/serving-core.yaml

首先部署crds定义crd资源

kubectl apply -f serving-crds.yaml

部署core资源

kubectl apply -f serving-cores.yaml

命名空间knative-serving下所有pod均正常运行即可。

部署kourier(knative的网络层插件)

Kourier 是一个轻量级的 Kubernetes Ingress 控制器,用于在 Knative Serving 中处理流量路由。它是Knative的默认网络代理,负责将外部请求路由到正确的 Knative 服务,并提供流量管理功能,如路由、负载均衡等。Kourier通常与Knative Serving一起使用,能够在无服务器环境中高效地处理流量。

wget https://github.com/knative-extensions/net-kourier/releases/download/knative-v1.18.0/kourier.yaml
kubectl apply -f kourier.yaml

运行以下命令将 Knative Serving 默认配置为使用 Kourier

kubectl patch configmap/config-network \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'

kourier的问题

自建集群无法使用loadbalancer类型

运行如下命令,获取kourier的service

kubectl --namespace kourier-system get service kourier

会发现TYPE为loadbalancer类型,外部ip无法获取

这是因为我们现在使用的是自建的 Kubernetes 集群没有云厂商LoadBalancer的支持,如果没有配置负载均衡器,就不能使用loadbalancer类型的服务,所以无法自动分配外部 IP。

我们可以使用 NodePort 类型,直接通过集群中任意节点的 IP + 固定端口访问 Kourier,从而实现外部访问。kourier是 Knative Serving 的流量入口(Ingress Controller),负责接收外部流量并根据 Knative 的路由规则,把流量分发给后端服务。loadbalancer只是实现了自动把外部发往kourier service的流量分发到节点的 NodePort 而已,没有loadbalancer我们自己直接访问节点的 NodePort即可。

使用LoadBalancer类型与NodePort类型流量转发的区别:

改为NodePort类型

编辑下载的 kourier.yaml 文件,找到Kourier的Service,修改为NodePort类型

apply应用修改,再次查看kourier的service,已经改为nodeport类型:

kubectl --namespace kourier-system get service kourier

测试knative-serving

knative-serving主要功能是自动管理容器化应用的部署、扩展和路由。我们自动化部署一个自动拓缩容、自动路由的nginx服务,只需定义一个knative service

定义knative service
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: nginx-service
  namespace: default
spec:
  template:
    metadata:
      annotations:
        # 自动扩缩容配置
        autoscaling.knative.dev/minScale: "0"           # 最小副本数
        autoscaling.knative.dev/maxScale: "3"          # 最大副本数
    spec:
      containers:
      - image: nginx:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"

部署

# 部署
kubectl apply -f nginx-service.yaml

# 查看状态
kubectl get ksvc

要访问到nginx服务,该需要以下步骤:

我们可以看到当前的ksvc的URL为 nginx-service.default.svc.cluster.local ,该地址只能从集群内部Pod中访问

在集群节点上访问:

在pod中访问:

根据官方教程,需要执行下面的指令,Knative 会自动把每个 Knative Service 的内部地址
(nginx-service.default.svc.cluster.local )映射为一个外部可访问的域名(*.example.com)。

kubectl patch configmap/config-domain \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"example.com":""}}'
访问knative管理的nginx服务

因为Kourier是根据请求的域名来判断发送到后端的哪一类服务的,所以要指定请求头中的 Host。如果请求域名写的不对,kourier找不到与之对应的后端服务,该请求将会被丢弃。

执行 curl -H "nginx-service.default.example.com" [pod ip]:[port],即可访问。

curl -H "Host: nginx-service.default.example.com" http://10.0.0.10:30800

当然也可以域名解析到本机后直接域名访问

测试knative自动管理的拓缩容

使用压测工具hey进行压测

hey -n 1000000 -c 10000 http://nginx-service.default.example.com:30800

可以看到nginx pod数量变为3个:

过一段时间不发送请求后,再次查看pod个数,可验证knative缩容到0的能力

更多推荐