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_REGIONGCLOUD_SERVICE_KEYGOOGLE_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}}`}}\
"]