做者:Juan Ignacio Giro 译者:段访 审校:罗广明 原文: https://caylent.com/kubernetes-autoscalingphp
许多Kubernetes用户,特别是那些企业级用户,很快就遇到了对环境自动缩放的需求。幸运的是,Kubernetes Horizontal Pod Autoscaler(HPA)容许您将部署配置为以多种方式水平扩展。使用Kubernetes Autoscaling的最大优点之一是您的集群能够跟踪现有Pod的负载能力,并计算是否须要更多的Pod。html
经过协调内置的两层可扩展性,能够充分利用高效的Kubernetes Autoscaling:node
HPA会在集群中缩放Pod副本的数量。该操做由CPU或内存触发,以根据须要向上或向下扩展。可是,也能够根据各类外部的和自定义指标(metrics.k8s.io,external.metrics.k8s.io和custom.metrics.k8s.io)来配置HPA以扩展Pod。linux
VPA主要用于有状态服务,它可根据须要为Pod添加CPU或内存——它也适用于无状态的Pod。为了应用这些更改,VPA从新启动Pod以更新新的CPU和内存资源,这些资源能够配置为响应OOM(内存不足)事件而启动。从新启动Pod的时候,VPA始终确保根据Pod分配预算(PDB)肯定最小数量,您能够设置该资源分配最大和最小速率。nginx
第二层的自动缩放涉及CA,它在如下状况下自动调整集群的大小:git
CA进行例行检查以肯定是否有任何pod因等待额外资源处于待定状态,或者集群节点是否未获得充分利用。若是须要更多资源,会相应地调整Cluster节点的数量。CA与云提供商交互以请求其余节点或关闭空闲节点,并确保按比例放大的集群保持在用户设置的限制范围内。它适用于AWS,Azure和GCP。github
本文提供了经过适用于Kubernetes(Amazon EKS)集群的Amazon Elastic容器服务,经过HPA和CA安装和自动扩展的分步指南。如下指南是两个测试用例示例:apache
1. 根据官方指南建立一个AWS EKS 集群(控制面板和和工做节点). 一旦你把工做节点以auto scaling group的形式启动了,它们会自动向EKS集群注册,你就能够开始部署k8s应用了。api
2. 部署度量服务器以便HPA可以根据API提供的CPU/内存数据自动缩放POD副本的数量。 metrics.k8s.io api 一般由metrics-server(负责从summary api收集cpu和内存度量)提供。
3. 把如下策略应用到EKS建立的worker节点的Role上
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup" ], "Resource": "*" } ] }
4. 部署k8s CA特性
根据你使用的linux发行版,你可能须要更新部署文件和证书路径。 例如,若是使用AMI Linux,须要用/etc/ssl/certs/ca-bundle.crt替换/etc/ssl/certs/ca-certificates.crt
5. 更新CA的部署YAML文件,找到指定的AWS AG(k8s.io/cluster-autoscaler/<CLUSTER NAME
>应该包含真实的集群名称)标签。 同时更新AWS_REGION
环境变量。
把如下tag添加到 AWS AG, 以便 k8s 的 cluster autoscaler 可以自动识别 AWS AG:
k8s.io/cluster-autoscaler/enabled k8s.io/cluster-autoscaler/
测试k8s hpa 特性和k8s ca 特性同时使用
要求:
1. 部署一个测试app,为app部署建立HPA资源。
2. 从不一样的地理位置发起请求以增长负载。
3. HPA 应该会随着负载的增长开始缩放pod的数量。它会根据hpa资源指定的进行缩放的。在某一时刻,新的POD在等待其余资源的时候会是等待状态。
$ kubectl get nodes -w NAME STATUS ROLES AGE VERSION ip-192-168-189-29.ec2.internal Ready 1h v1.10.3 ip-192-168-200-20.ec2.internal Ready 1h v1.10.3
$ kubectl get Pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE ip-192-168-200-20.ec2.internal php-apache-8699449574-4mg7w 0/1 Pending 0 17m php-apache-8699449574-64zkm 1/1 Running 0 1h 192.168.210.90 ip-192-168-200-20 php-apache-8699449574-8nqwk 0/1 Pending 0 17m php-apache-8699449574-cl8lj 1/1 Running 0 27m 192.168.172.71 ip-192-168-189-29 php-apache-8699449574-cpzdn 1/1 Running 0 17m 192.168.219.71 ip-192-168-200-20 php-apache-8699449574-dn9tb 0/1 Pending 0 17m ...
4. CA 检测到由于容量不足而进入等待状态的pods,调整AWS 自动缩放组的大小。一个新的节点加入了:
$ kubectl get nodes -w NAME STATUS ROLES AGE VERSION ip-192-168-189-29.ec2.internal Ready 2h v1.10.3 ip-192-168-200-20.ec2.internal Ready 2h v1.10.3 ip-192-168-92-187.ec2.internal Ready 34s v1.10.3
5. HPA可以把等待状态的POD调度到新的节点上了。 平均cpu使用率低于指定的目标,没有必要再调度新的pod了。
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache 40%/50% 2 25 20 1h $ kubectl get Pods -o wide -w
$ kubectl get Pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE php-apache-8699449574-4mg7w 1/1 Running 0 25m 192.168.74.4 ip-192-168-92-187 php-apache-8699449574-64zkm 1/1 Running 0 1h 192.168.210.90 ip-192-168-200-20 php-apache-8699449574-8nqwk 1/1 Running 0 25m 192.168.127.85 ip-192-168-92-187 php-apache-8699449574-cl8lj 1/1 Running 0 35m 192.168.172.71 ip-192-168-189-29 ...
6. 关闭几个terminal,停掉一些负载
7. CPU平均利用率减少了, 因此HPA开始更改部署里的pod副本数量并杀掉一些pods
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache 47%/50% 2 20 7 1h $ kubectl get Pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE ... php-apache-8699449574-v5kwf 1/1 Running 0 36m 192.168.250.0 ip-192-168-200-20 php-apache-8699449574-vl4zj 1/1 Running 0 36m 192.168.242.153 ip-192-168-200-20 php-apache-8699449574-8nqwk 1/1 Terminating 0 26m 192.168.127.85 ip-192-168-92-187 php-apache-8699449574-dn9tb 1/1 Terminating 0 26m 192.168.124.108 ip-192-168-92-187 php-apache-8699449574-k5ngv 1/1 Terminating 0 26m 192.168.108.58 ip-192-168-92-187 ...
8. CA 检测到一个节点未充分使用,正在运行的pod可以调度到其余节点上。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-189-29.ec2.internal Ready 2h v1.10.3 ip-192-168-200-20.ec2.internal Ready 2h v1.10.3 ip-192-168-92-187.ec2.internal NotReady 23m v1.10.3 $ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-189-29.ec2.internal Ready 2h v1.10.3 ip-192-168-200-20.ec2.internal Ready 2h v1.10.3
9. 在向下缩放的时候,terminal中应该没有明显的timeout
测试在若是没有足够的CPU容量调度pod下,CA是否可以自动调整集群的大小
要求:
1. 建立2个请求小于1vcpu的deployment
$ kubectl run nginx --image=nginx:latest --requests=cpu=200m $ kubectl run nginx2 --image=nginx:latest --requests=cpu=200m
2. 建立一个新的deployment,请求比剩余的cpu更多的资源
$ kubectl run nginx3 --image=nginx:latest --requests=cpu=1
3. 新的POD会处于等待状态,由于没有可用的资源:
$ kubectl get Pods -w NAME READY STATUS RESTARTS AGE nginx-5fcb54784c-lcfht 1/1 Running 0 13m nginx2-66667bf959-2fmlr 1/1 Running 0 3m nginx3-564b575974-xcm5t 0/1 Pending 0 41s
描述pod的时候,可能会看到没有足够的cpu的事件
$ kubectl describe Pod nginx3-564b575974-xcm5t ….. ….. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 32s (x7 over 1m) default-scheduler 0/1 nodes are available: 1 Insufficient cpu
4. CA自动调整集群的大小, 新加了一个节点
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-142-179.ec2.internal Ready 1m v1.10.3 << ip-192-168-82-136.ec2.internal Ready 1h v1.10.3
5. 集群如今有了足够的资源以运行pod
$ kubectl get Pods NAME READY STATUS RESTARTS AGE nginx-5fcb54784c-lcfht 1/1 Running 0 48m nginx2-66667bf959-2fmlr 1/1 Running 0 37m nginx3-564b575974-xcm5t 1/1 Running 0 35m
6. 两个部署删除了。 一段时间后,CA检测到集群中的一个节点未被充分利用,运行的pod能够安置到其余存在的节点上。AWS AG 更新,节点数量减1。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-82-136.ec2.internal Ready 1h v1.10.3 $ kubectl get Pods -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-5fcb54784c-lcfht 1/1 Running 0 1h 192.168.98.139 ip-192-168-82-136
清除环境的步骤:
其余的关于kubernetes autoscaling,能够阅读Stefan Prodan的文章 Kubernetes Horizontal Pod Autoscaler with Prometheus Custom Metrics。
还有这些连接也能够看看 link1, link2, link3。
ServiceMesher 社区是由一群拥有相同价值观和理念的志愿者们共同发起,于 2018 年 4 月正式成立。
社区关注领域有:容器、微服务、Service Mesh、Serverless,拥抱开源和云原生,致力于推进 Service Mesh 在中国的蓬勃发展。
社区官网:https://www.servicemesher.com