k8s自动扩缩容方案-HPA-VPA-KPA(18)
一、自动(弹性)扩缩容背景分析
背景:
弹性伸缩是根据用户的业务需求和策略,自动“调整”其“弹性资源”的管理服务。通过弹 性伸缩功能,用户可设置定时、周期或监控策略,恰到好处地增加或减少“弹性资源”,并完 成实例配置,保证业务平稳健康运行
在实际工作中,我们常常需要做一些扩容缩容操作,如:电商平台在 618 和双十一搞秒 杀活动;由于资源紧张、工作负载降低等都需要对服务实例数进行扩缩容操作。
在 k8s 中扩缩容分为两种:
1、Node 层面:
对 K8s 物理节点扩容和缩容,根据业务规模实现物理节点自动扩缩容
2、Pod 层面:
我们一般会使用Deployment中的replicas参数,设置多个副本集来保证服务的高可用, 但是这是一个固定的值,比如我们设置 10 个副本,就会启 10 个 pod 同时 running 来 提供服务。如果这个服务平时流量很少的时候,也是 10 个 pod 同时在 running,而流 量突然暴增时,又可能出现 10 个 pod 不够用的情况。针对这种情况怎么办?就需要自动扩容和缩容
二、k8s中自动伸缩的方案
2.1 HPA
Kubernetes HPA(Horizontal Pod Autoscaling):Pod 水平自动伸缩/横向自动收缩
通过此功能,只需简单的配置,便可以利用监控指标(cpu 使用率、磁盘、自定义的等) 自动的扩容或缩容服务中 Pod 数量,当业务需求增加时,系统将无缝地自动增加适量 pod 容器,提高系统稳定性。
要想实现自动扩缩容,需要先考虑如下几点:
1.通过哪些指标决定扩缩容?
HPA v1 版本可以根据 CPU 使用率来进行自动扩缩容: 但是并非所有的系统都可以仅依靠 CPU 或者 Memory 指标来扩容,对于大多数 Web 应用的后端来说,基于每秒的请求数量进行弹性伸缩来处理突发流量会更加的靠谱,所 以对于一个自动扩缩容系统来说,我们不能局限于 CPU、Memory 基础监控数据,每秒 请求数 RPS 等自定义指标也是十分重要。
HPA v2 版本可以根据自定义的指标进行自动扩缩容
注意:hpa v1 只能基于 cpu 做扩容所用
hpa v2 可以基于内存和自定义的指标做扩容和缩容
2.如何采集资源指标?
如果我们的系统默认依赖 Prometheus,自定义的 Metrics 指标则可以从各种数据源或 者 exporter 中获取,基于拉模型的 Prometheus 会定期从数据源中拉取数据。 也可以基于 metrics-server 自动获取节点和 pod 的资源指标
3.如何实现自动扩缩容?
K8s 的 HPA controller 已经实现了一套简单的自动扩缩容逻辑,默认情况下,每 30s 检测一次指标,只要检测到了配置 HPA 的目标值,则会计算出预期的工作负载的副本数, 再进行扩缩容操作。同时,为了避免过于频繁的扩缩容,默认在 5min 内没有重新扩缩容的情况下,才会触发扩缩容。 HPA 本身的算法相对比较保守,可能并不适用于很多场景。例如,一个快速的流量突发场景,如果正处在 5min 内的 HPA 稳定期,这个时候根据 HPA 的策略,会导致无法扩容.
更详细内容:https://zhuanlan.zhihu.com/p/360259459
自动伸缩的过程可以分为三个步骤:
获取被伸缩资源对象所管理的所有pod度量。
计算使度量数值到达(或接近)所指定目标数值所需的pod数量。
更新被伸缩资源的replicas字段。
2.2 KPA
KPA(Knative Pod Autoscaler):基于请求数对 Pod 自动扩缩容,KPA 的主要限制在于 它不支持基于 CPU 的自动扩缩容。
1、根据并发请求数实现自动扩缩容 .
2、设置扩缩容边界实现自动扩缩容
扩缩容边界指应用程序提供服务的最小和最大 Pod 数量。通过设置应用程序提供服务 的最小和最大 Pod 数量实现自动扩缩容。
相比 HPA,KPA 会考虑更多的场景,其中一个比较重要的是流量突发的时候
2.3 VPA
kubernetes VPA(Vertical Pod Autoscaler),垂直 Pod 自动扩缩容,VPA 会基于 Pod 的 资源使用情况自动为集群设置资源占用的限制,从而让集群将 Pod 调度到有足够资源的最佳节点上。VPA 也会保持最初容器定义中资源 request 和 limit 的占比。
它会根据容器资源使用率自动设置 pod 的 CPU 和内存的 requests,从而允许在节点上 进行适当的调度,以便为每个 Pod 提供适当的可用的节点。它既可以缩小过度请求资 源的容器,也可以根据其使用情况随时提升资源不足的容量。
三、利用HPA基于CPU指标实现Pod自动扩缩容
HPA 全称是 Horizontal Pod Autoscaler,翻译成中文是 POD 水平自动伸缩, HPA 可以 基于 CPU 利用率对 deployment 中的 pod 数量进行自动扩缩容(除了 CPU 也可以基于自定义的指标进行自动扩缩容)。pod 自动缩放不适用于无法缩放的对象,比如 DaemonSets。
HPA 由 Kubernetes API 资源和控制器实现。控制器会周期性的获取平均 CPU 利用率, 并与目标值相比较后调整 deployment 中的副本数量
3.1 HPA工作原理
HPA 是根据指标来进行自动伸缩的,目前 HPA 有两个版本–v1 和 v2beta
HPA 的 API 有三个版本,通过 kubectl api-versions | grep autoscal 可看到
[root@master k8s]# kubectl api-versions | grep autoscal
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
autoscaling/v1 只支持基于 CPU 指标的缩放;
autoscaling/v2beta1 支持 Resource Metrics(资源指标,如 pod 内存)和 Custom Metrics (自定义指标)的缩放;
autoscaling/v2beta2 支持 Resource Metrics(资源指标,如 pod 的内存)和 Custom Metrics (自定义指标)和 ExternalMetrics(额外指标)的缩放,但是目前也仅仅是处于 beta 阶段 指标从哪里来?
K8S 从 1.8 版本开始,CPU、内存等资源的 metrics 信息可以通过 Metrics API 来获取,用户可以直接获取这些 metrics 信息(例如通过执行 kubect top 命令),HPA 使用这些 metics 信息来实现动态伸缩。
Metrics server:
1、Metrics server 是 K8S 集群资源使用情况的聚合器
2、从 1.8 版本开始,Metrics server 可以通过 yaml 文件的方式进行部署
3、Metrics server 收集所有 node 节点的 metrics 信息
HPA 如何运作?
HPA 的实现是一个控制循环,由 controller manager 的--horizontal-pod-autoscaler-syncperiod 参数指定周期(默认值为 15 秒)。每个周期内,controller manager 根据每个 HorizontalPodAutoscaler 定义中指定的指标查询资源利用率。controller manager 可以从 resource metrics API(pod 资源指标)和 custom metrics API(自定义指标)获取指标。
然后,通过现有 pods 的 CPU 使用率的平均值(计算方式是最近的 pod 使用量(最近一分钟的平均 值,从 metrics-server 中获得)除以设定的每个 Pod 的 CPU 使用率限额)跟目标使用率进行比较, 并且在扩容时,还要遵循预先设定的副本数限制:MinReplicas <= Replicas <= MaxReplicas。
计算扩容后 Pod 的个数:sum(最近一分钟内某个 Pod 的 CPU 使用率的平均值)/CPU 使用上限的 整数+1
流程:
1、创建 HPA 资源,设定目标 CPU 使用率限额,以及最大、最小实例数
2、收集一组中(PodSelector)每个 Pod 最近一分钟内的 CPU 使用率,并计算平均值
3、读取 HPA 中设定的 CPU 使用限额
4、计算:平均值之和/限额,求出目标调整的实例个数
5、目标调整的实例数不能超过 1 中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数
6、回到 2,不断循环
3.2 安装数据采集组件metrics-server
metrics-server 是一个集群范围内的资源数据集和工具,同样的,metrics-server 也只是显示数据,并不提供数据存储服务,主要关注的是资源度量 API 的实现,比如 CPU、文件描述符、内存、 请求延时等指标,metric-server 收集数据给 k8s 集群内使用,如 kubectl,hpa,scheduler 等
(1) 部署 metrics-server 组件
#通过离线方式获取镜像
需要的镜像是:k8s.gcr.io/metrics-server-amd64:v0.3.6 和 k8s.gcr.io/addon-resizer:1.8.4,把镜像上传 到 k8s 的各个节点,并导入:
docker load -i addon.tar.gz
docker load -i metrics-server-amd64-0-3-6.tar.gz
# 部署metrics-server服务
#在/etc/kubernetes/manifests 里面改一下 apiserver 的配置
注意:这个是 k8s 在 1.7 的新特性,如果是 1.16 版本的可以不用添加,1.17 以后要添加。这个参 数的作用是 Aggregation 允许在不修改 Kubernetes 核心代码的同时扩展 Kubernetes API。
[root@master ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
增加如下内容: - --enable-aggregator-routing=true
重新更新 apiserver 配置:
[root@master ~]# kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
pod/kube-apiserver created
[root@master ~]# kubectl apply -f metrics.yaml
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
configmap/metrics-server-config created
deployment.apps/metrics-server created
service/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
#验证 metrics-server 是否部署成功
[root@master ~]# kubectl get pods -n kube-system | grep metrics
metrics-server-6595f875d6-bjgrv 2/2 Running 0 31s # 测试kubectl top命令
[root@master ~]# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 368m 9% 1641Mi 28%
node1 93m 4% 700Mi 19%
node3 75m 3% 559Mi 32% [root@master ~]# kubectl top pods -n kube-system
NAME CPU(cores) MEMORY(bytes)
calico-kube-controllers-56c7cdffc6-n2grp 1m 21Mi
calico-node-lcq82 41m 81Mi
calico-node-ltnpt 39m 101Mi
calico-node-zhvpx 76m 74Mi
coredns-7f89b7bc75-bd6k7 10m 15Mi
coredns-7f89b7bc75-thkbx 6m 15Mi
etcd-master 34m 71Mi
kube-apiserver-master 107m 459Mi
kube-controller-manager-master 40m 54Mi
kube-proxy-gjx9g 1m 18Mi
kube-proxy-wmnd4 1m 18Mi
kube-proxy-xz4b7 1m 18Mi
kube-scheduler-master 6m 23Mi
metrics-server-6595f875d6-bjgrv 1m 15Mi
3.3 创建php-apache服务,利用HAP进行自动扩缩容
#基于 dockerfile 构建一个 PHP-apache 项目
1)创建并运行一个 php-apache 服务
使用 dockerfile 构建一个新的镜像,在 k8s 的 master 构建
mkdir /root/php
cd php
[root@master php]# docker load -i php.tar.gz
[root@master php]# cat dockerfile
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php [root@master php]# cat index.php
<?php
$x = 0.0001;
for ($i = 0; $i <= 1000000;$i++) {
$x += sqrt($x);
}
echo "OK!";
?> # 2.构建镜像
[root@master php]# docker build -t 192.168.10.12/test/hap-example:v1 .
# 在各节点导入该镜像
docker save 192.168.10.12/test/hap-example:v1 -o hpa-example.tar.gz
docker load -i hpa-example.tar.gz # 3.通过deployment部署一个php-apache服务
[root@master php]# cat php-apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
replicas: 1
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: 192.168.10.12/test/hap-example:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
- port: 80
selector:
run: php-apache [root@master php]# kubectl apply -f php-apache.yaml
deployment.apps/php-apache created
service/php-apache created [root@master php]# kubectl get pods
NAME READY STATUS RESTARTS AGE
php-apache-58857b55d7-4sr6m 1/1 Running 0 15s
3.4 创建HPA
php-apache服务正在运行,使用kubectl autoscale创建自动缩放器,实现对php-apache 这个 deployment 创建的 pod 自动扩缩容,下面的命令将会创建一个 HPA,HPA 将会 根据 CPU,内存等资源指标增加或减少副本数,创建一个可以实现如下目的的 hpa:
1)让副本数维持在 1-10 个之间(这里副本数指的是通过 deployment 部署的 pod 的副本数)
2)将所有 Pod 的平均 CPU 使用率维持在 50%(通过 kubectl top 看到的每个 pod 如果 是 200 毫核,这意味着平均 CPU 利用率为 100 毫核)
#给上面 php-apache 这个 deployment 创建 HPA
[root@master php]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled #上面命令解释说明
kubectl autoscale deployment php-apache (php-apache 表示 deployment 的名字) --cpu-percent=50(表示 cpu 使用率不超过 50%) --min=1(最少一个 pod)--max=10(最多 10 个 pod) # 验证hpa是否创建成功
[root@master php]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 38s 注:由于我们没有向服务器发送任何请求,因此当前 CPU 消耗为 0%(TARGET 列显示了由相应的 deployment 控制的所有 Pod 的平均值)。
3.5 HPA基于CPU使用率实现Pod自动扩/缩容
压测php-apache服务,只针对CPU进行压测
# 1.准备好busybox和nginx镜像,并导入到节点中
docker load -i busybox.tar.gz
docker load -i nginx-1-9-1.tar.gz # 2.启动一个容器,并将无限查询循环发送到 php-apache 服务(复制 k8s 的 master 节点的终端,也就是打开一个新的终端窗口):
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
php-apache ClusterIP 10.105.167.249 <none> 80/TCP 14m [root@master php]# kubectl run v1 -it --image=busybox:latest --image-pull-policy=IfNotPresent -- /bin/sh
# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done [root@master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 194%/50% 1 10 1 22m
# 上面可以看到,CPU 消耗已经达到 194%,每个 pod 的目标 cpu 使用率是 50%,所以,php-apache 这个 deployment 创建的 pod 副本数将调整为 5 个副本,为什么是 4 个副本,因为 194/50=3 # 自动扩容到7个副本,满足了需求,直到cpu使用率不超过50%
[root@master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 48%/50% 1 10 7 24m [root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
php-apache-58857b55d7-skr4b 1/1 Running 0 86s
php-apache-58857b55d7-smkfp 1/1 Running 0 2m27s
php-apache-58857b55d7-vdsdj 1/1 Running 0 3m18s
php-apache-58857b55d7-wfvjg 1/1 Running 0 2m27s
v1 1/1 Running 0 2m57s
注意:可能需要几分钟来稳定副本数。由于不以任何方式控制负载量,因此最终副本数可能会与此示例不同 # 停止对 php-apache 服务压测,HPA 会自动对 php-apache 这个 deployment 创建的 pod做缩容
[root@master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 2%/50% 1 10 7 27m # 需要一段时间检测才进行缩容
3.6 HPA基于内存实现Pod自动扩容
# 1.导入镜像
docker load -i nginx-1-9-1.tar.gz # 2.执行yaml文件
[root@master ~]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hpa
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.9.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
protocol: TCP
resources:
requests:
cpu: 0.01
memory: 25Mi
limits:
cpu: 0.05
memory: 60Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
app: nginx
type: NodePort
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nginx 的 pod 里需要有如下字段,否则 hpa 会采集不到内存指标
resources:
requests:
cpu: 0.01
memory: 25Mi
limits:
cpu: 0.05
memory: 60Mi
[root@master ~]# kubectl apply -f nginx.yaml
deployment.apps/nginx-hpa created
service/nginx created [root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.110.32.245 <none> 80:30073/TCP 111s
[root@master manifests]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-hpa-fb74696c-vtgsg 1/1 Running 0 4m40s [root@master ~]# cat hpa-v1.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-hpa
metrics:
- type: Resource
resource:
name: memory
targetAverageUtilization: 60
#内存使用率超过60%就扩容
[root@master ~]# kubectl apply -f hpa-v1.yaml
horizontalpodautoscaler.autoscaling/nginx-hpa created [root@master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx-hpa 5%/60% 1 10 1 39s
压测nginx-hpa,针对内存使用超过60%就自动扩容
压测nginx-hpa
登录到上面通过 pod 创建的 nginx,并生成一个文件,增加内存
[root@master ~]# kubectl exec -it nginx-hpa-fb74696c-vtgsg -- /bin/sh
# dd if=/dev/zero of=/tmp/a # 在新终端里查看
[root@master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx-hpa 125%/60% 1 10 3 15m 上面的 targets 列可看到 125%/60%,125%表示当前内存使用率,60%表示所有 pod 的内存使用率维持在 60%,现在内存使用率达到 200%,所以 pod 增加到 3个,新增2个
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-hpa-fb74696c-4kmvv 1/1 Running 0 3m21s 10.244.166.156 node1 <none> <none>
nginx-hpa-fb74696c-vtgsg 1/1 Running 0 25m 10.244.166.141 node1 <none> <none>
nginx-hpa-fb74696c-x4wnx 1/1 Running 0 3m21s 10.244.166.155 node1 <none> <none>
# 当我停止压缩后,hap会对pod自动缩容
如何查看v2版本的hpa如何定义?
[root@master ~]# kubectl get hpa.v2beta2.autoscaling -o yaml > v2.yaml kubectl explain HorizontalPodAutoscaler
kubectl explain HorizontalPodAutoscaler.spec
四、VPA实现Pod自动扩缩容
Vertical Pod Autoscaler(VPA):垂直 Pod 自动扩缩容,用户无需为其 pods 中的容器设置最 新的资源 request。配置后,它将根据使用情况自动设置 request,从而允许在节点上进行适当的调度,以便为每个 pod 提供适当的资源量。
使用vpa前删除hpa
4.1 安装vpa
# k8s集群节点上导入镜像
[root@node1 data]# docker load -i vpa-admission-controller_0_8_0.tar.gz
Loaded image: scofield/vpa-admission-controller:0.8.0
[root@node1 data]# docker load -i vpa-recommender_0_8_0.tar.gz
b8cda3fb4e0a: Loading layer [==================================================>] 45.95MB/45.95MB
Loaded image: scofield/vpa-recommender:0.8.0
[root@node1 data]# docker load -i vpa-updater_0_8_0.tar.gz
9fe5b61fc509: Loading layer [==================================================>] 47.39MB/47.39MB
Loaded image: scofield/vpa-updater:0.8.0 # 控制节点
[root@master vpa]# unzip autoscaler-vertical-pod-autoscaler-0.8.0.zip
[root@master vpa]# cd /root/vpa/autoscaler-vertical-pod-autoscaler-0.8.0/vertical-pod-autoscaler/deploy
修改 admission-controller-deployment.yaml 里的 image:
image: scofield/vpa-admission-controller:0.8.0
imagePullPolicy: IfNotPresent 修改 recommender-deployment.yaml 里的 image:
image: scofield/vpa-recommender:0.8.0
imagePullPolicy: IfNotPresent 修改 updater-deployment.yaml 文件里的 image:
image: scofield/vpa-updater:0.8.0
imagePullPolicy: IfNotPresent cd /root/vpa/autoscaler-vertical-pod-autoscaler-0.8.0/vertical-pod-autoscaler/hack [root@master hack]# ./vpa-up.sh
Warning: apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalers.autoscaling.k8s.io created
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalercheckpoints.autoscaling.k8s.io created
clusterrole.rbac.authorization.k8s.io/system:metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:vpa-actor created
clusterrole.rbac.authorization.k8s.io/system:vpa-checkpoint-actor created
clusterrole.rbac.authorization.k8s.io/system:evictioner created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-actor created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-checkpoint-actor created
clusterrole.rbac.authorization.k8s.io/system:vpa-target-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-target-reader-binding created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-evictionter-binding created
serviceaccount/vpa-admission-controller created
clusterrole.rbac.authorization.k8s.io/system:vpa-admission-controller created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-admission-controller created
clusterrole.rbac.authorization.k8s.io/system:vpa-status-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-status-reader-binding created
serviceaccount/vpa-updater created
deployment.apps/vpa-updater created
serviceaccount/vpa-recommender created
deployment.apps/vpa-recommender created
Generating certs for the VPA Admission Controller in /tmp/vpa-certs.
Generating RSA private key, 2048 bit long modulus
.........................................................+++
.............+++
e is 65537 (0x10001)
Generating RSA private key, 2048 bit long modulus
..+++
............+++
e is 65537 (0x10001)
Signature ok
subject=/CN=vpa-webhook.kube-system.svc
Getting CA Private Key
Uploading certs to the cluster.
secret/vpa-tls-certs created
Deleting /tmp/vpa-certs.
deployment.apps/vpa-admission-controller created
service/vpa-webhook created [root@master manifests]# kubectl get pods -n kube-system | grep vpa
vpa-admission-controller-777694497b-bqpb2 1/1 Running 0 7m9s
vpa-recommender-64f6765bd9-twxbw 1/1 Running 0 7m9s
vpa-updater-c5474f4c7-h78xt 1/1 Running 0 7m9s [root@master manifests]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 18d
metrics-server ClusterIP 10.109.69.92 <none> 443/TCP 18h
vpa-webhook ClusterIP 10.99.181.122 <none> 443/TCP 12m
4.2 测试VPA实现Pod自动扩缩容
4.2.1 updateMode:"Off"
# 1、部署一个 nginx 服务,部署到 namespace: vpa 名称空间下:
[root@master vpa]# kubectl create ns vpa
namespace/vpa created [root@master vpa]# cat vpa-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: vpa
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources:
requests:
cpu: 200m
memory: 300Mi [root@master vpa]# kubectl apply -f vpa-1.yaml
deployment.apps/nginx created #2.在 nginx 管理的 pod 前端创建四层代理 Service
[root@master vpa]# cat vpa-service-1.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: vpa
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginx [root@master vpa]# kubectl apply -f vpa-service-1.yaml
service/nginx created
[root@master vpa]# kubectl get svc -n vpa
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.97.228.179 <none> 80:30127/TCP 9s
[root@master vpa]# curl -I 192.168.10.10:30127
HTTP/1.1 200 OK # 3.创建VPA
先使用 updateMode: "Off"模式,这种模式仅获取资源推荐值,但是不更新 Pod [root@master vpa]# cat vpa-nginx.yaml
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
namespace: vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: nginx
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: "nginx"
minAllowed:
cpu: "500m"
memory: "100Mi"
maxAllowed:
cpu: "2000m"
memory: "2600Mi" [root@master vpa]# kubectl apply -f vpa-nginx.yaml
verticalpodautoscaler.autoscaling.k8s.io/nginx-vpa created
[root@master vpa]# kubectl get vpa -n vpa
NAME AGE
nginx-vpa 31s # 查看详细信息
[root@master vpa]# kubectl describe vpa nginx-vpa -n vpa # 使用上面命令这次没看到
Recommendation:
Container Recommendations:
Container Name: nginx
Lower Bound:
Cpu: 500m
Memory: 262144k
Target:
Cpu: 500m
Memory: 262144k
Uncapped Target:
Cpu: 25m
Memory: 262144k
Upper Bound:
Cpu: 1349m
Memory: 1410936619
Events: <none> Lower Bound: 下限值
Target: 推荐值
Upper Bound: 上限值
Uncapped Target: 如果没有为 VPA 提供最小或最大边界,则表示目标利用率
上面结果表示,推荐的 Pod 的 CPU 请求为 500m,推荐的内存请求为 262144k 字节。
压测nginx:
[root@master vpa]# yum install -y httpd-tools ab [root@master manifests]# kubectl get svc -n vpa
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.97.228.179 <none> 80:30127/TCP 55m [root@master vpa]# ab -c 100 -n 10000000 http://192.168.10.10:30127/ [root@master vpa]# kubectl describe vpa nginx-vpa -n vpa VPA 对 Pod 给出了推荐值:Cpu: 763m,因为我们这里设置了
updateMode: "Off",所以不会更新 Pod
4.2.2 updateMode: "On"
现在我把 updateMode: "Auto",看看 VPA 会有什么动
把 resources 改为:memory: 50Mi,cpu: 100m
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: vpa
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources:
requests:
cpu: 100m
memory: 50Mi [root@master vpa]# kubectl apply -f vpa-nginx-1.yaml
deployment.apps/nginx created
[root@master vpa]# kubectl get pods -n vpa
NAME READY STATUS RESTARTS AGE
nginx-7d946f55c4-p52gj 1/1 Running 0 10s
nginx-7d946f55c4-s8ggc 1/1 Running 0 10s # 再次部署vpa
[root@master vpa]# cat vpa-nginx.yaml
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa-2
namespace: vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: nginx
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: "nginx"
minAllowed:
cpu: "500m"
memory: "100Mi"
maxAllowed:
cpu: "2000m"
memory: "2600Mi" [root@master vpa]# kubectl apply -f vpa-nginx.yaml
verticalpodautoscaler.autoscaling.k8s.io/nginx-vpa-2 created
[root@master vpa]# kubectl get vpa -n vpa
NAME AGE
nginx-vpa-2 9s # 再次压测
[root@master vpa]# ab -c 100 -n 1000000 http://192.168.10.10:30127/
几分钟后,使用 describe 查看 vpa 详情,只关注 Container Recommendations
kubectl describe vpa nginx-vpa -n vpa |tail -n 20
Target 变成了 Cpu: 656m ,Memory: 262144k
查看event事件
[root@master vpa]# kubectl get event -n vpa
vpa 执行了 EvictedByVPA,自动停掉了 nginx,然后使用 VPA 推荐的
资源启动了新的 nginx [root@master vpa]# kubectl describe pods nginx-7d946f55c4-p52gj -n vpa
查看Requests的cpu和memory是多少和部署的文件中作比较 随着服务的负载的变化,VPA 的推荐值也会不断变化。当目前运行的 pod 的资源达不到 VPA 的推荐值,就会执行 pod 驱逐,重新部署新的足够资源的服务。
VPA 使用限制:
不能与 HPA(Horizontal Pod Autoscaler )一起使用
Pod 比如使用副本控制器,例如属于 Deployment 或者 StatefulSet
VPA优点:
Pod 资源用其所需,所以集群节点使用效率高。
Pod 会被安排到具有适当可用资源的节点上。
不必运行基准测试任务来确定 CPU 和内存请求的合适值。
VPA 可以随时调整 CPU 和内存请求,无需人为操作,因此可以减少维护时间。
VPA 是 Kubernetes 比较新的功能,还没有在生产环境大规模实践过,小环境可以使用试试,也可以提前测试看看
五、kubernetes cluster-autoscaler
5.1 什么是cluster-autoscaler?
Cluster Autoscaler (CA)是一个独立程序,是用来弹性伸缩 kubernetes 集群的。它可以自动根据部署应用所请求的资源量来动态的伸缩集群。当集群容量不足时,它会自动去 Cloud Provider (支持 GCE、GKE 和 AWS)创建新的 Node,而在 Node 长时间资源 利用率很低时自动将其删除以节省开支。
项目地址:https://github.com/kubernetes/autoscaler
5.2 Cluster Autoscaler什么时候伸缩集群?
在以下情况下,集群自动扩容或者缩放:
扩容:由于资源不足,某些 Pod 无法在任何当前节点上进行调度
缩容: Node 节点资源利用率较低时,且此 node 节点上存在的 pod 都能被重新调度到 其他 node 节点上运行
5.3 什么时候集群节点不会被CA删除?
1)节点上有 pod 被 PodDisruptionBudget 控制器限制。
2)节点上有命名空间是 kube-system 的 pods。
3)节点上的 pod 不是被控制器创建,例如不是被 deployment, replica set, job, stateful set 创建。
4)节点上有 pod 使用了本地存储
5)节点上 pod 驱逐后无处可去,即没有其他 node 能调度这个 pod
6)节点有注解:"cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"(在 CA 1.0.3 或更高版本中受支持)
扩展:什么是 PodDisruptionBudget?
通过 PodDisruptionBudget 控制器可以设置应用 POD 集群处于运行状态最低个数,也可以设置应用 POD 集群处于运行状态的最低百分比,这样可以保证在主动销毁应用 POD 的时候,不会一次性销毁太多的应用 POD,从而保证业务不中断
5.4 Horizontal Pod Autoscaler 如何与 Cluster Autoscaler 一起使用?
Horizontal Pod Autoscaler 会根据当前 CPU 负载更改部署或副本集的副本数。如果负 载增加,则 HPA 将创建新的副本,集群中可能有足够的空间,也可能没有足够的空间。 如果没有足够的资源,CA 将尝试启动一些节点,以便 HPA 创建的 Pod 可以运行。如果 负载减少,则 HPA 将停止某些副本。结果,某些节点可能变得利用率过低或完全为空, 然后 CA 将终止这些不需要的节点。
扩展:如何防止节点被 CA 删除
节点可以打上以下标签: "cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"
可以使用 kubectl 将其添加到节点(或从节点删除):
kubectl annotate node cluster-autoscaler.kubernetes.io/scale-down-disabled=true
5.5 Cluster Autoscaler 支持那些云厂商?
GCE https://kubernetes.io/docs/concepts/cluster-administration/cluster-management/
Google 云服务商 GKE https://cloud.google.com/container-engine/docs/cluster-autoscaler
Google kubernetes 服务 AWS ( 亚 马 逊 ) https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md Azure ( 微 软 ) https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/azure/README.md Alibaba Cloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/alicloud/README.md OpenStack Magnum https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/magnum/README.md DigitalOcean https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/digitalocean/README.md CloudStack https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/cloudstack/README.md Exoscale https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/exoscale/README.md Packet https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/packet/READM.md OVHcloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/ovhcloud/README.md Linode https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/linode/README.md Hetzner https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/hetzner/README.md Cluster API https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/clusterapi/README.md
六、KPA实现pod扩缩容
Github: https://knative.dev/docs/install/
安装参考: https://knative.dev/docs/install/install-serving-with-yaml
k8s自动扩缩容方案-HPA-VPA-KPA(18)的更多相关文章
- 三十三、HPA实现自动扩缩容
通过HPA实现业务应用的动态扩缩容 HPA控制器介绍 当系统资源过高的时候,我们可以使用如下命令来实现 Pod 的扩缩容功能 $ kubectl -n luffy scale deployment m ...
- Knative 基本功能深入剖析:Knative Serving 自动扩缩容 Autoscaler
Knative Serving 默认情况下,提供了开箱即用的快速.基于请求的自动扩缩容功能 - Knative Pod Autoscaler(KPA).下面带你体验如何在 Knative 中玩转 Au ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...
- k8s手动扩缩容
1. 查询deploy副本数,ready数表示副本数 kubectl get deploy 2.通过命令直接扩容或者缩容,--replicas=1表示把my-dep缩容到副本数1,--replicas ...
- minikube metrics-server HPA 自动扩缩容错误
minikube metrics-server pod 错误 启动 minikube addons enable metrics-server 之后查看 metrics-server pod 会有如下 ...
- Marathon自动扩缩容(marathon-lb-autoscale)
我们在服务里面创建如下的应用(以下是创建完复制过来的json): { "id": "/nginxtest", "cmd": null, &q ...
- 13.深入k8s:Pod 水平自动扩缩HPA及其源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 Pod 水平自动扩缩 Pod 水平自动扩缩工作原理 Pod 水平自动 ...
- 【六】K8s-Pod 水平自动扩缩实践(简称HPA)
一.概述 Pod 水平自动扩缩(Horizontal Pod Autoscaler)简称 HPA,HPA 可以根据 CPU 利用率进行自动伸缩 Pod 副本数量,除了 CPU 利用率,也可以基于其他应 ...
- Kubernetes的垂直和水平扩缩容的性能评估
Kubernetes的垂直和水平扩缩容的性能评估 译自:Performance evaluation of the autoscaling strategies vertical and horizo ...
- Airbnb的动态kubernetes集群扩缩容
Airbnb的动态kubernetes集群扩缩容 本文介绍了Airbnb的集群扩缩容的演化历史,以及当前是如何通过Cluster Autoscaler 实现自定义扩展器的.最重要的经验就是Airbnb ...
随机推荐
- abp9 .net8 升级错误记录
错误一. Cannot find compilation library location for package 'System.Security.Cryptography.Pkcs' 修复方法: ...
- 冰河开始对Dubbo下手了!
写在前面 对冰河有一定了解的读者都知道,冰河经历了一个高并发电商系统用户从零到上亿的整个研发过程,后期也由此衍生出电商系统(商城+秒杀)和基于海量数据的实时精准商品推荐平台.部分核心知识已总结到我出版 ...
- KafkaConsumerDemo
pom <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>sp ...
- 为什么医疗保健需要MFT来帮助保护EHR文件传输
毫无疑问,医疗保健行业需要EHR技术来处理患者,设施,提供者等之间的敏感患者信息.但是,如果没有安全的MFT解决方案,您将无法安全地传输患者文件,从而使您的运营面临遭受数据泄露,尴尬,声誉损失以及随之 ...
- 7 CSS选择器优先级
7 选择器优先级 所谓CSS优先级,即是指CSS样式在浏览器中被解析的先后顺序.样式表中的特殊性描述了不同规则的相对权重. /* !important > 行内样式>ID选择器 > ...
- #斜率优化,单调栈#洛谷 5504 [JSOI2011] 柠檬
题目 分析 设\(dp[i]\)表示前\(i\)个贝壳可以获得的最大收益, 则\(dp[i]=\max\{dp[j-1]+S(c[i]-c[j]+1)^2\}[s_i==s_j]\) 可以发现当且仅当 ...
- 两个专栏帮你搞定【图像拼接(image stitching)】
[图像拼接论文精读]专栏:图像拼接论文精读 [图像拼接源码精读]专栏:图像拼接论文源码精读 前言 图像拼接(image stitching)是计算机视觉中的高级图像处理手段,是一个小众方向,研究的人很 ...
- OpenHarmony父子组件单项同步使用:@Prop装饰器
@Prop装饰的变量可以和父组件建立单向的同步关系.@Prop装饰的变量是可变的,但是变化不会同步回其父组件. 说明: 从API version 9开始,该装饰器支持在ArkTS卡片中使用. 概述 ...
- HarmonyOS Connect “Device Partner”专场FAQ来啦!
原文链接:https://mp.weixin.qq.com/s/mQJlAso293qgPlA1paxv5g,点击链接查看更多技术内容: Device Partner平台是面向AIoT产业链 ...
- 演示webuploader和cropperjs图片裁剪上传
最近有个项目要在浏览器端裁剪并上传图片.由于缺乏人力,只能我上阵杀敌.通过参考各种文章,最后决定用cropperjs进行图片裁剪,用webuploader上传文件.本文涉及到的知识至少有Java基础. ...