- 第5回スコープ・学習目標・今ここマップ
- Docker 単独の限界とオーケストレーターの必要性
- Kubernetes とは何か — 歴史・概念・現在の標準性
- Kubernetes アーキテクチャ全体像
- コア コンポーネント詳説 — Control Plane Node
- コア コンポーネント詳説 — Workload Node
- Pod — Kubernetes の最小デプロイ単位(概念先出し)
- kind とは — ローカル K8s 学習環境の仕組み
- alma-proxy 環境の制約と Docker Hub mirror 回避策
- やってみよう ①: kind / kubectl のインストール
- やってみよう ②: kind クラスタ起動 + kubectl get nodes 初接続
- 現場ヒヤリハット — whitelist proxy 環境で kind create がフリーズに見えた
- 理解度チェック + まとめ + 次回予告 + シリーズ一覧
第5回スコープ・学習目標・今ここマップ
動作確認バージョン: kind v0.31.0 / kindest/node:v1.35.0 / kubectl v1.35.0 / Docker CE 29.4.3 / containerd 2.2.3 / AlmaLinux 10.1(kernel 6.12.0-124.55.3.el10_1)(2026-05-10 時点・k8s-ops 実機検証済・SP_vol1-pre-07 起点)
本回は Kubernetes 実践教科書 第1巻(CKAD 対応・全 19 回)の第5回です。第2部「Kubernetes 基礎」の開幕回として、なぜ Kubernetes が必要か・Kubernetes の内部構造はどうなっているか・ローカル学習環境 kind をどう構築するか を扱います。
CKAD D1(Application Design and Build・20 %)の前提知識と、D2(Application Deployment・20 %)の起点となるクラスタ操作の基礎を習得します。
第4回からの継承状態確認(SP_vol1-pre-07 状態):
| 項目 | 状態 |
|---|---|
| k8s-ops Docker CE | 29.4.3 稼働中 |
| k8s-registry Docker Registry | registry:2 コンテナ稼働中・fanclub-backend:0.2.0 格納済み |
| kind | 未インストール(type kind → not found) |
| kubectl | 未インストール(type kubectl → not found) |
| ディスク空き(/ パーティション) | 27 GB(df -h / 確認済み) |
| メモリ空き | 4.8 GiB available(free -h 確認済み) |
今ここマップ(第1巻 19 回中の現在位置):
第1部 コンテナとDocker
第1回: コンテナ技術概念 + Docker環境準備 [完了]
第2回: Docker基本操作 [完了]
第3回: Dockerfile + マルチステージビルド + JDK 25/Payara Micro [完了]
第4回: コンテナレジストリ + イメージタグ戦略 + Trivy スキャン [完了]
第2部 Kubernetes基礎
★ 第5回: K8s全体像 + kind で軽量K8s ← 今ここ
第6回: kubectl基本操作 + Observability・Debug
第3部 アプリリソース(第7〜11回)
第4部 ワークロード戦略(第12〜14回)
第5部 セキュリティ基礎(第15〜16回)
第6部 パッケージ管理 + HTTPS公開(第17〜19回)
第5回を終えると、以下を習得した状態になります。
- Docker 単体の限界を「スケーリング・自己回復・複数ホスト跨ぎ」の観点で説明できる
- Kubernetes アーキテクチャ(Control Plane Node の 4 コンポーネント・Workload Node の 3 コンポーネント)を図解で説明できる
- kind と kubeadm(第2巻)の役割の違いを「学習用 vs 本番用」の観点で説明できる
- kind v0.31.0 と kubectl v1.35.0 をバイナリ取得でインストールし、動作確認できる
kind create cluster --image docker.io/kindest/node:v1.35.0でクラスタを起動し、kubectl get nodesで初接続を確認できる
模擬アプリ進捗(第5回):第5回は kind クラスタの基盤構築回のため、fanclub-api のデプロイ作業はありません。k8s-registry に push 済みの fanclub-backend:0.2.0 を K8s の Pod として動かすのは第7回からです。
Docker 単独の限界とオーケストレーターの必要性
第1〜4回で Docker の基本操作・Dockerfile 作成・レジストリ運用を学びました。docker run でコンテナを起動し、docker stop で停止し、docker push でイメージをレジストリに登録する一連の流れを体験しました。ここで問いを立てます。
fanclub-api を 10 台のサーバーに 50 個のコンテナで動かすには、どうすればよいでしょうか。
Docker 単体でこれを実現しようとすると、次のような問題が次々と現れます。
問題1: スケーリングの手動管理
トラフィックが増えてきたとします。コンテナを 5 個から 20 個に増やしたい場合、Docker 単体では docker run を 15 回手動で実行するしかありません。
増やす先のサーバーを決め、SSH でログインし、docker run を叩き、終わったら次のサーバーへ移動する。この作業を夜間のアクセス集中時に手動でやれるでしょうか。逆にトラフィックが減ったときにコンテナを減らすのも、すべて手動です。
Docker Compose を使えば複数コンテナをまとめて操作できますが、これは 1 台のホスト上でのみ有効です。複数サーバーに分散するスケーリングは Docker Compose の設計範囲外です。
問題2: 自己回復の欠如
稼働中のコンテナが OOM(Out of Memory)でクラッシュしたとします。docker run には --restart=always オプションがあり、同じホスト上であればコンテナを自動再起動できます。しかしこれは「1 台のホスト上の Docker デーモンが管理できる範囲」に限られます。
ホスト自体がダウンした場合には --restart=always は何もできません。別のホストにコンテナを移して再起動するには、誰かが手動で気づいてコマンドを実行する必要があります。この「誰か」が深夜 3 時に対応できるかどうかは、Docker 自体には関係のない問題です。
問題3: 複数ホスト跨ぎの複雑性
10 台のサーバーで動くコンテナの状態を確認したい場合、docker ps は 1 台ごとに SSH で接続して実行するしかありません。どのサーバーのどのコンテナが動いていて、どれが止まっているかを把握するには、10 台分のコマンド結果を目視で確認する必要があります。
コンテナのバージョンを新しいものに更新する場合も同様です。10 台に SSH して docker pull と docker stop / docker run を順番に実行する。サーバーが増えれば増えるほど、作業量は線形に増加します。
問題4: サービスディスカバリの欠如
コンテナの IP アドレスは、コンテナを再起動するたびに変わります。fanclub-api の frontend コンテナが backend コンテナに HTTP リクエストを送るには「接続先の IP アドレス」が必要ですが、backend が再起動するたびに IP が変わるため、frontend はどの IP に接続すればよいか分からなくなります。
Docker ネットワークの同一ネットワーク内ではコンテナ名で名前解決できますが、これも 1 台のホスト上の Docker ネットワーク内に限定された仕組みです。複数ホストに分散したコンテナ間での名前解決は、Docker 単体では解決できません。
オーケストレーターが解決すること
上記の問題を「宣言的に解決」するのがコンテナオーケストレーターです。「宣言的(declarative)」とは、「何をしてほしいか」を定義するだけで、「どうやって実現するか」はシステムが判断することを意味します。
たとえば「fanclub-backend のコンテナを常時 3 個動かし続けてほしい」と宣言します。オーケストレーターは次のことを自動で行います。
- 3 個のコンテナをどのホストに配置するかを判断して起動する
- コンテナが 1 個クラッシュしたら別のホストに 1 個新たに起動して「3 個」を維持する
- コンテナの IP が変わっても名前で接続できるよう、ロードバランサのルールを自動更新する
- 新バージョンのイメージに更新する際、ダウンタイムなしにローリングアップデートする
現時点では「そんな便利なものがあるのか」という認識で十分です。H2-4 以降でその仕組みを詳しく見ていきます。
Kubernetes とは何か — 歴史・概念・現在の標準性
Kubernetes(クーバネティス)は、コンテナ化されたアプリケーションのデプロイ・スケーリング・管理を自動化する OSS のコンテナオーケストレーターです。
Google Borg から Kubernetes へ
Kubernetes の原型は Google 社内の Borg(ボーグ)と呼ばれる大規模コンテナ管理システムです。Google は 2000 年代初頭から Borg を使って検索・Gmail・YouTube などのサービスを大量のサーバー上で管理してきました。Borg で培ったノウハウを再設計・OSS 化したものが Kubernetes であり、2014 年に公開されました。
2016 年には CNCF(Cloud Native Computing Foundation)—Linux Foundation 配下のベンダー中立な財団—に Kubernetes プロジェクトが寄贈されました。CNCF への寄贈により、特定の企業(Google)が開発をコントロールする状況を脱し、業界全体が関与するプロジェクトになりました。
名称の由来はギリシャ語で「船の操舵手(helmsman)」を意味する語です。ロゴにある舵(helm)もここから来ています。略称 K8s は “K” と “s” の間に 8 文字 “ubernete” があることに由来します。本シリーズでは「Kubernetes」と「K8s」を混用します。
現在の業界標準としての立ち位置
現在、主要なクラウドプロバイダーはすべて Kubernetes のマネージドサービスを提供しています。
| クラウド | サービス名 |
|---|---|
| AWS | Amazon EKS(Elastic Kubernetes Service) |
| Google Cloud | GKE(Google Kubernetes Engine) |
| Microsoft Azure | AKS(Azure Kubernetes Service) |
CNCF は Kubernetes エンジニアの技術力を認定する資格を提供しており、CKAD / CKA / CKS はその代表的な実技資格です。本シリーズ第1巻は CKAD(Certified Kubernetes Application Developer)の全 Competency を網羅することをゴールとしています。
クラウドネイティブの定義
CNCF が定義するクラウドネイティブとは、コンテナ・マイクロサービス・動的オーケストレーション・DevOps が揃った設計思想を指します。Kubernetes はこの「動的オーケストレーション」を担う中核コンポーネントとして位置づけられています。
他のオーケストレーターとの関係
Docker Swarm(Docker 社純正のオーケストレーター)や HashiCorp Nomad など、他のコンテナオーケストレーターも存在します。ただし、クラウドネイティブ業界の事実上の標準として Kubernetes が選択されています。本シリーズは Kubernetes のみを扱い、他のオーケストレーターとの詳細比較はスコープ外です。
Kubernetes アーキテクチャ全体像
Kubernetes クラスタは大きく 2 種類のノードから構成されます。
- Control Plane Node:クラスタ全体を管理・制御するノード。クラスタの「頭脳」に相当します
- Workload Node:アプリケーションコンテナ(Pod)を実際に動かすノード。クラスタの「腕」に相当します
本シリーズでは「Control Plane Node」と「Workload Node」という呼称を使います。古い書籍や記事では「Master Node / Worker Node」と書かれている場合がありますが、Kubernetes v1.20 以降の公式呼称は Control Plane Node / Workload Node です。
まず全体図(図解 05-01)を確認します。各コンポーネントが何をするかの 1 行概要は表で確認し、詳細説明は次の H2-5(Control Plane Node)と H2-6(Workload Node)で扱います。

コンポーネント 1 行概要:
| コンポーネント | 所属ノード | 1 行概要 |
|---|---|---|
| kube-apiserver | Control Plane Node | すべての API 通信の入口。kubectl / kubelet / Scheduler / Controller Manager はすべて API Server を経由して状態を読み書きする |
| etcd | Control Plane Node | クラスタ状態を保存する分散 KV ストア。唯一の真実のソース(SSOT) |
| kube-scheduler | Control Plane Node | 新しい Pod をどの Workload Node に配置するかを決定する |
| kube-controller-manager | Control Plane Node | Deployment / ReplicaSet / Node 等の各コントローラを内包し、「宣言した状態」と「実際の状態」の差異を解消し続ける |
| kubelet | Workload Node | Control Plane からの指示(Pod Spec)を受け取り containerd にコンテナ起動を依頼する |
| kube-proxy | Workload Node | Service の ClusterIP から Pod の IP への転送ルールを iptables / ipvs で管理する |
| containerd | Workload Node | 実際にコンテナを起動・停止する OCI 準拠のランタイム(第1回既習) |
kubectl からコンテナ起動までのフロー:
[kubectl apply -f pod.yaml]
| HTTPS
v
[kube-apiserver] -- etcd に "Pod を作れ" と記録
|
v
[kube-scheduler] が etcd を監視 -- 配置先 Workload Node を選択
|
v
[kube-apiserver] -- 選ばれた Workload Node の kubelet に通知
|
v
[kubelet] -- containerd に "このコンテナを起動せよ" と指示
|
v
[containerd] -- k8s-registry から OCI イメージを pull -- コンテナ起動
このフローは第7回以降で体験します。第5回では「全体像を把握する」ことにとどめ、各コンポーネントの詳細に移ります。
コア コンポーネント詳説 — Control Plane Node
(Pod という概念が以降の説明で登場します。Pod の詳細は H2-7 で説明します。ここでは「コンテナを包む K8s の最小デプロイ単位」として読み進めてください)
Control Plane Node には以下の 4 つのコンポーネントが稼働しています。
kube-apiserver — すべての通信のゲートウェイ
kube-apiserver は、Kubernetes クラスタへのすべての API リクエストを受け付けるコンポーネントです。kubectl コマンドを実行すると、実際には kube-apiserver への HTTP/2 リクエストが送られています。
kube-apiserver の重要な性質は次の 2 点です。
- すべての通信が kube-apiserver を経由する:kubectl / kubelet / kube-scheduler / kube-controller-manager はいずれも kube-apiserver を介して状態を読み書きします。コンポーネント間が直接通信することはありません
- 認証・認可・バリデーションを実施してから etcd に書き込む:リクエストが正当なユーザーからのものか(認証)・そのユーザーに操作権限があるか(認可)・YAML の書式は正しいか(バリデーション)を確認してから etcd に反映します
kubectl get pods も kubectl apply -f manifest.yaml も、内部では kube-apiserver の REST API へのリクエストです。第6回の kubectl 基本操作では、この動作をより深く観察します。
etcd — クラスタ状態の唯一の真実のソース(SSOT)
etcd(エトシーディー)は、Raft アルゴリズムによる分散合意を持つ KV(Key-Value)ストアです。Kubernetes クラスタの「全状態」—Pod の定義・Node の情報・ConfigMap の内容・Secret・RBAC ポリシー—を etcd に保存します。
SSOT(Single Source of Truth・唯一の真実のソース)という言葉は、「クラスタの状態を知りたければ etcd を見ればよい」という意味です。他のコンポーネントが独自にクラスタ状態を持つことはなく、すべての読み書きは kube-apiserver 経由で etcd に集約されます。
etcd が壊れると、kube-apiserver は新しい状態を保存できなくなり、Scheduler と Controller Manager も機能を失います。クラスタ全体が停止します。これが 本番では etcd を奇数台(3 台または 5 台)で冗長化する理由です。第2巻では kubeadm による HA クラスタ構成と etcd バックアップ(etcdctl)を扱います。
第5回では etcd を直接操作しません。etcdctl の使い方は第2巻 CKA 編で学びます。
kube-scheduler — Pod の配置先を決定するエンジン
kube-scheduler は、「新しい Pod をどの Workload Node で動かすか」を決定するコンポーネントです。
配置先の決定には以下の情報を使います。
- resources.requests:Pod が要求する CPU / メモリの量。ノードに余裕がなければ配置しない
- nodeSelector:Pod が特定のラベルを持つノードにのみ配置されるよう指定する
- Taint & Toleration:特定のノードに特定の Pod しか配置しない(第12回以降)
第5回では「配置先を決める担当者」という概念を覚えます。実際に Scheduler の動作を観察するのは第12回(Deployment)以降です。
kube-controller-manager — 制御ループのエンジン
kube-controller-manager は、Kubernetes の「制御ループ(control loop)」を担うコンポーネントです。Deployment Controller / ReplicaSet Controller / Node Controller など複数のコントローラを 1 つのバイナリに集約しています。
制御ループとは、次のサイクルを絶えず繰り返す動作です。
- desired state(宣言した状態)を確認する:「fanclub-backend の Pod を 3 個動かしてほしい」という YAML の定義
- actual state(実際の状態)を確認する:今 etcd に記録されている「現在動いている Pod の数」
- 差異を解消する:desired = 3、actual = 2 なら新たに 1 個の Pod を作成する指示を kube-apiserver に送る
この仕組みが H2-2 で説明した「自己回復」を実現します。Pod が 1 個クラッシュすると actual state が 2 になり、controller が差異を検出して 3 個になるよう新しい Pod を起動します。
kind 環境での注意点:kind のシングルノードクラスタでは、Control Plane Node と Workload Node が同一のコンテナ(kindest/node)内で動作します。
本番環境では Control Plane Node と Workload Node を必ず分離します。第2巻 kubeadm HA 構成では Control Plane Node 3 台 + Workload Node 2 台の計 5 台構成を作ります。
コア コンポーネント詳説 — Workload Node
Workload Node には以下の 3 つのコンポーネントが稼働しています。
kubelet — K8s エージェント
kubelet は、各 Workload Node に常時稼働する K8s エージェントです。役割は「Control Plane(kube-apiserver)から Pod の仕様(PodSpec)を受け取り、containerd にコンテナ起動を依頼する」ことです。
kubelet は systemd サービスとして動作します(systemctl status kubelet)。kubelet が停止するとそのノードの Pod 管理が止まり、kube-controller-manager がそのノードを「NotReady」と検出して別ノードへの Pod 再配置を始めます。
第1回との再接続:第1回で「K8s は containerd を直接使用する。Docker は K8s のコンテナランタイムではない」と学びました。kubelet がその「仲介者」です。
kubelet は CRI(Container Runtime Interface)—K8s が定めたコンテナランタイムとの標準 API—を通じて containerd に指示を出します。Docker は CRI に直接対応しておらず(shimコンポーネントが必要)、K8s v1.24 以降は Docker を Container Runtime として使用できなくなっています。
kube-proxy — Service のルール管理
kube-proxy は、Kubernetes の Service リソースが機能するために必要な転送ルールを各 Workload Node の OS レベルで管理するコンポーネントです。
Service(サービス)は、Pod の IP アドレスが変わっても同じ名前・同じ仮想 IP(ClusterIP)で接続できるようにする K8s のリソースです(第8回で詳説)。kube-proxy はこの ClusterIP から実際の Pod の IP への転送ルールを、各ノードの iptables または ipvs に書き込みます。
kind 環境では kube-proxy が iptables モードで動作しています。第8回 Service 回で実際の動作を観察します。
containerd — OCI 準拠のコンテナランタイム(第1回既習との再接続)
containerd(コンテイナーディー)は、実際にコンテナを起動・停止する OCI 準拠のコンテナランタイムです。第1回で「Docker CE をインストールすると containerd も一緒にインストールされる」と学びました。K8s では kubelet が CRI 経由で containerd を直接呼び出しており、Docker デーモンは関与しません。
第4回ヒヤリハットで「kind ノード内の containerd は Docker デーモンとは別プロセス・別設定ファイルを持つ」と予告しました。
kind の各ノードコンテナ内部にも containerd が稼働しており、これは k8s-ops 上の Docker が使う containerd(containerd.sock を通じた Docker デーモン配下の containerd)とは完全に別のプロセスです。
2 つの containerd の関係を整理します。
| containerd の場所 | 役割 | 管理するもの |
|---|---|---|
| k8s-ops ホスト上(Docker 配下) | Docker デーモンがコンテナを起動する際に使うランタイム | k8s-ops 上の Docker コンテナ(例: kind-control-plane コンテナ自体・k8s-registry の registry:2 コンテナ) |
| kind ノードコンテナ内部 | kubelet が Pod を起動する際に使うランタイム | kind クラスタ内の Pod コンテナ(fanclub-api など、第7回以降でデプロイするもの) |
この区別は第7回(Pod デプロイ)で k8s-registry を kind ノード内 containerd の insecure registry として設定する際に重要になります。
Pod — Kubernetes の最小デプロイ単位(概念先出し)
H2-4 の全体図から H2-6 の Workload Node 説明まで、「Pod をどの Workload Node に配置するか」「kubelet が Pod Spec を受け取る」という表現を繰り返し使いました。ここで Pod という概念を先出しで整理します。
Pod(ポッド)は、1 つ以上のコンテナを共有ネットワーク・共有ストレージで実行する K8s の最小デプロイ単位です。
なぜ「コンテナ」ではなく「Pod」が最小単位なのかは次の理由によります。
- 1 つのサービスが「メインコンテナ + ログ収集の sidecar コンテナ」のように複数コンテナから成る場合、それらを同じネットワーク名前空間で動かす必要があります
- Pod 内のコンテナはすべて同じ IP アドレスを共有します(
localhostで相互通信できます) - kube-scheduler が配置先を決定する単位も「コンテナ個別」ではなく「Pod」です
第5回では Pod を直接操作しません。理由は「Pod 単独でデプロイする構成はアンチパターン」であり、本シリーズでは最初から Deployment(複数 Pod を束ねて管理するリソース)を使うためです。第7回では Pod の YAML 定義・ライフサイクル・Init Container / Sidecar パターンを本格的に学びます。
第7回(Pod + Multi-container パターン)は 第7回 Pod + Multi-container パターン です。Pod の YAML 定義・Init Container・Sidecar パターンを扱います。
kind とは — ローカル K8s 学習環境の仕組み
kind(カインド)は “Kubernetes IN Docker” の略で、Docker コンテナ自体が Kubernetes のノードになる軽量な K8s 学習環境です。
公式リポジトリは github.com/kubernetes-sigs/kind(CKAD 試験中参照可)です。なお kind.sigs.k8s.io は試験規約上の参照可否について確証がないため、CKAD 試験準備としては kubernetes.io/docs を主参照にすることを推奨します。
kind の動作原理(図解 05-02)

動作原理を整理します。
- k8s-ops(AlmaLinux 10.1 VM)上に Docker CE が稼働している
kind create clusterを実行すると、Docker コンテナ(kindest/node:v1.35.0イメージ)が起動する- このコンテナ内部に Control Plane コンポーネント(kube-apiserver / etcd / kube-scheduler / kube-controller-manager)と kubelet / containerd が同居する
- k8s-ops 上の
kubectlは~/.kube/config(kubeconfig)経由でこのコンテナ内の kube-apiserver に接続する
つまり 「ノード = Docker コンテナ」 が kind の本質です。docker ps を実行すると kind のノードが Docker コンテナとして表示されます。これは演習 ② で確認します。
kindnet CNI
kind には kindnet という内蔵の CNI(Container Network Interface)プラグインが含まれています。CNI は Pod 間ネットワーキングを担う K8s のネットワークプラグイン仕様で、kind では追加インストール不要で kindnet が自動で設定されます。
kindnet は NetworkPolicy に対応しており(v0.20+)、第16回のネットワークポリシー演習でも使用します。
kind と本番 kubeadm の比較
| 観点 | kind(第1巻) | kubeadm(第2巻〜) |
|---|---|---|
| 用途 | 学習・CKAD 演習 | 本番・CKA 実技・HA クラスタ構築 |
| ノードの実体 | Docker コンテナ | 仮想マシン(VM) |
| セットアップ速度 | 数十秒(イメージ pull 済み状態) | 数十分(VM プロビジョニング + kubeadm init) |
| HA 構成 | 不可(シングルノード) | 可(Control Plane Node 3 台 + Workload Node 2 台 以上) |
| データの永続性 | クラスタ削除で消える | etcd バックアップで管理 |
| kubectl 操作感 | 本番と同一 | 本番と同一 |
kubectl の操作感は kind でも kubeadm でも完全に同じです。第5回で kind クラスタに対して kubectl get nodes を実行した経験は、第2巻の kubeadm クラスタでもそのまま使えます。
CKAD 試験との関係:CKAD 試験の実技環境は kind ではなく本番に近い構成のクラスタです。しかし kubectl コマンドの操作感・YAML 定義の書き方は種類を問わず同一のため、kind での練習が試験対策として有効です。
kind を採用する理由:k8s-ops(2 core / 5.5 GB)と k8s-registry の 2 VM 構成で kind クラスタが動作します。Docker CE は第1回で導入済みのため追加 VM は不要です。
alma-proxy 環境の制約と Docker Hub mirror 回避策
演習①(kind / kubectl インストール)と演習②(kind クラスタ起動)を実行する前に、本シリーズの検証環境における重要な制約と回避策を理解します。この内容は後述のヒヤリハット(H2-12)と対になっています。
registry.k8s.io の仕組みと HTTP 307 リダイレクト
kind create cluster をオプションなしで実行すると、デフォルトで registry.k8s.io/kindest/node:v1.35.0 のイメージを取得しようとします。
registry.k8s.io は Kubernetes 公式のイメージレジストリです。ただし、このレジストリはマニフェスト取得のリクエストに対して HTTP 307 リダイレクト で地域ごとの Google Artifact Registry(GAR)に転送する設計になっています。
東京リージョンからのアクセスでは asia-northeast2-docker.pkg.dev(asia-northeast2 = 大阪)に転送されます。
これは Google がインフラ運用コストを最適化するための設計であり、世界中のリクエストを地理的に近い GAR にルーティングします。
alma-proxy whitelist の制約
第1回で構築した alma-proxy は whitelist 方式の企業プロキシです。許可ドメインのみ通信でき、リスト外は HTTP 403(Squid ERR_ACCESS_DENIED)で拒否されます。
whitelist の状況を確認します。
registry.k8s.io:許可済みasia-northeast2-docker.pkg.dev(registry.k8s.io の redirect 先・Google Artifact Registry):未許可
結果として、kind create cluster がデフォルトで registry.k8s.io にアクセスしても、リダイレクト先の asia-northeast2-docker.pkg.dev への通信が HTTP 403 でブロックされてイメージ取得が失敗します。
回避策 B 採用: Docker Hub mirror を明示指定
この問題には 3 つの回避策があります。
| 案 | 内容 | 採否 |
|---|---|---|
| 案 A | asia-northeast2-docker.pkg.dev を alma-proxy whitelist に追加する | 第5回では不採用(管理者承認が必要な変更作業のため) |
| 案 B | kind create cluster --image docker.io/kindest/node:v1.35.0 で Docker Hub mirror を明示指定する | 第5回採用 |
| 案 C | 事前に docker pull docker.io/kindest/node:v1.35.0 して別のタグ名でローカルに持つ | 手順が多くなるため不採用 |
案 B を採用する理由は、docker.io/kindest/node:v1.35.0 が Docker Hub 上のミラーイメージとして公開されており、Docker Hub の pull は registry-1.docker.io 経由で行われ、これが alma-proxy whitelist に登録済みだからです。
docker manifest inspect docker.io/kindest/node:v1.35.0 で amd64 digest(sha256:986401fce0e567a9860075ba9df8c8459bd99a35f79024d8a682773fb40f0753)が確認でき、実機検証済みです。
現場視点の補足:本番で kind を継続利用する場合は、案 A(asia-northeast2-docker.pkg.dev を whitelist に正式追加)が長期的に望ましい選択です。Docker Hub は pull レート制限があり、大規模チームでの継続利用には向きません。
第5回では教材として「管理者承認を経ずに即実行できる Docker Hub mirror」を採用しますが、現場で運用環境に kind を継続導入する場合は whitelist 追加を検討してください。
企業ネットワークでのポイント:proxy whitelist 環境では「ドメインが許可されている」だけでは不十分で、「リダイレクト先ドメインも許可されているか」まで確認する必要があります。
registry.k8s.io は通るのに pull が止まる現象は、この redirect 構造に起因します。curl -v や docker pull --verbose でリクエストの流れを追うと原因を特定できます。
やってみよう ①: kind / kubectl のインストール
演習①では kind v0.31.0 と kubectl v1.35.0 を k8s-ops にインストールします。どちらもバイナリを GitHub / dl.k8s.io から取得して /usr/local/bin に配置するだけで完了します。
前提状態:SP_vol1-pre-07(kind / kubectl 未インストール・Docker CE 29.4.3 稼働中・alma-proxy proxy 設定済み)
Step 1: 前提状態の確認
実行コマンド:
$ type kind 2>&1
$ type kubectl 2>&1
$ docker version --format '{{.Server.Version}}'
実行結果:
bash: type: kind: 見つかりません
bash: type: kubectl: 見つかりません
29.4.3
kind と kubectl どちらも「見つかりません」が返れば未インストール状態です。Docker Server Version が 29.4.3 であることも確認します。
Step 2: プロキシ環境変数の確認
実行コマンド:
$ env | grep -i proxy
実行結果:
https_proxy=http://192.168.1.121:3128
http_proxy=http://192.168.1.121:3128
no_proxy=localhost,127.0.0.1,192.168.1.0/24
https_proxy が設定されていることを確認します。curl は https_proxy 環境変数が設定されていれば、--proxy フラグを明示しなくても自動的に alma-proxy(192.168.1.121:3128)を経由してダウンロードを行います。
Step 3: kind v0.31.0 バイナリ取得・インストール
実行コマンド:
$ curl -Lo /tmp/kind https://github.com/kubernetes-sigs/kind/releases/download/v0.31.0/kind-linux-amd64
$ sudo install -o root -g root -m 0755 /tmp/kind /usr/local/bin/kind
実行結果(curl のダウンロード進捗):
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 10.5M 100 10.5M 0 0 12.4M 0 --:--:-- --:--:-- --:--:-- 12.4M
実行コマンド(バージョン確認):
$ kind version
実行結果:
kind v0.31.0 go1.25.5 linux/amd64
kind v0.31.0 と表示されれば正常です。go1.25.5 は kind v0.31.0 のビルド時の Go バージョンを示します(バイナリは AlmaLinux 10.1 のホストでも問題なく動作する Linux amd64 バイナリ)。
Step 4: kubectl v1.35.0 バイナリ取得・インストール
実行コマンド:
$ curl -Lo /tmp/kubectl https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl
$ sudo install -o root -g root -m 0755 /tmp/kubectl /usr/local/bin/kubectl
実行結果(curl のダウンロード進捗):
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 55.8M 100 55.8M 0 0 937k 0 0:01:01 0:01:01 --:--:-- 1320k
実行コマンド(バージョン確認):
$ kubectl version --client
実行結果:
Client Version: v1.35.0
Kustomize Version: v5.7.1
--client フラグをつける理由は、クラスタに接続せずバイナリのバージョンのみを表示するためです。クラスタ未起動の状態でも実行できます。Kustomize Version: v5.7.1 は kubectl 内蔵の Kustomize バージョン(CKA D1 Kustomize で第2巻第14回に再登場します)。
なぜ v1.35.0 をピン留めするか:dl.k8s.io/release/stable.txt は 2026-05-10 時点で v1.36.0 を返しますが、本シリーズは CKAD 試験(v1.35 対応)に合わせ v1.35.0 をピン留めします。kubectl のバージョンと CKAD 試験環境のクラスタバージョンを一致させることで、試験本番と同じコマンド動作を学習中に体験できます。
やってみよう ②: kind クラスタ起動 + kubectl get nodes 初接続
演習②では kind create cluster で K8s クラスタを起動し、kubectl get nodes でクラスタへの初接続を体験します。H2-9 で学んだ Docker Hub mirror 指定(--image docker.io/kindest/node:v1.35.0)を使います。
前提状態:演習①完了後(kind / kubectl インストール済み)
Step 1: kindest/node イメージを事前 pull して進捗確認
kindest/node イメージは大きなサイズのため、kind create cluster 実行中に「Ensuring node image…」の表示で長時間待機が発生することがあります(詳細は後述 H2-12 ヒヤリハット参照)。先に docker pull でイメージを取得して進捗バーで完了を確認してから、kind create cluster を実行します。
実行コマンド:
$ docker pull docker.io/kindest/node:v1.35.0
実行結果:
v1.35.0: Pulling from kindest/node
b55da17b98bb: Pull complete
cb61a4cea51e: Pull complete
Digest: sha256:4613778f3cfcd10e615029370f5786704559103cf27bef934597ba562b269661
Status: Downloaded newer image for kindest/node:v1.35.0
docker.io/kindest/node:v1.35.0
実行コマンド(イメージサイズ確認):
$ docker images kindest/node
実行結果:
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
kindest/node:v1.35.0 4613778f3cfc 1.35GB 397MB
kindest/node イメージは Debian ベースの OS に K8s コンポーネント(kube-apiserver / etcd / kube-scheduler / kube-controller-manager / kubelet / kube-proxy / kindnet / containerd 等)を含むため、CONTENT SIZE で 397MB、DISK USAGE で 1.35GB と容量があります。
pull が完了すれば以降の kind create cluster は高速に動作します。
Step 2: kind クラスタ起動(Docker Hub mirror 明示)
実行コマンド:
$ kind create cluster --image docker.io/kindest/node:v1.35.0
実行結果:
Creating cluster "kind" ...
• Ensuring node image (docker.io/kindest/node:v1.35.0) 🖼 ...
✓ Ensuring node image (docker.io/kindest/node:v1.35.0) 🖼
• Preparing nodes 📦 ...
✓ Preparing nodes 📦
• Writing configuration 📜 ...
✓ Writing configuration 📜
• Starting control-plane 🕹️ ...
✓ Starting control-plane 🕹️
• Installing CNI 🔌 ...
✓ Installing CNI 🔌
• Installing StorageClass 💾 ...
✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:
kubectl cluster-info --context kind-kind
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
5 段階のチェックマーク(Ensuring node image → Preparing nodes → Writing configuration → Starting control-plane → Installing CNI → Installing StorageClass)が表示されれば成功です。
kindest/node イメージが pull 済みのため「Ensuring node image」は数秒で通過します。
「Set kubectl context to “kind-kind”」というメッセージが表示されます。これは kubectl がこの kind クラスタに接続するための設定(kubeconfig)が自動で行われたことを意味します。
Step 3: kubeconfig の確認
実行コマンド:
$ kubectl config view
実行結果:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://127.0.0.1:36183
name: kind-kind
contexts:
- context:
cluster: kind-kind
user: kind-kind
name: kind-kind
current-context: kind-kind
kind: Config
users:
- name: kind-kind
user:
client-certificate-data: DATA+OMITTED
client-key-data: DATA+OMITTED
kubeconfig の役割:kubectl はどのクラスタに接続するかを ~/.kube/config(kubeconfig)から読み取ります。kind create cluster は自動的にこのファイルを更新し、kind-kind というコンテキスト名でクラスタへの接続情報を追記します。
出力の contexts セクションに kind-kind エントリ・current-context に kind-kind が設定されていることを確認します。server の https://127.0.0.1:36183 はランダムに割り当てられた kube-apiserver のポート(環境ごとに異なる値)です。
Step 4: kubectl get nodes で初接続確認
実行コマンド:
$ kubectl get nodes
実行結果:
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 46s v1.35.0
出力の読み方:
| 列 | 内容 |
|---|---|
| NAME | ノード名。kind クラスタでは kind-control-plane の 1 ノードのみ |
| STATUS | Ready = 正常稼働中 / NotReady = 問題あり(kubelet が応答していない可能性がある) |
| ROLES | control-plane = Control Plane Node として機能している |
| AGE | クラスタ起動からの経過時間 |
| VERSION | Kubernetes バージョン。v1.35.0 であることを確認する |
実行コマンド(詳細表示):
$ kubectl get nodes -o wide
実行結果:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kind-control-plane Ready control-plane 46s v1.35.0 172.18.0.2 <none> Debian GNU/Linux 12 (bookworm) 6.12.0-124.55.3.el10_1.x86_64 containerd://2.2.0
注目ポイント:
- OS-IMAGE:
Debian GNU/Linux 12 (bookworm)。kindest/node イメージのベース OS は Debian です。k8s-ops のホスト OS(AlmaLinux 10.1)とは別の OS がコンテナ内で動いていることが確認できます - CONTAINER-RUNTIME:
containerd://2.2.0。H2-6 で説明した「kind ノード内部の containerd」が実際に動作していることを確認できます。なお k8s-ops ホストの containerd はv2.2.3ですが、kind ノードコンテナ(kindest/node)にはイメージ内に独自の containerd(v2.2.0)が同梱されているため、バージョンが異なります。これは「kind ノードコンテナ内部に完結した K8s スタック」という H2-8 の説明と整合します
Step 5: kubectl cluster-info で API Server の動作確認
実行コマンド:
$ kubectl cluster-info
実行結果:
Kubernetes control plane is running at https://127.0.0.1:36183
CoreDNS is running at https://127.0.0.1:36183/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Kubernetes control plane is running at https://127.0.0.1:36183 の 36183 は kind が自動でランダムに割り当てたポート番号です(環境・起動ごとに異なる値)。
kube-apiserver が 127.0.0.1 のこのポートで待ち受けており、kubectl はここに接続しています。kubectl config view の server: 値と一致することを確認できます。
Step 6: docker ps で kind ノードはコンテナであることを確認
実行コマンド:
$ docker ps
実行結果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d57222b2a636 kindest/node:v1.35.0 "/usr/local/bin/entr…" 54 seconds ago Up 52 seconds 127.0.0.1:36183->6443/tcp kind-control-plane
kind-control-plane という名前のコンテナが動いていることが確認できます。これが H2-8 で説明した「Docker コンテナが K8s ノードの実体」です。kubectl get nodes で表示された kind-control-plane ノードと、docker ps の kind-control-plane コンテナは同一のものです。
Step 7(オプション): kind クラスタの削除確認
演習の最後に kind クラスタを一度削除して、第6回に向けてクリーンな状態に戻します。
実行コマンド:
$ kind delete cluster
実行結果:
Deleting cluster "kind" ...
Deleted nodes: ["kind-control-plane"]
実行コマンド(コンテナが消えたことを確認):
$ docker ps
実行結果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
kind-control-plane コンテナが消えていれば削除成功です。
重要:kind delete cluster を実行すると、そのクラスタ上で稼働していたすべての K8s リソース(Pod / Service / ConfigMap 等)は削除されます。ただし k8s-registry に push したコンテナイメージ(fanclub-backend:0.2.0 等)は k8s-registry の永続 Volume に保存されているため、削除されません。
第6回は kind create cluster から始まります。
現場ヒヤリハット — whitelist proxy 環境で kind create がフリーズに見えた
H2-9 で説明した registry.k8s.io の redirect 問題を実際に踏んだ体験を紹介します。H2-11 の演習②で「Step 1 で事前に docker pull を実行する」手順を設けた理由がこのヒヤリハットから分かります。
状況
検証環境で kind create cluster を実行したところ、「Ensuring node image…」の表示でコンソールが進捗のないまま止まりました。Ctrl+C を押すべきか数分間待つべきか判断できない状況になりました。しばらく待っても進捗が止まったままのため強制終了したところ、クラスタ作成が途中で止まっていました。
原因分析
原因を調べると、次の連鎖で発生していました。
kind create cluster(オプション未指定)はデフォルトでregistry.k8s.io/kindest/node:v1.35.0を pull しようとするregistry.k8s.io自体は whitelist 許可済みのため manifest(イメージ一覧情報)の取得は成功する- イメージの実体(layer)は HTTP 307 で
asia-northeast2-docker.pkg.devにリダイレクトされ、そこで proxy に HTTP 403 でブロックされる - Docker のイメージ pull は「manifest 取得成功 → layer pull 試行 → layer pull 失敗」という順序で進むため、manifest 取得まで成功した状態で止まる。「Ensuring node image…」のまま固まって見える
回避策
実行コマンド(事前に Docker Hub mirror から pull して進捗を可視化する):
$ docker pull docker.io/kindest/node:v1.35.0
実行コマンド(pull 完了後に kind create cluster を実行する):
$ kind create cluster --image docker.io/kindest/node:v1.35.0
事前に docker pull でイメージを取得することで、進捗バー付きのダウンロード状況を確認できます。pull が完了した後に kind create cluster を実行すると「Ensuring node image」は数秒で通過します。
教育的補足
proxy whitelist 環境で「ドメインは通るのに pull が途中で止まる」現象は、redirect 先が whitelist に未登録の典型パターンです。curl -v や docker pull --verbose でリクエストの flow を追うと、どのドメインで詰まっているかを特定できます。
企業ネットワーク環境で新しい外部リソースを使うときは、接続先ドメインだけでなく「そのドメインがリダイレクトする先」まで確認する習慣をつけることが重要です。
理解度チェック + まとめ + 次回予告 + シリーズ一覧
理解度チェック(○× 形式・全 8 問)
第5回の理解度を確認します。○か×で答えてください。
問 1:Kubernetes の kube-apiserver はすべての API 通信のゲートウェイであり、kubectl や kubelet、Scheduler はすべて kube-apiserver を経由して状態を読み書きする。
問 2:etcd は Kubernetes のすべての構成データを保存するストレージであり、etcd が壊れてもクラスタは引き続き動作できる。
問 3:kube-scheduler は Pod が要求する CPU / メモリの requests やノードの状態を考慮して、Pod をどの Workload Node に配置するかを決定する。
問 4:kind クラスタでは Docker コンテナが Kubernetes のノードとして動作するため、docker ps で kind ノードを確認できる。
問 5:kubectl get nodes の STATUS 列に NotReady と表示されている場合、そのノードの kubelet が正常に動作していない可能性がある。
問 6:kind create cluster のデフォルト動作では registry.k8s.io から kindest/node イメージを取得しようとするが、whitelist proxy 環境では asia-northeast2-docker.pkg.dev への redirect がブロックされる場合がある。
問 7:kubectl v1.35.0 は K8s クラスタ v1.36.0 に対しても問題なく使用できる(kubectl とサーバーのバージョンスキューは ±1 マイナーバージョンまで許容される)。
問 8:kind クラスタを削除(kind delete cluster)すると、そのクラスタ上で稼働していたすべての K8s リソース(Pod / Service 等)は削除されるが、k8s-registry に push したコンテナイメージは削除されない。
解答:
| 問 | 解答 |
|---|---|
| 問 1 | ○ |
| 問 2 | × |
| 問 3 | ○ |
| 問 4 | ○ |
| 問 5 | ○ |
| 問 6 | ○ |
| 問 7 | × |
| 問 8 | ○ |
解説(重要問のみ):
- 問 2(×):etcd が壊れると kube-apiserver は新しい状態を保存できなくなり、Scheduler / Controller Manager も機能を失います。クラスタ全体が停止します。etcd の冗長化(本番は奇数台構成)が必須な理由であり、第2巻 kubeadm CKA 編で etcd バックアップ(etcdctl)を学びます。
- 問 7(×):kubectl のバージョンスキューポリシーは「kubectl はサーバーと ±1 マイナーバージョンまでサポート」です。v1.35.0 の kubectl で v1.36.0 サーバーへの接続は -1 minor の範囲なので許容されます。ただしサーバーが v1.36 で追加された新 API を kubectl v1.35 で使おうとすると機能しない場合があります。問 7 の「問題なく使用できる」は正確ではないため × です。なお CKAD 試験では試験環境の K8s バージョンと kubectl バージョンが一致しているため実質的に問題になりません。
第5回まとめ
第5回では以下を実施しました。
- Docker 単独の限界(スケーリング・自己回復・複数ホスト跨ぎ・サービスディスカバリ)を具体例で確認した
- Kubernetes の歴史(Google Borg → 2014年 OSS 公開 → CNCF 寄贈)と業界標準としての立ち位置を理解した
- Kubernetes アーキテクチャ(Control Plane Node の 4 コンポーネント・Workload Node の 3 コンポーネント)を全体図と詳説で確認した
- Pod が K8s の最小デプロイ単位である理由を概念として把握した(詳細は第7回)
- kind の「Docker コンテナが K8s ノードになる」仕組みを図解と
docker psの出力で確認した - alma-proxy whitelist 環境での kindest/node pull 制約と、Docker Hub mirror(
docker.io/kindest/node:v1.35.0)を使った回避策を学んだ - kind v0.31.0 / kubectl v1.35.0 をバイナリ取得でインストールし、
kubectl get nodesで初接続を体験した
次回予告
第6回 kubectl 基本操作 + Observability・Debug 入門では、第5回で起動した kind クラスタに対して kubectl を使い込みます。
kubectl get / describe / logs / exec / apply / diff / explain の基本コマンド・出力形式(-o yaml / -o json / -o jsonpath)・alias k=kubectl の設定を扱います。
CKAD D3(Observability and Maintenance・15 %)の全項目と、試験中の高速操作テクニック(--dry-run=client -o yaml)を習得します。
シリーズ一覧
第1部:コンテナと Docker
- 第1回 コンテナ技術概念 + Docker 環境準備
- 第2回 Docker 基本操作
- 第3回 Dockerfile + マルチステージビルド + JDK 25 / Payara Micro イメージビルド
- 第4回 コンテナレジストリ + イメージタグ戦略 + Trivy スキャン
第2部:Kubernetes 基礎
- 第5回 Kubernetes の全体像 + kind で軽量 K8s ← 今ここ
- 第6回 kubectl 基本操作 + Observability・Debug
第3部:アプリリソース
- 第7回 Pod + Multi-container パターン
- 第8回 Service とネットワーキング
- 第9回 ストレージ(PVC + StatefulSet)+ PostgreSQL DB 追加
- 第10回 ConfigMap + Secret + ServiceAccount 基礎
- 第11回 Job + CronJob + DaemonSet
第4部:ワークロード戦略
- 第12回 Deployment + 3 Probe + Rolling Update + Probe デバッグ実践
- 第13回 Deployment 戦略補完(Blue/Green + Canary + Recreate)
- 第14回 ResourceQuota + LimitRange + Multi-tenant Namespace
