Published on

Grafana+PrometheusでKubernetesのリソース監視(Helmを利用した環境設定について)

Authors

TL;DR

  • PrometheusもGrafanaも,helmを利用することで簡単にInstallできる
  • Helmを利用したInstallスクリプトまとめました

https://github.com/ko-da-k/grafana-prometheus-setup

  • GrafanaのDashboardはTerraformによる管理や,DashboardのJson化ができるので,監視体制やDashboardを Infrastructure as Code として管理できる

https://www.terraform.io/docs/providers/grafana/index.html

Helmを利用したInstallについて

PrometheusもGrafanaも,k8sの監視ツールとしてはかなり有名なので,名前を聞いたことのある人も多いと思います 今回は,備忘録も兼ねてHelmを利用したk8sへの導入をまとめたいと思います.

helmを利用したInstallについては,こちらを参考にしました

https://qiita.com/sotoiwa/items/993990edf2bb98af7c1d

なお,本記事は,クラスター及びクライアントでのHelmのセットアップが完了しているものとします

PrometheusのInstall

まずは,helmのvaluesの確認です.

https://github.com/helm/charts/tree/master/stable/prometheus

こちらにHelmで設定ができる項目が入っていますが,実際のYamlでの記法を確認するのであれば,

helm inspect values stable/prometheus > prometheus_values.yaml を実行して,デフォルトのYamlを確認してみてください.

自分が設定しているvalues.yamlは以下のとおりです

## Define serviceAccount names for components. Defaults to component's fully qualified name.
##
serviceAccounts:
  alertmanager:
    create: false

server:

  persistentVolume:

    ## Prometheus server data Persistent Volume size
    ##
    size: 10Gi

  ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below)
  ##
  replicaCount: 3

  statefulSet:
    ## If true, use a statefulset instead of a deployment for pod management.
    ## This allows to scale replicas to more than 1 pod
    ##
    enabled: true

alertmanagerをInstallしないのは,Grafana経由でのalertを行うため,必要がないからです また,replicaとstatefulsetを設定することで,autohealing時にも取得していた値を継続させます.

実行scriptは,以下のように行っています

#!/bin/bash

cd $(dirname $0)

echo Tune shell options && {
    set -o errexit
    set -o nounset
    set -o xtrace
}

: Define Variables && {
    readonly PROJECT="${1:?}"
    readonly CLUSTER="${2:?}"
    readonly REGION="${3:?}"
    readonly NAMESPACE="${4:?}"

    readonly PROMETHEUS_CHART_VERSION=8.8.0
}

: Set target project/cluser and tiller && {
    gcloud config set project "${PROJECT}"
    gcloud container clusters get-credentials ${CLUSTER} --region "${REGION}"
    kubectl config set-context $(kubectl config current-context) --namespace="${NAMESPACE}"
    helm init --client-only
}

: Deploy Prometheus using Helm && {
    helm upgrade --install \
        --namespace="${NAMESPACE}" \
        --version="${PROMETHEUS_CHART_VERSION}" \
        -f="values.yaml" \
        "prometheus" \
        stable/prometheus
}

解説をしていくと, Set target project/cluster and tillerに関しては,gcloudの設定と,clusterのcredentialsを取得し,helmの初期化を行っています.helmの初期化は,clusterにhelmを設定済みと仮定して,--client-onlyでの初期化を行っています

Deploy Prometheus using Helmでは,設定したvaluesに従って,prometheusをInstallしています.

ちなみに,Prometheusを外に出していないのは,Grafanaのみを外から見れるようにIngressを設定するためです.Prometheus自体を試したい場合は,kubectl port-forward svc/prometheus-server 3000:80 とport forwardingして,localhost:3000にアクセスすることでクエリの実行が可能になります

GrafanaのSetupについて

GrafanaのHelmの設定項目は https://github.com/helm/charts/tree/master/stable/grafana こちらにありますが,Prometheusと同様に,helm inspect values stable/grafana > grafana_values.yamlでYamlの記法を確認できます

自分が設定するものは以下のとおりです

rbac:
  namespace: true

replicas: 3

## Enable persistence using Persistent Volume Claims
## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
##
persistence:
  enabled: true

## Pod annotations
podAnnotations:
    # 秘密情報が入れ替わったときにpodを入れ替えるためにhash値をアノテーションしておく
    checksum/extra-secret: ${SECRET_CHECKSUM:?}

## Expose the grafana service to be accessed from outside the cluster (LoadBalancer service).
## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it.
## ref: http://kubernetes.io/docs/user-guide/services/
##
service:
  type: NodePort

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "static-ip"
    kubernetes.io/ingress.allow-http: "false"
    ingress.gcp.kubernetes.io/pre-shared-cert: "cert-name"
  path: /*
  hosts:
    - ${DOMAIN_URL}

# Use an existing secret for the admin user.
admin:
  existingSecret: "grafana-admin"

grafana.ini:
  server:
    domain: ${DOMAIN_URL}
    root_url: https://${DOMAIN_URL}
  auth.github:
    enabled: true
    client_id: ${AUTH_GITHUB_CLIENT_ID:?}
    client_secret: ${AUTH_GITHUB_CLIENT_SECRET:?}
    scopes: user:email,read:org
    auth_url: https://github.com/login/oauth/authorize
    token_url: https://github.com/login/oauth/access_token
    api_url: https://api.github.com/user
    allow_sign_up: true
    allowed_organizations: organization_name
  auth.google:
    enabled: ture
    client_id: "${AUTH_GOOGLE_CLIENT_ID:?}"
    client_secret: "${AUTH_GOOGLE_CLIENT_SECRET:?}"
    scopes: https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
    auth_url: https://accounts.google.com/o/oauth2/auth
    token_url: https://accounts.google.com/o/oauth2/token
    allowd_domains: domain.example.com
    allow_sign_up: true

Grafanaでは,ログイン認証に様々なauthを利用できますが,上記の設定ではGithubとGoogle認証を導入しています. 実際のkeyに関しては環境変数経由等で入れることを想定しています.導入すると,このようなログイン画面になります

capture

Ingressの設定もHelmで行うことができます.certやstatic-ipは任意の環境でお願いします

grafanaのAdminユーザとパスワードはSecret経由で取得することが推奨されています

apiVersion: v1
kind: Secret
metadata:
  name: grafana-admin
  namespace: ${NAMESPACE:?}
type: Opaque
data:
  admin-user: ${ADMIN_USER:?}
  admin-password: ${ADMIN_PASSWORD:?}

また,

## Pod annotations
podAnnotations:
    # 秘密情報が入れ替わったときにpodを入れ替えるためにhash値をアノテーションしておく
    checksum/extra-secret: ${SECRET_CHECKSUM:?}

これを設定することで,例えばKeyやIDを入れ替えたときにPodを自動的に入れ替えるようにしています.Grafana.iniが更新されても,自動で再読込をするわけではないので,grafana.iniに設定するものも含めてhash値にしてannotationsに設定することで,設定を自動で更新できるようにしています

Installのbashスクリプトは以下のとおりです

#!/bin/bash

cd $(dirname $0)

echo Tune shell options && {
    set -o errexit
    set -o nounset
    set -o xtrace
}

: Define Variables && {
    readonly PROJECT="${1:?}"
    readonly CLUSTER="${2:?}"
    readonly REGION="${3:?}"
    readonly NAMESPACE="${4:?}"

    # set secret env
    # readonly ADMIN_USER="${5:?}"
    # readonly ADMIN_PASSWORD="${6:?}"
    # readonly AUTH_GITHUB_CLIENT_ID="${7:?}"
    # readonly AUTH_GITHUB_CLIENT_SECRET="${8:?}"
    # readonly AUTH_GOOGLE_CLIENT_ID="${9:?}"
    # readonly AUTH_GOOGLE_CLIENT_SECRET="${10:?}"
    readonly GRAFANA_CHART_VERSION=2.2.1
}

: Set target project/cluser and tiller && {
    gcloud config set project "${PROJECT}"
    gcloud container clusters get-credentials ${CLUSTER} --region "${REGION}"
    kubectl config set-context $(kubectl config current-context) --namespace="${NAMESPACE}"
    helm init --client-only
}

: Create Secrets && {
    sigil -p -f secrets.yaml \
        NAMESPACE="${NAMESPACE}" \
        ADMIN_USER="$(echo ${ADMIN_USER} | base64 -w0)" \
        ADMIN_PASSWORD="$(echo ${ADMIN_PASSWORD} | base64 -w0)" \
    | kubectl apply -f - --record
}

: Deploy Grafana using Helm && {
    sigil -p -f grafana_values.yaml \
        DOMAIN_URL="${DOMAIN_URL}" \
        AUTH_GITHUB_CLIENT_ID="${AUTH_GITHUB_CLIENT_ID}" \
        AUTH_GITHUB_CLIENT_SECRET="${AUTH_GITHUB_CLIENT_SECRET}" \
        AUTH_GOOGLE_CLIENT_ID="${AUTH_GOOGLE_CLIENT_ID}" \
        AUTH_GOOGLE_CLIENT_SECRET="${AUTH_GOOGLE_CLIENT_SECRET}" \
        SECRET_CHECKSUM=$(echo \
            ${ADMIN_USER} \
            ${ADMIN_PASSWORD} \
            ${AUTH_GITHUB_CLIENT_ID} \
            ${AUTH_GITHUB_CLIENT_SECRET} \
            ${AUTH_GOOGLE_CLIENT_ID} \
            ${AUTH_GOOGLE_CLIENT_SECRET} \
        | sha256sum) \
    | helm upgrade --install \
        --namespace="${NAMESPACE}" \
        --version="${GRAFANA_CHART_VERSION}" \
        --values=- \
        "grafana" \
        stable/grafana
}

sigilを使って,Yamlのkey等を環境変数を利用して書き換え,grafanaをInstallしています.

詳細なスクリプトは本記事TopのGithubリンクにまとめてあります.

また,promQLでの設定やalert, terraformを利用したIaCもまとめていこうと思います

Prometheusについての参考記事

https://prometheus.io/

https://qiita.com/Chanmoro/items/ac0eb1bf93760566b338

https://qiita.com/sugitak/items/ff8f5ad845283c5915d2

Grafanaについての参考記事

https://grafana.com/

https://qiita.com/Chanmoro/items/a23f0408f0e64658a775

https://qiita.com/MahoTakara/items/7b414c2a0d47e75d7234