Kubernetes 解体新書Part 1 Kubernetes の全体像

Docker が解決すること、しないこと

アプリを作り、配り、動かす Docker。複数のマシンで動かし続けるとき、Kubernetes が引き受ける仕事を見ていきます。

  • L1 Web ターミナル
  • 更新 2026年10月6日

自分の PC では動いたアプリが、別のサーバーでは動かない。 Docker は、アプリに必要なファイルをイメージにまとめ、同じものを配って起動しやすくします。

では、そのサーバー自体が止まったらどうするのでしょうか。 別のサーバーで起動し直す、台数を増やす、順番に更新する。 この章では、Docker でできることから始めて、複数のマシンでアプリを動かし続ける Kubernetes の役割へ進みます。

GOAL この章のゴール

  • イメージを作り、配り、起動する流れを説明できる
  • 複数のマシンでアプリを動かすときに必要な仕事を挙げられる
  • Kubernetes がコンテナを動かす単位である Pod を説明できる

Build、Share、Run

Build、Share、Run: Dockerfile からイメージを作り、レジストリに push し、別のホストで pull して起動する左から Dockerfile、docker build、イメージ、docker push、レジストリ、docker pull、ホストで動くコンテナ。Dockerfile手順書buildイメージ層の tar + manifestpushレジストリghcr.io / ECRpullどこかのホストコンテナapprunBuildCI で 1 回だけShare同じハッシュ = 同じ中身Run開発機でも本番でも同じイメージが「ゴールデンイメージ」になり、ライブラリや言語ランタイムの差異が消える
図 1Build / Share / Run。Dockerfile からイメージを 1 回作り、レジストリ経由で配り、どのホストでも同じものを起動する。

まず、アプリを別のマシンへ届ける流れを見ます。

  1. Build: アプリに必要なファイルを、イメージにまとめます。
  2. Share: イメージを保管・配布する場所へ置き、使うマシンにダウンロードします。
  3. Run: そのイメージからコンテナを起動します。

この配布先をレジストリと呼び、置く操作を push、取得する操作を pull と呼びます。

この流れの要は、イメージが変更されないことと、内容のハッシュで識別されることです。 Docker のドキュメントは「イメージは不変 (immutable) で、一度作られたら変更できない」と書いています。 Kubernetes のドキュメントは、イメージの参照の仕方を 2 つに分けています。 タグ (:v1.2.0) は「同じ系列のイメージのバージョンを区別する名前で、別のイメージを指すように付け替えられる」のに対し、ダイジェスト (@sha256:…) は「イメージの内容のハッシュで、変わらない」ものです。 ghcr.io/example/web@sha256:3f1a… という参照は、世界中どこで pull しても同じバイト列を指します。 CI で作ったイメージをステージングと本番で同じダイジェストに固定すれば、イメージ内のライブラリやアプリを揃えられます。 外から渡す設定やファイル、ホストの違いは別に管理します。 この「1 回作って、どこでも同じものを動かす」ためのイメージを ゴールデンイメージ と呼びます。 Kubernetes のドキュメントはコンテナの利点として「開発、テスト、本番で環境が一貫する。ラップトップでもクラウドでも同じように動く」を挙げていて、これはゴールデンイメージの効果そのものです。

VM の世界でも AMI を焼いて配る運用はありましたが、イメージが数 GB で、焼くのに分単位かかりました。 コンテナイメージは層の差分なので、COPY した数 MB だけが新しい層になります。 AWS の語彙でいえば、イメージは AMI、レジストリは ECR、Dockerfile は Packer のテンプレートに相当します。 違いは粒度と速さで、考え方は同じです。

ゴールデンイメージが消す差異、消さない差異

イメージが固定するのはルートファイルシステムの中身です。 OS のライブラリ、言語ランタイム、アプリのコード、設定ファイルの初期値。 ここまでは、どのホストでも同じです。

イメージの外に残るものもあります。 環境変数、接続先の DB のアドレス、秘密情報、永続データ、そして カーネル です。 前の章の通り、コンテナはホストのカーネルを共有するので、ホストのカーネルが古ければ新しいシステムコールは使えません。 「開発機 (macOS の Linux VM) では動いたのに本番 (古い Amazon Linux) で動かない」はここで起きます。 イメージが同じでも、カーネルが違うからです。

1 台の Docker に無いもの

Docker が 1 台のホストで解決すること (同じイメージがどこでも動く、速い配布と起動、手順がコードになる) と、Kubernetes がクラスタ全体で提供すること (自己修復、ロールアウトとロールバック、水平スケール、空き資源を見た配置、サービスディスカバリとロードバランシング、設定と秘密情報の管理)左の列に Docker が解決する 3 つ、右の列に Kubernetes のドキュメントが挙げる 6 つの機能を並べる。右の 6 つはどれも複数のホストを前提にしている。Docker が 1 台のホストで解決すること同じイメージがどこでも動く開発機 / CI / 本番で同じバイト列速い配布と起動層の差分だけ pull、プロセス起動の速さ手順がコードになるDockerfile、CI で 1 回ビルドdocker run の相手は、そのホストの Docker だけKubernetes がクラスタ全体で提供すること自己修復落ちたら作り直すロールアウトと戻し制御された速さで入れ替え水平スケールコマンド 1 つ、または自動空き資源を見た配置CPU / メモリの要求で詰める名前解決と振り分けDNS 名と負荷分散設定と秘密情報イメージを作り直さず更新どれも「複数のホストを 1 つに見て」行う仕事(kubernetes.io「What Kubernetes can do」より)
図 2Docker が 1 台のホストで解決すること (左) と、Kubernetes のドキュメントが「Kubernetes が提供するもの」として挙げる機能 (右)。右はどれも複数のホストを 1 つに見て行う仕事。

ここまでの話は 1 台のホストで完結しています。 docker run が話しかける相手は、そのホストで動いている Docker デーモンだけです。 Docker Compose も、1 つの Docker デーモンに対して複数のコンテナをまとめて宣言する道具で、対象は 1 台です。

本番で動かすときに何が要るかは、Kubernetes のドキュメントの「Kubernetes が必要な理由と、できること」の一覧が、そのまま答えになっています。 複数ホストにまたがる管理で、Kubernetes が引き受ける仕事を挙げます。 単一ホストでの再起動や名前解決など、Docker にも備わる機能はあります。

  1. 自己修復。「落ちたコンテナを再起動し、置き換え、ヘルスチェックに応答しないコンテナを止め、準備ができるまでクライアントに見せない」。
  2. 自動化されたロールアウトとロールバック。「望む状態を書くと、Kubernetes は実際の状態を、制御された速さで望む状態に変えていく」。v1 の横で v2 を起動し、問題なければ v1 を止める手順が、これにあたります。
  3. 水平スケール。「コマンド 1 つ、UI、または CPU 使用率に応じて自動で、アプリの数を増減する」。
  4. 自動のビンパッキング。「各コンテナに必要な CPU とメモリを伝えると、資源を最大限使えるようにコンテナをノードに詰める」。つまり、どのホストに空きがあるかを見て、そこで起動する判断です。
  5. サービスディスカバリとロードバランシング。「コンテナを DNS 名か IP で公開し、負荷が高ければ通信を分散する」。
  6. 秘密情報と設定の管理。「イメージを作り直さずに、秘密情報と設定を配り、更新する」。

このうち 1 から 4 は、ホストが 1 台なら手作業やスクリプトでもどうにかなります。 ホストが 2 台以上になった瞬間に、「どのホストで」「落ちたらどこで」を決める主体が要るようになります。

複数ホストが問題を変える

ホストが 3 台になった途端に起きる問題: 1 台が落ちたらそのコンテナを誰がどこで起動し直すか3 台のホストにコンテナが散らばっている。真ん中のホストに×が付き、そのコンテナが消えている。上に「誰が気付いて、どこで起動し直す?」という問い。docker run を 3 台で手で打った世界host-110.0.1.11webnginxapiappCPU 90%host-210.0.1.12apiappdbpg落ちたhost-310.0.1.13webnginx空きCPU 15%誰が気付いて、どこで起動し直す?api は host-3 へ。web の LB の宛先も書き換え。db のデータは? 深夜 3 時に?この「誰が」をプログラムにしたものがオーケストレーター
図 33 台のホストで docker run を手で打った世界。1 台が落ちたとき、誰が気付いて、どこで起動し直すのか。

6 つのうち、「どのホストで」が絡むものは質が違います。 host-2 が深夜に落ちたとき、その上の api コンテナを host-3 で起動し直し、web からの接続先を書き換え、db のデータが host-2 のディスクに残っている問題を扱う、というのを人がやるのは無理です。 「気付く」「決める」「実行する」「宛先を直す」を全部プログラムにする必要があります。

Kubernetes では、この「気付く」もプログラムの仕事です。 Kubernetes のドキュメントによると、各ホストは自分の状態を定期的に報告していて、報告が途絶えたホストは一定時間後に「状態不明」と記録され、既定ではさらに 5 分後に、そのホスト上のコンテナの立ち退きが始まります。 入門チュートリアルの言い方では「インスタンスを載せているノードが落ちたり消されたりすると、Deployment controller がクラスタ内の別のノードにインスタンスを作り直す」ことになります (Deployment という言葉は 5 章で導入します)。

オーケストレーターは複数ホストを見張るプログラム。利用者は宣言を渡し、配置と復旧はオーケストレーターが行う上に利用者の宣言 (web を 2、api を 2)。中央にオーケストレーターの層。下に 3 台のホストと、そこに配置されたコンテナ。宣言: web ×2、api ×2、db ×1どこで動かすかは書かないオーケストレーター配置を決める / 死活を見る / 落ちたら別ホストで起動し直す / 宛先を更新する配置 / 起動配置 / 起動配置 / 起動host-1webnginxapiapphost-2apiappdbpghost-3webnginx(空き)
図 4オーケストレーターは複数ホストを見張るプログラムで、利用者は宣言を渡す。どのホストで動かすかの決定と、落ちたときの復旧はオーケストレーターが行う。

このように複数のホストを見張り、配置と復旧を行うプログラムを、一般に オーケストレーターオーケストレーター複数のホストを見張り、コンテナの配置、死活監視、復旧、宛先の更新を行うプログラム。Kubernetes、ECS、Nomad など。用語集で見る と呼びます。 オーケストレーターが 1 つにまとめて管理するホストの集まりが、前の章で出てきた「クラスタ」です。 利用者は「web を 2 つ、api を 2 つ、db を 1 つ」と宣言し、どのホストで動かすかは書きません。 オーケストレーターが空きを見て配置し、死活を見て、落ちたら別のホストで起動し直し、宛先を更新します。 Kubernetes はこのオーケストレーターの 1 つで、2026 年現在は事実上の標準です。 ECS も同じ役割のもので、AWS に閉じている代わりに覚えることが少ない、という位置づけです。

ここで扱う単位が「コンテナ」から「宣言」に変わる点に注意してください。 docker run は「起動しろ」という命令でしたが、オーケストレーターに渡すのは「こうあってほしい」という状態です。 この「こうあってほしい」を書いておき、現実との差を埋め続けるプログラムが Kubernetes の中心にあります (4 章と 5 章で見ます)。

Kubernetes が動かす単位: Pod

オーケストレーターに「web を 2 つ」と頼むとき、数える単位が要ります。 docker compose では、その単位は service で、1 つの service は 1 種類のコンテナです。 Kubernetes が数える単位は PodポッドKubernetes が配置と起動の単位として扱う、1 つ以上のコンテナの集まり。同じ Pod のコンテナは同じノードで動き、IP とネットワーク namespace を共有する。用語集で見る です。 Kubernetes のドキュメントは、Pod を「Kubernetes で作成、管理できる最小のデプロイ単位」であり、「共有のストレージとネットワーク資源を持つ、1 つ以上のコンテナの集まりと、それをどう動かすかの指定」だと定義しています。

Pod が必要になる場面は、docker compose でも思い当たります。 nginx のログを S3 に転送する小さなコンテナを、nginx の隣に置きたいとします。 転送側から nginx にアクセスするときに localhost で届き、ログのディレクトリを共有でき、2 つが必ず同じホストで動いてほしい。 この「必ず一緒に動かしたい組」を 1 つの単位にしたものが Pod です。 ドキュメントの言葉では、Pod の中身は「常に同じ場所に置かれ、同時にスケジュールされ、共有された文脈の中で動く」もので、「Pod の各コンテナはネットワーク namespace を共有し、IP アドレスとポートも共有する」ので、「Pod の中でだけ、コンテナ同士は localhost で通信できる」とあります。 ストレージも Pod 単位で共有できます。 ドキュメントは Pod を「アプリケーション専用の論理的なホスト」にたとえています。 1 章の Linux の言葉で言えば、Pod の共有される文脈とは「namespace と cgroups の集まり」で、コンテナを隔離しているのと同じものです。

多くの Pod には、コンテナが 1 つしか入っていません。 ドキュメントによると「1 Pod に 1 コンテナ」が最もよくある使い方で、その場合の Pod は、コンテナを Kubernetes の単位に包むための入れ物です。 また、Pod は「比較的短命で使い捨ての存在」として設計されていて、「個々の Pod を直接作ることは、1 つだけの Pod であっても滅多に無い」と書かれています。 Pod を作るのは、5 章で導入する Deployment のような上位のリソースの仕事です。

ハンズオン: イメージのダイジェストを見る

自分専用クラスタで動いている Pod (クラスタの部品自身も Pod として動いています) が、どのイメージをどのダイジェストで動かしているかを見ます。

Pod のイメージとダイジェストを見る
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[0].imageID}{"\n"}{end}' | head

出力例

cilium-xxxxx	quay.io/cilium/cilium@sha256:1e4c…
coredns-xxxxx	registry.k8s.io/coredns/coredns@sha256:8f1b…

imageID にはダイジェストが入ります。 Kubernetes はタグで pull しても、実際に動かしたイメージをダイジェストで記録します。 同じタグでも中身が差し替わることがあるので、障害調査ではこちらを見ます。

ふりかえり

Qゴールデンイメージが固定しないものはどれ?

イメージが固定するのはルートファイルシステムの中身です。カーネルはホストのもので、イメージには含まれません。

Q指す先が後から変わらないのはどちら?

タグは付け替えられます。ダイジェストは内容から計算されるので、同じダイジェストは同じバイト列を指します。

QKubernetes のドキュメントが「Kubernetes が提供するもの」に挙げていないのはどれ?

ログ、監視、アラートの方法は「Kubernetes が指定しないもの」の側に書かれています。自己修復と水平スケールは提供する側の一覧にあります。

参考