使用Prometheus监控Kubernetes的指标

这篇文章是Kubernetes Advent Calendar 2016的第15篇文章。在这篇文章中,我们将讨论在Kubernetes中监控指标的方法。

使用Kubernetes时应该关注的指标可以分为基于Kubernetes集群的系统指标、集群本身的指标以及在集群上运行的应用程序的指标。本文将讨论如何使用Prometheus监视这些指标。

另外,本文验证是使用 coreos-kubernetes 在 Vagrant 上构建 Kubernetes 集群。同时,Kubernetes 和 Prometheus 的版本如下所示。

プロダクトバージョンKubernetesv1.4.6Prometheusv1.4.0

另外,我们将 Prometheus 自身部署在作为监控目标的 Kubernetes 集群上。

構築普羅米修斯

首先,在Kubernetes集群上搭建Prometheus。

$ kubectl create -f https://raw.githubusercontent.com/kkohtaka/kubernetes-metrics/master/prometheus/service.yml
$ kubectl create -f https://raw.githubusercontent.com/kkohtaka/kubernetes-metrics/master/prometheus/deployment.yml
$ kubectl create -f https://raw.githubusercontent.com/kkohtaka/kubernetes-metrics/master/prometheus/configmap.yml

我使用的Kubernetes资源如下。

服务

kkohtaka/kubernetes-metrics/prometheus/service.yml 可以重新表述为:kkohtaka/kubernetes-metrics/prometheus/服务配置文件.yml。

为了从外部访问在 Kubernetes 集群内构建的 Prometheus,我们将创建一个 NodePort 类型的Service。这样,我们就可以通过类似于 http://${NODE_IP_ADDRESS}:30090 的 URL 访问 Prometheus。

部署 ( )

kkohtaka/kubernetes-metrics/prometheus/deployment.yml的意思是什么?

这是用于部署 Prometheus Pod 的资源。

配置映射

kkohtaka/kubernetes-metrics/prometheus/configmap.yml 的中文同义替换为:kkohtaka/kubernetes-度量标准/普罗米修斯/配置映射.yml。

我们将创建一个 ConfigMap,以便将 Prometheus 的配置文件从 Pod 中读取。

特别值得关注的是设置文件中关于服务发现的配置。通过在中记录,Prometheus会通过kube-apiserver监视集群中的状态变化(例如添加新的Pod等),并开始收集Kubernetes中Pod和Service导出的指标等信息。

我們將會在後續解釋如何撰寫設定檔案的描述方式。

系统的度量标准

接下来,让我们考虑如何监视作为Kubernetes集群基础的系统的指标。本次我们将使用Node exporter来获取主机机器的指标,并尝试使用cAdvisor来获取容器的指标。

主机系统的度量指标

Node exporter 是 Prometheus 的官方工具,用于导出主机机器的指标,如 CPU 和内存使用量。在收集指标时,每台主机上都需要运行一个 Node exporter,因此在 Kubernetes 集群中将其部署为 DaemonSet。这样可以每个主机(即 Node)运行一个 Node exporter 进程。

在这个验证中,我们使用了以下的DaemonSet。

kkohtaka/kubernetes-metrics/node-exporter/daemonset.yml

$ kubectl create -f https://raw.githubusercontent.com/kkohtaka/kubernetes-metrics/master/node-exporter/daemonset.yml

DaemonSet によりデプロイされた Node exporter の Pod で取得したメトリクスを収集するためには, Prometheus 側の設定を行う必要があります. 次の例では Pod からエクスポートされたメトリクスを収集するように設定しています.

# /etc/prometheus.yml

# ...省略...

scrape_configs:

# ...省略...

- job_name: 'kubernetes-pods'

  kubernetes_sd_configs:
  - role: pod

  relabel_configs:
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)
  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
    action: replace
    regex: (.+):(?:\d+);(\d+)
    replacement: ${1}:${2}
    target_label: __address__
  - action: labelmap
    regex: __meta_kubernetes_pod_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    action: replace
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_pod_name]
    action: replace
    target_label: kubernetes_pod_name

  # ...省略...

在为 Prometheus 进行上述设置后,您可以在 PodTemplateSpec 的 metadata 中添加以下的 annotation 来指定 Pod 导出指标的端口和路径。

  # ...省略...

  template:
    metadata:

      # ...省略...

      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '9100'
        prometheus.io/path: /metrics
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter:v0.13.0

      # ...省略...

Prometheus が Node exporter から収集しているメトリクスの一覧は次のようなコマンドで確認できます.

$ curl -g "http://${NODE_IP_ADDRESS}:30090/api/v1/series?match[]={app=\"node-exporter\"}" \
  | jq -r '.data[].__name__' \
  | sort \
  | uniq
...
node_boot_time
node_context_switches
node_cpu
node_disk_bytes_read
node_disk_bytes_written
node_disk_io_now
node_disk_io_time_ms
node_disk_io_time_weighted   
node_disk_read_time_ms
node_disk_reads_completed
...

容器系统的度量指标

コンテナのシステムメトリクスの取得には cAdvisor が有名なのでこれを利用してみたいと思います. Kubernetes の場合, cAdvisor は Kubelet に組み込まれているため cAdvisor 自体を新たに導入する必要はありません.

また, cAdvisor の取得したメトリクスを Prometheus で収集するためには次のような記述を Prometheus の設定ファイルに追加します.

# /etc/prometheus.yml

# ...省略...

scrape_configs:

# ...省略...

- job_name: 'kubernetes-nodes'

  scheme: https

  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

  kubernetes_sd_configs:
  - role: node

  relabel_configs:
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)

# ...省略...

これにより各 Node に配置されている Kubelet を通じて, cAdvisor により取得されたメトリクスを Prometheus が収集するようになります.

$ curl -g "http://${NODE_IP_ADDRESS}:30090/api/v1/series?match[]={container_name=\"heapster\"}" \
  | jq -r '.data[].__name__' \
  | sort \
  | uniq
...
container_cpu_cfs_periods_total
container_cpu_cfs_throttled_periods_total
container_cpu_cfs_throttled_seconds_total
container_cpu_system_seconds_total
container_cpu_usage_seconds_total
container_cpu_user_seconds_total
container_fs_inodes_free
container_fs_inodes_total
container_fs_io_current
container_fs_io_time_seconds_total
...

Kubernetes 集群的指标

クラスタのメトリクスの取得には kube-state-metrics を利用することにします.

在这个验证中,我们使用了如下的部署方式。

kkohtaka/kubernetes-metrics/kube-state-metrics/deployment.yml

$ kubectl create -f https://raw.githubusercontent.com/kkohtaka/kubernetes-metrics/master/kube-state-metrics/deployment.yml

kube-state-metrics の Pod が取得したメトリクスを収集するための Prometheus 側の設定は, Node exporter の利用よるシステムメトリクスの収集時に設定したもので問題ありません. また, kube-state-metrics の PodTemplateSpec にも Node exporter の場合と同様に次のような設定が必要です.

  # ...省略...

  template:
    metadata:

      # ...省略...

      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '8080'
    spec:
      containers:
      - name: kube-state-metrics
        image: gcr.io/google_containers/kube-state-metrics:v0.3.0
        ports:
        - containerPort: 8080

      # ...省略...

你可以使用以下命令查看 Prometheus 从 kube-state-metrics 收集的指标列表。

$ curl -g "http://${NODE_IP_ADDRESS}:30090/api/v1/series?match[]={app=\"kube-state-metrics\"}" \
  | jq -r '.data[].__name__' \
  | sort \
  | uniq
...
kube_deployment_metadata_generation
kube_deployment_spec_paused
kube_deployment_spec_replicas
kube_deployment_status_observed_generation
kube_deployment_status_replicas
kube_deployment_status_replicas_available
kube_deployment_status_replicas_unavailable
kube_deployment_status_replicas_updated
kube_node_info
kube_node_spec_unschedulable
...

应用程序的指标

最后我们要思考应用程序指标的监控问题。在这种情况下,根据被监控的应用程序处于以下哪种状态,对应的处理方法也会有所不同。

    • アプリケーションが Prometheus 形式のメトリクスのエクスポートをサポートしている

 

    • メトリクスのエクスポートをサポートしていないが, 改修することができる

 

    メトリクスのエクスポートをサポートしておらず, 改修することもできない

如果支持指标导出的话

Etcd や SkyDNS などはアプリケーションそのものが Prometheus 形式のメトリクスエクスポートをサポートしているため, 上述した Node expoter や kube-state-metrics と同様の方法でメトリクスを収集することができます.

在下面的 Deployment 示例中,设置了 Etcd 的度量数据收集。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: etcd
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: etcd
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '2379'
        prometheus.io/metrics: /metrics
    spec:
      containers:
      - name: etcd
        image: quay.io/coreos/etcd:v3.0.15
        args:
        - etcd
        - -listen-client-urls=http://0.0.0.0:2379,http://0.0.0.0:4001
        - -advertise-client-urls=http://0.0.0.0:2379,http://0.0.0.0:4001
        ports:
        - name: etcd
          containerPort: 2379
          protocol: TCP

可以通过以下命令确认 Prometheus 从 Etcd 收集的指标列表。

$ curl -g "http://${NODE_IP_ADDRESS}:30090/api/v1/series?match[]={app=\"etcd\"}" \
  | jq -r '.data[].__name__' \
  | sort \
  | uniq
...
etcd_disk_backend_commit_duration_seconds_bucket
etcd_disk_backend_commit_duration_seconds_count
etcd_disk_backend_commit_duration_seconds_sum
etcd_disk_wal_fsync_duration_seconds_bucket
etcd_disk_wal_fsync_duration_seconds_count
etcd_disk_wal_fsync_duration_seconds_sum
etcd_network_client_grpc_received_bytes_total
etcd_network_client_grpc_sent_bytes_total
etcd_server_has_leader
etcd_server_leader_changes_seen_total
...

如果可以对应用程序进行修改的话。

如果应用程序不支持 Prometheus 格式的指标导出,但可以进行修改并修复的话,使用 Prometheus 的客户端库也可以实现在应用程序中实现指标导出功能。

考虑到为多种编程语言提供的客户端库,因此在大多数情况下可以实现兼容性。

如果无法对应用程序进行修订的情况下

アプリケーションに手を入れることができない場合には, アプリケーションとは異なるプログラムを用意してアプリケーションを監視させ, さらにそのプログラムに Prometheus 形式のメトリクスをエクスポートさせるというアプローチが可能な場合があります. Prometheus ではこのようなプログラムを Exporter と呼んでいます.

すでに多数の Exporter がサードパーティから提供されており, その一覧がここにあります.

また, 目的のアプリケーションの Exporter が提供されていない場合でも, 上述した Prometheus のクライアントライブラリを利用することで Exporter を開発することも可能です.

在下面的 Deployment 示例中,我们使用 Exporter 来配置 Apache HTTP Server 的指标收集。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: apache
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: apache
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '9117'
        prometheus.io/path: /metrics
    spec:
      containers:
      - name: apache-exporter
        image: jecnua/apache-exporter
      - name: apache
        image: httpd:2.4
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: config-volume
          mountPath: /usr/local/apache2/conf
      # ...省略...

通过Expoter,您可以使用以下命令确认Prometheus从Apache HTTP Server收集的指标。

$ curl -g "http://${NODE_IP_ADDRESS}:30090/api/v1/series?match[]={app=\"apache\"}" \
  | jq -r '.data[].__name__' \
  | sort \
  | uniq
...
apache_accesses_total
apache_connections
apache_exporter_scrape_failures_total
apache_scoreboard
apache_sent_kilobytes_total
apache_up
apache_uptime_seconds_total
apache_workers
...

概括

使用 Prometheus 可以在 Kubernetes 的各个层面上收集指标。下表中列出了用于获取每个层面指标的工具和方法。

対象レイヤーメトリクス取得のためのツール・手法システム (ホストマシン)Node expoter + DaemonSetシステム (コンテナ)cAdvisor (Kubelet)Kubernetes クラスタkube-state-metricsアプリケーション (Prometheus 対応)そのまま取得可能アプリケーション (Prometheus 未対応, 改修可)Prometheus クライアントライブラリで実装アプリケーション (Prometheus 未対応, 改修不可)Prometheus Exporter を利用

我开始写了一篇标题为“监控指标”的文章,但只写到了收集指标的部分。接下来,我想总结一下这次收集的指标应该如何可视化。

参考文献

    • Configuration | Prometheus

 

    • Prometheus and Kubernetes up and running | CoreOS Blog

 

    • Monitoring in the Kubernetes era | Datadog Blog

 

    • Monitoring Kubernetes performance metrics| Datadog Blog

 

    • How to collect and graph Kubernetes metrics | Datadog Blog

 

    prometheus-kubernetes.yml