シリーズ記事一覧
- 第1回:全体像と環境構築
- 第2回:Pod・ReplicaSet・Deployment
- 第3回:Service・Ingress
- 第4回:ConfigMap・Secret・Volume
- 第5回:Namespace・RBAC
- 第6回:トラブルシュートと運用
- 第7回:設計総合演習
📑 目次
- この記事について
- この記事のゴール
- 前提条件
- ローカルk8s環境の選定 — なぜkindを選んだのか
- Docker Composeではこうだった(Before)
- k8sではこうなる(After)
- ハンズオン:kindでクラスタ構築
- つまずきポイント(体験談)
- まとめ
- 次回予告
1. この記事について
「Docker Composeで動いてるなら、それでよくない?」
「Kubernetes(k8s)」を調べてみると、
「Docker Composeの "その先" がここにある」とわかりました。
この記事では、
Docker Compose経験者の視点から
「なぜKubernetesが必要なのか?」を、比喩とハンズオンで体験していきます。
2. この記事のゴール
この記事で書いていること:
- Docker Composeの「3つの壁」の整理
- ローカルk8s環境を4ツール比較して選んだ話
- k8sの世界観(Master / Worker)の整理
- kindでクラスタを構築してみた話
3. 前提条件
| 項目 | 要件 |
|---|---|
| OS | Windows 11 + WSL2 Ubuntu |
| Docker | インストール済み・起動済み |
| 経験 | Docker Composeで docker-compose up したことがある |
| k8s経験 | 不要(ゼロから始めます) |
3-1. シリーズで作成するファイル(完成形)
前提が整ったところで、
このシリーズ全体で作成するファイルの完成形を先に見ておきましょう。
~/k8s-handson/
├── pod-deployment/ ← 第2回
│ └── nginx-deployment.yaml
├── service-ingress/ ← 第3回
│ ├── nginx-deployment.yaml
│ ├── nginx-service-clusterip.yaml
│ └── nginx-service-nodeport.yaml
├── config-secret-volume/ ← 第4回
│ ├── app-configmap.yaml
│ ├── pod-with-configmap.yaml
│ ├── app-secret.yaml
│ ├── pod-with-secret.yaml
│ ├── nginx-config.yaml
│ ├── pod-with-nginx-config.yaml
│ └── pod-with-emptydir.yaml
├── namespace-rbac/ ← 第5回
│ ├── prod-deployment.yaml
│ ├── dev-deployment.yaml
│ ├── serviceaccount.yaml
│ ├── role-readonly.yaml
│ └── rolebinding-readonly.yaml
├── troubleshoot/ ← 第6回
│ ├── broken-image.yaml
│ ├── broken-crash.yaml
│ └── broken-config.yaml
└── design-exercise/ ← 第7回
├── 01-namespace.yaml
├── 02-db-secret.yaml
├── 03-db-configmap.yaml
├── 04-api-configmap.yaml
├── 05-frontend-configmap.yaml
├── 06-db-deployment.yaml
├── 07-db-service.yaml
├── 08-api-deployment.yaml
├── 09-api-service.yaml
├── 10-frontend-deployment.yaml
└── 11-frontend-service.yaml
🔰 Memo:
第1回はkindクラスタの構築のみで、YAMLファイルの作成はありません。
4. ローカルk8s環境の選定 — なぜkindを選んだのか?
4-1. そもそもなぜ「ローカルk8s環境」が必要なのか?
k8sは本来、クラウド上のサーバー群で動くものです。
しかし、学習のためにいきなりAWSやGCPにクラスタを建てると、
コストもかかるし、設定も複雑です。
そのための「ローカルk8s環境」ツールが複数あります。
4-2. 選択肢の一覧
| ツール | 正式名 | 仕組み | 比喩 |
|---|---|---|---|
| kind | Kubernetes in Docker | Dockerコンテナの中に k8sを構築 |
自宅キッチンに ミニチュア本部を設置 |
| minikube | Mini Kube(rnetes) | VM またはコンテナ内に k8sを構築 |
小さなビルを 丸ごと1棟建てる |
| k3s | 軽量 Kubernetes | k8sの軽量ディストリビューション | 簡易プレハブで 本部を建てる |
| Docker Desktop | Docker Desktop 内蔵k8s | Docker Desktopの 機能としてk8sを有効化 |
既存ビルに k8s機能を後付け |
🔰 Memo:
全部「ローカルPCでk8sを動かす」ためのツールです。
ゴールは同じですが、仕組みと特徴が違います。
4-3. 4ツール比較表
| 観点 | kind | minikube | k3s | Docker Desktop内蔵k8s |
|---|---|---|---|---|
| k8sコアの忠実度 | ◎ テスト用に設計 | ◎ kubeadmで標準構築 | △ 独自拡張あり | ○ |
| 本番体験の再現度 | △ 自分で構築が必要 | ◎ add-on豊富 | ○ | ○ |
| 軽量さ・起動速度 | ◎ | △ VM利用時は重い | ◎ | ○ |
| WSL2での安定性 | ◎ | ○ | ○ | ◎ |
| マルチノード対応 | ◎ 設定ファイルで簡単 | △ 実験的機能 | ○ | × 非対応 |
| クラスタの使い捨てやすさ | ◎ 削除→再作成が秒 | ○ | ○ | △ リセットが重い |
| 学習環境の隔離性 | ◎ Docker本体と独立 | ◎ | ○ | △ Docker自体に影響しうる |
| 学習リソースの豊富さ | ○ | ◎ 歴史が長い | ○ | ○ |
| CI/CDとの相性 | ◎ GitHub Actionsで利用 | △ | ○ | × |
| 追加インストール不要 | ○ kindコマンドが必要 | △ ドライバ設定が必要 | ○ | ◎ チェック1つ |
🔰 Memo:
「k8sコアの忠実度」と「本番体験の再現度」は別物です。
コア忠実度 = k8s自体が改変されていないか。
本番体験 = Dashboard・Ingress等が最初から使えるか。
kindとminikubeはどちらも「素のk8s」ですが、体験の充実度が違うようです。
🍽️
kindは「本物の厨房設備だけがある空き物件」。
minikubeは「設備も食器もメニュー見本も揃ったモデル店舗」。
Docker Desktop内蔵k8sは「ビルに最初から付いてるフードコート」。
4-4. 今回の要件に対する評価マトリクス
今回の学習目的に照らして、各ツールを評価します。
今回の要件:
| # | 要件 | 理由 | 重み |
|---|---|---|---|
| A | k8sコアの忠実度が高い | 本番で使うk8sと同じ挙動で学びたい | ⭐⭐⭐ |
| B | WSL2 Ubuntu で安定動作 | 開発環境がWSL2 | ⭐⭐⭐ |
| C | クラスタの使い捨てやすさ | 壊しても即やり直せる安心感が学習に重要 | ⭐⭐⭐ |
| D | 学習環境の隔離性 | Docker本体や他の開発に影響させたくない | ⭐⭐ |
| E | 軽量・高速起動 | 学習のイテレーションを速く回したい | ⭐⭐ |
| F | マルチノード対応 | 将来的にWorkerノードを増やして学びたい | ⭐ |
評価結果:
| 要件 | 重み | kind | minikube | k3s | Docker Desktop内蔵のk8s |
|---|---|---|---|---|---|
| A. k8sコアの忠実度 | ⭐⭐⭐ | ◎ | ◎ | △ | ○ |
| B. WSL2で安定動作 | ⭐⭐⭐ | ◎ | ○ | ○ | ◎ |
| C. 使い捨てやすさ | ⭐⭐⭐ | ◎ | ○ | ○ | △ |
| D. 学習環境の隔離性 | ⭐⭐ | ◎ | ◎ | ○ | △ |
| E. 軽量・高速起動 | ⭐⭐ | ◎ | △ | ◎ | ○ |
| F. マルチノード対応 | ⭐ | ◎ | △ | ○ | × |
| 総合評価 | 🏆 最適 | ○ 次点 | △ | ○ 手軽さは最強 |
4-4-1. 「Docker Desktop内蔵k8sでよくない?」への回答
Docker Desktopをすでにインストールしているなら、
「設定 → Enable Kubernetes → チェック」で即k8sが使えます。
今回のシリーズのハンズオンも全て動きます。
ではなぜkindを選ぶのか?
| シナリオ | Docker Desktop内蔵k8s | kind |
|---|---|---|
| 設定をめちゃくちゃにした | Docker Desktopのリセット(重い・全体に影響) |
kind delete cluster → 10秒で再作成 |
| クリーンな状態からやり直し | 面倒 | 一瞬 |
| 学習用と他の開発を並行 | 1クラスタを共有 | 別クラスタを作れる |
| クラスタ設定を試行錯誤 | 毎回リセットが辛い | 壊して作り直すのが前提の設計 |
🍽️
Docker Desktop内蔵k8s = ビルに最初から付いてるフードコート、
便利だけど、実験で火事を起こすとビル全体に影響する。
kind = 駐車場に建てた仮設テント、
壊しても3秒で張り直せるし、ビルには何の影響もない。
学習では「壊す→直す」を何度も繰り返します。
その安心感がkindの最大の価値です。
4-5. 判断フロー
4-6. 選定結果
| 項目 | 内容 |
|---|---|
| 選定ツール | kind(Kubernetes in Docker) |
| 最大の決め手 | クラスタを壊して作り直すのが秒 + Docker本体と完全分離 |
| 前提 | Docker Desktop(WSL2)がインストール済み — kindはその上で動く |
| 注意点 | Ingress等の一部機能は追加設定が必要(第3回で説明) |
🍽️
minikubeは「設備が充実したモデル店舗で研修」、
Docker Desktop内蔵k8sは「ビルのフードコートで手軽に試食」、
kindは「駐車場の仮設テントで何度でも試行錯誤」。
学習で一番大事なのは「壊しても平気」という安心感。
だからkindを選びました。
🔰 Note:
「正解」はありません。
Docker Desktop内蔵k8sなら追加インストールなしで今すぐ始められますし、
minikubeにはGUIダッシュボードがあって便利です。
自分の目的に合ったツールを選ぶこと自体が、設計判断の練習です。
5. Docker Composeではこうだった(Before)
5-1. Docker Composeでできること
Docker Composeは素晴らしいツールです。
docker-compose.yml に書くだけで、複数のコンテナをまとめて管理できます。
# docker-compose.yml(よくある構成)
services:
api:
build: .
ports:
- "3000:3000" # APIサーバー
db:
image: postgres:14
ports:
- "5432:5432" # データベース
これで docker-compose up すればAPIもDBも一発起動。
開発環境としては最高です。
5-2. でも「これ困るよね」3つの壁
Docker Composeで開発していると、
本番運用を考えたときに3つの壁にぶつかります。
| # | 壁 | Docker Composeの現実 | 困る場面 |
|---|---|---|---|
| 壁1 | コンテナが落ちたら 手動で再起動 |
docker-compose up し直し |
深夜3時にコンテナが落ちたら? |
| 壁2 | アクセスが増えても スケールできない |
コンテナは1つのまま | セール時にアクセス10倍になったら? |
| 壁3 | デプロイ時に ダウンタイムが発生 |
古いコンテナを止めて → 新しいのを起動 | ユーザーが「サイト見れない!」と言ったら? |
🔰 Note:
「開発環境ではDocker Composeで十分」は正しいです。
これらの壁は本番運用で出てくる問題です。
Docker Composeがダメなのではなく、用途が違うのです。
6. k8sではこうなる(After)
6-1. k8sの世界観
🍽️ 比喩:個人経営の定食屋 vs チェーンレストランの本部
Docker Compose = 個人経営の定食屋
- 店主が調理も、接客も、仕入れも全部やる
- 1店舗なら回る
- でも店主が倒れたら? → お店は閉まる
- お客さんが急増したら? → 対応できない
Kubernetes = チェーンレストランの本部システム
- 本部(Master)が「どの店舗で何を作るか」を指示
- 各店舗(Worker)が実際に調理する
- スタッフが倒れても → 本部がすぐ代わりを手配
- お客さんが急増しても → 本部が臨時スタッフを追加
6-2. 3つの壁に対するk8sの回答
| # | Docker Composeの壁 | k8sの回答 | 比喩 |
|---|---|---|---|
| 壁1 | 手動で再起動 | Self-healing(自動復旧) | スタッフが倒れたら 本部が自動で代わりを手配 |
| 壁2 | スケールできない | オートスケール | 混雑したら 本部が臨時スタッフを増員 |
| 壁3 | ダウンタイム発生 | ローリングアップデート | 営業しながら 一人ずつ新メニューに切り替え |
6-3. k8sのクラスタ構成
では、k8sはどんな仕組みでこれを実現しているのでしょうか?
その答えが
「クラスタ」 ― Master Node(本部) と Worker Node(店舗)
で構成されるまとまりです。
上の図だと矢印が多くて少し分かりにくかったので、
「構造」と「流れ」に分けて整理してみます。
図1:構造 — 何がどこにあるか
⚠️本部が管理し、店舗でPodが動く。
図2:流れ — 命令がどう伝わるか
💡こうして見ると、すべてがAPI Serverを経由しているのがポイントです。
6-4. 各コンポーネントの役割
🍽️ チェーンレストランに当てはめて理解しましょう
| コンポーネント | 比喩 | 役割 |
|---|---|---|
| API Server | 本部の受付窓口 | 全ての命令はここを通る。kubectl はここに話しかける |
| Scheduler | 本部の配置担当 | 「この料理はA店舗で作って」と振り分ける |
| Controller Manager | 本部の監視・復旧担当 | 「B店舗のスタッフが倒れた!代わりを手配!」 |
| etcd | 本部の台帳 | 全店舗の状態・設定を記録している |
| Worker Node | 各店舗 | 実際にコンテナ(Pod)を動かす場所 |
| Pod | 調理スタッフ | コンテナの実行単位(k8sの最小単位) |
🔰 Memo:
今の時点では「Master = 指示する側」「Worker = 動かす側」だけ覚えればOKです。
各コンポーネントの詳細は使いながら身につきます。
7. ハンズオン:kindでクラスタ構築
7-1. 事前チェック
# WSL2 Ubuntu で実行
# Docker が起動しているか確認
docker version
期待される出力:
Client:
Version: ...
Server:
Engine:
Version: ...
❌ エラーが出る場合は、Docker Desktopを起動してください。
7-2. kindのインストール
# WSL2 Ubuntu で実行
# kindのバイナリをダウンロード
# ★ 最新バージョンは https://github.com/kubernetes-sigs/kind/releases で確認
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.27.0/kind-linux-amd64
# 実行権限を付与
chmod +x ./kind
# パスの通った場所に移動
sudo mv ./kind /usr/local/bin/kind
# インストール確認
kind version
期待される出力:
kind v0.27.0 go1.23.x ...
7-3. kubectlのインストール
# WSL2 Ubuntu で実行
# kubectlをダウンロード
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# 実行権限を付与
chmod +x kubectl
# パスの通った場所に移動
sudo mv kubectl /usr/local/bin/kubectl
# インストール確認
kubectl version --client
期待される出力:
Client Version: v1.xx.x
7-4. クラスタ作成
# WSL2 Ubuntu で実行
# kindでクラスタを作成(名前:my-first-cluster)
kind create cluster --name my-first-cluster
期待される出力:
Creating cluster "my-first-cluster" ...
✓ Ensuring node image (kindest/node:v1.xx.x) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-my-first-cluster"
7-5. クラスタの確認
# WSL2 Ubuntu で実行
# ノード一覧を表示
kubectl get nodes
期待される出力:
NAME STATUS ROLES AGE VERSION
my-first-cluster-control-plane Ready control-plane 1m v1.xx.x
無事にクラスタが起動しました。
手元でKubernetesが動いているのを見ると、思った以上に感動がありました。
🍽️ 比喩でいうと、今あなたは「自宅キッチンにチェーンレストランの本部を建てた」状態です。
セクション4で選定したkindが、Dockerコンテナの中でk8sクラスタを動かしてくれています。
7-6. もう少し触ってみよう
# クラスタ情報を表示
kubectl cluster-info
# 全ての名前空間のPodを表示(システム系のPodが見える)
kubectl get pods --all-namespaces
期待される出力(get pods):
NAMESPACE NAME READY STATUS ...
kube-system coredns-xxxxxxx-xxxxx 1/1 Running ...
kube-system etcd-my-first-cluster-control-plane 1/1 Running ...
kube-system kube-apiserver-my-first-cluster-control-plane 1/1 Running ...
kube-system kube-controller-manager-my-first-cluster-control-plane 1/1 Running ...
kube-system kube-scheduler-my-first-cluster-control-plane 1/1 Running ...
...
🔰 Memo:
ここに見えているのは、セクション6で説明した「本部のスタッフたち」です。
API Server、Controller Manager、Scheduler、etcd が全てPodとして動いているのが確認できます。
k8sは自分自身もPodで動かしているのです。
8. つまずきポイント(体験談)
ハンズオン中に起きたトラブルと対処法をまとめました。
8-1. Docker が起動していない
症状:
ERROR: failed to create cluster: failed to pull image "kindest/node:..."
対策: Docker Desktop(またはDockerデーモン)を起動してから再実行。
# Dockerの状態確認
docker info
8-2. WSL2のメモリ不足
症状: クラスタ作成が途中で止まる、または異常に遅い。
対策: .wslconfig でメモリ割り当てを増やす。
# Windows側:C:\Users\<ユーザー名>\.wslconfig
[wsl2]
memory=4GB
processors=2
変更後、PowerShellで wsl --shutdown → 再起動。
8-3. kubectlのPATHが通っていない
症状:
kubectl: command not found
対策:
# パスを確認
which kubectl
# 通っていなければ .bashrc に追加
echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrc
source ~/.bashrc
9. まとめ
9-1. この記事でやったこと
| # | 内容 | 状態 |
|---|---|---|
| 1 | Docker Composeの3つの壁を理解した | ✅ |
| 2 | ローカルk8s環境を4ツール比較して選定した | ✅ |
| 3 | k8sの世界観(Master / Worker)を学んだ | ✅ |
| 4 | kindでローカルクラスタを構築した | ✅ |
| 5 |
kubectl get nodes でクラスタを確認した |
✅ |
9-2. Docker Compose と k8s の対比(まとめ表)
| 観点 | Docker Compose | Kubernetes |
|---|---|---|
| 用途 | 開発環境 | 本番運用 |
| 障害復旧 | 手動 | 自動(Self-healing) |
| スケール | 手動・限定的 | 自動(オートスケール) |
| デプロイ | ダウンタイムあり | ローリングアップデート |
| 学習コスト | 低い | 高い(でもDocker経験が活きる) |
| 比喩 | 個人経営の定食屋 | チェーンレストランの本部 |
9-3. 後片付け
# クラスタを削除する場合(残しておいてもOK)
kind delete cluster --name my-first-cluster
10. 次回予告
第2回:「Pod / ReplicaSet / Deployment」— コンテナ管理の3層構造を理解する
今回は「本部を建てた」だけ。
次回はいよいよ「店舗にスタッフを配置する」= Podを作って動かします。
- なぜ「コンテナ」ではなく「Pod」なのか?
- ReplicaSet と Deployment の役割分担
- マニフェストファイル(YAML)の書き方