learn-tech/专栏/Kubernetes入门实战课/30系统监控:如何使用MetricsServer和Prometheus?.md
2024-10-16 06:37:41 +08:00

15 KiB
Raw Blame History

                        因收到Google相关通知网站将会择期关闭。相关通知内容
                        
                        
                        30 系统监控如何使用Metrics Server和Prometheus
                        你好我是Chrono。

在前面的两节课里我们学习了对Pod和对集群的一些管理方法其中的要点就是设置资源配额让Kubernetes用户能公平合理地利用系统资源。

虽然有了这些方法但距离我们把Pod和集群管好用好还缺少一个很重要的方面——集群的可观测性。也就是说我们希望给集群也安装上“检查探针”观察到集群的资源利用率和其他指标让集群的整体运行状况对我们“透明可见”这样才能更准确更方便地做好集群的运维工作。

但是观测集群是不能用“探针”这种简单的方式的所以今天我就带你一起来看看Kubernetes为集群提供的两种系统级别的监控项目Metrics Server和Prometheus以及基于它们的水平自动伸缩对象HorizontalPodAutoscaler。

Metrics Server

如果你对Linux系统有所了解的话也许知道有一个命令 top 能够实时显示当前系统的CPU和内存利用率它是性能分析和调优的基本工具非常有用。Kubernetes也提供了类似的命令就是 kubectl top不过默认情况下这个命令不会生效必须要安装一个插件Metrics Server才可以。

Metrics Server是一个专门用来收集Kubernetes核心资源指标metrics的工具它定时从所有节点的kubelet里采集信息但是对集群的整体性能影响极小每个节点只大约会占用1m的CPU和2MB的内存所以性价比非常高。

下面的这张图来自Kubernetes官网你可以对Metrics Server的工作方式有个大概了解它调用kubelet的API拿到节点和Pod的指标再把这些信息交给apiserver这样kubectl、HPA就可以利用apiserver来读取指标了

在Metrics Server的项目网址https://github.com/kubernetes-sigs/metrics-server可以看到它的说明文档和安装步骤不过如果你已经按照[第17讲]用kubeadm搭建了Kubernetes集群就已经具备了全部前提条件接下来只需要几个简单的操作就可以完成安装

Metrics Server的所有依赖都放在了一个YAML描述文件里你可以使用wget或者curl下载

wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

但是在 kubectl apply 创建对象之前,我们还有两个准备工作要做。

第一个工作是修改YAML文件。你需要在Metrics Server的Deployment对象里加上一个额外的运行参数 --kubelet-insecure-tls也就是这样

apiVersion: apps/v1 kind: Deployment metadata: name: metrics-server namespace: kube-system spec: ... ... template: spec: containers: - args: - --kubelet-insecure-tls ... ...

这是因为Metrics Server默认使用TLS协议要验证证书才能与kubelet实现安全通信而我们的实验环境里没有这个必要加上这个参数可以让我们的部署工作简单很多生产环境里就要慎用

第二个工作是预先下载Metrics Server的镜像。看这个YAML文件你会发现Metrics Server的镜像仓库用的是gcr.io下载很困难。好在它也有国内的镜像网站你可以用[第17讲]里的办法,下载后再改名,然后把镜像加载到集群里的节点上。

这里我给出一段Shell脚本代码供你参考

repo=registry.aliyuncs.com/google_containers

name=k8s.gcr.io/metrics-server/metrics-server:v0.6.1 src_name=metrics-server:v0.6.1

docker pull $repo/$src_name

docker tag $repo/$src_name $name docker rmi $repo/$src_name

两个准备工作都完成之后我们就可以使用YAML部署Metrics Server了

kubectl apply -f components.yaml

Metrics Server属于名字空间“kube-system”可以用 kubectl get pod 加上 -n 参数查看它是否正常运行:

kubectl get pod -n kube-system

现在有了Metrics Server插件我们就可以使用命令 kubectl top 来查看Kubernetes集群当前的资源状态了。它有两个子命令node 查看节点的资源使用率pod 查看Pod的资源使用率。

由于Metrics Server收集信息需要时间我们必须等一小会儿才能执行命令查看集群里节点和Pod状态

kubectl top node kubectl top pod -n kube-system

从这个截图里你可以看到:

集群里两个节点CPU使用率都不高分别是8%和4%但内存用的很多master节点用了差不多一半48%而worker节点几乎用满了89%)。 名字空间“kube-system”里有很多Pod其中apiserver最消耗资源使用了75m的CPU和363MB的内存。

HorizontalPodAutoscaler

有了Metrics Server我们就可以轻松地查看集群的资源使用状况了不过它另外一个更重要的功能是辅助实现应用的“水平自动伸缩”。

在[第18讲]里我们提到有一个命令 kubectl scale可以任意增减Deployment部署的Pod数量也就是水平方向的“扩容”和“缩容”。但是手动调整应用实例数量还是比较麻烦的需要人工参与也很难准确把握时机难以及时应对生产环境中突发的大流量所以最好能把这个“扩容”“缩容”也变成自动化的操作。

Kubernetes为此就定义了一个新的API对象叫做“HorizontalPodAutoscaler”简称是“hpa”。顾名思义它是专门用来自动伸缩Pod数量的对象适用于Deployment和StatefulSet但不能用于DaemonSet原因很明显吧

HorizontalPodAutoscaler的能力完全基于Metrics Server它从Metrics Server获取当前应用的运行指标主要是CPU使用率再依据预定的策略增加或者减少Pod的数量。

下面我们就来看看该怎么使用HorizontalPodAutoscaler首先要定义Deployment和Service创建一个Nginx应用作为自动伸缩的目标对象

apiVersion: apps/v1 kind: Deployment metadata: name: ngx-hpa-dep

spec: replicas: 1 selector: matchLabels: app: ngx-hpa-dep

template: metadata: labels: app: ngx-hpa-dep spec: containers: - image: nginx:alpine name: nginx ports: - containerPort: 80

    resources:
      requests:
        cpu: 50m
        memory: 10Mi
      limits:
        cpu: 100m
        memory: 20Mi

apiVersion: v1 kind: Service metadata: name: ngx-hpa-svc spec: ports:

  • port: 80 protocol: TCP targetPort: 80 selector: app: ngx-hpa-dep

在这个YAML里我只部署了一个Nginx实例名字是 ngx-hpa-dep。注意在它的 spec 里一定要用 resources 字段写清楚资源配额否则HorizontalPodAutoscaler会无法获取Pod的指标也就无法实现自动化扩缩容。

接下来我们要用命令 kubectl autoscale 创建一个HorizontalPodAutoscaler的样板YAML文件它有三个参数

minPod数量的最小值也就是缩容的下限。 maxPod数量的最大值也就是扩容的上限。 cpu-percentCPU使用率指标当大于这个值时扩容小于这个值时缩容。

现在我们就来为刚才的Nginx应用创建HorizontalPodAutoscaler指定Pod数量最少2个最多10个CPU使用率指标设置的小一点5%,方便我们观察扩容现象:

export out="--dry-run=client -o yaml" # 定义Shell变量 kubectl autoscale deploy ngx-hpa-dep --min=2 --max=10 --cpu-percent=5 $out

得到的YAML描述文件就是这样

apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: ngx-hpa

spec: maxReplicas: 10 minReplicas: 2 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: ngx-hpa-dep targetCPUUtilizationPercentage: 5

我们再使用命令 kubectl apply 创建这个HorizontalPodAutoscaler后它会发现Deployment里的实例只有1个不符合min定义的下限的要求就先扩容到2个

从这张截图里你可以看到HorizontalPodAutoscaler会根据YAML里的描述找到要管理的Deployment把Pod数量调整成2个再通过Metrics Server不断地监测Pod的CPU使用率。

下面我们来给Nginx加上压力流量运行一个测试Pod使用的镜像是“httpd:alpine”它里面有HTTP性能测试工具abApache Bench

kubectl run test -it --image=httpd:alpine -- sh

然后我们向Nginx发送一百万个请求持续1分钟再用 kubectl get hpa 来观察HorizontalPodAutoscaler的运行状况

ab -c 10 -t 60 -n 1000000 'http://ngx-hpa-svc/'

因为Metrics Server大约每15秒采集一次数据所以HorizontalPodAutoscaler的自动化扩容和缩容也是按照这个时间点来逐步处理的。

当它发现目标的CPU使用率超过了预定的5%后就会以2的倍数开始扩容一直到数量上限然后持续监控一段时间如果CPU使用率回落就会再缩容到最小值。

Prometheus

显然有了Metrics Server和HorizontalPodAutoscaler的帮助我们的应用管理工作又轻松了一些。不过Metrics Server能够获取的指标还是太少了只有CPU和内存想要监控到更多更全面的应用运行状况还得请出这方面的权威项目“Prometheus”。

其实Prometheus的历史比Kubernetes还要早一些它最初是由Google的离职员工在2012年创建的开源项目灵感来源于Borg配套的BorgMon监控系统。后来在2016年Prometheus作为第二个项目加入了CNCF并在2018年继Kubernetes之后顺利毕业成为了CNCF的不折不扣的“二当家”也是云原生监控领域的“事实标准”。

和Kubernetes一样Prometheus也是一个庞大的系统我们这里就只做一个简略的介绍。

下面的这张图是Prometheus官方的架构图几乎所有文章在讲Prometheus的时候必然要拿出来所以我也没办法“免俗”

Prometheus系统的核心是它的Server里面有一个时序数据库TSDB用来存储监控数据另一个组件Retrieval使用拉取Pull的方式从各个目标收集数据再通过HTTP Server把这些数据交给外界使用。

在Prometheus Server之外还有三个重要的组件

Push Gateway用来适配一些特殊的监控目标把默认的Pull模式转变为Push模式。 Alert Manager告警中心预先设定规则发现问题时就通过邮件等方式告警。 Grafana是图形化界面可以定制大量直观的监控仪表盘。

由于同属于CNCF所以Prometheus自然就是“云原生”在Kubernetes里运行是顺理成章的事情。不过它包含的组件实在是太多部署起来有点麻烦这里我选用了“kube-prometheus”项目https://github.com/prometheus-operator/kube-prometheus/),感觉操作起来比较容易些

下面就跟着我来在Kubernetes实验环境里体验一下Prometheus吧。

我们先要下载kube-prometheus的源码包当前的最新版本是0.11

wget https://github.com/prometheus-operator/kube-prometheus/archive/refs/tags/v0.11.0.tar.gz

解压缩后Prometheus部署相关的YAML文件都在 manifests 目录里有近100个你可以先大概看一下。

和Metrics Server一样我们也必须要做一些准备工作才能够安装Prometheus。

第一步,是修改 prometheus-service.yaml、grafana-service.yaml。

这两个文件定义了Prometheus和Grafana服务对象我们可以给它们添加 type: NodePort参考[第20讲]这样就可以直接通过节点的IP地址访问当然你也可以配置成Ingress

第二步,是修改 kubeStateMetrics-deployment.yaml、prometheusAdapter-deployment.yaml因为它们里面有两个存放在gcr.io的镜像必须解决下载镜像的问题。

但很遗憾我没有在国内网站上找到它们的下载方式为了能够顺利安装只能把它们下载后再上传到Docker Hub上。所以你需要修改镜像名字把前缀都改成 chronolaw

image: k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.5.0 image: k8s.gcr.io/prometheus-adapter/prometheus-adapter:v0.9.1

image: chronolaw/kube-state-metrics:v2.5.0 image: chronolaw/prometheus-adapter:v0.9.1

这两个准备工作完成之后,我们要执行两个 kubectl create 命令来部署Prometheus先是 manifests/setup 目录,创建名字空间等基本对象,然后才是 manifests 目录:

kubectl create -f manifests/setup kubectl create -f manifests

Prometheus的对象都在名字空间“monitoring”里创建之后可以用 kubectl get 来查看状态:

确定这些Pod都运行正常我们再来看看它对外的服务端口

kubectl get svc -n monitoring

前面修改了Grafana和Prometheus的Service对象所以这两个服务就在节点上开了端口Grafana是“30358”Prometheus有两个端口其中“9090”对应的“30827”是Web端口。

在浏览器里输入节点的IP地址我这里是“http://192.168.10.210”再加上端口号“30827”我们就能看到Prometheus自带的Web界面

Web界面上有一个查询框可以使用PromQL来查询指标生成可视化图表比如在这个截图里我就选择了“node_memory_Active_bytes”这个指标意思是当前正在使用的内存容量。

Prometheus的Web界面比较简单通常只用来调试、测试不适合实际监控。我们再来看Grafana访问节点的端口“30358”我这里是“http://192.168.10.210:30358”它会要求你先登录默认的用户名和密码都是“admin”

Grafana内部已经预置了很多强大易用的仪表盘你可以在左侧菜单栏的“Dashboards - Browse”里任意挑选一个

比如我选择了“Kubernetes / Compute Resources / Namespace (Pods)”这个仪表盘就会出来一个非常漂亮图表比Metrics Server的 kubectl top 命令要好看得多,各种数据一目了然:

关于Prometheus就暂时介绍到这里再往下讲可能就要偏离我们的Kubernetes主题了如果你对它感兴趣的话可以课后再去它的官网上看文档或者参考其他的学习资料。

小结

在云原生时代系统的透明性和可观测性是非常重要的。今天我们一起学习了Kubernetes里的两个系统监控项目命令行方式的Metrics Server、图形化界面的Prometheus利用好它们就可以让我们随时掌握Kubernetes集群的运行状态做到“明察秋毫”。

再简单小结一下今天的内容:

Metrics Server是一个Kubernetes插件能够收集系统的核心资源指标相关的命令是 kubectl top。 Prometheus是云原生监控领域的“事实标准”用PromQL语言来查询数据配合Grafana可以展示直观的图形界面方便监控。 HorizontalPodAutoscaler实现了应用的自动水平伸缩功能它从Metrics Server获取应用的运行指标再实时调整Pod数量可以很好地应对突发流量。

课下作业

最后是课下作业时间,给你留两个思考题:

部署了HorizontalPodAutoscaler之后如果再执行 kubectl scale 手动扩容会发生什么呢? 你有过应用监控的经验吗?应该关注哪些重要的指标呢?

非常期待在留言区看到你的发言,同我同其他同学一起讨论。我们下节课再见。