30
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

kubernetes Deep Dive (etcd + Raft)

30
Last updated at Posted at 2025-11-30

はじめに

TRIAL&RetailAI Advent Calendar 2025の1日目の記事になります。

本日のテーマは"kubernetes Deep Dive (etcd + Raft)"です。私はいつも開発でkubernetes(k8s)を使っています。より深くk8sについて知識を深めたく、再度基本的な事項からetcdとRaftについてまとめたいと思います。

自己紹介

基盤システム部に所属して、主にバックエンドの開発を行っております。
2024年にもAdvent Calendarの記事を書いていますので、よかったら見ていただけると幸いです。

k8sとは

k8sとはコンテナを自動で管理するコンテナオーケストレーションシステム
アプリケーションを「宣言的(desired state)」に保つことが特徴に挙げらます。

k8sが解決してくれること

  1. サーバーやコンテナの自動配置
  2. スケール(増減)の自動化
  3. 障害時の自己修復
  4. ロードバランシング
  5. 設定・機密情報の管理

基本構成

スクリーンショット 2025-11-30 14.41.57.png
引用元:Cluster Architecture

Control Plane の役割

  • クラスタ全体の desired state(あるべき状態)を定義して維持する
  • Node や Pod の状態を監視して調整する
  • Pod をどこで動かすか(スケジューリング)を決める
  • etcd にクラスタ全体の設定・状態を保存する
コンポーネント 役割
API Server すべての操作の入口となる REST API。
Scheduler Pod をどの Node に配置するか決定。
Controller Manager 各コントローラーによりクラスタ状態を desired state へ調整。
etcd Kubernetes の唯一のデータストア(全設定・全状態を保存)。

Worker Node の役割

  • Pod(アプリコンテナ)を実行する
  • コンテナのライフサイクルを管理
  • Pod のネットワーク通信を制御
  • Control Plane に状態を報告する
コンポーネント 役割
Kubelet Node 内の Pod を管理し、API Server と通信。
Kube-Proxy Service によるロードバランシング・ネットワーク制御。
Container Runtime 実際にコンテナを実行(containerd / CRI-O 等)。

etcd

k8sが内部状態を保存するための分散Key-Valueストア
Control Plane のすべての設定・状態は etcd に保存される。
そのため etcd が停止すると Kubernetes 全体が機能不全になる。

etcd Demo

# Macを使っているためHome brewでetcdをインストール
brew install etcd

# インストールの確認
which etcd

# etcd起動
export ETCDCTL_API=3
etcd

# 値の書き込み
# 別ターミナルで以下を実行
etcdctl put foo "hello etcd"
> OK

# 値の取得
etcdctl get foo
> OK
> foo
> hello etcd

# 変更監視
# 別ターミナルで以下を実行
etcdctl watch foo

# さらに別ターミナルで以下を実行
etcdctl put foo "new value"
> OK

# etcdctl watch fooを実行したターミナルでリアルタイムで変更確認
> PUT
> foo
> new value

Kubernetes Control Plane のコンポーネント(API Server など)がetcd に対して"PUT / GET / WATCH" をしていることを体験できると思います。

Raft

Raft は etcd・Consul・TiKV・Kubernetes(内部の etcd)が使っている
分散合意アルゴリズム。これにより強整合性が生まれる。

要点 説明
Leader は常に 1 台 書き込みの競合を防ぎ、一貫性を維持するため。
書き込みはすべて Leader 経由 分散システムでデータを線形化(Linearizable)するための基本原則。
過半数(Majority)がログを保持したらコミット 複数ノード故障時でも正しく復旧できるようにする仕組み。
Leader が死んだら自動選挙 フェイルオーバーによる高可用性を実現。クラスタは停止しない。
etcd の強整合性の基盤 etcd の Read/Write が Linearizable である理由は Raft によるログ複製と選挙。
役割 説明
Leader すべての書き込みを受け付ける唯一のノード。Follower にログを複製する。
Follower Leader からログ複製を受け取り、状態機械に適用する。
Candidate Follower が一定時間 Leader と通信できなかった場合に選挙へ立候補する役割。

Raft Demo

# 3つのターミナルで以下を1つずつ実行する
# 1つ目のターミナル
etcd \
  --name n1 \
  --listen-peer-urls http://127.0.0.1:2380 \
  --listen-client-urls http://127.0.0.1:2379 \
  --advertise-client-urls http://127.0.0.1:2379 \
  --initial-advertise-peer-urls http://127.0.0.1:2380 \
  --initial-cluster-token etcd-cluster \
  --initial-cluster n1=http://127.0.0.1:2380,n2=http://127.0.0.1:2382,n3=http://127.0.0.1:2384 \
  --initial-cluster-state new

# 2つ目のターミナル
etcd \
  --name n2 \
  --listen-peer-urls http://127.0.0.1:2382 \
  --listen-client-urls http://127.0.0.1:2377 \
  --advertise-client-urls http://127.0.0.1:2377 \
  --initial-advertise-peer-urls http://127.0.0.1:2382 \
  --initial-cluster-token etcd-cluster \
  --initial-cluster n1=http://127.0.0.1:2380,n2=http://127.0.0.1:2382,n3=http://127.0.0.1:2384 \
  --initial-cluster-state new

# 3つ目のターミナル
etcd \
  --name n3 \
  --listen-peer-urls http://127.0.0.1:2384 \
  --listen-client-urls http://127.0.0.1:2378 \
  --advertise-client-urls http://127.0.0.1:2378 \
  --initial-advertise-peer-urls http://127.0.0.1:2384 \
  --initial-cluster-token etcd-cluster \
  --initial-cluster n1=http://127.0.0.1:2380,n2=http://127.0.0.1:2382,n3=http://127.0.0.1:2384 \
  --initial-cluster-state new

# 3つのうちの一つで以下を確認する
{"level":"info","ts":"2025-11-30T15:14:15.626738+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:970","msg":"b71f75320dc06a6c became leader at term 2"}

# 3つの内のleaderのターミナルを閉じる
# 他の2つでleaderが変化したの確認
"level":"info","ts":"2025-11-30T15:24:09.243345+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:912","msg":"9e85cc091d4d15bb became candidate at term 3"}
{"level":"info","ts":"2025-11-30T15:24:09.243374+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:1064","msg":"9e85cc091d4d15bb [logterm: 2, index: 9] sent MsgVote request to 42b4c95db84f2660 at term 3"}
{"level":"info","ts":"2025-11-30T15:24:09.243410+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:1064","msg":"9e85cc091d4d15bb [logterm: 2, index: 9] sent MsgVote request to b71f75320dc06a6c at term 3"}
{"level":"info","ts":"2025-11-30T15:24:09.257516+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:1077","msg":"9e85cc091d4d15bb received MsgVoteResp from 9e85cc091d4d15bb at term 3"}
{"level":"info","ts":"2025-11-30T15:24:09.257597+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:1693","msg":"9e85cc091d4d15bb has received 1 MsgVoteResp votes and 0 vote rejections"}
{"level":"info","ts":"2025-11-30T15:24:09.262962+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:1077","msg":"9e85cc091d4d15bb received MsgVoteResp from 42b4c95db84f2660 at term 3"}
{"level":"info","ts":"2025-11-30T15:24:09.263028+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:1693","msg":"9e85cc091d4d15bb has received 2 MsgVoteResp votes and 0 vote rejections"}
{"level":"info","ts":"2025-11-30T15:24:09.263059+0900","logger":"raft","caller":"v3@v3.6.0/raft.go:970","msg":"9e85cc091d4d15bb became leader at term 3"}
{"level":"info","ts":"2025-11-30T15:24:09.263086+0900","logger":"raft","caller":"v3@v3.6.0/node.go:370","msg":"raft.node: 9e85cc091d4d15bb elected leader 9e85cc091d4d15bb at term 3"}

k8s の API Server → etcd への更新も
このメカニズムで 100% 安全な状態保存を実現していることを体験できると思います。

まとめ

Control Plane(API Server など)と etcd の関係が Kubernetes の基盤

  • API Server は すべての状態変更を etcd に保存
  • Worker Node(Kubelet)は etcd の状態を基に動作

Kubernetes の信頼性を支える中枢は etcd

  • 全設定・状態を保持する唯一のデータストア
  • etcd が止まると Control Plane は全体的に機能不全になる

etcd の強整合性(Linearizable Read/Write)は Raft が実現

  • Leader がすべての書き込みを一元管理
  • 過半数がログを保持した時点で「コミット」
  • Leader 障害時は自動選挙で速やかに復旧
  • “分散システムを安全に動かすための ログ複製 + 選挙アルゴリズム
  • 役割は以下の 3 つ:
    • Leader
    • Follower
    • Candidate
  • ノード障害やネットワーク分断でもデータを壊さない設計

最後に

次回は@mizoguchi_ryosukeさんによる『遺伝性とマンスキーから学ぶ「○○で決まる」の罠:生成AIで実践する誠実な分析』です。

ぜひお楽しみに!!

RetailAIとTRIALではエンジニアを募集しています。
Kotlin、Flutter、Go、Python、他いろいろな言語を扱っています。
興味ある方は以下から確認してもらうか、メッセージをいただければと思います。

30
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?