momo's Blog.

kube-prometheus operator学习

字数统计: 1.5k阅读时长: 7 min
2021/02/01 Share

前言

临时记录一下学习笔记

自定义清单

安装

整个项目都是使用 jsonnet 编写

  • 安装jsonnet

    1
    2
    3
    4
    # 下载对应的安装包
    https://github.com/google/go-jsonnet/releases/tag/v0.17.0

    tar zxf go-jsonnet_0.17.0_Linux_x86_64.tar.gz -C /usr/local/bin/
  • 安装jb

1
go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb
  • 将json编译成yaml文件我们需要用 gojsontoyaml,这里安装一下
1
go get github.com/brancz/gojsontoyaml
  • 将二进制包软链, 这一步看各位需求
1
ln -s $(pwd)/go/bin/* /usr/local/bin/
  • 初始化jb,如果写过node项目或者maven项目的都会知道,他们都有一个依赖描述的文件,而jb用的依赖描述文件叫jsonnetfile.json,这里init就会创建这个文件。
1
jb init
  • 安装项目, 版本请看官方支持文档

截止到本文编写, 已经发布到 release-0.7 版本, 并且在最新版本, kube-promtheus 项目结构发生了一次重构. 使用方法已经跟本文稍微有所区别.但是总体一样

本次我们选择:release-0.6 版本 支持的kubernetes版本为 1.17 1.18

1
jb install github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus@release-0.6

构建脚本

  • 目录结构

    1
    jsonnetfile.json  jsonnetfile.lock.json  vendor
  • 其中vendor目录为项目目录, 而且是库文件

简单了解过jsonnet以后, 我们可以知道. vendor 整个项目就是一个大的json对象, 我们可以通过 import 的方式导入, 来合并, 或者组合对象

  • 官方示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 这里定义了全局变量,并且import将库文件导入
local kp =
(import 'kube-prometheus/kube-prometheus.libsonnet') +
// + 号 是用来合并对象的, 类似于继承关系,右边继承左边,如果遇到相同的属性或者方法则右边重写,替换左边
// Uncomment the following imports to enable its patches
// (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
// (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
// (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
// (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
// (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
// (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
{
// 这里重写了_config 隐藏对象 的 namespace 字段
_config+:: {
namespace: 'monitoring',
},
};

// Python 的列表推导式, std.objectFields 是标准库方法, 迭代出对象的所有字段
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +

// 生成对象,并且像下继承
{
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
} +
// serviceMonitor is separated so that it can be created after the CRDs are ready
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
{ ['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) } +
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
  • 构建脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/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-example.jsonnet}" | xargs -I{} sh -c 'cat {} | gojsontoyaml > {}.yaml' -- {}

# Make sure to remove json files
find manifests -type f ! -name '*.yaml' -delete
rm -f kustomization
  • 构建
    1
    ./build.sh example.jsonnet

自定义配置

  • 镜像修改
    1
    quay.mirrors.ustc.edu.cn

kube-state-metrics

介绍

kube-state-metrics 是一个集群级别的组件,它负责从 kubelet 等服务中抓取集群中的监控指标, 并且存储到内存中.

保护并且访问指标

默认情况下, 是无法直接访问到kube-state-metrics 所收集到的指标.

首先我们看一下在 kube-prometheus 下的配置

1
2
3
4
5
6
7
- args:
- --host=127.0.0.1
- --port=8081
- --telemetry-host=127.0.0.1
- --telemetry-port=8082
image: quay.mirrors.ustc.edu.cn/coreos/kube-state-metrics:v1.9.5
name: kube-state-metrics

我们发现, 默认绑定的地址是127.0.0.1,所以我们无法直接访问. 并且, 在Pod,还有一个组件负责保护kube-state-metrics的指标不轻易对外

1
2
3
4
5
6
7
- args:
- --logtostderr
- --secure-listen-address=:8443
- --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GC_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- --upstream=http://127.0.0.1:8081/
image: quay.mirrors.ustc.edu.cn/coreos/kube-rbac-proxy:v0.4.1
name: kube-rbac-proxy-main

kube-rbac-proxy 通过rbac负责去验证 访问者是否有访问权限.

那么我们如何去定义权限呢?让我们看一下 promtheus的 rbac配置

  • prometheus-clusterRole.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    name: prometheus-k8s
    rules:
    - apiGroups:
    - ""
    resources:
    - nodes/metrics
    verbs:
    - get
    - nonResourceURLs:
    - /metrics
    verbs:
    - get
  • prometheus-clusterRoleBinding.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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

RBAC分为两种需要认证的资源类型, 一种是resources 另一种是 non-resources 通俗点来讲, resources 是集群中的资源, 比如pod,node,等等, 我们可以通过认证以后,可以对资源进行create,list,delete 操作的. 另一个non-resources,只是来验证非资源端点, 及URL地址

  • 我们绑定了非资源地址/metrics, 当我们携带serviceaccount Token时,就能去访问我们的指标, 只需要在请求头中加入: Authorization: 即可
1
curl -v -s -k -H "Authorization: Bearer `cat /var/run/secrets/kubernetes.io/serviceaccount/token`" https://kube-rbac-proxy.default.svc:8443/metrics

当我们请求的时候, kube-rbac-proxy 会尝试review这个账号是否有对应的权限,如果有则返回资源,如果没有则返回HTTP/1.1 401 Unauthorized

  • 那携带Token请求的操作是怎么在Promtheus中实现的呢?
  • kube-state-metrics-serviceMonitor.yaml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
    labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: 1.9.5
    name: kube-state-metrics
    namespace: monitoring
    spec:
    endpoints:
    - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    honorLabels: true
    interval: 30s
    port: https-main
    relabelings:
    - action: labeldrop
    regex: (pod|service|endpoint|namespace)
    scheme: https
    scrapeTimeout: 30s
    tlsConfig:
    insecureSkipVerify: true
    - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    interval: 30s
    port: https-self
    scheme: https
    tlsConfig:
    insecureSkipVerify: true
    jobLabel: app.kubernetes.io/name
    selector:
    matchLabels:
    app.kubernetes.io/name: kube-state-metrics

serviceMonitor中,我们指定了prometheus的配置bearerTokenFile 并且在deployment的时候挂载了相应的serviceaccount

alert Rule

参考

官方文档: kube-prometheus Quickstart

官方文档: kube-state-metrics

官方文档: kube-rbac-proxy

CATALOG
  1. 1. 前言
  2. 2. 自定义清单
    1. 2.1. 安装
    2. 2.2. 构建脚本
    3. 2.3. 自定义配置
  3. 3. kube-state-metrics
    1. 3.1. 介绍
    2. 3.2. 保护并且访问指标
  4. 4. alert Rule
  5. 5. 参考