7、在 Kubernetes 中管理 Prometheus:从静态配置到动态操作
在 Kubernetes 中管理 Prometheus:从静态配置到动态操作
清理测试环境
测试完成后,确保你处于
chapter05/
路径下,执行以下命令清理环境:
vagrant destroy -f
不用担心,若后续需要,你可以轻松重新启动环境。
Kubernetes 中 Prometheus 的管理背景
Kubernetes 是首个从云原生计算基金会(CNCF)毕业的项目,目前已成为容器编排的事实标准。早期,Heapster 作为 Kubernetes 自带的监控解决方案被广泛使用,它最初是将监控数据发送到外部系统的工具,后来逐渐发展成为一个监控系统。然而,不久之后,Prometheus 成为了 Kubernetes 集群的事实标准监控系统。如今,构成 Kubernetes 集群的大多数组件都具有原生的 Prometheus 检测功能。
集成所需准备
要在 Kubernetes 环境中集成 Prometheus,可参考 Kubernetes 项目和 Prometheus Operator 项目的示例。你可以在以下地址分别找到这两个项目的完整源代码:
- Kubernetes 项目:https://github.com/kubernetes/kubernetes
- Prometheus Operator 项目:https://github.com/coreos/prometheus-operator
同时,要确保你拥有在测试环境设置中定义的所有软件,且版本符合要求,特别是以下软件:
- Minikube
- kubectl
静态配置 Prometheus
虽然静态配置方法不太推荐,但它有助于我们更好地理解和排查在 Kubernetes 中运行的 Prometheus 服务器的问题。以下是使用 ConfigMap 定义服务器配置来创建 Prometheus 部署的详细步骤:
搭建 Kubernetes 环境
- 确保没有正在运行的 Minikube 实例,依次执行以下命令:
minikube status
minikube delete
注意,
minikube delete
是一个具有破坏性的指令,执行前请确保保存好工作。
2. 启动一个新的 Minikube 实例,使用以下配置:
minikube start \
--cpus=2 \
--memory=2048 \
--kubernetes-version="v1.14.0" \
--vm-driver=virtualbox
- 启动完成后,可通过以下命令打开 Kubernetes 仪表盘:
minikube dashboard
- 进入正确的仓库路径:
cd chapter05/provision/kubernetes/static
-
使用以下命令创建一个名为
monitoring的新命名空间:
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
kubectl apply -f monitoring-namespace.yaml
你可以在 Kubernetes 仪表盘上验证命名空间是否创建成功。
部署 Prometheus 服务器
- 创建一个简单的 Prometheus 配置,并将其保存到 ConfigMap 中:
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: monitoring
data:
prometheus.yml: |
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- localhost:9090
kubectl apply -f prometheus-configmap.yaml
- 启动一个新的 Prometheus 部署,将之前配置的 ConfigMap 挂载到部署的 Pod 中:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-deployment
namespace: monitoring
labels:
app: prometheus
spec:
template:
spec:
containers:
- name: prometheus
args:
- --config.file=/etc/config/prometheus.yml
- --storage.tsdb.path=/data
volumeMounts:
- name: config-volume
mountPath: /etc/config/prometheus.yml
subPath: prometheus.yml
- name: prometheus-data
mountPath: /data
subPath: ""
volumes:
- name: config-volume
configMap:
name: prometheus-config
- name: prometheus-data
emptyDir: {}
kubectl apply -f prometheus-deployment.yaml
- 查看部署状态:
kubectl rollout status deployment/prometheus-deployment -n monitoring
- 查看 Prometheus 实例的日志:
kubectl logs --tail=20 -n monitoring -l app=prometheus
- 部署成功后,为 Prometheus 实例分配一个新的服务,选择 NodePort 类型以便无需端口转发即可访问:
kind: Service
apiVersion: v1
metadata:
name: prometheus-service
namespace: monitoring
spec:
selector:
app: prometheus
type: NodePort
ports:
- name: prometheus-port
protocol: TCP
port: 9090
targetPort: 9090
kubectl apply -f prometheus-service.yaml
- 检查新的 Prometheus 服务:
minikube service prometheus-service -n monitoring
这将在浏览器中打开 Prometheus 服务端点,你可以通过 Prometheus 网页界面查看运行配置和目标。
为 Prometheus 添加目标
为了演示,我们将部署另一个名为 Hey 的服务,并将其添加到 Prometheus 服务器中:
1. 创建一个新的 Hey 部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hey-deployment
namespace: monitoring
labels:
app: hey
spec:
template:
spec:
containers:
- name: hey
image: kintoandar/hey:v1.0.1
ports:
- name: http
containerPort: 8000
kubectl apply -f hey-deployment.yaml
- 查看部署状态:
kubectl rollout status deployment/hey-deployment -n monitoring
- 查看 Hey 实例的日志:
kubectl logs --tail=20 -n monitoring -l app=hey
- 为 Hey 实例分配一个新的服务,选择 NodePort 类型:
kind: Service
apiVersion: v1
metadata:
name: hey-service
namespace: monitoring
spec:
selector:
app: hey
type: NodePort
ports:
- name: hey-port
protocol: TCP
port: 8000
targetPort: 8000
kubectl apply -f hey-service.yaml
- 检查新的 Hey 服务:
minikube service hey-service -n monitoring
- 由于 Prometheus 是静态管理的,需要更新 Prometheus ConfigMap 以添加新的 Hey 目标:
kind: ConfigMap
metadata:
name: prometheus-config
namespace: monitoring
data:
prometheus.yml: |
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- localhost:9090
- job_name: hey
static_configs:
- targets:
- hey-service.monitoring.svc:8000
kubectl create -f prometheus-configmap-update.yaml -o yaml --dry-run | kubectl apply -f -
- 由于没有触发新的部署,需要更改部署定义中的版本注释并应用新的清单:
kubectl apply -f prometheus-deployment-update.yaml
- 查看部署状态:
kubectl rollout status deployment/prometheus-deployment -n monitoring
片刻后,新的部署将更新 Prometheus 配置,你可以在 Prometheus 网页界面中验证新目标是否添加成功。
在这个静态部署示例中,由于所有 Pod 都在同一命名空间中,且 Prometheus 尚未需要访问 Kubernetes API,因此不需要基于角色的访问控制(RBAC)配置。但在安全的 Kubernetes 设置中,RBAC 是非常重要的。
动态配置:Prometheus Operator
CoreOS 开创了 Operator 模式,它将 Kubernetes 应用程序的打包、部署和管理的复杂性进行了抽象。Operator 将应用程序运行所需的知识(如配置和部署逻辑)整合到 Kubernetes 自定义资源和自定义控制器中。自定义资源扩展了 Kubernetes API,允许自定义 API 定义;自定义控制器则努力实现用户对资源的期望状态,并持续维护该状态。
在我们的场景中,Prometheus Operator 不仅可以管理 Prometheus 服务器的部署(包括 Pod 数量和持久卷),还可以使用 ServiceMonitor 动态更新配置,ServiceMonitor 根据运行容器的标签匹配规则来定位服务。
以下是使用 Prometheus Operator 部署和配置 Prometheus 并添加目标的详细步骤:
搭建 Kubernetes 环境
- 确保没有正在运行的 Minikube 实例,依次执行以下命令:
minikube status
minikube delete
- 启动一个新的 Minikube 实例,使用以下配置:
minikube start \
--cpus=2 \
--memory=2048 \
--kubernetes-version="v1.14.0" \
--vm-driver=virtualbox
- 启动完成后,可通过以下命令打开 Kubernetes 仪表盘:
minikube dashboard
- 进入正确的仓库路径:
cd chapter05/provision/kubernetes/operator
-
使用以下命令创建一个名为
monitoring的新命名空间:
kubectl apply -f monitoring-namespace.yaml
部署 Prometheus Operator
- 确保 Prometheus Operator 具有所有访问权限,首先定义 ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-operator
rules:
- apiGroups: [apiextensions.k8s.io]
verbs: ['*']
resources: [customresourcedefinitions]
- apiGroups: [monitoring.coreos.com]
verbs: ['*']
resources:
- alertmanagers
- prometheuses
- servicemonitors
- 将 ClusterRole 应用到 ClusterRoleBinding 中:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-operator
subjects:
- kind: ServiceAccount
name: prometheus-operator
namespace: monitoring
- 创建一个 ServiceAccount 用于 ClusterRoleBinding:
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus-operator
namespace: monitoring
- 应用包含上述配置的清单:
kubectl apply -f prometheus-operator-rbac.yaml
- 部署 Prometheus Operator 本身:
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
k8s-app: prometheus-operator
name: prometheus-operator
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
k8s-app: prometheus-operator
template:
spec:
serviceAccountName: prometheus-operator
kubectl apply -f prometheus-operator-deployment.yaml
- 查看部署状态:
kubectl rollout status deployment/prometheus-operator -n monitoring
部署 Prometheus 服务器
-
为 Prometheus 实例授予正确的访问控制权限,首先创建一个允许 Prometheus 通过 GET 请求访问
/metrics的 ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-k8s
rules:
- nonResourceURLs:
- /metrics
verbs:
- get
- 创建一个 ClusterRoleBinding,将上述 ClusterRole 的权限授予一个 ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-k8s
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-k8s
subjects:
- kind: ServiceAccount
name: prometheus-k8s
namespace: monitoring
- 创建一个 Prometheus 的 ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus-k8s
namespace: monitoring
- 应用包含上述配置的清单:
kubectl apply -f prometheus-rbac.yaml
- 使用 Prometheus Operator 部署 Prometheus 服务器:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
spec:
baseImage: quay.io/prometheus/prometheus
version: v2.9.2
replicas: 2
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
kubectl apply -f prometheus-server.yaml
- 查看部署进度:
kubectl rollout status statefulset/prometheus-k8s -n monitoring
- 部署完成后,为 Prometheus 服务器创建一个新的服务,并打开网页界面验证当前设置:
kubectl apply -f prometheus-service.yaml
minikube service prometheus-service -n monitoring
为 Prometheus 添加目标
- 部署一个应用程序以增加可用目标,这里再次使用 Hey 应用程序,这次使用默认命名空间:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hey-deployment
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: hey
template:
metadata:
labels:
app: hey
spec:
containers:
- name: hey
image: kintoandar/hey:v1.0.1
ports:
- name: hey-port
containerPort: 8000
kubectl apply -f hey-deployment.yaml
- 查看部署状态:
kubectl rollout status deployment/hey-deployment -n default
- 部署完成后,创建一个新的服务:
kind: Service
metadata:
labels:
squad: frontend
name: hey-service
namespace: default
spec:
selector:
app: hey
type: NodePort
ports:
- name: hey-port
protocol: TCP
port: 8000
targetPort: hey-port
kubectl apply -f hey-service.yaml
- 检查新的 Hey 服务:
minikube service hey-service -n default
-
创建 Prometheus 实例和 Hey 应用程序的 ServiceMonitor,以指示 Operator 配置 Prometheus 并添加所需目标:
- Prometheus 的 ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
k8s-app: prometheus
name: prometheus
namespace: monitoring
spec:
endpoints:
- interval: 30s
port: web
selector:
matchLabels:
prometheus: k8s
- Hey 应用程序的 ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
app: hey
name: hey-metrics
namespace: default
spec:
endpoints:
- interval: 30s
port: hey-port
selector:
matchLabels:
squad: frontend
kubectl apply -f prometheus-servicemonitor.yaml
kubectl apply -f hey-servicemonitor.yaml
- 验证 ServiceMonitor 是否成功部署:
kubectl get servicemonitors --all-namespaces
Operator 重新配置 Prometheus 可能需要几秒钟,之后你可以在 Prometheus 网页界面中看到添加的目标。
ServiceMonitor 是使用 Prometheus Operator 时的主要构建块,你可以配置抓取作业的各种参数,如抓取和超时间隔、要抓取的指标端点、HTTP 查询参数等。相关配置文档可参考:https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint
总结
本文介绍了设置 Prometheus 服务器的一些重要配置概念,这些知识对于根据具体场景定制 Prometheus 非常关键。从启动标志到配置文件,我们还启动了一个实例来验证所学知识。随着越来越多的工作负载迁移到容器,特别是 Kubernetes,我们深入探讨了如何在 Kubernetes 环境中设置和管理 Prometheus。我们从静态配置开始,逐步了解更强大的 Prometheus Operator 方法。
常见问题解答
- 如果未明确声明 scrape_timeout 会怎样?
- 如何让 Prometheus 重新加载其配置文件?
- Prometheus 在认为时间序列过时之前会向前查找多久的数据?
- relabel_configs 和 metric_relabel_configs 有什么区别?
- 在静态部署示例中,我们将 Kubernetes 服务的 Hey 应用程序作为目标添加到 Prometheus 中。如果增加 Hey Pod 的数量会出现什么问题?
- 在 Kubernetes 环境中,Prometheus 静态配置是否有意义?为什么?
- Prometheus Operator 依赖哪些 Kubernetes 功能来实现其目标?
进一步阅读
- Prometheus 配置:https://prometheus.io/docs/prometheus/latest/configuration/configuration/
- Prometheus TSDB API:https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis
- Prometheus 安全:https://prometheus.io/docs/operating/security/
- Kubernetes 自定义控制器:https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-controllers
- Kubernetes 自定义资源:https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions
- Prometheus Operator:https://github.com/coreos/prometheus-operator/blob/master/Documentation/design.md
在 Kubernetes 中管理 Prometheus:从静态配置到动态操作(续)
静态配置与动态配置对比
为了更清晰地了解静态配置和使用 Prometheus Operator 进行动态配置的差异,我们可以通过以下表格进行对比:
| 对比项 | 静态配置 | 动态配置(Prometheus Operator) |
|---|---|---|
| 配置复杂度 | 较高,需要手动管理配置文件和部署更新 | 较低,通过自定义资源和控制器自动管理 |
| 扩展性 | 较差,增加目标时需要手动修改配置并触发部署更新 | 较好,可通过 ServiceMonitor 自动发现和添加目标 |
| 灵活性 | 低,难以适应动态变化的环境 | 高,能根据环境变化自动调整配置 |
| 安全性 | 示例中未使用 RBAC,实际生产中需额外配置 | 可利用 Kubernetes RBAC 进行细粒度权限控制 |
通过这个对比表格,我们可以看出,在大多数生产环境中,动态配置的 Prometheus Operator 更具优势,能够更好地适应复杂多变的 Kubernetes 环境。
静态配置的潜在问题分析
在静态部署示例中,我们将 Kubernetes 服务的 Hey 应用程序作为目标添加到 Prometheus 中。如果增加 Hey Pod 的数量,会出现以下问题:
-
手动更新配置
:由于静态配置需要手动修改 Prometheus 的 ConfigMap 来添加新的目标,当 Hey Pod 数量增加时,需要频繁更新配置文件,容易出错且效率低下。
-
负载均衡问题
:静态配置无法自动处理 Pod 的负载均衡,可能导致某些 Pod 被过度抓取,而其他 Pod 被忽略。
-
缺乏自动发现
:无法自动发现新创建的 Pod,需要人工干预才能将其添加到监控目标中。
Prometheus Operator 的工作原理深入解析
Prometheus Operator 依赖于 Kubernetes 的自定义资源和自定义控制器来实现其目标。下面是其工作原理的 mermaid 流程图:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(用户请求):::process --> B(Kubernetes API Server):::process
B --> C(自定义资源):::process
C --> D(自定义控制器):::process
D --> E(管理 Prometheus 资源):::process
E --> F(创建/更新 Prometheus 实例):::process
F --> G(ServiceMonitor 发现目标):::process
G --> H(自动配置 Prometheus):::process
H --> I(监控目标):::process
从这个流程图可以看出,用户通过 Kubernetes API Server 发起请求,自定义资源和自定义控制器负责处理这些请求,并根据需求管理 Prometheus 资源。ServiceMonitor 会自动发现符合条件的目标,并将其添加到 Prometheus 的配置中,实现动态配置。
配置 Prometheus 的最佳实践
根据前面的介绍和分析,我们可以总结出一些在 Kubernetes 环境中配置 Prometheus 的最佳实践:
1.
优先使用动态配置
:如果可能,尽量使用 Prometheus Operator 进行动态配置,以提高配置的灵活性和可维护性。
2.
合理设置 ServiceMonitor
:在使用 ServiceMonitor 时,要合理设置选择器和端点配置,确保准确发现和监控目标。
3.
启用 RBAC
:在生产环境中,一定要启用基于角色的访问控制(RBAC),确保 Prometheus 对 Kubernetes API 的访问是安全的。
4.
定期备份数据
:Prometheus 的数据非常重要,要定期备份其数据,以防止数据丢失。
5.
监控 Prometheus 自身
:对 Prometheus 自身的性能和健康状况进行监控,及时发现和解决问题。
总结
本文全面介绍了在 Kubernetes 环境中管理 Prometheus 的方法,从静态配置到动态配置的 Prometheus Operator。我们了解了静态配置的基本步骤和存在的问题,以及 Prometheus Operator 的工作原理和优势。通过对比和分析,我们明确了在不同场景下应如何选择合适的配置方式,并总结了配置 Prometheus 的最佳实践。希望这些内容能帮助你更好地在 Kubernetes 中使用 Prometheus 进行监控。
常见问题解答回顾与解答
-
如果未明确声明 scrape_timeout 会怎样?
-
如果未明确声明
scrape_timeout,Prometheus 将使用其默认的抓取超时时间。默认情况下,这个时间通常是 10 秒。这意味着如果一个抓取操作在 10 秒内没有完成,Prometheus 将认为该操作失败,并记录相应的错误信息。
-
如果未明确声明
-
如何让 Prometheus 重新加载其配置文件?
- 在静态配置中,需要手动修改 ConfigMap 并触发新的部署来重新加载配置文件。在使用 Prometheus Operator 时,修改相关的自定义资源(如 Prometheus 或 ServiceMonitor),Operator 会自动检测到更改并重新配置 Prometheus。
-
Prometheus 在认为时间序列过时之前会向前查找多久的数据?
-
Prometheus 通过
stale_timeout参数来控制在认为时间序列过时之前向前查找数据的时间。默认情况下,stale_timeout是 5 分钟。这意味着如果一个时间序列在 5 分钟内没有新的数据点,Prometheus 将认为该序列过时。
-
Prometheus 通过
-
relabel_configs 和 metric_relabel_configs 有什么区别?
-
relabel_configs用于在抓取目标之前对目标的标签进行重新标记,它可以修改或过滤目标的标签,影响哪些目标会被抓取。而metric_relabel_configs用于在抓取到指标后对指标的标签进行重新标记,它可以修改或过滤指标的标签,影响哪些指标会被存储和展示。
-
-
在静态部署示例中,我们将 Kubernetes 服务的 Hey 应用程序作为目标添加到 Prometheus 中。如果增加 Hey Pod 的数量会出现什么问题?
- 如前面所述,会出现手动更新配置、负载均衡问题和缺乏自动发现等问题。
-
在 Kubernetes 环境中,Prometheus 静态配置是否有意义?为什么?
- 在某些简单的测试环境或对配置灵活性要求不高的场景下,静态配置有一定的意义。它可以帮助我们快速搭建一个基本的监控环境,并且有助于理解 Prometheus 在 Kubernetes 中的工作原理。但在大多数生产环境中,由于其缺乏灵活性和可维护性,静态配置的意义不大。
-
Prometheus Operator 依赖哪些 Kubernetes 功能来实现其目标?
- Prometheus Operator 依赖于 Kubernetes 的自定义资源和自定义控制器来实现其目标。自定义资源扩展了 Kubernetes API,允许定义和管理 Prometheus 相关的资源;自定义控制器则负责监控这些资源的状态,并根据用户的需求进行相应的操作,如创建、更新和删除 Prometheus 实例。
进一步探索
随着云原生技术的不断发展,Prometheus 和 Kubernetes 的集成也在不断演进。未来,我们可以进一步探索以下方面:
-
与其他监控系统的集成
:如将 Prometheus 与 Grafana 等可视化工具集成,实现更强大的监控和分析功能。
-
多集群监控
:在多个 Kubernetes 集群中部署和管理 Prometheus,实现跨集群的监控。
-
自动化运维
:结合自动化工具,实现 Prometheus 的自动化部署、配置和升级。
通过不断学习和实践,我们可以更好地利用 Prometheus 和 Kubernetes 的优势,为我们的业务提供更可靠的监控和保障。
更多推荐
所有评论(0)