GKE + datadogの監視の仕組みをhelmfileを使っての下準備
GKE + datadogの監視をするのにhelmfileを使ってdatadog-agentを入れるのと、 helmfileをCircle CIで回してパッケージ管理の準備までしてしまおうというもの。
Integrationの有効化
Datadogなので、まずはintegrationの有効化 必要に応じてだけど、代替以下
Docker Google Cloud Platform Google Container Engine Google Compute Engine Google CloudSQL Google Cloud Pubsub Google Cloud Storage kubernates
こちら参考 GCPのIntegrationを有効化するために サービスアカウント が必要なので作成しておく。
監視項目
監視したい内容は以下とする
- Kubernetes 上のアプリ/クラスタコンポーネントの監視
種類 | 監視対象 | 監視項目 | 監視方法 (使うメトリクス項目) |
---|---|---|---|
Work metrics | アプリの Pod (web, api, worker) | unavailable な Pod がいないことを確認 | kubernetes_state.deployment.replicas_unavailable |
Work metrics | アプリの Pod (web, api, worker) | Pod が restart loop に陥っていないことを確認 | "CrashLoopBackOff/n分間にn回以上再起動していないかどうか" |
Work metrics | kube-system namespace の Pods | unavailable な Pod がいないことを確認 | |
Work metrics | Kubernetes worker nodes | 全ての node status が Ready であることを確認 | check: kubernetes_state.node.ready |
Work metrics | Kubernetes worker nodes | 全ての node が schedulable であることを確認 | "metrics: kubernetes_state.node.status/tag: status:schedulable == 0" |
Resources metrics | Kubernetes worker nodes | node のリソースのキャパシティに余裕があることを確認 | "kube_node_status_capacity_cpu_cores/kube_node_status_capacity_memory_bytes" |
- GCEインスタンスの監視
種類 | 監視対象 | 監視項目 | 監視方法 (使うメトリクス項目) |
---|---|---|---|
Resources metrics | Kubernetes worker nodes | Keepalive (Connectivity) 監視 | 従来の VM 運用と同じやり方 |
Resources metrics | Kubernetes worker nodes | CPU Usage | 従来の VM 運用と同じやり方 |
Resources metrics | Kubernetes worker nodes | Memory Usage | 従来の VM 運用と同じやり方 |
Resources metrics | Kubernetes worker nodes | Disk Usage | 従来の VM 運用と同じやり方 |
- Datadog Dashboard に出しておきたい項目
項目 | メトリクス |
---|---|
CPU core 使用率 | kubernetes.cpu.usage.total / kubernetes.cpu.capacity |
Memory 使用率 | kubernetes.memory.usage / kubernetes.memory.capacity |
Disk 使用率 | kubernetes.filesystem.usage_pct |
CPU reqests/limits | kubernetes.cpu.requests / kubernetes.cpu.limits |
Mem reqests/limits | kubernetes.memory.requests / kubernetes.memory.limits |
DatadogのAgentの用意
Monitoring Kubernetes with Datadog How to monitor Google Kubernetes Engine with Datadog
datadogの記事をみるとGKEなどのkubernatesをdatadogでモニタリングするには各ノードにdatadog-agentをdeamonsetで常駐させるのが一般的らしい。 Pod間通信でメトリクスを取ってくるようです。
以下のようなものを用意して、 kubectl create -f datadog-agent.yaml
で当てる感じ。
datadogのkubernatesのintegrationのページにも書いてありまする。
TIPS
- DaemonSetのAPIversionはKubernetesバージョン1.9以降の場合は、
apps/v1
を使用 apps/v1
ではspec.selectorが必要になります。- 他のpodからcustom metricsをDogStatsD経由で送信するため、8125/UDPをHost(ノード)に公開します
- Traceの機能も同様に他のpodから使いたいため8126/TCPをHost(ノード)に開ける。
- API_KEYはSecretから取得。作成コマンドは以下参照。
kubectl create secret generic datadog-secret --from-literal=api_key=*****
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: datadog-agent spec: selector: matchLabels: name: datadog-agent template: metadata: labels: app: datadog-agent name: datadog-agent spec: serviceAccountName: datadog-agent containers: - image: datadog/agent:latest imagePullPolicy: Always name: datadog-agent ports: - containerPort: 8125 # Custom metrics via DogStatsD - uncomment this section to enable custom metrics collection # hostPort: 8125 name: dogstatsdport protocol: UDP - containerPort: 8126 # Trace Collection (APM) - uncomment this section to enable APM # hostPort: 8126 name: traceport protocol: TCP env: - name: DD_API_KEY valueFrom: secretKeyRef: name: datadog-secret key: api-key - name: DD_COLLECT_KUBERNETES_EVENTS value: "true" - name: DD_LEADER_ELECTION value: "true" - name: KUBERNETES value: "true" - name: DD_KUBERNETES_KUBELET_HOST valueFrom: fieldRef: fieldPath: status.hostIP - name: DD_APM_ENABLED value: "true" resources: requests: memory: "256Mi" cpu: "200m" limits: memory: "256Mi" cpu: "200m" volumeMounts: - name: dockersocket mountPath: /var/run/docker.sock - name: procdir mountPath: /host/proc readOnly: true - name: cgroups mountPath: /host/sys/fs/cgroup readOnly: true livenessProbe: exec: command: - ./probe.sh initialDelaySeconds: 15 periodSeconds: 5 volumes: - hostPath: path: /var/run/docker.sock name: dockersocket - hostPath: path: /proc name: procdir - hostPath: path: /sys/fs/cgroup name: cgroups
Kubernetesのintegrationをみると manifestを書いて、それにk8sクラスタに当てる必要がある。 manifest管理をどうするかの問題が発生するが、今回はhelmを使ってインストールをする。
helm + helmfileを用いたdatadog-agentインストール
ますhelmとはK8sのパッケージ管理ツール。
リポジトリに登録された構成情報(Chart)を、 installコマンドに適時引数で設定情報を与え、簡単に自分のクラスタに導入(Release)することができる。
そしてhelmfileはk8sクラスタのhelm releasesを管理してくれるもの。
helmfile.yaml
にデプロイしたいhelm Chartを書いて、 helmfile sync
を実行するとインストールやアップグレードを gemfile
のように冪等に管理してくれるもの。
datadog-agentをクラスタに配置する場合は以下のYAMLを書くだけ。
- datadogのhelm chart
prd.values.yaml
にdatadog-apiキーを入れて読み込ませる
releases: - name: datadog namespace: kube-system chart: stable/datadog version: 1.27.2 values: - ./datadog/prd.values.yaml
Circle CIでhelmインストールする
GKEなので、kubectl,helm,helmfileをインストールして、 gcloudコマンドでログインして、クラスタのクレデンシャルとって、helmを当てていく流れ。
以下はCircle CI側の環境変数に入れておく。
COOGLE_CLOUD_REGION
GCLOUD_SERVICE_KEY
GOOGLE_PROJECT_ID
version: 2 defaults: &defaults working_directory: ~/hogehoge docker: - image: google/cloud-sdk:242.0.0-slim global_env: &global_env GOOGLE_PROJECT_ID: hogehoge COOGLE_CLOUD_REGION: asia-northeast1 K8S_CLUSTER: hogehoge common_steps: install_base_packages: &install_base_packages command: apt-get update && apt-get install wget kubectl install_helm: &install_helm name: install helm command: | # install helm wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz tar zxvf helm-v2.13.1-linux-amd64.tar.gz mv ./linux-amd64/helm /usr/local/bin/helm helm init --client-only helm plugin install https://github.com/databus23/helm-diff # install helmfile wget https://github.com/roboll/helmfile/releases/download/v0.54.2/helmfile_linux_amd64 chmod +x ./helmfile_linux_amd64 mv ./helmfile_linux_amd64 /usr/local/bin/helmfile gcloud_login: &gcloud_login name: gcloud login command: | echo ${GCLOUD_SERVICE_KEY} | base64 -d | gcloud auth activate-service-account --key-file=- gcloud --quiet config set project ${GOOGLE_PROJECT_ID} setup_cluster_and_helm: &setup_cluster_and_helm name: setup cluster credential and helm environment command: | gcloud beta container clusters get-credentials ${K8S_CLUSTER} --region ${COOGLE_CLOUD_REGION} --project ${GOOGLE_PROJECT_ID} helm repo update jobs: helmfile-sync-dry-run: <<: *defaults environment: <<: *global_env steps: - checkout - run: *install_base_packages - run: *install_helm - run: *gcloud_login - run: *setup_cluster_and_helm - run: name: helmfile diff command: helmfile --file prd.helmfile.yaml diff - run: name: helmfile sync dry-run command: helmfile --file prd.helmfile.yaml sync --args --dry-run helmfile-sync: <<: *defaults environment: <<: *global_env steps: - checkout - run: *install_base_packages - run: *install_helm - run: *gcloud_login - run: *setup_cluster_and_helm - run: name: helmfile sync command: | helmfile --file prd.helmfile.yaml sync workflows: version: 2 dry-run-and-sync: jobs: - helmfile-sync-dry-run: filters: branches: only: /.*/ - helmfile-sync: requires: - helmfile-sync-dry-run filters: branches: only: master
- サービスアカウントを使用してアクセス承認
gcloud
コマンドライン ツールでアクティブなプロジェクトを設定gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
gcloud
は対話型インターフェースなので、自動化には邪魔なので、プロンプトの無効化を--quiet
でする。--quiet
フラグは先頭の項目の右側に挿入する。
- クラスタの認証情報を取得する
gcloud beta container clusters get-credentials [CLUSTER_NAME] [--internal-ip] [--region=REGION | --zone=ZONE, -z ZONE] [GCLOUD_WIDE_FLAG …]
でクラスタに対して認証を行う。- gcloud beta container clusters get-credentialsとは
- Helm CLI を初期設定
helm init --client-only
ちなみにインターネット環境がない場合は--skip-refresh
- helmクライアント側でキャッシュしているので、最新のリポジトリ内の情報を得るために
helm repo update
を実行して、再取得することでキャッシュをリフレッシュさせる。 helm diff
でreleasesのdiffをとるhelmfile diff
サブコマンドは、マニフェストで定義されているすべてのcharts/releases
にわたってhelm-diffプラグインを実行。helmfile --file prd.helmfile.yaml diff
- 使うには helm-diffパッケージが必要。
helmfile --file prd.helmfile.yaml sync --args --dry-run
- Helmfileは実行中にさまざまなイベントをトリガーとする。 イベントが発生すると、argsを指定してコマンドを実行することで、関連するフックが実行される。
helmfile --file prd.helmfile.yaml sync
- helmfile syncサブコマンドは、helmfileの説明に従ってクラスタの状態を同期する。 デフォルトのhelmfileはhelmfile.yaml。任意のyamlファイルを
--file path/to/your/yaml/file
フラグを指定することで渡すことができる。 - helmfileはマニフェストで宣言されたreleaseごとに
helm upgrade --install
を実行。必要に応じて、secretsを復号化してhelmチャートの値として使用する。 また、指定されたチャートリポジトリを更新し、参照されているローカルチャートの依存関係も更新する。 helm upgrade --install
は releaseが存在するかどうかに応じてインストールまたはアップグレードすることができる。
- helmfile syncサブコマンドは、helmfileの説明に従ってクラスタの状態を同期する。 デフォルトのhelmfileはhelmfile.yaml。任意のyamlファイルを
これで、helmで Datadog agent のインストールができる。また、何かhelmで追加したくなったらhelmfileに書いていくことになる。
気になりンゴ
--dry-run
は実はまだ機能追加されてない?helpに特に出てこない。
--args
でhookさせているけど、helmfileにhookさせるものをかかないとhookされないのかな
releases: - name: myapp chart: mychart # *snip* hooks: - events: ["prepare", "cleanup"] command: "echo" args: ["{{`{{.Environment.Name}}`}}", "{{`{{.Release.Name}}`}}", "{{`{{.HelmfileCommand}}`}}\ "]