Kubernetesで各Nodeの負荷監視 後編

DXブログ

はじめに

 サイオステクノロジー中島です。

 Kubernetesのノード負荷監視の後編となります。前回で、監視エージェントをインストールしましたので、本記事は、そのエージェントを使用してデータ監視を行います。

構築手順

 構築方法について、以下の手順で構築を行います。作業については、masterの機器にsshでログインして作業を実施します。手順1と2は前編を確認してください。

  1. 名前空間の作成
  2. 監視エージェントを各nodeに実行
  3. Prometheusで監視
  4. Grafanaを使用してPrometheusの視覚的に監視

 装置構成として以下のように構築した装置を使用します。

Prometheusで監視

 以下の図のように設定ファイルをmasterで読み込んで、node-exporterのエージェント監視するPrometheusが起動するpodを起動させます。

図 Prometheusの設定ファイル読み込みイメージ図

図 Prometheus設定ファイル読み込み後の動作イメージ図

 以下に、ServiceAccountを発行とRoleとユーザーやグループを紐付けるリソース定義を記載します。

・prometheus-account.yml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: gf-space
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
  namespace: gf-space
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
  - kind: ServiceAccount
    name: prometheus
    namespace: gf-space

以下に、アカウントに対して、操作できるロールを割り当てる定義を記載します。

・prometheus-role.yml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups:
  - extensions
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]

 以下に、prometheusを動作させるための設定ファイル(prometheus.yml)を定義します。本章では、kubernetesネットワーク内に存在するpodから、「__meta_kubernetes_pod_container_name」で定義された名前が「exporter」または、「cadvisor」であるpodが監視対象となるように設定しています。

・prometheus-conf.yml

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: gf-space
  name: prometheus-configmap
data:
  prometheus.yml: |
    global:
      scrape_interval:     15s # By default, scrape targets every 15 seconds.
      evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
      # Attach these labels to any time series or alerts when communicating with
      # external systems (federation, remote storage, Alertmanager).
    #external_labels:
    #  monitor: 'codelab-monitor'
    # A scrape configuration containing exactly one endpoint to scrape:
    # Here it's Prometheus itself.
    scrape_configs:
      # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
      - job_name: 'prometheus'
      # Override the global default and scrape targets from this job every 5 seconds.
        scrape_interval: 5s
        static_configs:
          - targets: ['localhost:9090']
      - job_name: 'kubernetes-pods'
        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: pod
        relabel_configs:
          - source_labels: [__meta_kubernetes_pod_container_name]
            regex: exporter|cadvisor
            action: keep
          - source_labels: [__meta_kubernetes_pod_node_name]
            action: replace
            target_label: node_name

 以下に、本章で定義したアカウントで動作するprometheusがpod起動する設定のDeployment記載ymlファイルを記載します。

・prometheus.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: gf-space
spec:
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccountName: prometheus
      serviceAccount: prometheus
      containers:
        - name: prometheus
          image: prom/prometheus
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9090
          volumeMounts:
            - name: config-vol
              mountPath: /etc/prometheus/prometheus.yml
              # mountPath: /prometheus/prometheus.yml
              subPath: prometheus.yml
      volumes:
        - name: config-vol
          configMap:
            name: prometheus-configmap
            items:
              - key: prometheus.yml
                path: prometheus.yml

 以下に、ネットワーク外から30747ポートにアクセスした通信をPrometheusのpodに渡しますサービスを記載します。

・prometheus-service.yml

apiVersion: v1
kind: Service
metadata:
  name: prometheus-service
  namespace: gf-space
spec:
  selector:
    app: prometheus
  ports:
    - port: 9090
      targetPort: 9090
      nodePort: 30747
  type: LoadBalancer

以下コマンドで動作させます。

$ kubectl apply -f prometheus-account.yml
$ kubectl apply -f prometheus-role.yml
$ kubectl apply -f rometheus-conf.yml 
$ kubectl apply -f prometheus.yml
$ kubectl apply -f prometheus-service.yml

以下のコマンドで、prometheusのステータスが「Running」になることを確認してください。もしならない場合は、prometheus-conf.yml内の設定ファイルが間違っている可能性が高いです。

 $ kubectl get pod --namespace=gf-space -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
exporter-hdrf9                1/1     Running   2          5d20h   192.168.0.25   raspberrypi5   <none>           <none>
exporter-sftk9                1/1     Running   1          5d20h   192.168.0.21   bookserver2    <none>           <none>
exporter-xqh25                1/1     Running   3          5d20h   192.168.0.24   k8s-worker-1   <none>           <none>
prometheus-8496447b96-jdwf4   1/1     Running   0          4m8s    10.244.2.69    raspberrypi5   <none>           <none>

起動後、「http://bookserver2.local:30747」にブラウザでアクセスすると以下のような画面が表示されます

また、status->targetの順でアクセスすると以下の図のように、Endpointにkubernetesネットワーク内で起動している監視エージェントを監視するように自動登録されています。

Grafanaを使用してPrometheusの視覚的に監視

 事前にNFS共有のフォルダ内にgrafanaフォルダを作りchmodコマンドで権限を777にする。

 本章で読み込む設定ファイルについて以下に示す。

図 Grafana起動の読み込みファイル図

また、読み込んだ後で、動作するKubernetesクラスタの状態を以下に示す。

図 Grafana設定ファイル読み込み後の動作イメージ図

 フォルダをマウントするための設定ファイルを以下に示します。なお、マウント対象となるフォルダは、k8s-worker-1(192.168.0.24)内で定義したNFSの対象フォルダとなります。また、このフォルダをコンテナにマウントした時に保存容量は1GBを定義します。

・grafana-volue.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: "grafana-pv-volume"
  namespace: gf-space
  labels:
    type: "local"
spec:
  storageClassName: "manual"
  persistentVolumeReclaimPolicy: Retain
  capacity:
    storage: "1Gi"
  accessModes:
    - ReadWriteOnce
#   hostPath:
#     path: /home/pi/usb/usb1/grafana
  nfs:
    server: 192.168.0.24
    path: /home/pi/nfs/grafana
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-pv-claim
  namespace: gf-space
spec:
  storageClassName: manual
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

 Grafanaのpodを起動させるための定義を以下に示します。なお、フォルダマウントについては、PersistentVolumeClaimで定義したフォルダをGrafanaのpodにマウントさせます。

・grafana.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: gf-space
spec:
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
        - name: grafana
          image: grafana/grafana
          imagePullPolicy: IfNotPresent
          env:
            - name: TZ
              value: 'Asia/Tokyo'
          ports:
            - containerPort: 3000
          volumeMounts:
            - name: grafana-vol
              mountPath: /var/lib/grafana
      volumes:
        - name: grafana-vol
          persistentVolumeClaim:
            claimName: grafana-pv-claim

 Grafanaのpodへの接続サービス設定を以下に示します。本設定の機能は、クラスタ外からの接続ポートは30748を開き、そこへの通信をGrafanaのpodに渡します。

・grafana-service.yml

apiVersion: v1
kind: Service
metadata:
  name: grafana-service
  namespace: gf-space
spec:
  selector:
    app: grafana
  ports:
    - port: 3000
      targetPort: 3000
      nodePort: 30748
  type: LoadBalancer

以下のコマンドで、起動させてください。

kubectl apply -f grafana-volue.yml
kubectl apply -f grafana.yml
kubectl apply -f grafana-service.yml

起動後、Grafanaにアクセスして、クラスタ上に存在するPrometheusのサーバを登録します。データソースでPrometheusを選択し、URL「http://prometheus-service:9090」を登録してください。

後は、ダッシュボードでグラフを登録をすれば以下の図に近いものを作ることができます。

参考までに以下図で使用した設定を記載します。

・CPU使用率

 avg(rate(node_cpu_seconds_total{mode=”user”}[1m] ) )by (node_name)*100

・使用メモリ

 node_memory_MemTotal_bytes-node_memory_MemFree_bytes