ブログ

etcdを監視する方法

Google Cloudとコンテナの継続的なセキュリティ

本文の内容は、2020年8月6日にDavid Lorite Solanasが投稿したブログ(https://sysdig.com/blog/monitor-etcd/)を元に日本語に翻訳・再構成した内容となっております。

etcdを監視する方法を学ぶことは、本番環境でKubernetesを実行する際に非常に重要です。etcdを監視することで、サービスが期待通りに動作しているかどうかを検証しながら、インフラストラクチャー全体をダウンさせる可能性のある問題を検出してトラブルシューティングすることができます。本ブログでは、etcdから最も重要なメトリクスを収集し、このサービスを監視するためにどのように使用するかを学んでいきます。

etcdはKubernetesコントロールプレーンの基本的なコンポーネントです。これは、他のものの中でも特にクラスターの望ましい状態(ポッド、シークレット、デプロイメントなど)を保存します。このサービスが実行されていないと、何もデプロイできず、クラスタは自己修復できません。

etcdとは何ですか?

etcdの動機は、"configuration registry"を維持する分散型のKey-Value動的データベースを提供することです。このレジストリーは、Kubernetesクラスターサービスディレクトリ、ピアディスカバリ、および集中構成管理の基盤の1つです。これらのテクノロジーに精通している場合は、Redisデータベース、従来のLDAP構成バックエンド、またはWindowsレジストリにある程度の類似点があります。

20200807-01.png

開発者によると、etcd は次のようなことを目指しています。

シンプル: 明確に定義された、ユーザーインターフェースのAPI (JSONとgRPC)

セキュア:オプションのクライアント証明書認証による自動TLS

高速:10,000回/秒の書き込みをベンチマーク

信頼性:Raftを使用して適切に配布

Kubernetes は etcd 分散データベースを使用して、REST API オブジェクト (/registry ディレクトリキーの下に) を格納します: ポッド、シークレット、デーモンセット、デプロイメント、ネームスペース、イベントなど。

Raftは、"コンセンサス"アルゴリズムであり、分散されたフォールトトレラントなクラスターノードのセット上で値の収束を達成する方法です。

参照されている記事の中にあるような、詳細な説明は省きますが、ここでは知っておくべき基本的なことを説明します。

  • ノードの状態は以下のいずれかになります。フォロワー、候補者(簡単に)、リーダー
  • フォロワーが現在のリーダーの位置を特定できない場合、そのフォロワーは候補者となります。
  • 投票制度により、候補者の中から新たなリーダーを選出します。
  • レジストリ値の更新(コミット)は常にリーダーを経由します。
  • リーダーが大多数のフォロワーからackを受け取ると、新しい値は"コミット"されたものとみなされます。
  • クラスタは、ほとんどのノードが生き残っている限り生き残ります。
  • etcdの最も注目すべき機能は、おそらくREST ライクな HTTP 呼び出しを使用してサービスにアクセスする簡単な方法であると言えます。サードパーティ製エージェントの統合を可能な限りシンプルにし、マスターマスタープロトコルが自動的にクラスタリーダーを選択し、必要に応じてこの役割を切り替えるためのフォールバック機構を提供します。

etcdクラスターの共通障害点

ほとんどの場合、etcdクラスターはきちんと機能しているため、ノードが実行されていることを忘れがちです。ただし、Kubernetesが機能するにはこのレジストリーが絶対に必要であり、etcdの重大な障害が発生すると、コンテナインフラストラクチャーが大幅に機能しなくなったり、停止したりすることもあります。現在、実行中のポッドは引き続き実行されますが、それ以上の操作はできません。etcdとKubernetesを再接続すると、状態の一貫性が失われると、さらに誤動作する可能性があります。

etcdを監視する方法は?

etcdは、Kubernetes内、Dockerコンテナ内、または独立したクラスター(仮想マシン内または直接ベアメタル内)として実行できます。通常、単純なシナリオでは、etcdは他のKubernetesサービス(APIサーバー、コントローラーマネージャー、スケジューラー、kubeletなど)のようなDockerコンテナでデプロイされます。より高度なシナリオでは、etcd は外部サービスであることが多く、このような場合には通常、必要な冗長性を実現するために 3つ以上のノードが使用されます。

etcdからメトリクスを取得する

Etcd はインスツルメンテーションが実装されており、マスターホストのポート 4001でPrometheusのメトリクスをデフォルトで公開し、ストレージの情報を提供しています。このエンドポイントは簡単にスクレイプすることができ、スクリプトやエクスポータを追加しなくても有用な情報を得ることができます。

認証なしにノード内のポートに直接アクセスする etcd メトリクスをスクレイプすることはできません。etcdはあらゆるKubernetesクラスタの中核であるため、そのメトリクスもセキュリティ化されています。メトリクスを取得するには、4001番ポートにアクセスしているか、マスター自体にいる必要があり、クライアント証明書も必要になります。マスターノードにアクセスできる場合は、そこからクライアント証明書のパスを指定してcurlするだけです。証明書は /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.crt にあり、鍵は /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.key にあります。

curl https://localhost:4001/metrics -k --cert /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.crt --key /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.key

マスターノードの外部から接続し、マスターノードからの証明書があり、ポート4001が開いている場合は、IPを使用してアクセスすることもできます。

curl https://[master_ip]:4001/metrics -k --cert /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.crt --key /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.key

これは、次の構造を持つメトリクスのロングリストを返します(省略)。

# HELP etcd_disk_backend_snapshot_duration_seconds The latency distribution of backend snapshots.
# TYPE etcd_disk_backend_snapshot_duration_seconds histogram
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.01"} 0
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.02"} 0
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.04"} 0
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.08"} 0
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.16"} 0
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.32"} 3286
etcd_disk_backend_snapshot_duration_seconds_bucket{le="0.64"} 4617
etcd_disk_backend_snapshot_duration_seconds_bucket{le="1.28"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="2.56"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="5.12"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="10.24"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="20.48"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="40.96"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="81.92"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="163.84"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="327.68"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="655.36"} 4620
etcd_disk_backend_snapshot_duration_seconds_bucket{le="+Inf"} 4620
etcd_disk_backend_snapshot_duration_seconds_sum 1397.2374600930025
etcd_disk_backend_snapshot_duration_seconds_count 4620
# HELP etcd_disk_wal_fsync_duration_seconds The latency distributions of fsync called by wal.
# TYPE etcd_disk_wal_fsync_duration_seconds histogram
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.001"} 4.659349e+06
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.002"} 7.276276e+06
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.004"} 8.589085e+06

etcdをスクレイピングするようにPrometheusを設定する場合は、証明書をマウントしてジョブを作成する必要があります。

証明書はマスターノードの /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.key と /etc/kubernetes/pki/etcd-manager-main/etcd-clients-ca.crt にありますので、証明書をダウンロードして、次のコマンドでKubernetes上に秘密を作成してください。

免責事項: etcdはあらゆるKubernetesクラスタの中核であり、証明書の取り扱いに注意しなければ、クラスター全体を公開し、潜在的に標的にされる可能性があります。

kubectl -n monitoring create secret generic etcd-ca --from-file=etcd-clients-ca.key --from-file etcd-clients-ca.crt


kubectl -n monitoring patch deployment prometheus-server -p '{"spec":{"template":{"spec":{"volumes":[{"name":"etcd-ca","secret":{"defaultMode":420,"secretName":"etcd-ca"}}]}}}}'
kubectl -n monitoring patch deployment prometheus-server -p '{"spec":{"template":{"spec":{"containers":[{"name":"prometheus-server","volumeMounts": [{"mountPath": "/opt/prometheus/secrets","name": "etcd-ca"}]}]}}}}'

scrape_configs:
    ...
    - job_name: etcd
      scheme: https
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_namespace
        - __meta_kubernetes_pod_name
        separator: '/'
        regex: 'kube-system/etcd-manager-main.+'
      - source_labels:
        - __address__
        action: replace
        target_label: __address__
        regex: (.+?)(\\:\\d)?
        replacement: $1:4001
      tls_config:
        insecure_skip_verify: true
        cert_file: /opt/prometheus/secrets/etcd-clients-ca.crt
        key_file: /opt/prometheus/secrets/etcd-clients-ca.key

独自のラベルと再ラベル設定をカスタマイズできます。

etcdの監視:何を探すべきか?

免責事項: etcdのメトリクスはKubernetesのバージョンによって異なる場合があります。ここではKubernetes 1.15を使用しています。バージョンに応じて利用可能なメトリクスはKubernetes repoで確認できます(1.15.3バージョンの場合のリンク)。

etcd ノードの可用性:どのクラスターでも明らかなエラーシナリオは、ノードの1つを失うことです。クラスターは動作を継続しますが、ノードを失い続けて次のシナリオであるサービス全体の障害に直面するリスクを負う前に、アラートを受信して診断し、回復するのは良いアイデアかもしれません。これを確認する最も簡単な方法は、PromQL クエリです。

sum(up{job=\"etcd\"})

これにより、実行中のノードの数がわかります。一部のノードがダウンしている場合はそれを確認できます。最悪の場合は、数が0の場合に問題があることがわかります。

etcdにリーダーがある: 1つの重要なメトリクスは、すべてのノードにリーダーがあるかどうかを知ることです。1つのノードにリーダーがない場合、このノードは使用できません。すべてのノードにリーダーがない場合、クラスターは完全に使用できなくなります。これを確認するために、ノードにリーダーがあるかどうかを示すメトリクスがあります。

# HELP etcd_server_has_leader Whether or not a leader exists. 1 is existence, 0 is not.
# TYPE etcd_server_has_leader gauge
etcd_server_has_leader 1

etcdリーダーの変更:リーダーは時間とともに変化する可能性がありますが、頻繁に変更すると、etcd自体のパフォーマンスに影響を与える可能性があります。これは、接続の問題が原因でリーダーが不安定である、またはetcdの負荷が多すぎることを示す可能性もあります。

# HELP etcd_server_leader_changes_seen_total The number of leader changes seen.
# TYPE etcd_server_leader_changes_seen_total counter
etcd_server_leader_changes_seen_total 1

コンセンサスプロポーザル:プロポーザルとは、ラフトプロトコルを通過する必要があるリクエスト(すなわち、書き込みリクエスト、設定変更リクエスト)です。プロポーザルのメトリクスには、コミット、適用、保留、失敗の4つの異なるタイプがあります。この4つはすべて、etcdが直面する問題についての情報を与えることができますが、最も重要なのは失敗したものです。提案が失敗したものがある場合、それは2つの理由が考えられます: リーダー選挙が失敗したか、定足数の喪失です。

例えば、15分間の間に5つ以上のコンセンサスプロポーザルが失敗したことを示すアラートを設定したい場合は、次のようなステートメントを使用することができます。

rate(etcd_server_proposals_failed_total{job=~"etcd"}[15m]) > 5

# HELP etcd_server_proposals_applied_total The total number of consensus proposals applied.
# TYPE etcd_server_proposals_applied_total gauge
etcd_server_proposals_applied_total 1.3605153e+07
# HELP etcd_server_proposals_committed_total The total number of consensus proposals committed.
# TYPE etcd_server_proposals_committed_total gauge
etcd_server_proposals_committed_total 1.3605153e+07
# HELP etcd_server_proposals_failed_total The total number of failed proposals seen.
# TYPE etcd_server_proposals_failed_total counter
etcd_server_proposals_failed_total 0
# HELP etcd_server_proposals_pending The current number of pending proposals to commit.
# TYPE etcd_server_proposals_pending gauge
etcd_server_proposals_pending 0

ディスク同期期間: etcdはKubernetesに関するすべての重要な情報を保存しているため、変更をディスクにコミットする速度とストレージの正常性は、etcdが適切に機能しているかどうかの主要なメトリクスです。ディスク同期の待ち時間が長い場合、ディスクに問題があるか、クラスターが使用できなくなる可能性があります。これを示すメトリクスは、wal_fsync_duration_secondsとbackend_commit_duration_secondsです。

# HELP etcd_disk_backend_commit_duration_seconds The latency distributions of commit called by backend.
# TYPE etcd_disk_backend_commit_duration_seconds histogram
etcd_disk_backend_commit_duration_seconds_bucket{le="0.001"} 0
etcd_disk_backend_commit_duration_seconds_bucket{le="0.002"} 5.402102e+06
etcd_disk_backend_commit_duration_seconds_bucket{le="0.004"} 6.0471e+06
...
etcd_disk_backend_commit_duration_seconds_sum 11017.523900176226
etcd_disk_backend_commit_duration_seconds_count 6.157407e+06
# HELP etcd_disk_wal_fsync_duration_seconds The latency distributions of fsync called by wal.
# TYPE etcd_disk_wal_fsync_duration_seconds histogram
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.001"} 4.659349e+06
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.002"} 7.276276e+06
...
etcd_disk_wal_fsync_duration_seconds_sum 11580.35429902582
etcd_disk_wal_fsync_duration_seconds_count 8.786736e+06

バックエンドのコミットの持続時間が十分かどうかを知るには、各コミットの持続時間が十分かどうかをヒストグラムで可視化することができます。次のコマンドでは、リクエストの99%がカバーされている時間のレイテンシーを表示することができます。

histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket{job=~"etcd"}[5m]))

Sysdigモニターでのetcdメトリクスのモニタリング

Sysdig Monitorでetcdをトラッキングするためには、エージェントのYAML設定ファイルにいくつかのセクションを追加して、Prometheusを使ってメトリクスを集めてフィルタリングする必要があります。そうしないという選択肢もありますが、要らないデバッグメトリクスを大量に保存してしまうことになります。なので、まずはPrometheusを立ち上げて実行しておくべきですが、そうでない場合は心配ありません。新しい Prometheus のデプロイは、2 つのコマンドを実行するだけで簡単にできます。

kubectl create ns monitoring
helm install -f values.yaml prometheus -n monitoring stable/prometheus

values.yamlであること

server:
 strategy:
   type: Recreate
 podAnnotations:
   prometheus.io/scrape: "true"
   prometheus.io/port: "9090"

Prometheusを起動して実行したら、ルールを作成する必要があります。これらのルールは、Sysdigエージェントによって収集されたメトリクスをフィルタリングするカスタムタグを使用して新しいメトリクスを作成します。PromCat.ioのルールと、Sysdigでモニタリングなどを行うために実行する必要があるすべての手順を確認できます。例として、これはエージェントのconfigmapになります。

apiVersion: v1
kind: ConfigMap
metadata:
  name: sysdig-agent
  namespace: sysdig-agent
data:
  prometheus.yaml: |-
    global:
      scrape_interval: 15s
      evaluation_interval: 15s
    scrape_configs:
    - job_name: 'prometheus' # config for federation
      honor_labels: true
      metrics_path: '/federate'
      metric_relabel_configs:
      - regex: 'kubernetes_pod_name'
        action: labeldrop
      params:
        'match[]':
          - '{sysdig="true"}'
      sysdig_sd_configs:
      - tags:
          namespace: monitoring
          deployment: prometheus-server
20200807-02.png

まとめ

etcdはKubernetesクラスタのデプロイに必要なシンプルで堅牢なサービスです。Raft分散コンセンサスアルゴリズムは、時間的なネットワーク障害、ノードロス、クラスタの分裂などのほとんどを克服することができるとはいえ、本番環境でKubernetesを運用している場合は、手遅れになる前に関連するクラスタイベントを監視し、アラートを設定することが不可欠です。

etcdのエラーコードのリストを掘り下げてみると、もちろん、この簡単な記事で取り上げたものよりも高度なケースがあります: クラスタ内のピアの最大数、Kubernetesとetcdノード間の異常検出、Raftの内部エラー、レジストリサイズなどです。これらは将来的にこの記事の後編に残しておきます。

Sysdig Monitorを使ったetcdの監視は本当に簡単です。たった一つのツールでetcdとKubernetesの両方を監視することができます。Sysdig Monitorエージェントが全てのetcdのメトリクスを収集してくれるので、最も重要なetcdのアラートを素早く設定することができます。

まだSysdig Monitorをお試しになっていない方は、1クリックで無料トライアルをお試しいただけます

関連コンテンツ

Sysdigに関するお問い合わせはこちらから

最近の投稿

カテゴリー

アーカイブ

ご質問・お問い合わせはこちら

top