前面学习使用了一个kubectl scale命令可以来实现Pod的扩缩容功能,但是这个毕竟是完全手动操作的,要应对线上的各种复杂情况,需要能够做到自动化去感知业务,来自动进行扩缩容。为此,k8s提供了一个资源对象:Horizontal Pod Autoscaling(Pod 水平自动伸缩),简称HPA,HPA通过监控分析一些控制器控制的所有Pod的负载变化情况来确定是否需要调整Pod的副本数量,这是HPA最基本的原理:
简单的通过kubectl autoscale命令来创建一个HPA资源对象,HPA Controller默认30s轮询一次(可以通过kube-controller-manager的--horizontal-pod-autoscaler-sync-period参数进行设置),查询指定的资源中Pod的资源使用率,并且与创建时设定的值和指标做对比,从而实现自动伸缩的功能。
Metrics Server
在HPA v1中,需要Heapster提供CPU和内存指标,在HPA v2过后就需要安装Metrics Server,Metric Server可以通过标准的k8s API把监控数据暴露出去,有了Metrics Server之后,可以通过k8s API来访问想要获取的监控数据。
https://10.96.0.1/apis/metrics.k8s.io/v1beta1/namespaces/<namespace-name>/pods/<pod-name>
比如访问上面的API的时候,就可以获取该Pod的资源数据,这些数据其实是来自kubelet的Summary API采集而来的。这里通过标准的API来获取资源监控数据,并不是因为Metrics Server就是APIServer的一部分,而是通过k8s提供的Aggregator汇聚插件来实现的,是独立于APIServer之外运行的。
聚合API
Aggregator允许开发人员编写一个自己的服务,那这个服务注册到k8s的APIServer里面,这样就可以像原生的APIServer提供的API,把自己的服务运行在k8s集群里面,然后k8s的Aggregator通过Service名称就可以转发到自己写的Service里,这个聚合层就带来很多好处:
- 增加了 API 的扩展性,开发人员可以编写自己的 API 服务来暴露他们想要的 API。
- 丰富了 API,核心 kubernetes 团队阻止了很多新的 API 提案,通过允许开发人员将他们的 API 作为单独的服务公开,这样就无须社区繁杂的审查了。
- 开发分阶段实验性 API,新的 API 可以在单独的聚合服务中开发,当它稳定之后,在合并会 APIServer 就很容易了。
- 确保新 API 遵循 Kubernetes 约定,如果没有这里提出的机制,社区成员可能会被迫推出自己的东西,这样很可能造成社区成员和社区约定不一致。
安装
需要在集群中安装Metrics Server服务,要安装Metrics Server就需要开启Aggregator,因为Metrics Server就是通过该代理进行扩展的。集群通过kubeadm安装的,默认是开启的,如果是二进制安装的集群,需要单独配置kube-apiserver添加如下参数:
--requestheader-client-ca-file=<path to aggregator CA cert>
--requestheader-allowed-names=aggregator
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--proxy-client-cert-file=<path to aggregator proxy cert>
--proxy-client-key-file=<path to aggregator proxy key>
如果kube-proxy没有和APIServer运行在同一台主机,那么需要确保启用了如下kube-apisever的参数:
--enable-aggregator-routing=true
证书生成方式,查看官方文档:https://github.com/kubernetes-sigs/apiserver-builder-alpha/blob/master/docs/concepts/auth.md
Aggregator聚合层启动完成后,就可以来安装Metrics Server了,获取该仓库的官方安装资源清单:
# 官方仓库地址:https://github.com/kubernetes-sigs/metrics-server
$ wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.0/components.yaml
在部署之前,修改下资源清单的镜像地址:
hostNetwork: true # 使用hostNetwork模式
containers:
- name: metrics-server
image: cnych/metrics-server:v0.4.0
部署完成后,查看Pod日志:
$ kubectl apply -f components.yaml
$ kubectl get pods -n kube-system -l k8s-app=metrics-server
NAME READY STATUS RESTARTS AGE
metrics-server-84944fdf6b-4ktfk 1/1 Running 0 33s
$ kubectl logs -f metrics-server-84944fdf6b-4ktfk -n kube-system
......
E1107 09:55:23.061340 1 server.go:132] unable to fully scrape metrics: [unable to fully scrape metrics from node node1: unable to fetch metrics from node node1: Get "https://10.151.30.22:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.151.30.22 because it doesn't contain any IP SANs, unable to fully scrape metrics from node master1: unable to fetch metrics from node master1: Get "https://10.151.30.11:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.151.30.11 because it doesn't contain any IP SANs, unable to fully scrape metrics from node node2: unable to fetch metrics from node node2: Get "https://10.151.30.23:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.151.30.23 because it doesn't contain any IP SANs]
I1107 09:55:23.588099 1 secure_serving.go:197] Serving securely on [::]:4443
......
因为部署集群的时候,CA 证书并没有把各个节点的 IP 签上去,所以这里 Metrics Server 通过 IP 去请求时,提示签的证书没有对应的 IP(错误:x509: cannot validate certificate for 10.151.30.22 because it doesn’t contain any IP SANs),我们可以添加一个—kubelet-insecure-tls参数跳过证书校验:
args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
