暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes部署Prometheus operator

NFT艺术之家 2019-09-29
359


必要条件

  • 有一个Kubeadm部署的集群



介绍

Prometheus 是一个开源的监控它本身已经成为了云原生中指标监控的事实标准,几乎所有 k8s 的核心组件以及其它云原生系统都以 Prometheus 的指标格式输出自己的运行时监控信息。我在工作中也比较深入地使用过 Prometheus,最大的感受就是它非常容易维护,突出一个简单省心成本低。当然,这当中也免不了踩过一些坑。

之前也有手动部署过Prometheus,手动部署关键的就是需要自己维护好Prometheus的YAML配置文件,比如添加服务删除服务后,我们需要实时的增删配置文件的内容,步骤还是相当的繁琐的。


prometheus operator的出现了改变了这种现状。

Operator是由CoreOS公司开发的,用来扩展 Kubernetes API,特定的应用程序控制器,它用来创建、配置和管理复杂的有状态应用,如数据库、缓存和监控系统。Operator基于 Kubernetes 的资源和控制器概念之上构建,但同时又包含了应用程序特定的一些专业知识,比如创建一个数据库的Operator,则必须对创建的数据库的各种运维方式非常了解,创建Operator的关键是CRD(自定义资源)的设计。


Operator是将运维的操作从以往的负载配置,统一化,可编程化,代码化了,统一使用类似Kubernetes的YAML部署配置文件,可编程化由于YAML的字段和内容是固定的,可以轻松的通过python或者golang对YAML进行修改。



上图是Prometheus-Operator官方提供的架构图,其中Operator是最核心的部分,作为一个控制器,他会去创建Prometheus、ServiceMonitor、AlertManager以及PrometheusRule4个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。


安装

Prometheus operator的安装方式有很多:helm安装、源码安装。这里我们选择源码安装,这样可以加深理解。prometheus operator 的源代码已经从coreos的官方保存到了github上面。


Clone 源代码到我们本地,这里有一些因素的导致这里的克隆会比较慢:

# ALL_PROXY=socks5://10.0.7.103:1086 git clone https://github.com/coreos/kube-prometheus
正克隆到 'kube-prometheus'...
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 6552 (delta 1), reused 6 (delta 1), pack-reused 6541
接收对象中: 100% (6552/6552), 3.99 MiB | 1.46 MiB/s, done.
处理 delta 中: 100% (3908/3908), done.


进入项目,查看manifests目录下面,有我们需要的所有资源清单。


# cd kube-prometheus/
# ls manifests/
00namespace-namespace.yaml grafana-dashboardDatasources.yaml node-exporter-daemonset.yaml prometheus-prometheus.yaml
0prometheus-operator-0alertmanagerCustomResourceDefinition.yaml grafana-dashboardDefinitions.yaml node-exporter-serviceAccount.yaml prometheus-roleBindingConfig.yaml
0prometheus-operator-0podmonitorCustomResourceDefinition.yaml grafana-dashboardSources.yaml node-exporter-serviceMonitor.yaml prometheus-roleBindingSpecificNamespaces.yaml
0prometheus-operator-0prometheusCustomResourceDefinition.yaml grafana-deployment.yaml node-exporter-service.yaml prometheus-roleConfig.yaml
0prometheus-operator-0prometheusruleCustomResourceDefinition.yaml grafana-serviceAccount.yaml prometheus-adapter-apiService.yaml prometheus-roleSpecificNamespaces.yaml
0prometheus-operator-0servicemonitorCustomResourceDefinition.yaml grafana-serviceMonitor.yaml prometheus-adapter-clusterRoleAggregatedMetricsReader.yaml prometheus-rules.yaml
0prometheus-operator-clusterRoleBinding.yaml grafana-service.yaml prometheus-adapter-clusterRoleBindingDelegator.yaml prometheus-serviceAccount.yaml
0prometheus-operator-clusterRole.yaml kube-state-metrics-clusterRoleBinding.yaml prometheus-adapter-clusterRoleBinding.yaml prometheus-serviceMonitorApiserver.yaml
0prometheus-operator-deployment.yaml kube-state-metrics-clusterRole.yaml prometheus-adapter-clusterRoleServerResources.yaml prometheus-serviceMonitorCoreDNS.yaml
0prometheus-operator-serviceAccount.yaml kube-state-metrics-deployment.yaml prometheus-adapter-clusterRole.yaml prometheus-serviceMonitorKubeControllerManager.yaml
0prometheus-operator-serviceMonitor.yaml kube-state-metrics-roleBinding.yaml prometheus-adapter-configMap.yaml prometheus-serviceMonitorKubelet.yaml
0prometheus-operator-service.yaml kube-state-metrics-role.yaml prometheus-adapter-deployment.yaml prometheus-serviceMonitorKubeScheduler.yaml
alertmanager-alertmanager.yaml kube-state-metrics-serviceAccount.yaml prometheus-adapter-roleBindingAuthReader.yaml prometheus-serviceMonitor.yaml
alertmanager-secret.yaml kube-state-metrics-serviceMonitor.yaml prometheus-adapter-serviceAccount.yaml prometheus-service.yaml
alertmanager-serviceAccount.yaml kube-state-metrics-service.yaml prometheus-adapter-service.yaml
alertmanager-serviceMonitor.yaml node-exporter-clusterRoleBinding.yaml prometheus-clusterRoleBinding.yaml
alertmanager-service.yaml node-exporter-clusterRole.yaml prometheus-clusterRole.yaml

检查一下 prometheus-serviceMonitorKubelet.yaml文件的配置,默认serviceMonitor是关联kubelet 的10250端口采集metrics数据为了安全,已经将数据迁移到了10255上面,这里我们只需要将https-metrics更改为http-metrics。有兴趣的可以查看源代码,需要对Go语言有点了解。


修改完成以后直接应用,当前路径下面的所有YAML配置:

# kubectl apply -f .

部署完成会自动创建CRD资源、一个命名为monitor的namespace、svc、以及各个监控组件等等。


CRD资源:

# kubectl get crd |egrep coreos
alertmanagers.monitoring.coreos.com 2019-07-19T07:46:41Z
podmonitors.monitoring.coreos.com 2019-07-19T07:46:41Z
prometheuses.monitoring.coreos.com 2019-07-19T07:46:41Z
prometheusrules.monitoring.coreos.com 2019-07-19T07:46:41Z
servicemonitors.monitoring.coreos.com 2019-07-19T07:46:41Z

命名空间以及其他监控组件:


# kubectl get namespaces |egrep monitor
monitoring Active 67d


# kubectl get deployments -n monitoring
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
grafana 1 1 1 1 67d
kube-state-metrics 1 1 1 1 67d
prometheus-adapter 1 1 1 1 67d
prometheus-operator 1 1 1 1 67d


SVC


# kubectl get -n monitoring svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 172.23.35.101 <none> 9093/TCP 67d
alertmanager-operated ClusterIP None <none> 9093/TCP,6783/TCP 67d
grafana ClusterIP 172.23.244.138 <none> 3000/TCP 67d
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 67d
node-exporter ClusterIP None <none> 9100/TCP 67d
prometheus-adapter ClusterIP 172.23.92.175 <none> 443/TCP 67d
prometheus-k8s ClusterIP 172.23.146.26 <none> 9090/TCP 67d
prometheus-operated ClusterIP None <none> 9090/TCP 35d
prometheus-operator ClusterIP None <none> 8080/TCP 67d


有了svc以后我们就可以通过Ingress或者NodePort的方式访问集群内的http或者TCP的服务,比如promehtues的页面、alertmanager的页面、grafana的监控模版页面。个人比较推荐使用Ingress无论你是使用nginx-ingress还是traefik-ingress控制器。NodePort我觉的是一个很不好的习惯尤其是当你访问的目标端口上面没有NodePort所对应的端口时,时会通过iptables端口转发的形式转发到目标端口所在的节点,效率非常低,生产上面不推荐使用。不过,如果时使用阿里云的SLB做负载均衡这个问题不是很严重,因为阿里云的kubernetes的集群会在kube-system命名空间下面安装一个组件,这个组件是在我们集群中使用了LoadBalancer的方式的时候,组件会获取目标pod所运行的节点,以及节点对应的IP,并添加到SLB中。除非自建的集群也写一个这个这样的工具,否则不是很推荐NodePort的方式。


Pod的资源:

# kubectl get pods -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 67d
alertmanager-main-1 2/2 Running 0 67d
alertmanager-main-2 2/2 Running 0 46d
grafana-89894d799-fffgn 1/1 Running 1 25d
kube-state-metrics-7fbddc9b89-7l9d7 4/4 Running 0 42h
node-exporter-4vl7c 2/2 Running 1 53d
node-exporter-54fzs 2/2 Running 2 67d
node-exporter-55fcj 2/2 Running 1 36d
node-exporter-6h7nz 2/2 Running 0 53d
node-exporter-78c54 2/2 Running 2 67d
node-exporter-7wdbq 2/2 Running 1 67d
node-exporter-9gz2r 2/2 Running 1 14d
node-exporter-9kvnh 2/2 Running 0 50d
node-exporter-b78kz 2/2 Running 1 14d
node-exporter-bh7qv 2/2 Running 0 67d
node-exporter-br5n2 2/2 Running 0 29d
node-exporter-cb8nr 2/2 Running 1 50d
node-exporter-cdjtz 2/2 Running 1 50d
node-exporter-fcd6g 2/2 Running 0 67d
node-exporter-fh5vp 2/2 Running 1 53d
node-exporter-fsh4x 2/2 Running 0 29d
node-exporter-h7jk4 2/2 Running 0 20d
node-exporter-hhsng 2/2 Running 0 67d
node-exporter-hnz9n 2/2 Running 0 29d
node-exporter-j5k7v 2/2 Running 0 50d
node-exporter-km8fq 2/2 Running 0 29d
node-exporter-lps9s 2/2 Running 1 50d
node-exporter-lpsx4 2/2 Running 0 67d
node-exporter-mp6km 2/2 Running 0 29d
node-exporter-msz54 2/2 Running 2 67d
node-exporter-pfz2h 2/2 Running 2 67d
node-exporter-pmwbd 2/2 Running 0 67d
node-exporter-pnz4x 2/2 Running 2 67d
node-exporter-pvcm6 2/2 Running 0 53d
node-exporter-tp2ph 2/2 Running 1 28d
node-exporter-vtp56 2/2 Running 0 29d
node-exporter-wg8dd 2/2 Running 0 67d
node-exporter-whw7k 2/2 Running 0 29d
node-exporter-wzf4w 2/2 Running 2 67d
prometheus-adapter-b7d894c9c-xw7vp 1/1 Running 0 67d
prometheus-k8s-0 3/3 Running 0 28d
prometheus-k8s-1 3/3 Running 0 35d
prometheus-operator-66bbf6b5b7-wcg2b 1/1 Running 0 67d

当然还有很多prometheus-operator的自定义API对象,比如:


# kubectl get -n monitoring servicemonitors.monitoring.coreos.com
NAME AGE
alertmanager 67d
app-account 19d
app-b-veterantam 19d
app-business 19d
app-college 19d
app-commodity 19d
app-config 19d

配置

我这里通过ingress访问prometheus后页面如下:



这个页面一直往下拉取发现有红色出现,这表示服务没有被prometheus监控到,或者监控配置有误。


通过上面的红色名字内容我们可以找到对应的serviceMonitor文件:


prometheus-serviceMonitorKubeScheduler.yaml

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
k8s-app: kube-scheduler
name: kube-scheduler
namespace: monitoring
spec:
endpoints:
- interval: 30s # 拉取metrics的周期
port: http-metrics #对应service的Port
jobLabel: k8s-app
namespaceSelector: # 匹配的命名空间
matchNames:
- kube-system
selector: # 匹配的 Service 的labels,如果使用mathLabels,则下面的所有标签都匹配时才会匹配该service,如果使用matchExpressions,则至少匹配一个标签的service都会被选择
matchLabels:
k8s-app: kube-scheduler

根据上面的配置文件我们可以查看kube-system命名空间下面的svc,发现没有labels为kube-scheduler的svc。这里我们自己创建一个prometheus-kube-schedule的svc:

apiVersion: v1
kind: Service
metadata:
namespace: kube-system
name: kube-scheduler
labels:
k8s-app: kube-scheduler
spec:
selector:
component: kube-scheduler
ports:
- name: http-metrics
port: 10251
targetPort: 10251
protocol: TCP

上面配置文件最终的要是labels和selector,这两个配置可以从已经部署的好的kube-scheduler的pod文件中获取(我这里的kubernetes是使用kubeadm部署的所以组件是运行在容器中的),如果是运行在外面的话也有方法需要手动配置endpoint,并且endpoint必须和svc对应就可以了。


从对应的Pod中获取labels:

# kubectl describe -n kube-system pods  kube-scheduler-cn-hangzhou.10.1.65.201
Name: kube-scheduler-cn-hangzhou.10.1.65.201
Namespace: kube-system
Priority: 2000000000
PriorityClassName: system-cluster-critical
Node: cn-hangzhou.10.1.65.201/10.1.65.201
Start Time: Thu, 25 Jul 2019 17:33:03 +0800
Labels: component=kube-scheduler
tier=control-plane

这里的component: kube-scheduler和我们刚刚创建的svc刚刚好对上。


应用我们上面的svc:

# kubectl apply -f prometheus-kube-schedule.yaml

过一会就能看到prometheus已经成功监控到了:


集群中的kube-controller-manager、coreDNS如果没有svc也可以用这种方法。


对于kubeadm部署etcd是集群之外的svc建立的比较特殊,需要自己编写endpoint。


各位看官如果还满意的话,可否关注一下我们:

微信订阅号:ITBuf

企鹅号:TSG技术分享

您的认可是对我们最大的支持。

文章转载自NFT艺术之家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论