使用prometheus监控traefik、redis、k8s集群各节点、各节点kubelet

1、Prometheus的数据指标是通过一个公开的 HTTP(S) 数据接口获取到的,我们不需要单独安装监控的 agent,只需要暴露一个 metrics 接口,Prometheus 就会定期去拉取数据;对于一些普通的 HTTP 服务,我们完全可以直接重用这个服务,添加一个/metrics接口暴露给 Prometheus
2、有一些服务即使没有原生集成该接口,也完全可以使用一些 exporter 来获取到指标数据,比如 mysqld_exporter、node_exporter,redis-exporter,这些 exporter 就有点类似于传统监控服务中的 agent,用来收集目标服务的指标数据然后直接暴露给 Prometheus。

监控自带metric接口的Traefik
1、修改其配置文件traefik.toml,增加如下内容,开启metirc接口

[metrics]
  [metrics.prometheus]
    entryPoint = "traefik"
    buckets = [0.1, 0.3, 1.2, 5.0]

2、然后更新traefik configmap及traefik pod
$ kubectl get configmap -n kube-system
traefik-conf 1 83d
$ kubectl delete configmap traefik-conf -n kube-system
$ kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
$ kubectl apply -f traefik.yaml
$ kubectl get svc -n kube-system |grep traefik
traefik-ingress-service NodePort 10.100.222.78 <none> 80:31657/TCP,8080:31572/TCP
$ curl 10.100.222.78:8080/metrics
$ curl 192.168.1.243:31572/metrics
3、更新prometheus的配置文件,增加job

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: kube-ops
data:
  prometheus.yml: |
    global:
      scrape_interval: 30s
      scrape_timeout: 30s

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
        - targets: ['localhost:9090']

    - job_name: 'traefik'
      static_configs:
        - targets: ['traefik-ingress-service.kube-system.svc.cluster.local:8080']

$ kubectl apply -f prome-cm.yaml #更新prometheus configemap文件
由于我们这里 Traefik 对应的 servicename 是traefik-ingress-service,并且在 kube-system 这个 namespace 下面,所以我们这里的targets的路径配置则需要使用FQDN的形式:traefik-ingress-service.kube-system.svc.cluster.local
$ kubectl get svc -n kube-ops |grep prometheus
prometheus NodePort 10.102.197.83 <none> 9090:32619/TCP
$ curl -X POST "http://192.168.1.243:32619/-/reload" #使配置生效,可能需要一段时间,使用reload命令不用更新prometheus pod即可使配置生效

使用redis-exporter来监控 redis 服务
redis-exporter以sidecar的形式和redis部署在同一个pod内
1、构建pod及svc
$ docker pull redis:4
$ docker pull oliver006/redis_exporter:latest

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis
  namespace: kube-ops
spec:
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
      - name: redis-exporter
        image: oliver006/redis_exporter:latest
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 9121
---
kind: Service
apiVersion: v1
metadata:
  name: redis
  namespace: kube-ops
spec:
  selector:
    app: redis
  ports:
  - name: redis
    port: 6379
    targetPort: 6379
  - name: prom
    port: 9121
    targetPort: 9121

$ kubectl get svc -n kube-ops |grep redis
redis ClusterIP 10.105.241.59 <none> 6379/TCP,9121/TCP
$ curl 10.105.241.59:9121/metrics #查看是否能监控到
2、增加job并更新prometheus configmap配置文件

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: kube-ops
data:
  prometheus.yml: |
    global:
      scrape_interval: 30s
      scrape_timeout: 30s
    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']
    - job_name: 'traefik'
      static_configs:
      - targets: ['traefik-ingress-service.kube-system.svc.cluster.local:8080']
    - job_name: 'redis'
      static_configs:
      - targets: ['redis:9121']

由于我们这里的 redis 服务和 Prometheus 处于同一个 namespace,所以我们直接使用 servicename
$ kubectl apply -f prometheus-cm.yaml #更新配置
$ kubectl get svc -n kube-ops |grep prometheus
prometheus NodePort 10.102.197.83 <none> 9090:32619/TCP
$ curl -X POST "http://10.102.197.83:9090/-/reload" #使配置生效
http://http://192.168.1.243:32619/targets

使用node-exporter监控k8s集群中的所有节点及每个节点的kubelet
1、部署node-exporter
通过 DaemonSet 控制器来部署该服务,这样每一个节点都会自动运行一个这样的 Pod

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: kube-ops
  labels:
    name: node-exporter
spec:
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:v0.16.0
        ports:
        - containerPort: 9100
        resources:
          requests:
            cpu: 0.15
        securityContext:
          privileged: true
        args:
        - --path.procfs
        - /host/proc
        - --path.sysfs
        - /host/sys
        - --collector.filesystem.ignored-mount-points
        - '"^/(sys|proc|dev|host|etc)($|/)"'
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /rootfs
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /

由于我们要获取到的数据是主机的监控指标数据,而我们的 node-exporter 是运行在容器中的,所以我们在 Pod 中需要配置一些 Pod 的安全策略,这里我们就添加了hostPID: true、hostIPC: true、hostNetwork: true3个策略,用来使用主机的 PID namespace、IPC namespace 以及主机网络,这些 namespace 就是用于容器隔离的关键技术,要注意这里的 namespace 和集群中的 namespace 是两个完全不相同的概念。
由于指定了hostNetwork=true,所以在每个节点上就会绑定一个端口 9100,我们可以通过这个端口去获取到监控指标数据
$ curl 127.0.0.1:9100/metrics
$ curl 127.0.0.1:10255/metrics #通过10255端口监控kubelet
2、增加job,更新prometheus配置

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: kube-ops
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s
    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']
    - job_name: 'traefik'
      static_configs:
      - targets: ['traefik-ingress-service.kube-system.svc.cluster.local:8080']
    - job_name: 'redis'
      static_configs:
      - targets: ['redis:9121']
    - job_name: 'kubernetes-nodes'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    - job_name: 'kubernetes-kubelet'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:10255'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

在 Kubernetes 下,Promethues 通过与 Kubernetes API 集成,目前主要支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。
kubelet默认监听的端口,分别为 10250 、10255、10248
$ vim /var/lib/kubelet/config.yaml
healthzPort: 10248
port: 10250
readOnlyPort: 10255
prometheus 去发现 Node 模式的服务的时候,访问的端口默认是10250,而现在该端口下面已经没有了/metrics指标数据了,现在 kubelet 只读的数据接口统一通过10255端口进行暴露了,所以我们应该去替换掉这里的端口,但是我们是要替换成10255端口吗?不是的,因为我们是要去配置上面通过node-exporter抓取到的节点指标数据,而我们上面是不是指定了hostNetwork=true,所以在每个节点上就会绑定一个端口9100,所以我们应该将这里的10250替换成9100
$ kubectl apply -f prometheus-cm.yaml
$ kubectl get svc -n kube-ops |grep prometheus
prometheus NodePort 10.102.197.83 <none> 9090:32619/TCP
$ curl -X POST "http://10.102.197.83:9090/-/reload" #使配置生效

猜你喜欢

转载自blog.51cto.com/dongdong/2432584