APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【デプロイ編】Prometheus+Thanos+Grafanaでクラウドネイティブな監視を。

はじめに

こんにちは、ACS事業部の小原です。
先日クラウドネイティブなメトリクス監視ツールをご紹介しましたが、 今回はそれらをAKSにデプロイする過程をご紹介したいと思います。
※マニフェストの詳細などの細かい説明は省略しています。

もっといい方法があるよという方は是非ご教示ください!

前回の記事はこちら↓

techblog.ap-com.co.jp

事前準備

まずは監視対象であるAKSクラスタとストレージアカウントを準備します。

AKSでは専用の namespace を作成しておきます。 今回は metrics で作成しています。

また、ストレージアカウントには、メトリクス情報を格納するためのコンテナを作成しておきます。

kube-prometheus-stack のインストール

Prometheus のコミュニティがリリースしているHelmチャートを利用します。
これにより、以下のコンポーネントが簡単にデプロイできます。

  • Alertmanager
  • Exporter
    • kube-state-metrics
    • Node Exporter
  • Prometheus Operator
  • Prometheus
  • Grafana

加えて Prometheus の Pod に同居させる Thanos-Sidecar というコンポーネントも一緒にデプロイします。
Sidecar は Prometheus がスクレイピングしたメトリクスを、 Azure Blob Storage に送ってくれます。

まずはじめに、Thanos-Sidecar が Azure Blob Storage にメトリクスをアップロードするためのシークレットを作成します。

1. thanos.yml にストレージアカウントの名前とキーを入力し、コマンドを実行します。

type: AZURE
config:
  storage_account: <STORAGE_ACCOUNT_NAME>
  storage_account_key: <STORAGE_ACCOUNT_KEY>
  container: <CONTAINER_NAME>
$ kubectl -n metrics create secret generic thanos-objstore-config --from-file=thanos.yml=thanos.yml 

2. kube-prometheus-stack の Helm リポジトリ情報を取得します。

$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update

3. リポジトリ情報が取得出来たら Helm チャートのインストールをします。
Thanos Sidecar をデプロイするために values.yml に以下のフィールドを追加します。

prometheus:
  prometheusSpec:
    thanos:  
      objectStorageConfig:     # BLOBと接続するためのシークレット情報
        existingSecret:
          name: thanos-objstore-config
          key: thanos.yml

また、アラートの送信先の設定は以下のように行います。

alertmanager:
  config:
    #メールの送信に使用するSMTPサーバーの情報を指定
    global:
      smtp_smarthost: <SMTPサーバーのホスト>:<ポート>
      smtp_from: <From:行で使用するメールアドレス>
      smtp_auth_username: <SMTP AUTHで使用するユーザー名>
      smtp_auth_password: <SMTP AUTHで使用するパスワード>
      smtp_require_tls: true           
      resolve_timeout: 5m
    #特定のアラートがこのレシーバーを使用するためのルーティング設定
    route:
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 12h
      # レシーバーをここに指定(sample-receiverを使う)
      receiver: sample-receiver 
      routes:
      - matchers:
      receiver: sample-receiver
    #電子メールでアラートを送信するための設定
    receivers:
    - name: sample-receiver
      email_configs:
      - to: '<送信したいメールアドレス>'
        send_resolved: true
    # Alertの通知テンプレートを指定
    templates:                           
    - '/etc/alertmanager/config/*.tmpl'

詳しく設定は下記リンクのページやデフォルトのvalues.yamlを参考にしてみてください!

prometheus.io

github.com

ここまで出来たらhelm install コマンドでインストールしていきましょう。

$ helm install -n metrics prometheus prometheus-community/kube-prometheus-stack -f values.yml

各コンポーネントが入ったか確認してみます。

$ k -n metrics get pod
NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-prometheus-kube-prometheus-alertmanager-0   2/2     Running   0          3m12s
prometheus-grafana-6ffd599f89-4ffk2                      3/3     Running   0          3m22s
prometheus-kube-prometheus-operator-8d8b94cc8-lvwsf      1/1     Running   0          3m22s
prometheus-kube-state-metrics-786d54d4bd-bpf4p           1/1     Running   0          3m22s
prometheus-prometheus-kube-prometheus-prometheus-0       3/3     Running   0          3m11s
prometheus-prometheus-node-exporter-tdk8q                1/1     Running   0          3m22s

また、PrometheusのPodを見てみると、中にThanos-Sidecarのコンテナが存在することが確認できます。

$ k -n metrics describe pod prometheus-prometheus-kube-prometheus-prometheus-0 
# 一部を抜粋
thanos-sidecar:
    Container ID:  containerd://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Image:         quay.io/thanos/thanos:v0.34.1
    Image ID:      quay.io/thanos/thanos@256xxxxxxxxxxxxxxxxxxxxxxxxxxx
    Ports:         10902/TCP, 10901/TCP
    Host Ports:    0/TCP, 0/TCP

Thanos コンポーネントのデプロイ

続いて Thanos コンポーネントをデプロイしていきます。
こちらは公式のHelmチャートが存在しないため、ひとつずつマニフェストを用意してkubectl applyコマンドでデプロイしていきます。

ここで用意するマニフェストは以下の通りです。

  • Thanos-Sidecar
    • service.yml
  • Thanos-Query
    • thanos-query.yml
    • thanos-query-service.yml
  • Thanos-Store
    • thanos-store.yml
    • thanos-store-service.yml
  • Thanos-Compactor
    • compactor-statefulset.yml
    • compactor-service.yml

詳細な設定はThanosのドキュメントをご覧ください。

thanos.io

Thanos-Sidecar

先ほどのHelmチャートでデプロイしたSidecarが他のコンポーネントと通信するためのServiceを作成します。
下記のservice.ymlマニフェストをapplyします。

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: thanos-sidecar
  name: thanos-sidecar
  namespace: metrics
spec:
  type: ClusterIP
  ports:
  - name: grpc
    port: 10901
    targetPort: grpc
  - name: http
    port: 10902
    targetPort: http
  selector:
    prometheus: prometheus-prometheus-kube-prometheus-prometheus-0 
    app.kubernetes.io/instance: prometheus-prometheus-kube-prometheus-prometheus-0 

Thanos-Query

Thanosのコンポーネントに対するクエリを集約し、結果を返すコンポーネントです。
本体であるdeploymentと、他コンポーネントとの通信のためのServiceをapplyします。

thanos-query.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: thanos-query
  name: thanos-query
  namespace: metrics
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: thanos-query
  template:
    metadata:
      labels:
        app.kubernetes.io/name: thanos-query
    spec:
      containers:
      - args:
        - query
        - --grpc-address=0.0.0.0:10901
        - --http-address=0.0.0.0:19192
        - --query.replica-label=prometheus_replica
        - --query.replica-label=thanos_ruler_replica
        - --endpoint=thanos-sidecar:10901
        - --endpoint=thanos-store:10901
        image: quay.io/thanos/thanos:v0.33.0
        name: thanos-query
        ports:
        - containerPort: 10901
          name: grpc
        - containerPort: 19192
          name: web

thanos-query-service.yml

apiVersion: v1
kind: Service
metadata:
  name: thanos-query
  namespace: metrics
spec:
  selector:
    app.kubernetes.io/name: thanos-query
  ports:
  - protocol: TCP
    port: 80
    targetPort: 19192
  type: ClusterIP

Thanos-Store

このコンポーネントは、オブジェクトストレージに保存されたメトリクス情報に対してクエリを実行できるようにします。
DeploymentとServiceそれぞれapplyします。

thanos-store.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: thanos-store
  name: thanos-store
  namespace: metrics
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: thanos-store
  template:
    metadata:
      labels:
        app.kubernetes.io/name: thanos-store
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 65534
        fsGroup: 65534
      containers:
        - args:
            - store
            - --no-cache-index-header
            - --grpc-address=0.0.0.0:10901
            - --http-address=0.0.0.0:10902
            - --objstore.config-file=/config/thanos.yml
          image: quay.io/thanos/thanos:v0.33.0
          name: thanos-store
          ports:
          - containerPort: 10902
            name: http
          - containerPort: 10901
            name: grpc
          volumeMounts:
            - name: config
              mountPath: /config     
      volumes:
        - name: config
          secret:
            secretName: thanos-objstore-config

thanos-store-service.yml

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: thanos-store
  name: thanos-store
  namespace: metrics
spec:
  type: ClusterIP
  ports:
  - name: grpc
    port: 10901
    targetPort: grpc
  - name: http
    port: 10902
    targetPort: http
  selector:
    app.kubernetes.io/name: thanos-store

Thanos-Compactor

Compactorはオブジェクトストレージ内のデータを効率的な形式に圧縮・最適化し、ストレージコストを削減します。また、データのダウンサンプリングや削除も行います。 Azure Blob Storageでのメトリクス保持期間はcompactor-statefulset.ymlで設定します。

compactor-statefulset.yml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: thanos-compactor
  namespace: metrics
  labels:
    app: thanos-compactor
spec:
  serviceName: thanos-compactor
  replicas: 1
  selector:
    matchLabels:
      app: thanos-compactor
  template:
    metadata:
      labels:
        app: thanos-compactor
    spec:
      containers:
        - name: thanos-compactor
          image: quay.io/thanos/thanos:v0.33.0   
          args:
            - compact
            - --log.level=debug
            - --data-dir=/var/thanos/store
            - --objstore.config-file=/config/thanos.yml
            - --wait
            #Azure Blob Storageでの保持期間設定
            - --retention.resolution-raw=180d
            - --retention.resolution-5m=365d
            - --retention.resolution-1h=1095d
          ports:
            - name: http
              containerPort: 10902
          volumeMounts:
            - name: config
              mountPath: /config/
              readOnly: true
            - name: data
              mountPath: /var/thanos/store
      volumes:
        - name: data
          emptyDir: {}
        - name: config
          secret:
            secretName: thanos-objstore-config

compactor-service.yml

apiVersion: v1
kind: Service
metadata:
  name: thanos-compactor
  labels:
    app: thanos-compactor
  namespace: metrics
spec:
  selector:
    app: thanos-compactor
  ports:
    - port: 10902
      name: http

リソースの確認

ここまでで今回の構成に必要なツールのデプロイが完了しました。 コマンドで以下のように確認できます。

$ kubectl -n metrics get pod
NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-prometheus-kube-prometheus-alertmanager-0   2/2     Running   0          168m
prometheus-grafana-6ffd599f89-rvvbc                      3/3     Running   0          168m
prometheus-kube-prometheus-operator-8d8b94cc8-h8dwp      1/1     Running   0          168m
prometheus-kube-state-metrics-786d54d4bd-69w7t           1/1     Running   0          168m
prometheus-prometheus-kube-prometheus-prometheus-0       3/3     Running   0          168m
prometheus-prometheus-node-exporter-57fgk                1/1     Running   0          37m
thanos-compactor-0                                       1/1     Running   0          168m
thanos-query-fb57cf95-r8dgn                              1/1     Running   0          168m
thanos-store-766dfb6df5-559vh                            1/1     Running   0          168m

補足(AlertRuleの設定)

kube-prometheus-stackによるデプロイで、デフォルトでいくつかアラートルールがAKSに入っていますが、
実際に運用する際にこのまま使用ケースは少ないと思います。

ここでは、values.yamlに直接アラートルールを書き込んで設定する手順を説明します。

values.yamldefaultRules.createfalseにする

defaultRules:
  create: false

このように書き換えてデフォルトでルールが追加されないように設定します。
もしデフォルトのルールから取捨選択したい場合は、下記リンクのソースを確認しつつ、アラート毎にステータスを変えてください。

ここではデフォルトのルールの詳細な説明は省略しますm(__)m

github.com

additionalPrometheusRulesにルールを定義

デフォルトでコメントアウトされているこちらの編集でルールを追加します。

ルールの定義は以下のフォーマットで行います。 Prometheusのドキュメントにあるルール定義と大差ないですね。
グループやアラートそのものの名前を決める前に、kind: PrometheusRuleとしての名前を決める必要がある点に注意してください。
my-rule-fileがそれに当たります)

kube-prometheus-stackにおけるルール定義

 additionalPrometheusRules: 
  - name: my-rule-file
    groups:
      - name: my_group
        rules:
        - record: my_record
          expr: 100 * my_record

Prometheusのドキュメントにおけるルール定義

groups:
- name: example
  rules:
  - alert: HighRequestLatency
    expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
    for: 10m
    labels:
      severity: page
    annotations:
      summary: High request latency

$ helm upgradeの実施

アラートルールの定義が完了したらマニフェストを保存し、helm upgradeコマンドでアップグレードを実施してください。

アップグレードが完了したら以下のコマンドで確認してください。

$ kubectl -n metrics get prometheusrules

おわりに

これで一通りツールのデプロイは完了です!
次回はアラートとGrafanaについて解説する記事をupする予定なので、是非ご覧ください!


私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。ご相談等ありましたらぜひご連絡ください。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 小原陽希