k8sはKubernetesの略記で、先頭のkと末尾のsの間にある8文字を数字に置き換えた書き方です。座学だけで全体像をつかもうとすると、Pod・Deployment・Serviceといった抽象の層が積み上がって手が止まりがちになります。本記事は、手元のマシンにkindで使い捨てのクラスタを作り、コンテナを1つ起動してブラウザから疎通し、壊して直して撤収するまでを、そのまま実行できるコマンドで通す内容です。仕組みや読み方といった概念の整理はKubernetes(クバネティス)とはで扱っているため、ここでは動かす側に振り切って進めます。
まとめ:k8sをローカルで動かす最短手順と学習の進め方
最短手順は3つです。Docker環境を用意し、kindでクラスタを1つ作り、DeploymentとServiceの2つのマニフェストを適用します。kind create cluster の1行でコントロールプレーンが立ち上がるため、クラウドの課金も専用マシンも不要です。所要時間は初回のイメージ取得を含めて10分ほどで、片付けは kind delete cluster の1行で済みます。
学習の進め方としては、リソースの種類を暗記するのではなく「壊して直す」を先に通してください。Podを手で削除してDeploymentが作り直す挙動、kubectl describe のEventsに出る失敗理由、kubectl logs と kubectl port-forward の3点を体で覚えると、以降の設定項目の意味が腹落ちします。逆に、業務利用でいきなり自前クラスタを構える判断は勧めません。ノード管理まで自社で背負う構成が見合うのは常時稼働のワークロードと運用担当がそろう場合に限られ、条件は最終章で示します。
k8sという略記が指す範囲と、ローカル検証環境の3つの選択肢
環境構築で迷う原因は、k8sという言葉が仕様一式と手元で動く実装の両方を指す点にあります。最初に何を入れるのかを切り分けます。
k8sとKubernetesの呼び分けと、kubectlが操作している対象
k8sはKubernetesの綴りを短縮した表記で、指しているものは同じです。実際に触るのは、クラスタ内のAPIサーバーと、そこへ命令を送るコマンドラインツールのkubectlの2つになります。kubectlはYAMLで書いた「あるべき状態」をAPIサーバーへ登録するだけで、コンテナを起こす仕事は各ノードのkubeletが引き受ける仕組みです。この分業を頭に置くと、コマンドが即座に返ってきたのにPodがまだ起動していない、という初回のつまずきを読み解けます。サブコマンドの一覧と書式はkubectlのクイックリファレンスにまとまっています。
kind・minikube・Docker Desktopを検証環境として比べる基準
ローカルで動かす選択肢は主に3つあり、選定基準は「マルチノードを再現できるか」と「作り直しの速さ」です。kindはDockerコンテナ自体をノードとして扱う方式で、control-planeとworkerを並べた構成をYAML数行で再現でき、作成と破棄も速く済みます。minikubeは複数のドライバに対応し、アドオンでIngressやダッシュボードを足せる点が便利です。Docker Desktopの設定画面から有効化する方式は導入が最も簡単ですが、単一ノード固定でノード障害の挙動を試せません。
| 環境 | ノード構成 | 向く用途 |
|---|---|---|
| kind | 複数ノード可 | 検証と使い捨て |
| minikube | 単一が基本 | アドオン込みの学習 |
| Docker Desktop | 単一固定 | 最短の初回体験 |
| k3s | 複数ノード可 | 省リソースの常設 |
本記事はkindで進めます。手順の差はクラスタ作成の1コマンドだけなので、minikubeを選ぶ場合はminikubeの開始手順に沿って minikube start に読み替えれば、以降のマニフェストはそのまま通ります。省リソースの常設環境を作りたい場合はk3sとKubernetesの違いもあわせて検討してください。
事前に必要なDocker環境と、kubectlのバージョン差の許容範囲
kindはノードをDockerコンテナとして起動するため、先にDocker EngineかDocker Desktopが動いている必要があります。導入がまだならDockerのインストール手順を済ませてください。メモリは4GB程度を割り当てておくと、後半でレプリカを増やしても詰まりません。kubectlとクラスタの版のずれは、公式のサポート範囲がマイナー1つ分までなので、クラスタが1.37ならkubectlは1.36から1.38に収めます。
kubectl version --client
docker version --format '{{.Server.Version}}'
kindでクラスタを作る手順とマルチノード構成を書くconfigの記述
ここから実際に作ります。kindはバイナリ1つで動くため、インストールから最初のノード表示までは数分で到達します。
kindのインストールとクラスタ1台を作るまでの実行コマンド
導入方法はパッケージマネージャ、Goツールチェーン、バイナリ直接取得の3通りです。kindのクイックスタートが案内する現行版はv0.33.0系で、Homebrewを使うなら1行で済みます。
brew install kind
kind version
# Go を使う場合
go install sigs.k8s.io/[email protected]
入ったらクラスタを作ります。名前を付けておくと複数クラスタを並行して持てるため、後片付けの取り違えを防げます。
kind create cluster --name k8s-lab
kubectl cluster-info --context kind-k8s-lab
kubectl get nodes
ノードが Ready と表示されれば成功です。初回はノードイメージの取得に時間がかかりますが、2回目以降はキャッシュが効いて1分前後で立ち上がります。
control-planeとworkerを並べるkind configの書き方
単一ノードでは、Podがノードをまたいで配置される様子やノード停止時の挙動を観察できません。kindはクラスタ定義をYAMLで受け取れるので、workerを2台足した3ノード構成にします。
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
このファイルを kind-config.yaml として保存し、作成時に渡します。既存クラスタがある場合は先に削除してから実行してください。
kind delete cluster --name k8s-lab
kind create cluster --name k8s-lab --config kind-config.yaml
kubectl get nodes -o wide
3行のノードが並べば準備完了です。ノード間の通信経路やCNIの選び分けまで踏み込む段階になったら、Kubernetesネットワーク設計で扱う内容が次の教材になります。
ローカルでビルドしたイメージをkindクラスタへ持ち込む方法
自作アプリを試すとき、手元でビルドしたイメージはレジストリに無いためPodがImagePullBackOffで止まります。kindにはノードのイメージストアへ直接投入する仕組みがあり、レジストリを立てずに検証を回せます。
docker build -t my-app:dev .
kind load docker-image my-app:dev --name k8s-lab
投入したイメージを使う場合は、マニフェスト側で imagePullPolicy: IfNotPresent を指定します。既定の挙動ではタグによって取得しに行くため、外部へ問い合わせて失敗するのを避ける指定です。
Deploymentを適用してPodを起動しkubectlで状態を読み取る
クラスタができたら、最初に置くリソースはDeploymentです。Podを直接作らずDeploymentを経由する理由も、ここで実際の挙動から確認します。
Deploymentのマニフェストに書く4つの必須フィールド
Deploymentは「このイメージのPodを何個保て」という宣言で、レプリカ数の維持と更新の段取りを引き受けます。公式のDeployment仕様にある必須要素は、apiVersion、kind、名前などのmetadata、望ましい状態を書くspecの4つです。次の内容を deployment.yaml として保存します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
初学者がつまずくのは selector.matchLabels と template.metadata.labels の対応です。前者は「どのPodを自分の管理下とみなすか」の条件、後者は「作るPodに貼るラベル」で、両者が一致していないと作成時に弾かれます。
applyでの適用と、ロールアウト状況を安全に確認するコマンド
適用はkubectl applyで行います。同じファイルを何度流しても差分だけが反映されるため、編集と再適用を繰り返す学習スタイルに向いています。
kubectl apply -f deployment.yaml
kubectl rollout status deployment/web
kubectl get pods -o wide
get pods の出力では、STATUSがRunning、READYが1/1になっているかを見ます。3つのPodが別々のノードへ散っていれば、スケジューラが配置を決めた結果を目で確認できる状態です。イメージのタグを1.28へ書き換えて再適用すると、ローリング更新で1つずつ入れ替わる様子も追えます。
Podをわざと削除してDeploymentの自己修復挙動を観察する
Deploymentを挟む価値は、壊したときに現れます。Podを1つ手で消しても、宣言したレプリカ数を保とうとして即座に新しいPodが作られます。
kubectl get pods
kubectl delete pod <対象のPod名>
kubectl get pods --watch
削除したPodがTerminatingに移り、別名のPodがContainerCreatingを経てRunningへ変わるまでを追ってください。復旧が自動で走るため、Podの名前を前提にした運用は成り立ちません。名前ではなくラベル経由で扱う設計の理由が、この一連で分かります。
Serviceを作って疎通させport-forwardでブラウザから確認する
Podは作り直しのたびにIPが変わるため、宛先として直接指すことができません。前段に置く安定した宛先がServiceです。
ClusterIPとNodePortの違いと、typeを省略したときの既定
Serviceの公式ドキュメントでは、公開方法としてClusterIP・NodePort・LoadBalancer・ExternalNameの4種類が定義されています。typeを省略した場合はClusterIPが選ばれ、クラスタ内部からのみ到達できる仮想IPが割り当てられます。NodePortは各ノードのポートを開いて外部から入れる方式で、割り当ての既定範囲は30000番台から32767番までです。ローカル検証ではClusterIPのまま作り、外から見るときは転送でつなぐ進め方が扱いやすくなります。
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
port-forwardでローカルの画面から到達を確かめる手順
Serviceを適用したら、手元のポートをクラスタ内のServiceへ転送します。転送はコマンドを実行している間だけ有効で、停止すれば閉じるため、検証中の一時的な穴として安全に使えます。
kubectl apply -f service.yaml
kubectl get svc web
kubectl port-forward service/web 8080:80
ブラウザで localhost:8080 を開き、nginxの初期画面が出れば疎通は成立です。応答が返らないときは、ServiceのselectorとPodのラベルが一致しているかを最初に疑ってください。kubectl get endpoints web の出力が空なら、転送先のPodを1つも掴めていない状態を示します。
なおport-forwardは検証専用で、常時公開には使いません。実運用ではIngressやLoadBalancerで入口を作り、TLS終端と経路制御を前段へ置く構成になります。
ConfigMapとリソース要求・上限を設定してPodの挙動を安定させる
起動と疎通は通りました。次は設定値を外に出す方法と、コンテナへ配る資源量の指定を足します。
ConfigMapで設定値を外出ししてPodへ環境変数として渡す
接続先やログレベルをイメージへ焼き込むと、環境ごとにビルドし直す羽目になります。ConfigMapの仕様は、機密でない設定をキーと値の組でクラスタに置き、Podから環境変数やファイルとして読み込む仕組みです。上限は1MiBまでで、パスワードやトークンはConfigMapではなくSecretへ分けます。
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
APP_ENV: staging
LOG_LEVEL: debug
Deployment側ではenvFromでまとめて読み込むか、valueFromで個別に指定します。反映のされ方には差があり、環境変数として渡した値はPodを作り直すまで更新されません。設定を書き換えたらkubectl rollout restartで入れ替える運用が要ります。
containers:
- name: nginx
image: nginx:1.27
envFrom:
- configMapRef:
name: web-config
requestsとlimitsの意味の違いと、指定しない場合の危険
資源指定は2種類あり、混同すると障害の形が読めなくなります。公式の資源管理ドキュメントによれば、requestsはスケジューラが配置先を決めるときに確保する最低量、limitsは実行中に超えられない上限です。CPUのlimitsを超えた場合は処理が絞られるだけですが、メモリのlimitsを超えたコンテナは強制終了され、OOMKilledとして記録されます。無指定のPodは上限なしで動くため、1つのコンテナが周囲のPodを巻き込む事故が起こり得ます。
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
cpuの100mは1コアの10分の1を指す表記です。検証段階では小さめのrequestsから始め、kubectl top pod の実測値を見て寄せていく進め方が無駄がありません。
状態を持つアプリを載せる前に確認する保存領域の扱い方と選び方
Pod内に書いたファイルは、Podが作り直された時点で消えます。データベースのように状態を持つものを載せるなら、PersistentVolumeとPersistentVolumeClaimで保存領域を切り出す設計が前提です。kindは既定のStorageClassを備えるためPVCの動作確認はローカルでも試せますが、実運用では性能と冗長性の検討が別途要ります。設計の勘所はKubernetes永続化ストレージ入門にまとめています。
動かないPodを切り分けるdescribe・logs・debugの使い分け
手を動かすと必ず詰まります。詰まった場所を特定する順路を先に決めておくと、調査が短時間で終わります。
STATUS別に読み解く代表的な失敗パターンと確認先の調査順序
調査はkubectl get podsのSTATUS欄から始めます。表示される文字列がそのまま原因の分類になっており、次に見る場所も決まります。
| STATUS | 主な原因 | 次に見る場所 |
|---|---|---|
| Pending | 資源不足や配置不可 | describeのEvents |
| ImagePullBackOff | イメージ名や権限 | タグとレジストリ |
| CrashLoopBackOff | 起動直後の異常終了 | logsの–previous |
| OOMKilled | メモリ上限の超過 | limitsの設定値 |
Pendingが続くのは、Podが作られたのに置き場所の決まらない状態です。requestsを大きく取りすぎていないか、ノードの空きが足りているかを順に確かめます。
describeのEventsとlogsの–previousで原因を絞る
Podのデバッグ手順が最初に案内するのがkubectl describeです。出力の末尾にあるEventsに、スケジューリング結果やイメージ取得の失敗理由が時系列で並びます。アプリ自体が落ちているならログを見ますが、再起動を繰り返すPodでは現在のコンテナのログが空のことが多く、直前の実行分を指定して初めて例外が読めます。
kubectl describe pod <Pod名>
kubectl logs <Pod名> --previous
kubectl logs -l app=web --tail=50
3行目のようにラベルで束ねてログを引くと、レプリカが複数あっても横断して追えます。
execとdebugでコンテナの中身を確かめる2つの実行方法
ログに出ない事象は、コンテナの中に入って確かめます。シェルが入っているイメージならkubectl execで足りますが、ツールを削ぎ落とした軽量イメージでは実行できません。その場合はエフェメラルコンテナを差し込むkubectl debugで、調査用イメージを同じPodへ相乗りさせます。
kubectl exec -it <Pod名> -- sh
kubectl debug -it <Pod名> --image=busybox:1.28 --target=nginx
--targetで指定したコンテナとプロセス名前空間を共有するため、相手のプロセス一覧やネットワークの状態を覗けます。調査用コンテナはPodの再作成で消えるので、後始末は不要です。
クラスタの撤収と、バージョン確認・EOLに合わせた上げ方の実務
検証が終わったら片付けます。あわせて、運用で避けて通れない版の管理も確認方法だけ押さえます。
使い捨てクラスタの削除と、残りがちなイメージの掃除と確認手順
kindのクラスタはコンテナとして存在するため、削除も1行です。複数作った場合は一覧で確認してから消します。
kind get clusters
kind delete cluster --name k8s-lab
docker system df
クラスタを消してもノードイメージやビルドしたイメージはDocker側に残り、数GB単位を占めます。ディスクを空けるときはdocker system pruneで不要分を落としてください。
現行バージョンとEOLを確認して上げる時期を決めるための運用基準
Kubernetesはマイナー版の更新が速く、放置するとサポート切れの版に取り残されます。公式のリリース一覧によれば、最新版は1.37.0で2026年8月26日に公開され、サポート終了日は2027年10月28日と告知されています(2026年9月時点)。パッチリリースの方針では、各系列にパッチが提供される期間はおよそ14か月、通常の配信間隔は月次と定められています。過去分を含む詳細はリポジトリのリリース一覧でも追えます。
kubectl version
kubectl get nodes -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
上げ方は飛び級ができず、1つずつマイナー版を進める手順です。新しい系列は年に複数回出るため、上げる作業を年1度も回さない体制ではいずれサポート外へ落ちます。版の確認方法とEOL一覧はKubernetesの最新バージョンとアップグレード手順で整理しています。
受託開発でk8sを採用する条件と、採用を見送る場面の判断基準
ここからは、手順ではなく判断の話です。ローカルで動いたからといって、案件へそのまま持ち込めるとは限りません。私たちが実際の開発案件で線を引いている条件を示します。
k8sを採用してよいと判断する3つの条件と各案件での確認基準
採用してよいのは次の3条件がそろう場合です。第一に、コンテナ化されたサービスが5つ以上あり、相互に依存して動くこと。単一のWebアプリと単一のデータベースであれば、コンテナを直接動かすマネージドサービスのほうが構成も費用も軽く済みます。第二に、平日夜間や月末など負荷の山谷があり、自動での増減が費用に効くこと。常時同じ負荷ならスケール機構の恩恵は薄くなります。第三に、YAMLの管理と版上げを担当できる人員が社内か委託先に確保できること。この3つ目が抜けたまま導入した現場では、作った本人の異動後に誰も触れないクラスタが残ります。
自前構築を避けてマネージドへ寄せるべき場面と運用体制の判断基準
コントロールプレーンを自分で建てる構成は、学習目的を除いて勧めません。etcdのバックアップ、証明書の更新、コンポーネントの版上げが継続的に発生し、差別化に寄与しない作業だからです。クラウド上で動かすなら、コントロールプレーンを引き受けるマネージドサービスを選び、ノード管理も自動化された方式へ寄せます。選定の観点はGKEのAutopilotとStandardの違いで比較していますが、他社クラウドでも考え方は共通です。要員が2名を下回るなら、オーケストレーション自体を外してサーバーレス寄りへ切り替える判断も現実的でしょう。
設計から運用までを外部と組んで進める場合の役割分担と合意事項
設計と初期構築だけを外部に任せ、その後の運用を社内で回す分担は、引き継ぎの粒度を決めておかないと形骸化します。少なくとも、マニフェストの置き場とレビュー体制、版上げの実施時期、障害時の一次切り分け範囲の3点を着手前に合意してください。当社は設計・構築から運用移管まで対応しており、構成の相談はインフラ構築(AWS・Google Cloud・Azure)で受け付けています。
よくある質問
k8sとKubernetesは何が違うのですか?
指すものは同じで、k8sはKubernetesの短縮表記です。KとSの間にある8文字を数字の8で置き換えた書き方で、公式サイトやリリースノートでも併記されています。
k8sの学習にクラウドの費用はかかりますか?
本記事の手順どおりkindやminikubeを使う限り、費用はかかりません。手元のDocker上にクラスタを作るため、課金対象のクラウド資源を使わずに一通りの操作を試せます。
Docker DesktopのKubernetesでも同じ手順を試せますか?
Deployment・Service・ConfigMapの適用はそのまま通ります。ただし単一ノード固定のため、ノードをまたぐ配置やノード停止時の挙動は再現できません。マルチノードの動きまで確認したい場合はkindを選んでください。
Podが起動しないときは最初に何を見ればよいですか?
kubectl get podsのSTATUSを確認し、続けてkubectl describe podのEvents欄を読みます。イメージ取得の失敗、資源不足による配置待ち、起動直後の異常終了は、いずれもここに理由が記録される仕組みです。アプリ側の例外を追う場合はログを直前の実行分まで含めて確認します。
ローカルで動いた構成をそのまま本番へ持ち込めますか?
マニフェストの大枠は流用できますが、そのままの移行は勧めません。永続化の方式、外部公開の入口、監視とログの経路、資源の指定値は本番向けに設計し直す必要があります。
関連記事
- Kubernetes(クバネティス)とは?仕組み・Dockerとの違い・読み方をわかりやすく解説
- コンテナオーケストレーションとは?Kubernetesの役割と自社に必要かの判断を解説
- k3sとは?読み方・Kubernetes(k8s)との違いとインストール方法
- Kubernetesネットワーク設計|Service・Ingress・Pod間通信とCNI選定の実装判断
- Kubernetes永続化ストレージ入門|PV・PVC・StorageClassの設計と運用の落とし穴
- Kubernetes監視・モニタリングの設計|メトリクス・ログ・アラート閾値の実装判断
- Kubernetesの最新バージョンは1.37|確認方法・EOL一覧とアップグレード手順