背景
公司的容器云平台需要新增应用的自动扩缩容的功能,以便能够更加智能化的对应用进行管理。
Kubernetes官方提供了HPA(Horizontal Pod Autoscaling)资源对象。要让我们部署的应用做到自动的水平的(水平指的是增减Pod副本数量)进行扩缩容,我们只需要在Kubernetes集群中创建HPA资源对象,然后让该资源对象关联某一需要进行自动扩缩容的应用即可。
HPA默认的是以Pod平均CPU利用率作为度量指标,也就是说,当应用Pod的平均CPU利用率高于设定的阈值时,应用就会增加Pod的数量。CPU利用率的计算公式是:Pod当前CPU的使用量除以它的Pod Request(这个值是在部署deployment时自己设定的)值。而平均CPU利用率指的就是所有Pod的CPU利用率的算术平均值。
Pod平均CPU利用率的计算需要知道每个Pod的CPU使用量,目前是通过查询Heapster扩展组件来得到这个值,所以需要安装部署Heapster。
接下来我就将我们在Kubernetes集群中部署Heapster的过程记录下来,也会描述我们在部署过程中遇到的问题以及解决的方法,希望能够帮助到也准备在Kubernetes集群中部署Heapster的朋友。
Heapster成功部署之后,我们使用了性能测试工具对http应用做了压力测试,以观察HPA进行自动扩缩容时的实际效果。
部署过程
1
首先,我们在github中搜索Heapster,会找到Kubernetes中的Heapster库:
将这个库clone到集群的master节点中。
在Heapster目录下运行命令kubectl create -f deploy/kube-config/standalone/Heapster-controller.yaml
理论上创建完成后会启动三个资源对象,deployment、service、serviceaccount,此时Heapster应该就能够为HPA提供CPU的使用量了。
此时为验证Heapster是否可用,在集群中部署一个HPA资源对象,关联某个应用,并设定阈值为90:
查看这个HPA时我们可以看到,CURRENT的CPU利用率为,也就是说,HPA没能从Heapster中取得CPU的使用量。
于是,我们用kubectl get pod –namespace=kube-system命令查看Heapster的pod的运行情况,发现是拉取镜像失败的缘故。
打开部署Heapster的yaml文件如下:
apiVersion: v1 kind: ServiceAccount metadata: name: Heapster namespace: kube-system --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: Heapster namespace: kube-system spec: replicas: 1 template: metadata: labels: task: monitoring k8s-app: Heapster spec: serviceAccountName: Heapster containers: - name: Heapster image: gcr.io/google_containers/Heapster-amd64:v1.4.0 imagePullPolicy: IfNotPresent command: - /Heapster - --source=kubernetes:https://kubernetes.default --- apiVersion: v1 kind: Service metadata: labels: task: monitoring # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons) # If you are NOT using this as an addon, you should comment out this line. kubernetes.io/cluster-service: 'true' kubernetes.io/name: Heapster name: Heapster namespace: kube-system spec: ports: - port: 80 targetPort: 8082 selector: k8s-app: Heapster
可以看到23行,镜像是要从谷歌的gcr.io镜像仓库中拉取的,由于我们的集群服务器不能连通外网,所以镜像当然就拉取失败了。
2
此时,我们使用之前使用过的自己仓库中的Heapster镜像来替代此yaml文件中使用的镜像。
清除刚才部署失败的资源对象后再次在Heapster目录下使用命令:kubectl create -f deploy/kube-config/standalone/Heapster-controller.yaml
这个时候发现对应的资源对象都创建成功了,而且pod也成功运行了。
此时看HPA的情况如下:
此时问题没有得到解决,虽然Heapster的pod运行起来了,但是HPA还是没能取到CPU使用量的值。
现在的情况来看,此时还不能确定问题是在于Heapster安装没成功还是HPA没能从Heapster中取得值。
所以,接下来就是要确定一下Heapster是否安装成功了。
这个时候,我们想到去Heapster中的docs目录下看看有没有什么debug的方法,也就是进入Heapster目录下的docs中的debugging。
用curl命令对URL/api/v1/model/debug/allkeys 做取值,得到的结果如下:
然后再用kubectl describe hpa yce –namespace=yce命令来查看HPA资源对象的详情
Message中显示,从Heapster获取指标失败。
此时结论就得出了,Heapster已经成功安装,不过集群无法从Heapster中获取到监控数据。
好了,接下来我们决定再给Heapster换一个镜像试试,有可能是我们的镜像版本问题导致与Kubernetes集群不能协同工作。
在docker hub中搜索到了版本为v1.2.0的Heapster镜像,替换为此镜像后再次创建资源对象。
3
创建成功后,惊喜出现了
可以看到,HPA已经可以从Heapster中取到值了。然后用kubectl top node命令查看节点的指标,发现也可以取到值了。
对HPA关联的应用做压力测试
理论上Heapster已经安装成功。为了验证HPA是否可用,我们写了一个简单的http程序,名为helloworldhey。该程序就是做了一个自增整型变量1000次的循环。
将该程序打包成镜像,部署对应的deployment和service资源对象,然后在集群外部通过暴露的节点端口用性能测试工具ab对其进行压力测试。可以看到结果如下:
可以看到,我这里设置的阈值为50%,也就是说,在平均CPU使用率超过50%时,HPA会对pod进行自动的扩容,也即是增加pod的数量,使增加后的pod总数量可以让平均CPU使用率低于50%。可以看到此时的CPU使用率已经为110%,所以,理论上HPA应该自动的拉起2个pod来分担CPU的使用量。看看pod的目前情况,结果如下:
可以看到此时共有三个pod,与预期的结果相同。
不过,可能有人会有疑问,为什么最初创建的pod会重启多次?原因就在于Kubernetes在部署deployment时,每个pod都设置有requests与limits值,当该pod的CPU(或内存)使用量超过该limits值时,kubelet就会重启这个pod,由于在压力测试的开始时刻只有此一个pod,所以CPU使用量肯定是超过了这个limit值于是pod就被重启了。
至此,heapter就被部署成功且可以正常使用了。
欢迎关注译者微信公众号