创建项目:
oc new-project knativetutorial
git clone https://github.com/redhat-developer-demos/knative-tutorial &&\ export TUTORIAL_HOME="$(pwd)/knative-tutorial"
我们分析应用配置文件:cd $TUTORIAL_HOME/basics。该文件使用quay.io/rhdevelopers/knative-tutorial-greeter:quarkus镜像创建应knative service:
应用配置:
oc apply -n knativetutorial -f service.yaml
接下来,我们查看knativetutorial项目中被创建了什么资源:
产生了一个K8S层面的deployments:
产生了三个K8S的service:
产生了一个knative的service,greeter。
利用oc get rt -n knativetutorial查看knative route:
利用oc get route -n knativetutorial查看OCP route,未发现:
查看pod,未发现:
接下来,我们查看knative路由指向:100%指向了knative service:greeter:
# oc get rt greeter -o yaml -n knativetutorial
我们查看knative service greeter 的内容:其中包含了指向revision的流量信息。
# kn service list greeter -o yaml
接下来,我们从OCP的角度,查看svc:greeter。
从下面图内容我们可以得知:greeter的svc的外部地址是:kourier-internal.knative-serving-ingress.svc.cluster.local,也就是说与knative-serving-ingress项目中的service:kourier-internal关联起来了。
# oc get svc greeter -o yaml -n knativetutorial
我们查看knative-serving-ingress项目中service:kourier-internal的内容,它指向了knative-serving-ingress项目中的ingress pod:
# oc get svc kourier-internal -o yaml -n knative-serving-ingress
接下来,我们查看knative-serving-ingress项目中的资源:
项目中没有knative route:
有OCP route:route-db15f484-546d-46b9-8e31-2fad2527ed5c-356631366663
查看这条OCP route的指向,指向service:kourier
# oc get route route-db15f484-546d-46b9-8e31-2fad2527ed5c-356631366663 -o yaml -n knative-serving-ingress
继续分析,发现这条OCP路由与haproxy的关系:
查看service:kourier的内容,指向了ingress pod:
kourier和kourier-internal的区别是:前者是
External Load Balancer,Ingress point(s) of load balancer后者是Accessible within the cluster only。这两个service其实指向相同的pod。类型不同。第一种通常和lb结合使用,比如云厂商的lb,可以对内也可以对外。第二种是对内,完全是k8s管理的。
从上面一系列图我们可以得出OCP上Kvative网络流量图(这是大魏理解的图,仅供参考):
二、测试应用
使用http调用我们部署的greeter应用:
[root@lb.weixinyucluster ~]# export SVC_URL=`oc get rt greeter -o yaml | yq read - 'sta.url'` && \
> http $SVC_URL
调用反馈结果是:Hi greeter => '9861675f8845' : 1
此时查看pod:
在没有新的请求时,pod会自动删除:
我们查看configuration:
oc --namespace knativetutorial get configurations.serving.knative.dev greeter
oc --namespace knativetutorial get rev \
--selector=serving.knative.dev/service=greeter \
--sort-by="{.metadata.creationTimestamp}"
接下来,我们部署version2的应用,我们查看配置文件,版本2的应用被注入了MESSAGE_PREFIX:Namaste
应用配置:
我们查看revision信息:
oc --namespace knativetutorial get rev \ --selector=serving.knative.dev/service=greeter \ --sort-by="{.metadata.creationTimestamp}"
此时OCP也创新了新的K8S SVC:
我们再用http访问应用:
export SVC_URL=`oc get rt greeter -o yaml | yq read - 'sta.url'` && \
> http $SVC_URL
我们看到此次访问结果增加了MESSAGE_PREFIX:Namaste。
我们可以动态调整到两个revision的流量百分比。使用OCP的UI较为方便:
进行修改:
命令行双重确认,调整成功:
三、scale-to-zero
假设已经部署了Greeter服务,一旦看到没有更多流量进入该服务,我们希望将该服务缩减为零个副本。这就是所谓的scale-to-zero.。
scale-to-zero.是使Knative成为无服务器平台的主要特性之一。在定义的空闲时间(所谓的稳定窗口)之后,revisions被视为无效。现在,所有指向当前无效revisions的路由都将指向所谓的activator。网络的重新编程本质上是异步的,因此从零到零的宽限期应该提供足够的松弛时间来实现。一旦scale-to-zero宽限期结束,revisions将最终缩放到零副本。
如果另一个请求试图到达revision,则activator将获取它,指示autoscaler尽快为该revision建新的容器,并缓冲该请求,直到创建了这些新容器。
默认情况下,scale-to-zero宽限期为30秒,稳定窗口为60秒。向greeter 服务发出请求将调出pod(如果已终止,如上所述)(如果已被终止)以处理该请求。保留它而没有任何其他请求将自动导致它在大约60-70秒内缩放为零。pod开始终止后到完全终止之前,至少需要20秒。
四、弹性伸缩
默认情况下,Knative Serving允许将100个并发请求放入pod中。这是由knative-serving名称空间中configmap config-autoscaler中的container-concurrency-target-default设置定义的。让我们使我们的服务仅处理10个并发请求。一旦我们针对revision并行运行10个以上的请求,这将导致Knative自动缩放器扩展到更多的Pod。
创建一个新的项目:
# oc new-project knativetutorial
[root@lb.weixinyucluster ~/knative-tutorial/basics]# cat service-10.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: prime-generator
spec:
template:
metadata:
annotations:
# Target 10 in-flight-requests per pod.
autoscaling.knative.dev/target: "10"
spec:
containers:
- image: quay.io/rhdevelopers/prime-generator:v27-quarkus
livenessProbe:
httpGet:
path: /healthz
readinessProbe:
httpGet:
path: /healthz
[root@lb.weixinyucluster ~/knative-tutorial/basics]# oc apply -f service-10.yaml
service.serving.knative.dev/prime-generator created
export SVC_URL=`oc get rt prime-generator -o yaml | yq read - 'status.url'`
hey -c 50 -z 10s \ "${SVC_URL}/?sleep=3&upto=10000&memload=100"
在现实世界中,您的服务可能需要处理突然的请求高峰。Knative使用默认的1个副本启动每个服务。如上所述,最终将如上所述将其缩放为零。如果您的应用在任何情况下都需要保持特别的响应速度和/或启动时间较长,那么始终保持最少数量的Pod可能是有益的。这可以通过注释autoscaling.knative.dev/minScale完成。
以下示例显示了如何使Knative创建以2的副本数开始并且永远不会扩展到其以下的服务。
[root@lb.weixinyucluster ~/knative-tutorial/basics]# cat service-min-max-scale.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: prime-generator
spec:
template:
metadata:
annotations:
# the minimum number of pods to scale down to
autoscaling.knative.dev/minScale: "2"
# Target 10 in-flight-requests per pod.
autoscaling.knative.dev/target: "10"
spec:
containers:
- image: quay.io/rhdevelopers/prime-generator:v27-quarkus
livenessProbe:
httpGet:
path: /healthz
readinessProbe:
httpGet:
path: /healthz
[root@lb.weixinyucluster ~/knative-tutorial/basics]# oc apply -f service-min-max-scale.yaml
service.serving.knative.dev/prime-generator created
在没有外部请求时,pod的数量也是两个:
发起峰值压力后,pod的数量会增加: