恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Kubernetes 集群与应用监控实战:从 Heapster 到 Prometheus 的云原生可观测体系
首页
资讯中心
/
Kubernetes 集群与应用监控实战:从 Heapster 到 Prometheus 的云原生可观测体系
Kubernetes 集群与应用监控实战:从 Heapster 到 Prometheus 的云原生可观测体系
发布时间:2026/9/24 19:49:01
Kubernetes 集群与应用监控实战从 Heapster 到 Prometheus 的云原生可观测体系【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbookKubernetes 将复杂的应用环境管理变得简单但要对集群自身的各组件以及运行在其上的应用做到良好洞察却并不容易。本文以 Kubernetes Handbook 的监控实践为主线完整讲解 Kubernetes 监控的三大层次集群组件、Pod、应用、cAdvisor 数据模型与容器命名规则、Heapster/InfluxDB/Grafana 的部署与 API 使用、应用级监控架构以及基于 Weave Scope 的应用拓扑可视化并梳理 Prometheus 作为新一代云原生监控方案的核心组件与适用边界。读完本文你将掌握一套可落地的 Kubernetes 监控体系搭建与数据获取方法。Kubernetes 监控为什么比传统监控更难Kubernetes 对应用做了大量抽象Deployment、Service、Pod 等在生产环境下这些不同抽象组件的健康状态监控是迫在眉睫的事。与物理机和虚拟机的监控不同Kubernetes 集群的监控多了一层虚拟化抽象在 docker 容器之上Kubernetes 又抽象出 Pod 和 Service 的概念监控复杂度显著提升。实践中需要关注三个方面Kubernetes 集群本身的监控主要是 apiserver、kubelet、controller-manager、scheduler 等集群组件的健康与性能集群中 Pod 的监控Pod 的 CPU、内存、网络、磁盘等资源指标集群内部应用的监控针对应用本身的运行状态、业务指标进行监控。在设计 Kubernetes 监控方案时还应重点思考以下问题应该给 Pod 打上哪些 label这些 label 将直接成为监控的 metric 标签应用的 Pod 漂移重建、调度到其他节点之后怎么办Pod 的生命周期远比虚拟机、物理机短如何持续追踪应用状态监控项如何覆盖更多层次Kubernetes 本身、容器、应用监控指标从哪里取是通过 Heapster 收集汇聚还是直接从每台主机的 docker 上取原始数据。理解数据源头cAdvisor 与容器命名规则要设计好监控方案首先需要弄清楚 cAdvisor 收集的数据格式与字段含义。通过访问${NODE_IP}:4194/api/v1.3/docker获取的 JSON 结果中某个容器包含如下字段labels: { annotation.io.kubernetes.container.hash: f47f0602, annotation.io.kubernetes.container.ports: [{\containerPort\:80,\protocol\:\TCP\}], annotation.io.kubernetes.container.restartCount: 0, annotation.io.kubernetes.container.terminationMessagePath: /dev/termination-log, annotation.io.kubernetes.container.terminationMessagePolicy: File, annotation.io.kubernetes.pod.terminationGracePeriod: 30, io.kubernetes.container.logpath: /var/log/pods/d8a2e995-3617-11e7-a4b0-ecf4bbe5d414/php-redis_0.log, io.kubernetes.container.name: php-redis, io.kubernetes.docker.type: container, io.kubernetes.pod.name: frontend-2337258262-771lz, io.kubernetes.pod.namespace: default, io.kubernetes.pod.uid: d8a2e995-3617-11e7-a4b0-ecf4bbe5d414, io.kubernetes.sandbox.id: 843a0f018c0cef2a5451434713ea3f409f0debc2101d2264227e814ca0745677 }这些信息是 Kubernetes 创建容器时给 docker container 打的Labels使用docker inspect $container_name命令同样可以看到。问题在于这些 label 与容器名字有什么关系在 node 节点上执行docker ps看到的容器名又对应哪个应用的 Pod在 Kubernetes 的 kubelet 代码pkg/kubelet/dockertools/docker.go中BuildDockerName方法定义了容器的名称规范核心代码如下// Creates a name which can be reversed to identify both full pod name and container name. // This function returns stable name, unique name and a unique id. // Although rand.Uint32() is not really unique, but its enough for us because error will // only occur when instances of the same container in the same pod have the same UID. The // chance is really slim. func BuildDockerName(dockerName KubeletContainerName, container *v1.Container) (string, string, string) { containerName : dockerName.ContainerName . strconv.FormatUint(kubecontainer.HashContainerLegacy(container), 16) stableName : fmt.Sprintf(%s_%s_%s_%s, containerNamePrefix, containerName, dockerName.PodFullName, dockerName.PodUID) UID : fmt.Sprintf(%08x, rand.Uint32()) return stableName, fmt.Sprintf(%s_%s, stableName, UID), UID } // Unpacks a container name, returning the pod full name and container name we would have used to // construct the docker name. If we are unable to parse the name, an error is returned. func ParseDockerName(name string) (dockerName *KubeletContainerName, hash uint64, err error) { // For some reason docker appears to be appending / to names. // If its there, strip it. name strings.TrimPrefix(name, /) parts : strings.Split(name, _) if len(parts) 0 || parts[0] ! containerNamePrefix { err fmt.Errorf(failed to parse Docker container name %q into parts, name) return nil, 0, err } if len(parts) 6 { // We have at least 5 fields. We may have more in the future. glog.Warningf(found a container with the %q prefix, but too few fields (%d): %q, containerNamePrefix, len(parts), name) err fmt.Errorf(Docker container name %q has less parts than expected %v, name, parts) return nil, 0, err } nameParts : strings.Split(parts[1], .) containerName : nameParts[0] if len(nameParts) 1 { hash, err strconv.ParseUint(nameParts[1], 16, 32) if err ! nil { glog.Warningf(invalid container hash %q in container %q, nameParts[1], name) } } podFullName : parts[2] _ parts[3] podUID : types.UID(parts[4]) return KubeletContainerName{podFullName, podUID, containerName}, hash, nil }从中可以看出容器名称的组成字段之间用下划线隔开至少包含 6 个字段未来可能更多其中四个基本字段为containerNamePrefix_containerName_PodFullName_PodUID所有由 Kubernetes 启动的容器的containerNamePrefix都是k8s。containerName字段由容器名 容器配置 hash构成如php-redis.f47f0602PodFullName则由 Deployment/ReplicaSet 生成的 pod 名与命名空间拼合而成。下面以官方示例 guestbook 为例。Deployment 名为frontend其中启动了名为php-redis的容器副本数为 3其配置如下apiVersion: extensions/v1beta1 kind: Deployment metadata: name: frontend spec: template: metadata: labels: app: guestbook tier: frontend spec: containers: - name: php-redis image: harbor-001.jimmysong.io/library/gb-frontend:v4 resources: requests: cpu: 100m memory: 100Mi env: - name: GET_HOSTS_FROM value: dns ports: - containerPort: 80选取三个实例中的一个运行 php-redis 的 docker 容器在节点上docker ps会看到类似k8s_php-redis_frontend-2337258262-154p7_default_d8a2e2dd-3617-11e7-a4b0-ecf4bbe5d414_0逐字段解析containerNamePrefixk8scontainerNamephp-redispodFullNamefrontend-2337258262-154p7computeHash154p7deploymentNamefrontendreplicaSetNamefrontend-2337258262namespacedefaultpodUIDd8a2e2dd-3617-11e7-a4b0-ecf4bbe5d414理解了命名规则就可以在监控采集时把 node 上的 docker 容器准确反查到其所属的 Pod、ReplicaSet、Deployment 与 namespace从而把容器级原始指标与业务应用对应起来。使用 Heapster 进行集群监控Heapster 是 Kubernetes 官方提供的监控方案仓库中的安装说明见 heapster 插件安装。安装 Kubernetes 集群时默认会安装该插件可对集群上的应用做基础监控获取Pod 级别的内存、CPU和网络监控信息同时通过 API 暴露 Kubernetes 中的基本资源监控指标。完整部署清单位于仓库的 manifests/heapster 目录包括以下文件heapster-deployment.yaml、heapster-service.yamlHeapster 主进程及其 Serviceinfluxdb-deployment.yaml、influxdb-service.yaml、influxdb-cm.yaml时序数据库 InfluxDB 及配置grafana-deployment.yaml、grafana-service.yaml可视化面板 Grafanaheapster-rbac.yamlHeapster 所需的 RBAC 权限。从 heapster-deployment.yaml 可以看出 Heapster 的启动方式与数据链路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: harbor-001.jimmysong.io/library/heapster-amd64:v1.4.3 imagePullPolicy: IfNotPresent command: - /heapster - --sourcekubernetes:https://kubernetes.default - --sinkinfluxdb:http://monitoring-influxdb:8086关键参数只有两个--source指定数据源通过 kubelet 的 cAdvisor 采集节点与容器指标--sink指定数据输出端本例为 InfluxDB。Heapster 收集 Node 节点上的 cAdvisor 数据并可按照 Kubernetes 的资源类型聚合资源例如 Pod、Namespace 域分别获取其 CPU、内存、网络和磁盘的 metric默认的 metric 数据聚合时间间隔是 1 分钟。在 Grafana 中按 label 增加 service 层分类默认安装的 Grafana 面板只根据 Namespace 和 Pod 两层来分类展示指标实在有些单薄。可以在不改变原有架构的基础上通过应用的自定义 label 来区分不同应用的 Pod从而在监控面板中增加 service 这一层分类维度。Heapster 的部署细节镜像替换与 InfluxDB 配置官方镜像保存在 gcr.io 中需要提前拷贝到私有仓库。部署时主要修改点包括grafana-deployment将镜像替换为私有仓库地址并把GF_SERVER_ROOT_URL设置为/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/。如果后续使用 kube-apiserver 或kubectl proxy访问 Grafana dashboard则必须这样设置否则访问 Grafana 时提示找不到.../api/dashboards/home页面influxdb-deploymentInfluxDB 从 v1.1.0 开始默认关闭 admin UI。开启办法是先导出镜像内的 influxdb 配置文件将[admin]段的enabled false改为true然后通过kubectl create configmap influxdb-config --from-fileconfig.toml -n kube-system创建 ConfigMap最后在 Deployment 中挂载到/etc/覆盖原始配置仓库中的 influxdb-cm.yaml 即为修改后的完整配置influxdb-service将 Service 类型改为NodePort并额外增加 8083admin端口映射便于后续浏览器访问 admin UI。部署时执行kubectl create -f .或对每个文件kubectl apply后可通过如下命令检查结果$ kubectl get deployments -n kube-system | grep -E heapster|monitoring heapster 1 1 1 1 2m monitoring-grafana 1 1 1 1 2m monitoring-influxdb 1 1 1 1 2m访问 Grafana 有两种途径通过kubectl cluster-info获取 monitoring-grafana 服务 URL 后经 kube-apiserver 代理访问形如http://172.20.0.113:8080/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana或先运行kubectl proxy --address172.20.0.113 --port8086 --accept-hosts^*$再经代理端口访问。注意安装 Grafana 后默认模板中 namespace 选择里只有default和kube-system这并非其他 namespace 的指标没被监控只是没有开启显示。将 Templating 中 namespace 的 Data source 设置为 influxdb-datasource、Refresh 设置为 on Dashboard Load 并保存刷新浏览器即可看到其他 namespace 选项。通过 Heapster API 获取集群对象的 metricHeapster 提供 RESTful API可用kubectl cluster-info获取其地址$ kubectl cluster-info Heapster is running at https://172.20.0.113:6443/api/v1/proxy/namespaces/kube-system/services/heapster ...以获取spark-clusternamespace 的 memory usage 为例构造完整 URLhttps://172.20.0.113:6443/api/v1/proxy/namespaces/kube-system/services/heapster/api/v1/model/namespaces/spark-cluster/metrics/memory/usage?start2017-10-16T09:14:00Zend2017-10-16T09:16:00ZURL 分为三部分API 地址https://172.20.0.113:6443/api/v1/proxy/namespaces/kube-system/services/heapster/API 参数/api/v1/model/namespaces/spark-cluster/metrics/memory/usage表示查询spark-clusternamespace 中的memory/usage指标时间片?start...end...使用 RFC-3339 时间格式Linux 下可用date --rfc-3339seconds生成将空格替换为T、时区偏移替换为Z也可以只指定 startend 自动取当前时间。返回结果示例{ metrics: [ { timestamp: 2017-10-16T09:14:00Z, value: 322592768 }, { timestamp: 2017-10-16T09:15:00Z, value: 322592768 }, { timestamp: 2017-10-16T09:16:00Z, value: 322592768 } ], latestTimestamp: 2017-10-16T09:16:00Z }注意Heapster 中查询的所有值都以最小单位表示例如 CPU 为 1 milicore内存为 B字节。Heapster 同时被 Horizontal Pod Autoscaling 用作Resource Metrics API在kube-controller-manager中配置指向 kube-aggregator 的--api-server或在启动 heapster 时指定--api-servertrue。版本提示Kubernetes 1.11 起不建议使用 Heapster。SIG Instrumentation 正持续转向新的 Kubernetes 监控模型仍使用 Heapster 做自动扩展的集群应迁移到 metrics-server 与自定义指标 API。Prometheus面向云原生的新一代监控方案Heapster 解决了能监控的问题但 Prometheus 的出现提供了更强大的指标模型与查询能力。Prometheus 由 SoundCloud 开源2012 年开始编写代码2015 年在 GitHub 上开源2016 年成为继 Kubernetes 之后第二个加入 CNCF 的项目成员也是第二个正式毕业的项目。作为新一代开源解决方案其很多设计理念与 Google SRE 运维之道不谋而合。云原生时代监控对象随微服务和容器化呈指数级增加监控对象的生命周期也更短暂因此需要一款统一监控指标与数据查询语言的工具。Prometheus 主要功能包括多维数据模型时序由 metric 名字和 k/v 的 labels 构成灵活的查询语句 PromQL无依赖存储支持 local 和 remote 不同模型采用 http 协议、pull 模式拉取数据简单易懂监控目标支持服务发现或静态配置支持多种统计数据模型图形化友好。其核心组件包括Prometheus Server抓取数据、存储时序数据并提供查询和 Alert Rule 配置管理client libraries用于对接 Prometheus Server查询和上报数据push gateway批量、短期监控数据的汇总节点主要用于业务数据汇报exporters各类指标导出器如机器指标 node_exporter、MongoDB exporter 等alertmanager告警通知管理负责聚合、去重、降噪后发送告警。其工作逻辑是Prometheus server 定期从静态配置或服务发现的目标拉取数据当新拉取数据大于配置内存缓存区时将数据持久化到磁盘remote storage 则持久化到云端配置 rule 后定时查询数据条件触发时将 alert 推送到 Alertmanager最终可通过 API、Prometheus Console 或 Grafana 查询和聚合数据。适用边界Prometheus 的数据是基于时序的 float64 值若你的数据还有其他类型则无法满足它也不适合做审计计费——审计计费需要记录每个请求并长期存储数据而 Prometheus 关注的是系统运行瞬时状态与趋势能容忍少量数据丢失。这类场景需要专门的审计系统。应用监控基于 Kubernetes API 的指标采集架构对于集群内应用的监控可以采用如下架构通过访问 Kubernetes API 获取应用 Pod 的 IP 和端口将 Pod labels 作为监控 metric 的 tag直接访问应用的 Pod IP 和端口获取应用监控数据最后将 metrics 发送到存储与展示系统。这种方式有以下几个要点访问 Kubernetes API 获取应用 Pod 的 IP 和端口Pod labels 作为监控 metric 的 tag直接访问应用的 Pod 的 IP 和端口获取应用监控数据metrics 发送到存储与展示平台统一管理。当应用 Pod 发生漂移时由于始终通过 Kubernetes API 动态获取最新 Pod 地址监控采集可跟随应用实例的生命周期持续工作这正是容器化应用监控与传统监控的关键差异。应用拓扑状态图用 Weave Scope 一览集群全景对于复杂的应用编排和依赖关系我们希望能有清晰的图来一览应用状态和拓扑关系。可以使用 Weaveworks 开源的 scope。仓库提供了完整的部署清单 manifests/weave/scope.yaml其中定义了weave-scope-app Deploymentweaveworks/scope:1.5.1--no-probe与对应的 Service端口 80 → 容器 4040weave-scope-agent DaemonSet以hostNetwork: true、hostPID: true方式在每个节点运行挂载 docker socket--probe.dockertrue并启用 Kubernetes 探针--probe.kubernetestrue配套的 ServiceAccount、ClusterRole 与 ClusterRoleBindingRBAC安装于kube-systemnamespace。安装方式为$ kubectl apply -f scope.yaml由于服务安装在kube-systemnamespace 下可创建一个新的 Ingress如kube-system.yaml暴露访问入口apiVersion: extensions/v1beta1 kind: Ingress metadata: name: traefik-ingress namespace: kube-system spec: rules: - host: scope.weave.io http: paths: - path: / backend: serviceName: weave-scope-app servicePort: 80执行kubectl apply -f kube-system.yaml后在主机/etc/hosts中添加一条记录172.20.0.119 scope.weave.io浏览器访问scope.weave.io即可打开应用拓扑界面。如上图所示scope 可以监控 Kubernetes 集群中一系列资源的状态、资源使用情况、应用拓扑、扩缩容还可以直接通过浏览器进入容器内部进行调试等。小结一套完整的 Kubernetes 监控体系通常由三层组成集群组件监控apiserver、kubelet 等、Pod 资源监控CPU、内存、网络、磁盘和应用业务监控。数据层面需要理解 cAdvisor 的原始数据模型与容器命名规则才能把容器指标准确反查到 Pod/Deployment 维度采集与存储层面Heapster InfluxDB Grafana 是入门最轻的官方组合而 Prometheus 凭借多维数据模型、PromQL 与服务发现能力成为云原生监控的主流选择可视化和拓扑层面Weave Scope 提供了直观的集群与依赖关系视图。仓库中 practice/monitor.md、practice/monitoring.md、practice/using-heapster-to-get-object-metrics.md 与 manifests/heapster 目录提供了完整的部署清单与 API 使用细节practice/prometheus.md 给出了 Prometheus 的组件与架构总览可作为继续深入实践的入口。【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考