kube-operator-stack监控k8s集群
文章目录
prometheus-operator 已弃用,更名为 kube-prometheus-stack,以更清楚地反映它安装了 kube-prometheus 项目堆栈,其中 Prometheus Operator 只是一个组件。
- 原项目地址:https://github.com/helm/charts/tree/master/stable/prometheus-operator
- 新项目地址:https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack
一、Operator介绍
Operator
是由CoreOS公司开发的,用来扩展 Kubernetes API,特定的应用程序控制器,它用来创建、配置和管理复杂的有状态应用,如数据库、缓存和监控系统。Operator
基于 Kubernetes 的资源和控制器概念之上构建,但同时又包含了应用程序特定的一些专业知识,比如创建一个数据库的Operator
,则必须对创建的数据库的各种运维方式非常了解,创建Operator
的关键是CRD
(自定义资源)的设计。
CRD
是对 Kubernetes API 的扩展,Kubernetes 中的每个资源都是一个 API 对象的集合,例如我们在YAML文件里定义的那些spec
都是对 Kubernetes 中的资源对象的定义,所有的自定义资源可以跟 Kubernetes 中内建的资源一样使用 kubectl 操作。
Operator
是将运维人员对软件操作的知识给代码化,同时利用 Kubernetes 强大的抽象来管理大规模的软件应用。目前CoreOS
官方提供了几种Operator
的实现,其中就包括我们今天的主角:Prometheus Operator
,Operator
的核心实现就是基于 Kubernetes 的以下两个概念:
- 资源:对象的状态定义
- 控制器:观测、分析和行动,以调节资源的分布
二、kube-prometheus架构
上图是Prometheus-Operator
官方提供的架构图,其中Operator
是最核心的部分,作为一个控制器,他会去创建Prometheus
、ServiceMonitor
、AlertManager
以及PrometheusRule
4个CRD
资源对象,然后会一直监控并维持这4个资源对象的状态。
其中创建的prometheus
这种资源对象就是作为Prometheus Server
存在,而ServiceMonitor
就是exporter
的各种抽象,exporter
前面我们已经学习了,是用来提供专门提供metrics
数据接口的工具,Prometheus
就是通过ServiceMonitor
提供的metrics
数据接口去 pull 数据的,当然alertmanager
这种资源对象就是对应的AlertManager
的抽象,而PrometheusRule
是用来被Prometheus
实例使用的报警规则文件。
这样我们要在集群中监控什么数据,就变成了直接去操作 Kubernetes 集群的资源对象了,是不是方便很多了。上图中的 Service 和 ServiceMonitor 都是 Kubernetes 的资源,一个 ServiceMonitor 可以通过 labelSelector 的方式去匹配一类 Service,Prometheus 也可以通过 labelSelector 去匹配多个ServiceMonitor。
三、kube-prometheus-stack安装
这里直接通过helm包进行安装!
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update
$ helm install my-kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 39.7.0
helm安装完成后,会提示两个镜像无法下载:
k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.2.0
registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0
# 替换成以下镜像
docker.io/jettech/kube-webhook-certgen:v1.2.0
kubesphere/kube-state-metrics:v2.5.0
安装完成后,如图所示:
创建应用可以采用NodePort的方式,个人比较喜欢使用ingress的方式,这里以ingress为例:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: prometheus
namespace: monitoring
spec:
rules:
- host: prometheus.lvzhenjiang.cn
http:
paths:
- backend:
serviceName: kube-prometheus-stack-prometheus
servicePort: 9090
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grafana
namespace: monitoring
spec:
rules:
- host: grafana.lvzhenjiang.cn
http:
paths:
- backend:
serviceName: kube-prometheus-stack-grafana
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: alertmanager
namespace: monitoring
spec:
rules:
- host: alertmanager.lvzhenjiang.cn
http:
paths:
- backend:
serviceName: kube-prometheus-stack-alertmanager
servicePort: 9093
自行解决域名解析的问题后,访问页面进行测试:
http://prometheus.lvzhenjiang.cn
http://grafana.lvzhenjiang.cn 默认的账号/密码:admin/prom-operator
http://alertmanager.lvzhenjiang.cn
访问prometheus页面 ——> Status ——> Targets 页面,会发现etcd、controller-manager、scheduler、kube-proxy这几个标签无法正常采集数据,接下来一个一个解决!
四、解决ETCD组件监控问题
无论是 Kubernetes 集群外的还是使用 Kubeadm 安装在集群内部的 etcd 集群,我们这里都将其视作集群外的独立集群,因为对于二者的使用方法没什么特殊之处。
4.1 解决etcd证书问题
对于 etcd 集群一般情况下,为了安全都会开启 https 证书认证的方式,所以要想让 Prometheus 访问到 etcd 集群的监控数据,就需要提供相应的证书校验。
由于我们这里演示环境使用的是 Kubeadm 搭建的集群,我们可以使用 kubectl 工具去获取 etcd 启动的时候使用的证书路径:
$ kubectl get pod -n kube-system | grep etcd
etcd-k8s-master 1/1 Running 3 17h
$ kubectl -n kube-system get pod etcd-k8s-master -oyaml
......
spec:
containers:
- command:
- etcd
- --advertise-client-urls=https://192.168.99.1:2379
- --cert-file=/etc/kubernetes/pki/etcd/server.crt
- --client-cert-auth=true
- --data-dir=/var/lib/etcd
- --initial-advertise-peer-urls=https://192.168.99.1:2380
- --initial-cluster=k8s-master=https://192.168.99.1:2380
- --key-file=/etc/kubernetes/pki/etcd/server.key
- --listen-client-urls=https://127.0.0.1:2379,https://192.168.99.1:2379
- --listen-metrics-urls=http://127.0.0.1:2381
- --listen-peer-urls=https://192.168.99.1:2380
- --name=k8s-master
- --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt
- --peer-client-cert-auth=true
- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
- --snapshot-count=10000
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
......
我们可以看到 etcd 使用的证书都对应在节点的 /etc/kubernetes/pki/etcd
这个路径下面,所以首先我们使用证书命令行测试etcd监控接口:
$ curl --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key https://localhost:2379/metrics -k
命令行测试etcd监控接口没有问题后。将需要使用到的证书通过 secret 对象保存到集群中去:
$ kubectl -n monitoring create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key --from-file=/etc/kubernetes/pki/etcd/ca.crt
然后将上面创建的 etcd-certs 对象配置到 prometheus 资源对象中,直接更新 prometheus 资源对象即可:
$ kubectl -n monitoring edit prometheus kube-prometheus-stack-prometheus
# 添加如下的 secrets 属性:
replicas: 1
secrets:
- etcd-certs
更新完成后,我们就可以在 Prometheus 的 Pod 中获取到上面创建的 etcd 证书文件了,具体的路径我们可以进入 Pod 中查看:
$ kubectl exec -it prometheus-kube-prometheus-stack-prometheus-0 /bin/sh -n monitoring
/prometheus $ ls /etc/prometheus/secrets/etcd-certs/
ca.crt healthcheck-client.crt healthcheck-client.key
4.2 解决ServiceMonitor问题
$ kubectl -n monitoring edit servicemonitors.monitoring.coreos.com kube-prometheus-stack-kube-etcd
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
annotations:
meta.helm.sh/release-name: kube-prometheus-stack
meta.helm.sh/release-namespace: monitoring
generation: 2
labels:
app: kube-prometheus-stack-kube-etcd
app.kubernetes.io/instance: kube-prometheus-stack
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: kube-prometheus-stack
app.kubernetes.io/version: 39.7.0
chart: kube-prometheus-stack-39.7.0
heritage: Helm
release: kube-prometheus-stack
name: kube-prometheus-stack-kube-etcd
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
interval: 30s
port: http-metrics
######添加内容开始(添加的路径是容器内的路径,直接复制即可!)######
scheme: https
tlsConfig:
caFile: /etc/prometheus/secrets/etcd-certs/ca.crt
certFile: /etc/prometheus/secrets/etcd-certs/healthcheck-client.crt
insecureSkipVerify: true
keyFile: /etc/prometheus/secrets/etcd-certs/healthcheck-client.key
######添加内容结束######
jobLabel: jobLabel
namespaceSelector:
matchNames:
- kube-system
selector:
matchLabels:
app: kube-prometheus-stack-kube-etcd
release: kube-prometheus-stack
查看ServiceMonitor对应的service信息:
$ kubectl -n kube-system get svc -l app=kube-prometheus-stack-kube-etcd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-prometheus-stack-kube-etcd ClusterIP None <none> 2379/TCP 16h
$ kubectl -n kube-system describe svc kube-prometheus-stack-kube-etcd
......
Port: http-metrics 2379/TCP
TargetPort: 2379/TCP
Endpoints: 192.168.99.1:2379
......
以上准备就绪后,再次访问prometheus targets页面,查看etcd监控状态,如图:
五、解决controller-manager组件监控问题
5.1 解决controller-manager组件的监听地址
$ vim /etc/kubernetes/manifests/kube-controller-manager.yaml
......
--bind-address=127.0.0.1
修改为:
--bind-address=0.0.0.0
......
5.2 解决ServiceMonitor问题
$ kubectl -n monitoring edit servicemonitors.monitoring.coreos.com kube-prometheus-stack-kube-controller-manager
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
annotations:
meta.helm.sh/release-name: kube-prometheus-stack
meta.helm.sh/release-namespace: monitoring
generation: 3
labels:
app: kube-prometheus-stack-kube-controller-manager
app.kubernetes.io/instance: kube-prometheus-stack
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: kube-prometheus-stack
app.kubernetes.io/version: 39.7.0
chart: kube-prometheus-stack-39.7.0
heritage: Helm
release: kube-prometheus-stack
name: kube-prometheus-stack-kube-controller-manager
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
port: http-metrics
######添加内容开始######
scheme: https
tlsConfig:
insecureSkipVerify: true
######添加内容结束######
jobLabel: jobLabel
namespaceSelector:
matchNames:
- kube-system
selector:
matchLabels:
app: kube-prometheus-stack-kube-controller-manager
release: kube-prometheus-stack
5.3 修改service监听的端口
$ netstat -anpt | grep LISTEN| grep contro
tcp6 0 0 :::10257 :::* LISTEN 91528/kube-controll
# 也可以查看controller-manager组件的启动日志查看端口
$ kubectl -n kube-system get svc -l app=kube-prometheus-stack-kube-controller-manager
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-prometheus-stack-kube-controller-manager ClusterIP None <none> 10257/TCP 16h
$ kubectl -n kube-system describe svc kube-prometheus-stack-kube-controller-manager
Name: kube-prometheus-stack-kube-controller-manager
......
Selector: component=kube-controller-manager
......
Port: http-metrics 10257/TCP
TargetPort: 10257/TCP
Endpoints: 192.168.99.1:10257
以上准备就绪后,再次访问prometheus targets页面,查看controller-manager监控状态,如图:
六、解决scheduler组件监控问题
6.1 解决scheduler组件的监听地址
$ vim /etc/kubernetes/manifests/kube-scheduler.yaml
......
--bind-address=127.0.0.1
修改为:
--bind-address=0.0.0.0
......
6.2 解决ServiceMonitor问题
$ kubectl -n monitoring edit servicemonitors.monitoring.coreos.com kube-prometheus-stack-kube-scheduler
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"monitoring.coreos.com/v1","kind":"ServiceMonitor","metadata":{"annotations":{"meta.helm.sh/release-name":"kube-prometheus-stack","meta.helm.sh/release-namespace":"monitoring"},"generation":5,"labels":{"app":"kube-prometheus-stack-kube-scheduler","app.kubernetes.io/instance":"kube-prometheus-stack","app.kubernetes.io/managed-by":"Helm","app.kubernetes.io/part-of":"kube-prometheus-stack","app.kubernetes.io/version":"39.7.0","chart":"kube-prometheus-stack-39.7.0","heritage":"Helm","release":"kube-prometheus-stack"},"name":"kube-prometheus-stack-kube-scheduler","namespace":"monitoring"},"spec":{"endpoints":[{"bearerTokenFile":"/var/run/secrets/kubernetes.io/serviceaccount/token","port":"http-metrics"}],"jobLabel":"jobLabel","namespaceSelector":{"matchNames":["kube-system"]},"selector":{"matchLabels":{"app":"kube-prometheus-stack-kube-scheduler","release":"kube-prometheus-stack"}}}}
meta.helm.sh/release-name: kube-prometheus-stack
meta.helm.sh/release-namespace: monitoring
generation: 3
labels:
app: kube-prometheus-stack-kube-scheduler
app.kubernetes.io/instance: kube-prometheus-stack
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: kube-prometheus-stack
app.kubernetes.io/version: 39.7.0
chart: kube-prometheus-stack-39.7.0
heritage: Helm
release: kube-prometheus-stack
name: kube-prometheus-stack-kube-scheduler
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
port: http-metrics
######添加内容开始######
scheme: https
tlsConfig:
insecureSkipVerify: true
######添加内容开始######
jobLabel: jobLabel
namespaceSelector:
matchNames:
- kube-system
selector:
matchLabels:
app: kube-prometheus-stack-kube-scheduler
release: kube-prometheus-stack
6.3 修改service监听的端口
$ netstat -anpt | grep LISTEN| grep schedu
tcp6 0 0 :::10259 :::* LISTEN 96771/kube-schedule
# 也可以查看scheduler组件的启动日志查看端口
[root@k8s-master ~]# kubectl -n kube-system get svc -l app=kube-prometheus-stack-kube-scheduler
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-prometheus-stack-kube-scheduler ClusterIP None <none> 10259/TCP 16h
[root@k8s-master ~]# kubectl -n kube-system describe svc kube-prometheus-stack-kube-scheduler
Name: kube-prometheus-stack-kube-scheduler
......
Selector: component=kube-scheduler
......
Port: http-metrics 10259/TCP
TargetPort: 10259/TCP
Endpoints: 192.168.99.1:10259
以上准备就绪后,再次访问prometheus targets页面,查看scheduler监控状态,如图:
七、解决kube-proxy组件监控问题
7.1 修改kube-proxy的metrics监听地址及端口
$ netstat -antp | grep proxy | grep LISTEN
tcp 0 0 0.0.0.0:32567 0.0.0.0:* LISTEN 59417/kube-proxy
tcp6 0 0 :::10249 :::* LISTEN 59417/kube-proxy
tcp6 0 0 :::10256 :::* LISTEN 59417/kube-proxy
$ kubectl -n kube-system edit cm kube-proxy
......
metricsBindAddress: "0.0.0.0:10249"
......
$ kubectl -n kube-system delete pod `kubectl get pod -n kube-system | grep proxy | awk '{print $1}'`
# 重启kube-proxy容器
修改完成后,再次访问prometheus targets页面,查看scheduler监控状态,如图:
八、自定义监控项
除了 Kubernetes 集群中的一些资源对象、节点以及组件需要监控,有的时候我们可能还需要根据实际的业务需求去添加自定义的监控项,添加一个自定义监控的步骤也是非常简单的。
- 第一步建立一个 ServiceMonitor 对象,用于 Prometheus 添加监控项
- 第二步为 ServiceMonitor 对象关联 metrics 数据接口的一个 Service 对象
- 第三步确保 Service 对象可以正确获取到 metrics 数据