- 技術 💻
Kubernetes入門|主要リソースとYAMLの書き方、kubectl早見表
Kubernetes(クバネティス、略してK8s)とは、たくさんのコンテナを複数のサーバーにまたがって配置し、落ちたら自動で立て直し、負荷に合わせて数を増減させる「コンテナのオーケストレーション(まとめて管理する)」基盤です。「コンテナをこういう状態で3つ動かしておいて」とYAMLであるべき状態を宣言すると、Kubernetesがその状態を保ち続けます。
入門の段階でつまずきやすいのは、リソースの種類が多く、どれが何をするのかが見えにくいことです。この記事では、よく使う8つのリソースを1枚の表にまとめ、Docker Composeの書き方と対応づけて説明します。記事中のYAMLは、Kubernetes 1.36 のAPIスキーマで実際に検証ツールにかけて、正しく書けていることを確認しました。わざと間違えたYAMLで出るエラーも載せています。
Kubernetesの主要リソース早見表
| リソース | ひとことで言うと | Docker Composeでいうと |
|---|---|---|
| Pod | コンテナを動かす最小単位(1つ以上のコンテナの組) | 1つのコンテナ |
| ReplicaSet | 同じPodを指定した数だけ保つ | deploy.replicas |
| Deployment | ReplicaSetを管理し、ローリングアップデートやロールバックを行う | services: の1サービス |
| Service | Podの集まりに固定の名前とIPを与え、振り分ける | サービス名での名前解決 |
| Ingress | 外部からのHTTP(S)を、ホスト名やパスでServiceに振り分ける | 前段に置くNginxなどのリバースプロキシ |
| ConfigMap | 設定値をまとめて、Podに環境変数やファイルとして渡す | environment: / configs: |
| Secret | パスワードやトークンなど秘密の値を渡す | secrets: / .env |
| Namespace | クラスターの中を区切るフォルダのようなもの | プロジェクト名(-p) |
普段の開発で自分で書くのは、Deployment・Service・ConfigMap・Secret・Ingressの5つが中心です。PodとReplicaSetは、Deploymentが自動で作ります。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Kubernetes入門|主要リソースとYAMLの書き方、kubectl早見表」
なぜKubernetesが必要なのか
コンテナ1つ、サーバー1台なら docker run やDocker Composeで十分です。サービスが大きくなると、次のような仕事が増えていきます。
| 増えていく仕事 | Kubernetesがしてくれること |
|---|---|
| コンテナが落ちたら起動し直す | 自己修復:あるべき数に戻るまで自動で作り直す |
| どのサーバーに置くか決める | スケジューリング:CPU・メモリの空きを見て配置する |
| 新しいバージョンに入れ替える | ローリングアップデート:少しずつ入れ替え、止めずに更新する |
| 失敗したら戻す | ロールバック:1コマンドで前のバージョンに戻す |
| アクセスが増えたら増やす | スケール:数の変更、負荷に応じた自動増減(HPA) |
| 入れ替わるコンテナへ振り分ける | サービスディスカバリ:Serviceの名前で常に今のPodに届く |
「手順を実行する」のではなく「あるべき状態を宣言する」のがKubernetesの考え方です。Podを手で消しても、Deploymentに replicas: 3 と書いてあれば、すぐに3つ目が作り直されます。
クラスターの構成
┌──────────── クラスター ────────────┐
│ コントロールプレーン │
│ API Server / etcd / Scheduler / │ ← kubectl はここに命令する
│ Controller Manager │
├─────────────────────────────────────┤
│ ワーカーノード1 ワーカーノード2 │
│ kubelet kubelet │
│ [Pod][Pod] [Pod] │ ← コンテナが実際に動く
└─────────────────────────────────────┘
| 部品 | 役割 |
|---|---|
| API Server | すべての操作の窓口。kubectl もここに話しかける |
| etcd | クラスターの状態(あるべき状態)を保存するデータベース |
| Scheduler | 新しいPodをどのノードに置くか決める |
| Controller Manager | 「あるべき状態」と「今の状態」の差を埋め続ける |
| kubelet | 各ノードで、指示されたPodを実際に起動・監視する |
マネージドサービス(EKS・GKE・AKS)では、コントロールプレーンの運用はクラウド側が担当し、利用者はワーカーノードとアプリに集中できます。
Docker Composeとの対応
Docker Composeを使ったことがあれば、次の対応で理解が早くなります。
# compose.yaml
services:
web:
image: nginx:1.30
ports:
- "8080:80"
environment:
APP_MODE: production
deploy:
replicas: 3
| Docker Compose | Kubernetes | 補足 |
|---|---|---|
services.web |
Deployment web + Service web |
Kubernetesでは「動かす」と「つなぐ」が別のリソース |
image |
spec.template.spec.containers[].image |
同じ |
ports: "8080:80" |
Service の port / targetPort、外部公開は Ingress や type: LoadBalancer |
|
environment |
env / ConfigMap |
|
.env、secrets |
Secret | |
deploy.replicas |
spec.replicas |
|
healthcheck |
livenessProbe / readinessProbe |
目的別に分かれている |
depends_on |
直接の対応なし | readinessProbeやinitContainersで「準備ができるまで待つ」を表す |
volumes(名前付き) |
PersistentVolumeClaim | |
docker compose up -d |
kubectl apply -f . |
|
docker compose logs -f web |
kubectl logs -f deploy/web |
|
docker compose exec web sh |
kubectl exec -it deploy/web -- sh |
depends_on がない点が大きな違いです。Kubernetesでは、アプリ自身が「接続先がまだ準備中なら待って再試行する」ように作り、準備が整ったかどうかはreadinessProbeで伝えます。
YAMLの例:Deployment+Service
nginxを3つ動かし、Service web で振り分ける最小構成に、プローブ・リソース指定・ConfigMap/Secretの読み込みを加えた例です。
# app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web # ① このラベルのPodを管理する
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web # ② ①と一致させる
spec:
containers:
- name: web
image: nginx:1.30
ports:
- containerPort: 80
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: web-config
key: APP_MODE
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: web-secret
key: DB_PASSWORD
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP
selector:
app: web # ③ ②のラベルを持つPodに振り分ける
ports:
- port: 80 # Serviceが受けるポート
targetPort: 80 # Podのコンテナのポート
# config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
APP_MODE: production
---
apiVersion: v1
kind: Secret
metadata:
name: web-secret
type: Opaque
stringData:
DB_PASSWORD: change-me
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
①②③の3か所のラベルがつながっていることが、Kubernetesの配線そのものです。
| 書く場所 | 役割 |
|---|---|
① spec.selector.matchLabels |
Deploymentが「自分のPod」と見なす条件 |
② spec.template.metadata.labels |
作られるPodに付くラベル |
③ Service の spec.selector |
Serviceが転送先にするPodの条件 |
検証ツールにかけた結果
Pythonの kubernetes-validate(KubernetesのOpenAPI定義から作られたJSONスキーマで検証するツール)で、上の2ファイルを確認しました。
$ pip install kubernetes-validate
$ kubernetes-validate --strict app.yaml config.yaml
INFO app.yaml passed for resource deployment/web against version 1.36
INFO app.yaml passed for resource service/web against version 1.36
INFO config.yaml passed for resource configmap/web-config against version 1.36
INFO config.yaml passed for resource secret/web-secret against version 1.36
INFO config.yaml passed for resource ingress/web against version 1.36
よくある書き間違いを2つ入れると、次のように検出されました。
# replicas を replica と書いた(--strict なしでは通ってしまう)
ERROR ... spec: Additional properties are not allowed ('replica' was unexpected)
# containerPort を "80"(文字列)と書いた
ERROR ... spec.template.spec.containers.0.ports.0.containerPort: '80' is not of type 'integer'
--strict を付けないと、replica のようなつづりの間違いは「知らない項目」として見逃され、検証を通過しました。この場合、Kubernetesは初期値の1台で動かします。検証には --strict を付けるのがおすすめです。
一方、②のラベルを app: webx に変えて①と食い違わせたYAMLは、スキーマ検証を通過しました。スキーマは「型と項目名」しか見ないためです。公式ドキュメントでは、selectorとテンプレートのラベルが一致しないDeploymentはAPIサーバーが受け付けない仕様になっています。クラスターがあれば kubectl apply --dry-run=server -f app.yaml で、APIサーバーのチェックまで事前に確認できます。
kubectlの基本コマンド早見表
| やりたいこと | コマンド |
|---|---|
| YAMLを反映する(作成・更新) | kubectl apply -f app.yaml(フォルダなら -f k8s/) |
| 一覧を見る | kubectl get pods / kubectl get deploy,svc |
| もっと詳しく一覧 | kubectl get pods -o wide |
| 全Namespaceで見る | kubectl get pods -A |
| 詳細とイベントを見る | kubectl describe pod <Pod名> |
| ログを見る | kubectl logs -f deploy/web(前回落ちたコンテナは --previous) |
| コンテナに入る | kubectl exec -it deploy/web -- sh |
| 手元のPCから接続する | kubectl port-forward svc/web 8080:80 |
| 数を変える | kubectl scale deploy/web --replicas=5 |
| イメージを更新する | kubectl set image deploy/web web=nginx:1.31 |
| 更新の進み具合 | kubectl rollout status deploy/web |
| 更新の履歴 / 戻す | kubectl rollout history deploy/web / kubectl rollout undo deploy/web |
| 全Podを順に再起動 | kubectl rollout restart deploy/web |
| 削除する | kubectl delete -f app.yaml |
| 反映前の差分を見る | kubectl diff -f app.yaml |
| 項目の説明を見る | kubectl explain deployment.spec.strategy |
| 使うNamespaceを切り替える | kubectl config set-context --current --namespace=dev |
| 最近のイベント | kubectl get events --sort-by=.lastTimestamp |
困ったらまず kubectl describe の一番下の Events を見ます。イメージが取得できない、メモリ不足で配置できない、プローブが失敗している、といった理由がここに出ます。
Podの状態とよくある原因
| STATUS | 意味 | よくある原因 |
|---|---|---|
Pending |
配置先のノードが決まらない | requestsが大きすぎる、ノードの空き不足 |
ContainerCreating |
起動準備中 | イメージの取得中、Secret/ConfigMapの読み込み待ち |
ImagePullBackOff / ErrImagePull |
イメージを取得できない | イメージ名・タグの誤り、非公開レジストリの認証 |
CrashLoopBackOff |
起動してすぐ終了を繰り返す | アプリのエラー、設定不足。kubectl logs --previous で確認 |
OOMKilled(Last State) |
メモリ上限を超えて強制終了 | limits.memory が小さい、メモリリーク |
Running だが READY 0/1 |
readinessProbeが通っていない | ヘルスチェックのパスやポートの誤り |
ローリングアップデート
Deploymentのイメージを変えると、新しいPodを少しずつ増やし、前のバージョンのPodを少しずつ減らして入れ替えます。
| 設定 | 意味 | 初期値 |
|---|---|---|
maxSurge |
更新中に replicas を超えて作ってよい数 |
25% |
maxUnavailable |
更新中に使えなくなってよい数 | 25% |
上のYAMLでは maxSurge: 1、maxUnavailable: 0 にしています。「1つ新しいPodを作り、readinessProbeが通ってから前のPodを1つ消す」を繰り返すので、常に3つ以上が応答できる状態を保ちます。
kubectl set image deploy/web web=nginx:1.31
kubectl rollout status deploy/web # 完了まで待って結果を表示
kubectl rollout undo deploy/web # 問題があれば1つ前に戻す
readinessProbeがないと、起動しただけでまだ準備ができていないPodにもアクセスが振り分けられます。ローリングアップデートを止めずに行うには、readinessProbeが重要です。
プローブ:liveness・readiness・startup
| プローブ | 確認すること | 失敗したとき |
|---|---|---|
| readinessProbe | リクエストを受けられるか | Serviceの振り分け先から外す(再起動はしない) |
| livenessProbe | 生きているか(固まっていないか) | コンテナを再起動する |
| startupProbe | 起動が完了したか | 成功するまで liveness/readiness を始めない。起動の遅いアプリ向け |
| 確認の方法 | 書き方 |
|---|---|
| HTTP | httpGet: {path: /healthz, port: 8080}(200〜399で成功) |
| TCP | tcpSocket: {port: 5432} |
| コマンド | exec: {command: ["cat", "/tmp/ready"]} |
| gRPC | grpc: {port: 9090} |
livenessProbeにDBへの接続確認を入れないのがポイントです。DBが一時的に止まると全Podが再起動を繰り返し、DBが戻っても復旧に時間がかかります。livenessは「プロセス自身が応答できるか」だけ、外部への依存はreadinessで見ると役割がはっきりします。
requestsとlimits
| 項目 | 意味 | 使われ方 |
|---|---|---|
requests |
最低限確保したい量 | Schedulerが配置先を決める基準。空きが足りないノードには置かれない |
limits |
使ってよい上限 | CPUは超えると抑えられる(遅くなる)、メモリは超えると強制終了(OOMKilled) |
| 単位 | 意味 |
|---|---|
cpu: 100m |
0.1コア(1000m = 1コア) |
memory: 128Mi |
128メビバイト(Mi・Gi は1024単位、M・G は1000単位) |
requestsを書かないと、ノードに詰め込みすぎて性能が不安定になることがあります。まずは実際の使用量(kubectl top pods、metrics-serverが必要)を見て、requestsを平常時の使用量、limits.memoryを余裕を持った上限に設定するのが始めやすい方法です。
Namespaceで区切る
kubectl create namespace dev
kubectl apply -f app.yaml -n dev
kubectl get pods -n dev
同じNamespaceの中なら、Service web には http://web で届きます。別のNamespaceからは http://web.dev.svc.cluster.local(サービス名.Namespace名.svc.cluster.local)で指定します。チームや環境(dev/stg)ごとに分け、権限(RBAC)やリソースの上限(ResourceQuota)をNamespace単位でかけられます。
ConfigMapとSecretの注意点
- Secretは初期状態では暗号化ではなくBase64で保存されています。
kubectl get secret web-secret -o yamlで見える値は、誰でも元に戻せます - SecretのYAMLをそのままGitにコミットしないのが基本です。クラウドのシークレット管理サービスと連携する仕組みや、暗号化してから保存するツールを組み合わせます
- 環境変数として読み込んだ値は、ConfigMapを変えてもPodを作り直すまで反映されません。
kubectl rollout restart deploy/webで入れ替えます
Ingressと、これからのGateway API
Ingressは、1つの入口(ロードバランサー)で、ホスト名やパスごとに複数のServiceへ振り分けるリソースです。Ingressを動かすには、別途Ingressコントローラーのインストールが必要です。
2026年時点では、Ingressの後継として設計された Gateway API(HTTPRoute など)が標準的な選択肢になっています。Kubernetesコミュニティが提供していたコントローラー「ingress-nginx」は2026年3月にメンテナンスを終えており、新しく構築する場合は、Gateway APIに対応したコントローラーや、クラウドが提供するロードバランサー連携を選ぶとよいでしょう。Ingressリソース自体は引き続き利用できます。
ローカルで試す方法
| ツール | 特徴 | 始め方 |
|---|---|---|
| kind | Dockerコンテナをノードとして使う。起動が速く、CIでもよく使われる | kind create cluster |
| minikube | 入門向け。minikube dashboard などの便利機能が多い |
minikube start |
| Docker Desktop | 設定画面でKubernetesを有効にするだけ | Settings → Kubernetes |
| k3d / k3s | 軽量なKubernetes(k3s)を使う | k3d cluster create |
# kind の例
kind create cluster --name dev
kubectl apply -f config.yaml -f app.yaml
kubectl get pods
kubectl port-forward svc/web 8080:80 # ブラウザで http://localhost:8080
kind delete cluster --name dev
まずkindかminikubeで、この記事のYAMLを apply → Podを1つ削除して自動で戻ることを確認 → イメージを変えてローリングアップデート、の順に触ってみると、Kubernetesの動きが体でわかります。
マネージドKubernetes:EKS・GKE・AKS
| サービス | 提供元 | 特徴 |
|---|---|---|
| Amazon EKS | AWS | IAMやALBなどAWSサービスとの連携。ノード管理を任せるAuto Modeもある |
| Google Kubernetes Engine(GKE) | Google Cloud | Kubernetesを開発したGoogleのサービス。ノード管理まで任せるAutopilotモード |
| Azure Kubernetes Service(AKS) | Microsoft Azure | Entra IDとの連携。構成を自動化するAKS Automatic |
どれもKubernetesのAPIは共通なので、この記事のYAMLとkubectlの知識はそのまま使えます。違いが出るのは、ロードバランサー・ストレージ・認証など、クラウドの機能とつなぐ部分です。
Kubernetesは約4か月ごとに新しいマイナーバージョンが出て、各バージョンのサポート期間は約1年です(2026年9月時点の最新は1.37)。マネージドサービスでも定期的なバージョンアップが必要になるため、運用の計画に含めておきます。
Kubernetesを使うかどうかの判断表
| 状況 | おすすめ |
|---|---|
| サーバー1台、コンテナ数個 | Docker Compose |
| 数台規模、とにかく手間を減らしたい | クラウドのコンテナ実行サービス(Amazon ECS、Cloud Run、Azure Container Appsなど) |
| 多数のサービス、チームが複数、細かく制御したい | Kubernetes(マネージド) |
| 学習・検証 | kind / minikube |
Kubernetesは強力な分、覚えることも多い仕組みです。規模と必要な機能に合わせて選ぶのが、無理のない進め方です。
よくある質問
Q. DockerとKubernetesの違いは何ですか? A. Dockerはコンテナを作って動かすための道具、Kubernetesはたくさんのコンテナを複数のサーバーで管理するための基盤です。KubernetesはDockerなどで作ったコンテナイメージを受け取って動かします。
Q. PodではなくDeploymentを書くのはなぜですか? A. Podを直接作ると、落ちたときやノードが止まったときに作り直されません。Deploymentにすると、指定した数を保ち、更新とロールバックもできるためです。
Q. Serviceに接続できません。どこを見ればいいですか?
A. kubectl get endpoints web(または kubectl get endpointslices)で、振り分け先のPodが登録されているかを確認します。空なら、ServiceのselectorとPodのラベルが一致していないか、readinessProbeが通っていないことが多いです。
Q. 入門にはどのくらいのPCスペックが必要ですか? A. kindやminikubeで小さなアプリを動かすなら、メモリ8GB程度から試せます。Docker Desktopなどに割り当てるメモリを増やしておくと安定します。
まとめ
- Kubernetesは、あるべき状態をYAMLで宣言し、その状態を自動で保つコンテナ管理基盤
- 自分で書くのは Deployment・Service・ConfigMap・Secret・Ingress が中心
- selectorとラベルの一致が配線そのもの。検証ツールは
--strictを付けて使う - 困ったら
kubectl describeのEvents とkubectl logs --previous - readinessは振り分けの判断、livenessは再起動の判断。役割を分けて設定する
- requestsは配置の基準、limitsは上限。メモリ上限を超えるとOOMKilled
- まずは kind・minikube で、自己修復とローリングアップデートを体験する
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Kubernetes入門|主要リソースとYAMLの書き方、kubectl早見表」
株式会社RJCでは、コンテナからKubernetesへと広がるインフラの技術も、手を動かしながら仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。