《OpenShift 4.x HOL教程汇总》
说明:本文已经在OpenShift 4.13 + OpenShift Serverless 1.29.1环境中验证
自动扩展和收缩功能说明
在自动扩展和收缩过程中,Revision 有三种状态:
- Active:当他们活跃地服务请求时。在Active状态下,每个Revision都有一个Deployment,用以维护所需数量的Pod。 它还有一个Autoscaler(单租户时每个Revision一个;多租户时所有Revision用一个),Autoscaler监视流量指标并调整部署所需的pod数量。每个Pod每秒钟向Autoscaler报告其并发请求数。
- Reserve:当他们缩小到0个Pod。在Reserve状态下,Revision没有预定的Pod并且不使用CPU。Revision的Istio路由规则指向单个多租户Activator,Activator将捕获所有到Reserve Revision的流量。当Activator捕获一个Reserve Revision的请求时,它会将Revision修改为Active状态,然后在准备就绪时将请求转发给Revision。
- Retired:当他们将不再接收流量。
Autoscaler 收集发到 Revision 并发请求数量的有关信息。为了做到这一点,它在 Revision Pod 内运行一个称之为 queue-proxy 的 sidecar 容器。Autoscaler 采用的伸缩算法针对两个独立的时间间隔计算所有数据点的平均值:分别是 60 秒和 6 秒。Autoscaler 使用这些数据以两种模式运作:Stable Mode (稳定模式) 和 Panic Mode (忙乱模式)。在 Stable 模式下,它使用 60 秒时间窗平均值决定如何伸缩部署以满足期望的并发量。如果 6 秒窗口的平均并发量两次到达期望目标,Autoscaler 转换为 Panic Mode 并使用 6 秒时间窗。这让它更加快捷的响应瞬间流量的增长。它也仅仅在 Panic Mode 期间扩容以防止 Pod 数量快速波动。如果超过 60 秒没有扩容发生,Autoscaler 会转换回 Stable Mode。
默认情况下,Autoscaler 尝试维持每 Pod 每秒平均 100 个并发请求。例如,一个 Revision 每秒收到 350 个请求并且每次请求大约需要处理 0.5 秒。使用默认设置 (每 Pod 100 个并发请求),这个 Revision 将扩展至两个 Pod:
350 * .5 = 175
175 / 100 = 1.75
ceil(1.75) = 2 pods
假设一个Knative服务一旦不再看到流量进入它,我们希望将此服务收缩到零个副本。这称为"缩放到零"。缩放到零是使 Knative 成为无服务器平台的主要属性之一。在定义的空闲时间(所谓的稳定窗口)后,Revision被视为非活动。此时指向现在非活动Revision的所有路由都将指向所谓的Activator。由于这种网络的重新指向是异步的,因此应提供足够的宽延时间,这个时间就为scale-to-zero-grace-period。当scale-to-zero-grace-period结束后,Revision最终将缩放为零副本。此时如果再有请求尝试获访问Revision,Activator将获取它,指示Autoscaler尽快为Revision创建新的 Pod,并缓冲请求,直到创建Pod成功。
Knative将定义Autoscaler的配置参数放在knative-serving项目中的一个ConfigMap对象中,我们可以查看该对象。
$ oc get cm -n knative-serving
NAME DATA AGE
config-autoscaler 1 7h33m
config-defaults 1 7h33m
config-deployment 2 7h33m
config-domain 2 7h33m
config-features 1 7h33m
config-gc 1 7h33m
config-leader-election 1 7h33m
config-logging 1 7h33m
config-network 5 7h33m
config-observability 1 7h33m
config-service-ca 2 7h33m
config-service-ca-service-ca 1 7h33m
config-service-ca-trusted-ca 1 7h33m
config-tracing 1 7h33m
kube-root-ca.crt 1 7h47m
openshift-service-ca.crt 1 7h47m
$ oc get cm config-autoscaler -oyaml -n knative-serving
apiVersion: v1
kind: ConfigMap
metadata:
name: config-autoscaler
namespace: knative-serving
data:
_example: |
activator-capacity: "100.0"
allow-zero-initial-scale: "false"
container-concurrency-target-default: "100"
container-concurrency-target-percentage: "70"
enable-scale-to-zero: "true"
initial-scale: "1"
max-scale: "0"
max-scale-limit: "0"
max-scale-down-rate: "2.0"
max-scale-up-rate: "1000.0"
panic-threshold-percentage: "200.0"
panic-window-percentage: "10.0"
pod-autoscaler-class: "kpa.autoscaling.knative.dev"
scale-down-delay: "0s"
scale-to-zero-grace-period: "30s"
scale-to-zero-pod-retention-period: "0s"
stable-window: "60s"
target-burst-capacity: "200"
。。。
这些配置参数含义:
- container-concurrency-target-default:指定一个容器最多处理的并发请求。
- container-concurrency-target-percentage:在稳定状态情况下,使用container-concurrency-target-default最大值比例,例如 70 代表70%的比例。如果Revision指定container-concurrency-target-default为 10,则Autoscaler将为每个Pod尝试维护 7 个并发连接 。
- enable-scale-to-zero:是否可以收缩到零个。
- max-scale-up-rate:在一个Autoscaler扩展期间,最高的扩展倍数。如果是10,代表一次可以将Pod从N扩展到10N。
- panic-window:panic模式的监控时间窗口长度。
- panic-window-percentage:在panic-window内,当Container的并发处理达到container-concurrency-target的百分比(例如200%),就进入panic模式。
- panic-window-percentage:Panic窗口和Stable窗口的时间比。
配置自动扩展收缩
- 创建以下内容的prime-service.yaml文件。它定义了每个Pod能处理10个并发请求。
$ oc apply -f - << EOF
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
EOF
- 执行命令,创建资源。
$ oc apply -f prime-service.yaml
service.serving.knative.dev/prime-generator created
- 确认环境中有hey应用。如果没有,在此下载。
- 执行命令,向prime-generator的route持续发送请求。
$ hey -c 50 -z 10s "$(kn route list prime-generator --no-headers | awk '{print $2}')/?sleep=3&upto=10000&memload=100"
[1] 11849
[2] 11850
[2]+ Done upto=10000
- 稍后运行以下命令查看Pod数量,可以看到本例Knative通过Autoscaler启动了8个Pod处理请求(你看的可能是其他数量)。
$ oc get pod
NAME READY STATUS RESTARTS AGE
prime-generator-00001-deployment-554c7ff5d6-5rg4t 2/2 Running 0 32s
prime-generator-00001-deployment-554c7ff5d6-8vrn2 2/2 Running 0 32s
prime-generator-00001-deployment-554c7ff5d6-d6r2k 2/2 Running 0 32s
prime-generator-00001-deployment-554c7ff5d6-fxsh7 2/2 Running 0 33s
prime-generator-00001-deployment-554c7ff5d6-j6v65 2/2 Running 0 32s
prime-generator-00001-deployment-554c7ff5d6-kdskf 2/2 Running 0 32s
prime-generator-00001-deployment-554c7ff5d6-nvgv9 2/2 Running 0 32s
prime-generator-00001-deployment-554c7ff5d6-rz89h 2/2 Running 0 32s
- 稍等一段时间,再执行查看,最后Knative将会把pod数量缩减到0个。
$ oc get pod
No resources found in kn-blue-green namespace.
配置扩展收缩上下限
在Knative服务实际运行中Knative 以默认的 1 个副本启动每个服务。如果应用启动时间很长,但还需要在任何情况下保持及时响应,则可通过设置autoscaling.knative.dev/minScale的注释来保留最少运行的 Pod 数。
- 创建以下内容的service-min-max-scale.yaml文件。其中定义了Autoscaler上下限是10-2。
$ oc apply -f - << EOF
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
EOF
- 查看当前Pod数量已经是最小的2了。
$ oc get pod
NAME READY STATUS RESTARTS AGE
prime-generator-00002-deployment-7f8d89cdb6-qjd5d 2/2 Running 0 5s
prime-generator-00002-deployment-7f8d89cdb6-zd7r5 2/2 Running 0 5s