使用 kube-prometheus 部署完整的 prometheus 监控
·
使用 kube-prometheus 部署完整的 prometheus 监控
kube-prometheus 是一个开源项目,其目的是提供基于 prometheus-operator 的,容易部署到 Kubernetes 集群的监控方案。
1. 部署说明
操作系统及已部署程序信息
| 程序 | 版本 |
|---|---|
| OS | CentOS-Stream-9-20241007.0 |
| Linuex Kernel | 5.14.0-514.el9.x86_64 |
| kubernetes | v1.32.5.x86_64 |
| docker-ce | 24.0.9-1.el9.x86_64 |
| containerd | 1.7.22-3.1.el9.x86_64 |
| cri-docker | 0.3.20.el9.x86_64 |
| flannel | v0.24.2 |
主机信息
| 节点 | ip | 容器运行时 |
|---|---|---|
| master1 | 192.167.16.116 | docker |
| node1 | 192.167.16.117 | docker |
| node2 | 192.167.16.118 | containerd |
注意:
kube-prometheus 的版本选择可以参考其兼容性说明,尽量选择与 kubernetes 相兼容的版本。兼容性表明当时在对应的kubenetes 版本上进行了测试。
部署情况说明:
- 本次部署 kubernetes 版本为 1.32.5,选择 kube-prometheus v0.16;
- 将 prometheus,grafana 和 alertmanager 通过 nodeport 暴漏;
- 因 prometheus 被扫出过未授权访问的漏洞,所以开启 prometheus basic-auth 认证,开启认证涉及到 prometheus 自身,grafana 的数据源配置调整;
- 开启 prometheus 多副本部署,加载 thanos sidecar 组件;
- etcd 是由 kubeadm 部署的静态 Pod,本次增加了静态 ectd 的监控(prometheusRule 和 serviceMonitor),在 grafana 中也增加了 etcd 的图表。
- kubernetes 是由 kubeadm 部署的,kube-controllerManager 和 kube-scheduler 都默认绑定 127.0.0.1,如果不处理对应的 target 就是是异常的,该问题需要调整两个的服务绑定 ip;
注意:
- etcd 的地址和证书路径需要按需修改为实际的地址
- 此处的密码都默认为 1234567,如需修改,已在每处密码信息都标注了对应的密码生成方案。
2. 参考链接
github - kube-prometheus
jsonnet - jsonnet
夸克网盘 - 所需镜像
3. 基础依赖安装
# 安装 git
yum install git
# 安装 gog
yum install go
# 设置 go 的源为国内源
go env -w GOPROXY=https://goproxy.cn,direct
# 修改环境变量,增加 gopath
export PATH=$PATH:/root/go/bin
# 安装 gojsontoyaml
go install github.com/brancz/gojsontoyaml@latest
# 安装 jsonnet
go install github.com/google/go-jsonnet/cmd/jsonnet@latest
# 安装 jb(jsonnet-bundler) 这个是 jsonnet 的包管理器
go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest
4. 下载 kube-prometheus 的 jsonnet 包
先根据 kubernetes 版本确认 kube-prometheus 的版本。本例以 kubernetes v1.32.5 为例,对应 kube-prometheus release-0.16 版本。
# 创建目录
mkdir -p /root/kube-prometheus/release-0.16
cd /root/kube-prometheus/release-0.16
# 初始化
jb init
# 下载远程包
jb install github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus@release-0.16
5. 创建编译文件及编译脚本
创建编译文件:
cat << 'EOF' | tee /root/kube-prometheus/release-0.16/release-0.16.jsonnet
local kp =
(import 'kube-prometheus/main.libsonnet') +
// Uncomment the following imports to enable its patches
(import 'kube-prometheus/addons/anti-affinity.libsonnet') +
// (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
(import 'kube-prometheus/addons/node-ports.libsonnet') +
(import 'kube-prometheus/addons/static-etcd.libsonnet') +
// (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
// (import 'kube-prometheus/addons/external-metrics.libsonnet') +
// (import 'kube-prometheus/addons/pyrra.libsonnet') +
(import 'kube-prometheus/platforms/kubeadm.libsonnet') +
{
// 进行深度合并,同名字段如果都是对象,会继续合并而不是覆盖
values+:: {
// 进行浅合并,同名字段会覆盖原值
common+: {
namespace: 'monitoring',
},
prometheus+: {
// 配置 thanos sidecar
thanos: {
version: 'v0.38.0',
image: 'quay.io/thanos/thanos:v0.38.0',
},
// 此处需要增加下 prometheus 的标签,否则无法关联到 service
commonLabels+:: {
app: 'prometheus',
}
},
// 启用静态 etcd 时,增加 etcd 配置
etcd+: {
ips: ['192.167.16.108'],
clientCA: importstr '/etc/kubernetes/pki/etcd/ca.crt',
clientCert: importstr '/etc/kubernetes/pki/etcd/server.crt',
clientKey: importstr '/etc/kubernetes/pki/etcd/server.key',
serverName: 'etcd.kube-system.svc.cluster.local',
insecureSkipVerify: true,
},
// grafana 配置
grafana+: {
// 开启数据源修改,开启后可以在 Grafana UI 中修改数据源
// 增加 Prometheus 数据源 basic auth 认证
datasources: [
{
name: 'prometheus',
type: 'prometheus',
access: 'proxy',
orgId: 1,
url: 'http://prometheus-k8s.monitoring.svc:9090',
version: 1,
editable: true,
basicAuth: true,
basicAuthUser: 'admin',
secureJsonData: {
basicAuthPassword: '1234567',
}
}
],
// 增加 Grafana 认证
config: {
// sections 是 Grafana 配置文件 ini 中的 sections
sections: {
data_formats: {
default_timezone: 'CST',
},
security: {
admin_user: 'admin',
admin_password: '1234567',
},
}
},
// 启用静态 etcd 时,增加 etd 的 Grafana 仪表盘
dashboards+:: kp.grafanaDashboards,
},
},
// prometheus 配置
prometheus+:: {
prometheus+: {
spec+: {
// 数据保存时常
retention: '30d',
// 数据存储,在阿里云ssd云盘中
// storage: {
// volumeClaimTemplate: {
// apiVersion: 'v1',
// kind: 'PersistentVolumeClaim',
// spec: {
// accessModes: ['ReadWriteOnce'],
// resources: {
// requests: {
// storage: '100Gi',
// },
// },
// storageClassName: 'alicloud-disk-ssd',
// },
// },
// },
// 资源限制
resources: {
limits: {
cpu: '2',
memory: '2Gi',
},
requests: {
cpu: '1',
memory: '400Mi',
},
},
// 增加 prometheus basic auth 认证
containers+: [
// prometheus 增加 basic auth 的认证配置
{
name: 'prometheus',
args+: [
'--web.console.templates=/etc/prometheus/consoles',
'--web.console.libraries=/etc/prometheus/console_libraries',
'--config.file=/etc/prometheus/config_out/prometheus.env.yaml',
'--storage.tsdb.path=/prometheus',
'--storage.tsdb.retention.time=30d',
'--web.enable-lifecycle',
'--storage.tsdb.no-lockfile',
'--web.route-prefix=/',
'--web.config.file=/etc/prometheus/secrets/basic-auth/web-config.yaml',
],
// 增加 basic auth 认证后,探针需要修改
readinessProbe:{
failureThreshold: 3,
httpGet: {
path: '/-/ready',
port: 'web',
scheme: 'HTTP',
httpHeaders: [{
name: 'Authorization',
// echo -n 'admin:1234567' | base64
value: 'Basic YWRtaW46MTIzNDU2Nw==',
}],
},
periodSeconds: 5,
successThreshold: 1,
timeoutSeconds: 3,
},
startupProbe: {
failureThreshold: 60,
httpGet: {
path: '/-/ready',
port: 'web',
scheme: 'HTTP',
httpHeaders: [{
name: 'Authorization',
// echo -n 'admin:1234567' | base64
value: 'Basic YWRtaW46MTIzNDU2Nw==',
}],
},
periodSeconds: 15,
successThreshold: 1,
timeoutSeconds: 3,
},
livenessProbe: {
failureThreshold: 6,
httpGet: {
path: '/-/healthy',
port: 'web',
scheme: 'HTTP',
httpHeaders: [{
name: 'Authorization',
// echo -n 'admin:1234567' | base64
value: 'Basic YWRtaW46MTIzNDU2Nw==',
}],
},
periodSeconds: 5,
successThreshold: 1,
timeoutSeconds: 3,
},
},
// config-reloader 访问 prometheus 时增加 basic auth 信息
{
args: [
'--listen-address=:8080',
'--reload-url=http://admin:1234567@localhost:9090/-/reload',
'--config-file=/etc/prometheus/config/prometheus.yaml.gz',
'--config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml',
'--watched-dir=/etc/prometheus/rules/prometheus-k8s-rulefiles-0'
],
name: 'config-reloader'
},
// thanos-sidecar 访问 prometheus 时增加 basic auth 信息
{
args: [
'sidecar',
'--prometheus.url=http://admin:1234567@localhost:9090/',
'--grpc-address=[$(POD_IP)]:10901',
'--http-address=[$(POD_IP)]:10902',
],
env: [
{
name: 'POD_IP',
valueFrom:
{
fieldRef:
{
apiVersion: 'v1',
fieldPath: 'status.podIP',
},
},
},
],
image: 'quay.io/thanos/thanos:v0.38.0',
imagePullPolicy: 'IfNotPresent',
name: 'thanos-sidecar',
ports: [
{
containerPort: 10902,
name: 'http',
protocol: 'TCP',
},
{
containerPort: 10901,
name: 'grpc',
protocol: 'TCP',
}
],
terminationMessagePath: '/dev/termination-log',
terminationMessagePolicy: 'FallbackToLogsOnError',
},
],
// 将 Baisc Auth 的配置文件挂载到容器中
secrets+: [
"basic-auth",
]
}
},
// 因为 Prometheus 开启了 basic-auth 的认证,要修改抓取规则,从 secret 中读取认证信息
serviceMonitor+: {
spec+: {
endpoints: [{
port: 'web',
interval: '30s',
basicAuth: {
username: {
name: 'basic-auth',
key: 'username',
},
password: {
name: 'basic-auth',
key: 'password',
}
},
}]
}
},
},
};
// 生成 prometheus basic-auth 认证相关的 Secret
{
'prometheus-secret-basicAuth': {
apiVersion: 'v1',
kind: 'Secret',
metadata: {
name: 'basic-auth',
namespace: 'monitoring',
},
data: {
// echo -n '1234567' | base64
password: 'MTIzNDU2Nw==',
// echo -n 'admin' | base64
username: 'YWRtaW4=',
//# 生成 bcrypt 加密的密码
//htpasswd -nBC 10 "" | tr -d ':\n'
//# 创建文件 web-config.yaml
//basic_auth_users:
// admin: 生成的密钥
//# 生成 web-config.yaml secret 内容
//cat web-config.yaml |base64 -w 0
'web-config.yaml': 'YmFzaWNfYXV0aF91c2VyczoKICBhZG1pbjogJDJiJDEyJEprTmkuVWtYejdJRVBicFE0cmt1Nk9mVzlKRTlRZzNybHlhVHRzL0E2V2JsSjh3MHRUdmxtCg==',
},
type: 'Opaque'
}
}+
// 启用静态 etcd 时,增加 etcd PrometheusRule 配置
{
'kube-etcd-prometheusRule': {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'PrometheusRule',
metadata: {
name: 'kube-etcd-rules',
namespace: kp.values.common.namespace,
labels: kp.values.common.ruleLabels,
},
spec: kp.prometheusAlerts,
},
}+
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
{
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
} +
// { 'setup/pyrra-slo-CustomResourceDefinition': kp.pyrra.crd } +
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
// { ['pyrra-' + name]: kp.pyrra[name] for name in std.objectFields(kp.pyrra) if name != 'crd' } +
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) } +
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
EOF
创建编译脚本:
cat << 'EOF' | tee /root/kube-prometheus/release-0.16/build.sh
#!/usr/bin/env bash
# This script uses arg $1 (name of *.jsonnet file to use) to generate the manifests/*.yaml files.
set -e
set -x
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
# Make sure to use project tooling
PATH="$(pwd)/tmp/bin:${PATH}"
# Make sure to start with a clean 'manifests' dir
rm -rf manifests
mkdir -p manifests/setup
# Calling gojsontoyaml is optional, but we would like to generate yaml, not json
jsonnet -J vendor -m manifests "${1-release-0.16.jsonnet}" | xargs -I{} sh -c 'cat {} | gojsontoyaml > {}.yaml' -- {}
# Make sure to remove json files
find manifests -type f ! -name '*.yaml' -delete
rm -f kustomization
EOF
6. 编译、部署
编译,生成 kubernetes yaml 清单
[root@master release-0.16]# sh build.sh
部署 kube-prometheus
# 如果无法拉取镜像,可在所有节点上先导入准备好的镜像
tar -zxf kube-prometheus-release-0.16-images.tar.gz
cd release-0.16
# docker 导入
for i in $(ls); do docker load -i ${i}; done
# containerd 导入
for i in $(ls); do ctr -n k8s.io i import ${i}; done
# 部署
kubectl create -f manifests/setup
kubectl apply -f manifests/
访问地址:
Prometheus(admin/1234567):http://192.167.16.116:30900
Grafana(admin/1234567):http://192.167.16.116:30902
AlertManager:http://192.167.16.116:30903
更多推荐




所有评论(0)