kubectl

kubectl 完全ガイド — Kubernetes CLI リファレンス

本ドキュメントは SRE エンジニア向けの kubectl 包括的リファレンスです。基本操作から高度な運用ワークフローまで、実践的なコマンド例とともに解説します。


目次

  1. kubectl とは
  2. インストールと設定
  3. リソース管理の基本
  4. Pod の操作
  5. Deployment とロールアウト
  6. Service とネットワーキング
  7. ConfigMap と Secret
  8. Namespace 管理
  9. Label とセレクタ
  10. RBAC 管理
  11. 高度なリソース操作
  12. デバッグとトラブルシューティング
  13. 出力フォーマット
  14. プラグインと拡張機能
  15. 生産性向上のヒント
  16. 運用ワークフロー

1. kubectl とは

1.1 概要

kubectl は Kubernetes クラスタを管理するための公式コマンドラインツール(CLI)です。Kubernetes API サーバーと通信し、クラスタ内のリソース(Pod、Service、Deployment など)の作成・参照・更新・削除(CRUD)を行います。

kubectl の基本的な動作フローは以下のとおりです。

ユーザー → kubectl コマンド → kubeconfig 読み込み → API サーバーへ REST リクエスト → レスポンス表示

1.2 kubectl のアーキテクチャ

kubectl は内部的に以下のステップでコマンドを処理します。

  1. コマンド解析: ユーザーが入力したコマンド・フラグ・引数を解析
  2. kubeconfig の読み込み: ~/.kube/config またはt KUBECONFIG 環境変数で指定されたファイルから接続情報を取得
  3. 認証・認可: kubeconfig に定義された認証情報(トークン、証明書など)を使用して API サーバーに認証
  4. API リクエスト: 適切な REST API エンドポイントに HTTP リクエストを送信
  5. レスポンス処理: API サーバーからのレスポンスを整形して表示

1.3 kubeconfig の構造

kubeconfig は YAML 形式のファイルで、以下の 3 つの主要要素で構成されます。

apiVersion: v1
kind: Config
preferences: {}

# 1. クラスタ情報: API サーバーの接続先
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRU...  # CA 証明書(Base64)
    server: https://k8s-api.example.com:6443    # API サーバー URL
  name: production-cluster

- cluster:
    certificate-authority-data: LS0tLS1CRU...
    server: https://k8s-staging.example.com:6443
  name: staging-cluster

# 2. ユーザー認証情報
users:
- name: admin-user
  user:
    client-certificate-data: LS0tLS1CRU...  # クライアント証明書(Base64)
    client-key-data: LS0tLS1CRU...           # クライアント秘密鍵(Base64)

- name: developer-user
  user:
    token: eyJhbGciOiJSUzI1NiIs...           # Bearer トークン

- name: oidc-user
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubectl-oidc-login
      args:
      - get-token
      - --oidc-issuer-url=https://accounts.example.com
      - --oidc-client-id=kubernetes

# 3. コンテキスト: クラスタとユーザーの組み合わせ
contexts:
- context:
    cluster: production-cluster
    user: admin-user
    namespace: default           # デフォルト Namespace
  name: prod-admin

- context:
    cluster: staging-cluster
    user: developer-user
    namespace: development
  name: staging-dev

# 現在のコンテキスト
current-context: prod-admin

1.4 コンテキスト管理

コンテキストは「どのクラスタに」「どのユーザーで」「どの Namespace に」接続するかを定義する設定単位です。

# 現在のコンテキストを表示
$ kubectl config current-context
prod-admin

# 利用可能なコンテキスト一覧を表示
$ kubectl config get-contexts
CURRENT   NAME          CLUSTER              AUTHINFO         NAMESPACE
*         prod-admin    production-cluster   admin-user       default
          staging-dev   staging-cluster      developer-user   development

# コンテキストを切り替え
$ kubectl config use-context staging-dev
Switched to context "staging-dev".

# コンテキストの詳細を表示
$ kubectl config view --minify
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://k8s-staging.example.com:6443
  name: staging-cluster
contexts:
- context:
    cluster: staging-cluster
    namespace: development
    user: developer-user
  name: staging-dev
current-context: staging-dev
kind: Config
preferences: {}
users:
- name: developer-user
  user:
    token: REDACTED

# 新しいコンテキストを作成
$ kubectl config set-context my-context \
    --cluster=production-cluster \
    --user=admin-user \
    --namespace=monitoring
Context "my-context" created.

# コンテキストのデフォルト Namespace を変更
$ kubectl config set-context --current --namespace=kube-system
Context "staging-dev" modified.

# コンテキストを削除
$ kubectl config delete-context my-context
deleted context my-context from /home/user/.kube/config

2. インストールと設定

2.1 インストール方法

macOS

# Homebrew を使用(推奨)
$ brew install kubectl

# バージョン確認
$ kubectl version --client
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3

# curl を使用して直接ダウンロード
$ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
$ chmod +x kubectl
$ sudo mv kubectl /usr/local/bin/

Linux

# apt(Debian/Ubuntu)
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
$ echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubectl

# yum(RHEL/CentOS)
$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
EOF
$ sudo yum install -y kubectl

# curl を使用して直接ダウンロード
$ 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/

Windows

# Chocolatey を使用
choco install kubernetes-cli

# winget を使用
winget install -e --id Kubernetes.kubectl

# curl を使用して直接ダウンロード
curl.exe -LO "https://dl.k8s.io/release/v1.30.2/bin/windows/amd64/kubectl.exe"

2.2 kubeconfig の設定

複数クラスタの管理

# KUBECONFIG 環境変数で複数の設定ファイルをマージ
$ export KUBECONFIG=~/.kube/config:~/.kube/config-staging:~/.kube/config-production

# マージされた設定を確認
$ kubectl config view
apiVersion: v1
kind: Config
clusters:
- cluster:
    server: https://k8s-prod.example.com:6443
  name: production
- cluster:
    server: https://k8s-staging.example.com:6443
  name: staging
- cluster:
    server: https://k8s-dev.example.com:6443
  name: development
contexts:
- context:
    cluster: production
    user: prod-admin
  name: prod
- context:
    cluster: staging
    user: staging-user
  name: staging
- context:
    cluster: development
    user: dev-user
  name: dev
current-context: prod
...

# マージした設定を 1 つのファイルに統合
$ kubectl config view --flatten > ~/.kube/config-merged
$ cp ~/.kube/config-merged ~/.kube/config

クラスタ情報の手動追加

# クラスタを追加
$ kubectl config set-cluster my-cluster \
    --server=https://k8s.example.com:6443 \
    --certificate-authority=/path/to/ca.crt
Cluster "my-cluster" set.

# ユーザー認証情報を追加(証明書ベース)
$ kubectl config set-credentials my-user \
    --client-certificate=/path/to/client.crt \
    --client-key=/path/to/client.key
User "my-user" set.

# ユーザー認証情報を追加(トークンベース)
$ kubectl config set-credentials token-user \
    --token=eyJhbGciOiJSUzI1NiIs...
User "token-user" set.

# コンテキストを作成
$ kubectl config set-context my-context \
    --cluster=my-cluster \
    --user=my-user \
    --namespace=default
Context "my-context" created.

2.3 シェル補完の設定

# Bash 補完
$ echo 'source <(kubectl completion bash)' >> ~/.bashrc
$ source ~/.bashrc

# エイリアスにも補完を有効化
$ echo 'alias k=kubectl' >> ~/.bashrc
$ echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc

# Zsh 補完
$ echo 'source <(kubectl completion zsh)' >> ~/.zshrc
# または autoload を使用
$ mkdir -p ~/.zsh/completion
$ kubectl completion zsh > ~/.zsh/completion/_kubectl
$ echo 'fpath=(~/.zsh/completion $fpath)' >> ~/.zshrc
$ echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
$ source ~/.zshrc

# Fish 補完
$ kubectl completion fish | source
# 永続化
$ kubectl completion fish > ~/.config/fish/completions/kubectl.fish

2.4 接続確認

# クラスタ情報を確認
$ kubectl cluster-info
Kubernetes control plane is running at https://k8s-api.example.com:6443
CoreDNS is running at https://k8s-api.example.com:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# API サーバーのバージョンを確認
$ kubectl version
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.1

# ノード一覧で接続を確認
$ kubectl get nodes
NAME                    STATUS   ROLES           AGE   VERSION
master-1                Ready    control-plane   90d   v1.30.1
worker-1                Ready    <none>          90d   v1.30.1
worker-2                Ready    <none>          90d   v1.30.1
worker-3                Ready    <none>          85d   v1.30.1

3. リソース管理の基本

3.1 リソースの取得 (get)

kubectl get は最も頻繁に使用されるコマンドで、クラスタ内のリソースの一覧を表示します。

# Pod の一覧を表示
$ kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k   1/1   Running   0          2h
nginx-deploy-6b7f675859-8kl9m   1/1   Running   0          2h
redis-master-0                   1/1   Running   0          5d

# 全 Namespace の Pod を表示
$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
default       nginx-deploy-6b7f675859-2xj4k             1/1     Running   0          2h
kube-system   coredns-5dd5756b68-4xz7j                  1/1     Running   0          90d
kube-system   etcd-master-1                              1/1     Running   0          90d
kube-system   kube-apiserver-master-1                    1/1     Running   0          90d
monitoring    prometheus-server-0                        2/2     Running   0          30d

# 短縮形 -A も使用可能
$ kubectl get pods -A

# 複数のリソースタイプを同時に表示
$ kubectl get pods,services,deployments
NAME                                      READY   STATUS    RESTARTS   AGE
pod/nginx-deploy-6b7f675859-2xj4k        1/1     Running   0          2h
pod/nginx-deploy-6b7f675859-8kl9m        1/1     Running   0          2h

NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
service/kubernetes      ClusterIP      10.96.0.1      <none>           443/TCP        90d
service/nginx-svc       LoadBalancer   10.96.45.123   203.0.113.50     80:31234/TCP   2h

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deploy   2/2     2            2           2h

# ワイド出力で追加情報を表示
$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
nginx-deploy-6b7f675859-2xj4k   1/1   Running   0          2h    10.244.1.5    worker-1   <none>           <none>
nginx-deploy-6b7f675859-8kl9m   1/1   Running   0          2h    10.244.2.8    worker-2   <none>           <none>

# 特定のリソースを名前で取得
$ kubectl get pod nginx-deploy-6b7f675859-2xj4k

# リソースの変更を監視(watch モード)
$ kubectl get pods --watch
NAME                          READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k   1/1   Running   0          2h
nginx-deploy-6b7f675859-8kl9m   1/1   Running   0          2h
# 変更があるとリアルタイムで表示される

3.2 リソースの詳細表示 (describe)

# Pod の詳細情報を表示
$ kubectl describe pod nginx-deploy-6b7f675859-2xj4k
Name:             nginx-deploy-6b7f675859-2xj4k
Namespace:        default
Priority:         0
Service Account:  default
Node:             worker-1/192.168.1.101
Start Time:       Mon, 07 Apr 2026 10:00:00 +0900
Labels:           app=nginx
                  pod-template-hash=6b7f675859
Annotations:      <none>
Status:           Running
IP:               10.244.1.5
IPs:
  IP:           10.244.1.5
Controlled By:  ReplicaSet/nginx-deploy-6b7f675859
Containers:
  nginx:
    Container ID:   containerd://abc123def456...
    Image:          nginx:1.25
    Image ID:       docker.io/library/nginx@sha256:abc123...
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 07 Apr 2026 10:00:05 +0900
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     500m
      memory:  256Mi
    Requests:
      cpu:     100m
      memory:  128Mi
    Liveness:   http-get http://:80/ delay=10s timeout=5s period=10s #success=1 #failure=3
    Readiness:  http-get http://:80/ delay=5s timeout=3s period=5s #success=1 #failure=3
    Environment:
      ENV_VAR:  production
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xxxxx (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-xxxxx:
    Type:                    Projected (a]volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  2h    default-scheduler  Successfully assigned default/nginx-deploy-6b7f675859-2xj4k to worker-1
  Normal  Pulling    2h    kubelet            Pulling image "nginx:1.25"
  Normal  Pulled     2h    kubelet            Successfully pulled image "nginx:1.25" in 3.2s
  Normal  Created    2h    kubelet            Created container nginx
  Normal  Started    2h    kubelet            Started container nginx

# Node の詳細を表示
$ kubectl describe node worker-1
Name:               worker-1
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=worker-1
                    kubernetes.io/os=linux
                    node.kubernetes.io/instance-type=m5.xlarge
Annotations:        ...
Capacity:
  cpu:                4
  ephemeral-storage:  100Gi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             16384Mi
  pods:               110
Allocatable:
  cpu:                3800m
  ephemeral-storage:  92Gi
  memory:             15872Mi
  pods:               110
...
Non-terminated Pods:          (12 in total)
  Namespace     Name                             CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------     ----                             ------------  ----------  ---------------  -------------
  default       nginx-deploy-6b7f675859-2xj4k   100m (2%)     500m (13%)  128Mi (0%)       256Mi (1%)
  ...
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                1200m (31%)  3000m (78%)
  memory             2Gi (12%)    4Gi (25%)
  ephemeral-storage  0 (0%)       0 (0%)

3.3 リソースの作成 (create / apply)

# YAML ファイルからリソースを作成(命令的)
$ kubectl create -f deployment.yaml
deployment.apps/nginx-deploy created

# YAML ファイルからリソースを適用(宣言的 — 推奨)
$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deploy created

# 既存リソースへの apply は更新として動作
$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deploy configured

# ディレクトリ内の全 YAML を適用
$ kubectl apply -f ./manifests/
configmap/app-config created
deployment.apps/app-deploy created
service/app-svc created

# URL から直接適用
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/application/nginx-app.yaml

# 再帰的にディレクトリを適用
$ kubectl apply -f ./manifests/ -R

# stdin から作成
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  labels:
    app: test
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
EOF
pod/test-pod created

3.4 リソースの削除 (delete)

# 名前で削除
$ kubectl delete pod test-pod
pod "test-pod" deleted

# YAML ファイルで定義されたリソースを削除
$ kubectl delete -f deployment.yaml
deployment.apps/nginx-deploy deleted

# ラベルセレクタで削除
$ kubectl delete pods -l app=test
pod "test-pod-1" deleted
pod "test-pod-2" deleted

# Namespace 内の全 Pod を削除
$ kubectl delete pods --all -n development
pod "dev-app-1" deleted
pod "dev-app-2" deleted

# 強制削除(グレースピリオドなし)
$ kubectl delete pod stuck-pod --grace-period=0 --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated.
pod "stuck-pod" force deleted

# 複数のリソースタイプを削除
$ kubectl delete deployment,service nginx-deploy nginx-svc
deployment.apps "nginx-deploy" deleted
service "nginx-svc" deleted

3.5 リソースの編集 (edit)

# デフォルトエディタで編集
$ kubectl edit deployment nginx-deploy
# エディタが起動し、保存するとリソースが更新される
deployment.apps/nginx-deploy edited

# エディタを指定
$ KUBE_EDITOR="code --wait" kubectl edit deployment nginx-deploy

# 特定の Namespace のリソースを編集
$ kubectl edit service nginx-svc -n production

3.6 リソースのパッチ (patch)

Strategic Merge Patch(デフォルト)

# コンテナのイメージを更新
$ kubectl patch deployment nginx-deploy -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.26"}]}}}}'
deployment.apps/nginx-deploy patched

# レプリカ数を変更
$ kubectl patch deployment nginx-deploy -p '{"spec":{"replicas":5}}'
deployment.apps/nginx-deploy patched

JSON Merge Patch

# JSON Merge Patch を明示的に指定
$ kubectl patch deployment nginx-deploy \
    --type=merge \
    -p '{"spec":{"replicas":3}}'
deployment.apps/nginx-deploy patched

# アノテーションを追加
$ kubectl patch deployment nginx-deploy \
    --type=merge \
    -p '{"metadata":{"annotations":{"description":"Production nginx deployment"}}}'
deployment.apps/nginx-deploy patched

JSON Patch (RFC 6902)

# 配列の特定の要素を操作
$ kubectl patch deployment nginx-deploy \
    --type=json \
    -p='[{"op":"replace","path":"/spec/replicas","value":4}]'
deployment.apps/nginx-deploy patched

# 複数の操作を一度に実行
$ kubectl patch deployment nginx-deploy \
    --type=json \
    -p='[
      {"op":"replace","path":"/spec/template/spec/containers/0/image","value":"nginx:1.26"},
      {"op":"add","path":"/metadata/labels/version","value":"v2"},
      {"op":"remove","path":"/metadata/annotations/old-annotation"}
    ]'
deployment.apps/nginx-deploy patched

# 環境変数を追加
$ kubectl patch deployment nginx-deploy \
    --type=json \
    -p='[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"NEW_VAR","value":"new-value"}}]'
deployment.apps/nginx-deploy patched

4. Pod の操作

4.1 Pod の実行 (run)

# シンプルな Pod を実行
$ kubectl run nginx --image=nginx:1.25
pod/nginx created

# ポートを公開して実行
$ kubectl run nginx --image=nginx:1.25 --port=80
pod/nginx created

# 環境変数を設定して実行
$ kubectl run myapp --image=myapp:latest \
    --env="DATABASE_HOST=db.example.com" \
    --env="DATABASE_PORT=5432"
pod/myapp created

# リソース制限を設定して実行
$ kubectl run nginx --image=nginx:1.25 \
    --requests='cpu=100m,memory=128Mi' \
    --limits='cpu=500m,memory=256Mi'
pod/nginx created

# ラベルを付与して実行
$ kubectl run nginx --image=nginx:1.25 --labels="app=nginx,env=dev"
pod/nginx created

# Dry-run で YAML を生成(テンプレートとして活用)
$ kubectl run nginx --image=nginx:1.25 --port=80 --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx:1.25
    name: nginx
    ports:
    - containerPort: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

# 一時的な Pod を実行して終了後に自動削除
$ kubectl run tmp-shell --rm -it --image=busybox:1.36 -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- http://nginx-svc
<!DOCTYPE html>
<html>
<head><title>Welcome to nginx!</title></head>
...
/ # exit
Session ended, resume using 'kubectl attach tmp-shell -c tmp-shell -i -t' command when the pod is running
pod "tmp-shell" deleted

# 特定の Namespace で Pod を実行
$ kubectl run debug-pod --image=busybox:1.36 -n debugging --command -- sleep 3600
pod/debug-pod created

4.2 コンテナ内でコマンドを実行 (exec)

# Pod 内でコマンドを実行
$ kubectl exec nginx-deploy-6b7f675859-2xj4k -- ls /usr/share/nginx/html
50x.html
index.html

# インタラクティブシェルを起動
$ kubectl exec -it nginx-deploy-6b7f675859-2xj4k -- /bin/bash
root@nginx-deploy-6b7f675859-2xj4k:/# cat /etc/nginx/nginx.conf
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
...
root@nginx-deploy-6b7f675859-2xj4k:/# exit

# マルチコンテナ Pod で特定のコンテナを指定
$ kubectl exec -it multi-container-pod -c sidecar-container -- /bin/sh

# 環境変数を確認
$ kubectl exec nginx-deploy-6b7f675859-2xj4k -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-deploy-6b7f675859-2xj4k
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
...

# Pod 内からネットワーク接続をテスト
$ kubectl exec -it debug-pod -- nslookup kubernetes.default
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes.default
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

# Pod 内から他のサービスへの接続をテスト
$ kubectl exec -it debug-pod -- wget -qO- http://nginx-svc.default.svc.cluster.local
<!DOCTYPE html>
<html>
<head><title>Welcome to nginx!</title></head>
...

4.3 ログの表示 (logs)

# Pod のログを表示
$ kubectl logs nginx-deploy-6b7f675859-2xj4k
10.244.1.1 - - [07/Apr/2026:01:00:00 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.88.1"
10.244.1.1 - - [07/Apr/2026:01:00:05 +0000] "GET /healthz HTTP/1.1" 200 0 "-" "kube-probe/1.30"

# ログをリアルタイムで追跡(tail -f 相当)
$ kubectl logs -f nginx-deploy-6b7f675859-2xj4k
# ログがリアルタイムで表示され続ける...

# 最新 N 行のみ表示
$ kubectl logs --tail=50 nginx-deploy-6b7f675859-2xj4k

# 過去 1 時間のログを表示
$ kubectl logs --since=1h nginx-deploy-6b7f675859-2xj4k

# 特定の時刻以降のログを表示
$ kubectl logs --since-time="2026-04-07T10:00:00Z" nginx-deploy-6b7f675859-2xj4k

# 前回のコンテナインスタンスのログ(クラッシュループ時に有用)
$ kubectl logs --previous nginx-deploy-6b7f675859-2xj4k
# 前回のコンテナが出力したログが表示される

# マルチコンテナ Pod で特定のコンテナのログ
$ kubectl logs multi-container-pod -c sidecar
[2026-04-07 10:00:00] INFO: Sidecar started
[2026-04-07 10:00:01] INFO: Watching for config changes...

# 全コンテナのログを表示
$ kubectl logs multi-container-pod --all-containers=true

# ラベルセレクタで複数 Pod のログを表示
$ kubectl logs -l app=nginx --all-containers=true
# app=nginx ラベルを持つ全 Pod のログが表示される

# Deployment の全 Pod のログを表示
$ kubectl logs deployment/nginx-deploy
Found 2 pods, using pod/nginx-deploy-6b7f675859-2xj4k
10.244.1.1 - - [07/Apr/2026:01:00:00 +0000] "GET / HTTP/1.1" 200 615

# タイムスタンプを付与
$ kubectl logs --timestamps nginx-deploy-6b7f675859-2xj4k
2026-04-07T01:00:00.123456789Z 10.244.1.1 - - [07/Apr/2026:01:00:00 +0000] "GET / HTTP/1.1" 200 615

4.4 ポートフォワーディング (port-forward)

# Pod のポートをローカルにフォワード
$ kubectl port-forward pod/nginx-deploy-6b7f675859-2xj4k 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
# 別のターミナルで curl http://localhost:8080 でアクセス可能

# Service のポートをフォワード
$ kubectl port-forward service/nginx-svc 8080:80
Forwarding from 127.0.0.1:8080 -> 80

# Deployment のポートをフォワード
$ kubectl port-forward deployment/nginx-deploy 8080:80
Forwarding from 127.0.0.1:8080 -> 80

# 全インターフェースでリッスン(リモートアクセス可能)
$ kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80
Forwarding from 0.0.0.0:8080 -> 80

# 複数のポートを同時にフォワード
$ kubectl port-forward pod/myapp 8080:80 8443:443
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from 127.0.0.1:8443 -> 443

4.5 ファイルコピー (cp)

# ローカルから Pod へファイルをコピー
$ kubectl cp ./local-file.txt nginx-deploy-6b7f675859-2xj4k:/tmp/remote-file.txt

# Pod からローカルへファイルをコピー
$ kubectl cp nginx-deploy-6b7f675859-2xj4k:/var/log/nginx/access.log ./access.log

# ディレクトリをコピー
$ kubectl cp ./config-dir nginx-deploy-6b7f675859-2xj4k:/etc/app/

# 特定のコンテナを指定してコピー
$ kubectl cp ./data.json multi-pod:/tmp/data.json -c main-container

# 別の Namespace の Pod とコピー
$ kubectl cp ./file.txt monitoring/prometheus-0:/tmp/file.txt

4.6 コンテナへのアタッチ (attach)

# 実行中のコンテナにアタッチ(stdin/stdout に接続)
$ kubectl attach nginx-deploy-6b7f675859-2xj4k
# コンテナの stdout がリアルタイムで表示される

# インタラクティブにアタッチ(stdin も接続)
$ kubectl attach -it interactive-pod
# コンテナに対して入力が可能

4.7 デバッグ用エフェメラルコンテナ (debug)

Kubernetes 1.25 以降で安定版機能として利用可能なエフェメラルコンテナを使ったデバッグ手法です。

# 既存の Pod にデバッグコンテナを追加
$ kubectl debug -it nginx-deploy-6b7f675859-2xj4k --image=busybox:1.36 --target=nginx
Targeting container "nginx". If you don't see processes from this container, set \
`shareProcessNamespace: true` in the pod spec.
Defaulting debug container name to debugger-xxxxx.
If you don't see a command prompt, try pressing enter.
/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process nginx -g daemon off;
   29 101       0:00 nginx: worker process
   50 root      0:00 /bin/sh
/ # cat /proc/1/root/etc/nginx/nginx.conf
...
/ # exit

# Pod のコピーを作成してデバッグ(オリジナルに影響なし)
$ kubectl debug nginx-deploy-6b7f675859-2xj4k -it --copy-to=debug-pod --image=busybox:1.36
# デバッグ用のコピー Pod が作成される

# コピー Pod でコンテナイメージを変更(デバッグツール入りイメージに差し替え)
$ kubectl debug nginx-deploy-6b7f675859-2xj4k -it --copy-to=debug-pod \
    --container=nginx --image=nginx:1.25-debug

# ノードレベルのデバッグ(ノードのファイルシステムにアクセス)
$ kubectl debug node/worker-1 -it --image=ubuntu:22.04
Creating debugging pod node-debugger-worker-1-xxxxx with container debugger on node worker-1.
If you don't see a command prompt, try pressing enter.
root@worker-1:/# chroot /host
root@worker-1:/# journalctl -u kubelet --since "1 hour ago"
...
root@worker-1:/# crictl ps
CONTAINER   IMAGE     CREATED       STATE     NAME    ATTEMPT   POD ID    POD
abc123...   nginx     2 hours ago   Running   nginx   0         def456    nginx-deploy-xxx
root@worker-1:/# exit

5. Deployment とロールアウト

5.1 Deployment の作成とスケーリング

# Deployment を命令的に作成
$ kubectl create deployment nginx-deploy --image=nginx:1.25 --replicas=3
deployment.apps/nginx-deploy created

# Dry-run で YAML を生成
$ kubectl create deployment nginx-deploy --image=nginx:1.25 --replicas=3 \
    --dry-run=client -o yaml > nginx-deployment.yaml

# YAML マニフェストの例
$ cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5

# YAML から作成
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deploy created

# レプリカ数をスケール
$ kubectl scale deployment nginx-deploy --replicas=5
deployment.apps/nginx-deploy scaled

# 確認
$ kubectl get deployment nginx-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   5/5     5            5           10m

# 条件付きスケール(現在のレプリカ数が一致する場合のみ)
$ kubectl scale deployment nginx-deploy --replicas=3 --current-replicas=5
deployment.apps/nginx-deploy scaled

5.2 ロールアウト管理

# コンテナイメージを更新(ローリングアップデートが開始される)
$ kubectl set image deployment/nginx-deploy nginx=nginx:1.26
deployment.apps/nginx-deploy image updated

# ロールアウトの状態を確認
$ kubectl rollout status deployment/nginx-deploy
Waiting for deployment "nginx-deploy" spec update to be observed...
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx-deploy" successfully rolled out

# ロールアウト履歴を表示
$ kubectl rollout history deployment/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

# 特定リビジョンの詳細を表示
$ kubectl rollout history deployment/nginx-deploy --revision=2
deployment.apps/nginx-deploy with revision #2
Pod Template:
  Labels:       app=nginx
                pod-template-hash=7c9f8b6d54
  Containers:
   nginx:
    Image:      nginx:1.26
    Port:       80/TCP
    Host Port:  0/TCP
    Limits:
      cpu:      500m
      memory:   256Mi
    Requests:
      cpu:      100m
      memory:   128Mi
    ...

# ロールバック(前のリビジョンに戻す)
$ kubectl rollout undo deployment/nginx-deploy
deployment.apps/nginx-deploy rolled back

# 特定のリビジョンにロールバック
$ kubectl rollout undo deployment/nginx-deploy --to-revision=1
deployment.apps/nginx-deploy rolled back

# ロールアウトを一時停止
$ kubectl rollout pause deployment/nginx-deploy
deployment.apps/nginx-deploy paused

# 一時停止中に複数の変更を適用
$ kubectl set image deployment/nginx-deploy nginx=nginx:1.27
$ kubectl set resources deployment/nginx-deploy -c=nginx --limits=cpu=1,memory=512Mi

# ロールアウトを再開(一括で変更が適用される)
$ kubectl rollout resume deployment/nginx-deploy
deployment.apps/nginx-deploy resumed

# Deployment を再起動(全 Pod をローリングリスタート)
$ kubectl rollout restart deployment/nginx-deploy
deployment.apps/nginx-deploy restarted

5.3 オートスケーリング

# Horizontal Pod Autoscaler (HPA) を作成
$ kubectl autoscale deployment nginx-deploy --min=2 --max=10 --cpu-percent=80
horizontalpodautoscaler.autoscaling/nginx-deploy autoscaled

# HPA の状態を確認
$ kubectl get hpa
NAME           REFERENCE                 TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-deploy   Deployment/nginx-deploy   45%/80%   2         10        3          5m

# HPA の詳細を表示
$ kubectl describe hpa nginx-deploy
Name:                                                  nginx-deploy
Namespace:                                             default
Labels:                                                <none>
Annotations:                                           <none>
CreationTimestamp:                                      Mon, 07 Apr 2026 12:00:00 +0900
Reference:                                             Deployment/nginx-deploy
Metrics:                                               ( current / target )
  resource cpu on pods  (as a percentage of request):  45% (45m) / 80%
Min replicas:                                          2
Max replicas:                                          10
Deployment pods:                                       3 current / 3 desired
Conditions:
  Type            Status  Reason               Message
  ----            ------  ------               -------
  AbleToScale     True    ReadyForNewScale     recommended size matches current size
  ScalingActive   True    ValidMetricFound     the HPA was able to successfully calculate a replica count
  ScalingLimited  False   DesiredWithinRange   the desired count is within the acceptable range
Events:           <none>

# HPA の YAML マニフェスト(高度な設定)
$ cat <<EOF | kubectl apply -f -
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-deploy-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deploy
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
      - type: Pods
        value: 4
        periodSeconds: 15
      selectPolicy: Max
EOF
horizontalpodautoscaler.autoscaling/nginx-deploy-hpa created

# HPA を削除
$ kubectl delete hpa nginx-deploy
horizontalpodautoscaler.autoscaling "nginx-deploy" deleted

6. Service とネットワーキング

6.1 Service の作成 (expose)

# Deployment から ClusterIP Service を作成
$ kubectl expose deployment nginx-deploy --port=80 --target-port=80
service/nginx-deploy exposed

# NodePort Service を作成
$ kubectl expose deployment nginx-deploy --port=80 --target-port=80 --type=NodePort
service/nginx-deploy exposed

# LoadBalancer Service を作成
$ kubectl expose deployment nginx-deploy --port=80 --target-port=80 --type=LoadBalancer --name=nginx-lb
service/nginx-lb exposed

# Service の確認
$ kubectl get services
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
kubernetes     ClusterIP      10.96.0.1       <none>           443/TCP        90d
nginx-deploy   ClusterIP      10.96.45.123    <none>           80/TCP         5m
nginx-lb       LoadBalancer   10.96.78.234    203.0.113.50     80:31234/TCP   2m

# Service の詳細を表示
$ kubectl describe service nginx-lb
Name:                     nginx-lb
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.78.234
IPs:                      10.96.78.234
LoadBalancer Ingress:     203.0.113.50
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31234/TCP
Endpoints:                10.244.1.5:80,10.244.2.8:80,10.244.3.12:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  2m    service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   1m    service-controller  Ensured load balancer

6.2 Service タイプの解説

# 1. ClusterIP(デフォルト): クラスタ内部からのみアクセス可能
apiVersion: v1
kind: Service
metadata:
  name: backend-svc
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
  - port: 8080        # Service のポート
    targetPort: 8080   # Pod のポート
    protocol: TCP

# 2. NodePort: 各ノードの特定ポートで外部公開(30000-32767)
apiVersion: v1
kind: Service
metadata:
  name: frontend-svc
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080    # 省略すると自動割り当て

# 3. LoadBalancer: クラウドプロバイダのロードバランサーを自動作成
apiVersion: v1
kind: Service
metadata:
  name: api-svc
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb    # AWS NLB を使用
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"  # 内部 LB
spec:
  type: LoadBalancer
  selector:
    app: api
  ports:
  - port: 443
    targetPort: 8443

# 4. ExternalName: 外部 DNS 名へのエイリアス
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.external.example.com

# 5. Headless Service(clusterIP: None): DNS ベースのサービスディスカバリ
apiVersion: v1
kind: Service
metadata:
  name: stateful-svc
spec:
  clusterIP: None
  selector:
    app: stateful-app
  ports:
  - port: 5432

6.3 kubectl proxy

# API サーバーへのプロキシを起動
$ kubectl proxy --port=8001
Starting to serve on 127.0.0.1:8001

# 別のターミナルから API にアクセス
$ curl http://localhost:8001/api/v1/namespaces/default/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  "items": [...]
}

# Service に直接アクセス
$ curl http://localhost:8001/api/v1/namespaces/default/services/nginx-svc/proxy/
<!DOCTYPE html>
<html>
<head><title>Welcome to nginx!</title></head>
...

# 特定の API パスにアクセス
$ curl http://localhost:8001/apis/apps/v1/namespaces/default/deployments
{
  "kind": "DeploymentList",
  ...
}

6.4 Endpoints の確認

# Service のエンドポイントを確認
$ kubectl get endpoints nginx-svc
NAME        ENDPOINTS                                   AGE
nginx-svc   10.244.1.5:80,10.244.2.8:80,10.244.3.12:80 30m

# EndpointSlice を確認(Kubernetes 1.21+ で推奨)
$ kubectl get endpointslices -l kubernetes.io/service-name=nginx-svc
NAME                  ADDRESSTYPE   PORTS   ENDPOINTS                            AGE
nginx-svc-xxxxx       IPv4          80      10.244.1.5,10.244.2.8,10.244.3.12   30m

7. ConfigMap と Secret

7.1 ConfigMap の作成と管理

# リテラル値から ConfigMap を作成
$ kubectl create configmap app-config \
    --from-literal=DATABASE_HOST=db.example.com \
    --from-literal=DATABASE_PORT=5432 \
    --from-literal=LOG_LEVEL=info
configmap/app-config created

# ファイルから ConfigMap を作成
$ cat > app.properties <<EOF
database.host=db.example.com
database.port=5432
database.name=myapp
log.level=info
log.format=json
EOF

$ kubectl create configmap app-config-file --from-file=app.properties
configmap/app-config-file created

# ディレクトリから ConfigMap を作成
$ kubectl create configmap nginx-config --from-file=./nginx-configs/
configmap/nginx-config created

# 環境変数ファイルから ConfigMap を作成
$ cat > env.txt <<EOF
DATABASE_HOST=db.example.com
DATABASE_PORT=5432
LOG_LEVEL=info
EOF

$ kubectl create configmap app-env --from-env-file=env.txt
configmap/app-env created

# ConfigMap の内容を確認
$ kubectl get configmap app-config -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: default
data:
  DATABASE_HOST: db.example.com
  DATABASE_PORT: "5432"
  LOG_LEVEL: info

# ConfigMap の詳細を表示
$ kubectl describe configmap app-config
Name:         app-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
DATABASE_HOST:
----
db.example.com
DATABASE_PORT:
----
5432
LOG_LEVEL:
----
info

BinaryData
====

Events:  <none>

ConfigMap の使用パターン

# 1. 環境変数として使用
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    envFrom:
    - configMapRef:
        name: app-config    # 全キーを環境変数として読み込み
    env:
    - name: SPECIFIC_KEY    # 特定のキーのみ読み込み
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: DATABASE_HOST

# 2. ボリュームとしてマウント
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
      readOnly: true
  volumes:
  - name: config-volume
    configMap:
      name: app-config-file
      # 特定のキーのみマウント
      items:
      - key: app.properties
        path: application.properties

7.2 Secret の作成と管理

# リテラル値から Secret を作成
$ kubectl create secret generic db-secret \
    --from-literal=username=admin \
    --from-literal=password='S3cureP@ss!'
secret/db-secret created

# ファイルから Secret を作成
$ kubectl create secret generic tls-cert \
    --from-file=tls.crt=./server.crt \
    --from-file=tls.key=./server.key
secret/tls-cert created

# TLS Secret を作成(専用コマンド)
$ kubectl create secret tls my-tls-secret \
    --cert=./server.crt \
    --key=./server.key
secret/my-tls-secret created

# Docker レジストリ認証用 Secret
$ kubectl create secret docker-registry regcred \
    --docker-server=registry.example.com \
    --docker-username=myuser \
    --docker-password='MyP@ssw0rd' \
    --docker-email=user@example.com
secret/regcred created

# Secret の確認(値は Base64 エンコード済み)
$ kubectl get secret db-secret -o yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
  namespace: default
type: Opaque
data:
  password: UzNjdXJlUEBzcyE=    # Base64 エンコード
  username: YWRtaW4=

# Secret の値をデコードして確認
$ kubectl get secret db-secret -o jsonpath='{.data.username}' | base64 -d
admin

$ kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
S3cureP@ss!

# 環境変数ファイルから Secret を作成
$ cat > secret-env.txt <<EOF
DB_USER=admin
DB_PASS=S3cureP@ss!
API_KEY=abc123def456
EOF

$ kubectl create secret generic app-secrets --from-env-file=secret-env.txt
secret/app-secrets created

Secret の使用パターン

# 1. 環境変数として使用
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    envFrom:
    - secretRef:
        name: app-secrets    # 全キーを環境変数として読み込み

# 2. ボリュームとしてマウント
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: tls-cert
      defaultMode: 0400    # ファイルパーミッション

# 3. imagePullSecrets として使用
apiVersion: v1
kind: Pod
metadata:
  name: private-app
spec:
  imagePullSecrets:
  - name: regcred
  containers:
  - name: app
    image: registry.example.com/myapp:latest

8. Namespace 管理

8.1 Namespace の基本操作

# Namespace 一覧を表示
$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   90d
kube-node-lease   Active   90d
kube-public       Active   90d
kube-system       Active   90d

# Namespace を作成
$ kubectl create namespace development
namespace/development created

$ kubectl create namespace staging
namespace/staging created

$ kubectl create namespace production
namespace/production created

# YAML で作成
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring
  labels:
    purpose: monitoring
    team: sre
EOF
namespace/monitoring created

# デフォルト Namespace を設定
$ kubectl config set-context --current --namespace=development
Context "staging-dev" modified.

# 現在のデフォルト Namespace を確認
$ kubectl config view --minify -o jsonpath='{..namespace}'
development

# Namespace を削除(中の全リソースも削除される — 注意)
$ kubectl delete namespace development
namespace "development" deleted

8.2 ResourceQuota

# ResourceQuota を作成
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    pods: "20"
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    persistentvolumeclaims: "10"
    services.loadbalancers: "2"
    services.nodeports: "5"
    configmaps: "20"
    secrets: "20"
    replicationcontrollers: "10"
    resourcequotas: "1"
EOF
resourcequota/dev-quota created

# ResourceQuota の確認
$ kubectl get resourcequota -n development
NAME        AGE   REQUEST                                                                                                                                   LIMIT
dev-quota   30s   configmaps: 1/20, persistentvolumeclaims: 0/10, pods: 0/20, replicationcontrollers: 0/10, requests.cpu: 0/4, requests.memory: 0/8Gi ...   limits.cpu: 0/8, limits.memory: 0/16Gi

# 詳細な使用状況を表示
$ kubectl describe resourcequota dev-quota -n development
Name:                   dev-quota
Namespace:              development
Resource                Used  Hard
--------                ----  ----
configmaps              1     20
limits.cpu              0     8
limits.memory           0     16Gi
persistentvolumeclaims  0     10
pods                    0     20
replicationcontrollers  0     10
requests.cpu            0     4
requests.memory         0     8Gi
resourcequotas          1     1
secrets                 1     20
services.loadbalancers  0     2
services.nodeports      0     5

8.3 LimitRange

# LimitRange を作成(Pod/Container のデフォルトリソース制限)
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: development
spec:
  limits:
  - type: Container
    default:          # リソース制限のデフォルト値
      cpu: 500m
      memory: 256Mi
    defaultRequest:   # リソース要求のデフォルト値
      cpu: 100m
      memory: 128Mi
    max:              # 最大値
      cpu: "2"
      memory: 2Gi
    min:              # 最小値
      cpu: 50m
      memory: 64Mi
  - type: Pod
    max:
      cpu: "4"
      memory: 4Gi
  - type: PersistentVolumeClaim
    max:
      storage: 50Gi
    min:
      storage: 1Gi
EOF
limitrange/dev-limits created

# LimitRange の確認
$ kubectl describe limitrange dev-limits -n development
Name:                  dev-limits
Namespace:             development
Type                   Resource  Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
----                   --------  ---   ---   ---------------  -------------  -----------------------
Container              cpu       50m   2     100m             500m           -
Container              memory    64Mi  2Gi   128Mi            256Mi          -
Pod                    cpu       -     4     -                -              -
Pod                    memory    -     4Gi   -                -              -
PersistentVolumeClaim  storage   1Gi   50Gi  -                -              -

9. Label とセレクタ

9.1 Label の操作

# Pod にラベルを付与
$ kubectl label pod nginx-deploy-6b7f675859-2xj4k env=production
pod/nginx-deploy-6b7f675859-2xj4k labeled

# 複数のラベルを同時に付与
$ kubectl label pod nginx-deploy-6b7f675859-2xj4k tier=frontend version=v1.25
pod/nginx-deploy-6b7f675859-2xj4k labeled

# ラベルを上書き(--overwrite が必要)
$ kubectl label pod nginx-deploy-6b7f675859-2xj4k env=staging --overwrite
pod/nginx-deploy-6b7f675859-2xj4k labeled

# ラベルを削除(キー名の後に - を付ける)
$ kubectl label pod nginx-deploy-6b7f675859-2xj4k version-
pod/nginx-deploy-6b7f675859-2xj4k unlabeled

# ノードにラベルを付与(スケジューリング制御に使用)
$ kubectl label node worker-1 disk=ssd
node/worker-1 labeled

$ kubectl label node worker-2 disk=hdd
node/worker-2 labeled

$ kubectl label node worker-1 zone=ap-northeast-1a
node/worker-1 labeled

# Namespace 内の全 Pod にラベルを付与
$ kubectl label pods --all env=development -n development
pod/app-1 labeled
pod/app-2 labeled

# ラベルを表示
$ kubectl get pods --show-labels
NAME                              READY   STATUS    RESTARTS   AGE   LABELS
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h    app=nginx,env=staging,pod-template-hash=6b7f675859,tier=frontend
nginx-deploy-6b7f675859-8kl9m    1/1     Running   0          3h    app=nginx,pod-template-hash=6b7f675859

# 特定のラベルのみカラム表示
$ kubectl get pods -L app,env,tier
NAME                              READY   STATUS    RESTARTS   AGE   APP     ENV       TIER
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h    nginx   staging   frontend
nginx-deploy-6b7f675859-8kl9m    1/1     Running   0          3h    nginx

9.2 ラベルセレクタ

# 等価ベースのセレクタ
$ kubectl get pods -l app=nginx
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h
nginx-deploy-6b7f675859-8kl9m    1/1     Running   0          3h

# 不等価セレクタ
$ kubectl get pods -l app!=nginx
NAME              READY   STATUS    RESTARTS   AGE
redis-master-0    1/1     Running   0          5d
myapp-pod-1       1/1     Running   0          1d

# セットベースのセレクタ(in)
$ kubectl get pods -l 'env in (production, staging)'
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h

# セットベースのセレクタ(notin)
$ kubectl get pods -l 'env notin (production)'

# ラベルの存在チェック
$ kubectl get pods -l env
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h

# ラベルの非存在チェック
$ kubectl get pods -l '!env'
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-8kl9m    1/1     Running   0          3h

# 複数条件の組み合わせ(AND)
$ kubectl get pods -l 'app=nginx,env=staging'
$ kubectl get pods -l 'app=nginx,tier in (frontend, backend)'

# ラベルセレクタで削除
$ kubectl delete pods -l env=staging
pod "nginx-deploy-6b7f675859-2xj4k" deleted

9.3 フィールドセレクタ

# ステータスでフィルタ
$ kubectl get pods --field-selector status.phase=Running
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h

# 特定ノード上の Pod をフィルタ
$ kubectl get pods --field-selector spec.nodeName=worker-1

# Namespace でフィルタ
$ kubectl get pods --field-selector metadata.namespace=kube-system -A

# 複数条件
$ kubectl get pods --field-selector status.phase=Running,spec.nodeName=worker-1

# 不等条件
$ kubectl get pods --field-selector status.phase!=Succeeded

9.4 Annotation の操作

# アノテーションを付与
$ kubectl annotate pod nginx-deploy-6b7f675859-2xj4k \
    description="Production nginx web server" \
    owner="sre-team" \
    oncall-contact="sre@example.com"
pod/nginx-deploy-6b7f675859-2xj4k annotated

# Deployment にアノテーションを付与(変更理由の記録に有用)
$ kubectl annotate deployment nginx-deploy \
    kubernetes.io/change-cause="Updated nginx to 1.26 for security patch"
deployment.apps/nginx-deploy annotated

# アノテーションを上書き
$ kubectl annotate pod nginx-deploy-6b7f675859-2xj4k \
    description="Updated production nginx" --overwrite
pod/nginx-deploy-6b7f675859-2xj4k annotated

# アノテーションを削除
$ kubectl annotate pod nginx-deploy-6b7f675859-2xj4k owner-
pod/nginx-deploy-6b7f675859-2xj4k annotated

10. RBAC 管理

10.1 権限の確認 (auth can-i)

# 自分の権限を確認
$ kubectl auth can-i create deployments
yes

$ kubectl auth can-i delete pods
yes

$ kubectl auth can-i create namespaces
no

# 特定の Namespace での権限を確認
$ kubectl auth can-i get pods -n kube-system
yes

$ kubectl auth can-i delete pods -n production
no

# 特定のリソースに対する権限を確認
$ kubectl auth can-i get pods/log
yes

$ kubectl auth can-i create pods/exec
yes

# 全権限を一覧表示
$ kubectl auth can-i --list
Resources                                       Non-Resource URLs   Resource Names   Verbs
pods                                            []                  []               [get list watch create delete]
deployments.apps                                []                  []               [get list watch create update patch delete]
services                                        []                  []               [get list watch]
secrets                                         []                  []               [get list]
...

# 特定の Namespace での全権限を一覧
$ kubectl auth can-i --list -n production

# 他のユーザーの権限を確認(クラスタ管理者権限が必要)
$ kubectl auth can-i create deployments --as=developer-user
no

$ kubectl auth can-i get pods --as=developer-user -n development
yes

# サービスアカウントの権限を確認
$ kubectl auth can-i get pods \
    --as=system:serviceaccount:default:my-service-account
yes

# グループの権限を確認
$ kubectl auth can-i create deployments \
    --as=developer --as-group=system:authenticated
no

# whoami(認証情報の確認)
$ kubectl auth whoami
ATTRIBUTE                                           VALUE
Username                                            admin-user
UID                                                 abc123-def456-ghi789
Groups                                              [system:masters system:authenticated]
Extra: scopes.authorization.openshift.io            [user:full]

10.2 Role と ClusterRole の作成

# Role を作成(Namespace スコープ)
$ kubectl create role pod-reader \
    --verb=get,list,watch \
    --resource=pods \
    -n development
role.rbac.authorization.k8s.io/pod-reader created

# 複数リソースに対する Role
$ kubectl create role app-manager \
    --verb=get,list,watch,create,update,patch,delete \
    --resource=deployments,services,configmaps \
    -n development
role.rbac.authorization.k8s.io/app-manager created

# ClusterRole を作成(クラスタスコープ)
$ kubectl create clusterrole node-viewer \
    --verb=get,list,watch \
    --resource=nodes
clusterrole.rbac.authorization.k8s.io/node-viewer created

# 特定のリソース名に限定した Role
$ kubectl create role configmap-updater \
    --verb=get,update \
    --resource=configmaps \
    --resource-name=app-config \
    -n development
role.rbac.authorization.k8s.io/configmap-updater created

# YAML で詳細な Role を定義
$ cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-role
  namespace: development
rules:
- apiGroups: [""]           # コア API グループ
  resources: ["pods", "pods/log", "pods/exec", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]       # apps API グループ
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]    # Secret は読み取りのみ
- apiGroups: ["batch"]
  resources: ["jobs", "cronjobs"]
  verbs: ["get", "list", "watch", "create", "delete"]
EOF
role.rbac.authorization.k8s.io/developer-role created

10.3 RoleBinding と ClusterRoleBinding

# RoleBinding を作成(ユーザーに Role をバインド)
$ kubectl create rolebinding pod-reader-binding \
    --role=pod-reader \
    --user=developer-user \
    -n development
rolebinding.rbac.authorization.k8s.io/pod-reader-binding created

# グループに Role をバインド
$ kubectl create rolebinding developer-binding \
    --role=developer-role \
    --group=developers \
    -n development
rolebinding.rbac.authorization.k8s.io/developer-binding created

# サービスアカウントに Role をバインド
$ kubectl create rolebinding app-sa-binding \
    --role=app-manager \
    --serviceaccount=development:app-service-account \
    -n development
rolebinding.rbac.authorization.k8s.io/app-sa-binding created

# ClusterRoleBinding を作成
$ kubectl create clusterrolebinding node-viewer-binding \
    --clusterrole=node-viewer \
    --user=developer-user
clusterrolebinding.rbac.authorization.k8s.io/node-viewer-binding created

# ClusterRole を Namespace にバインド(ClusterRole を特定の Namespace で使用)
$ kubectl create rolebinding admin-in-dev \
    --clusterrole=admin \
    --user=developer-user \
    -n development
rolebinding.rbac.authorization.k8s.io/admin-in-dev created

# RBAC リソースの確認
$ kubectl get roles -n development
NAME               CREATED AT
app-manager        2026-04-07T03:00:00Z
configmap-updater  2026-04-07T03:05:00Z
developer-role     2026-04-07T03:10:00Z
pod-reader         2026-04-07T03:00:00Z

$ kubectl get rolebindings -n development
NAME                  ROLE                   AGE
app-sa-binding        Role/app-manager       5m
developer-binding     Role/developer-role    3m
pod-reader-binding    Role/pod-reader        5m

$ kubectl get clusterroles | head -20
NAME                                                                   CREATED AT
admin                                                                  2026-01-07T00:00:00Z
cluster-admin                                                          2026-01-07T00:00:00Z
edit                                                                   2026-01-07T00:00:00Z
node-viewer                                                            2026-04-07T03:00:00Z
system:aggregate-to-admin                                              2026-01-07T00:00:00Z
view                                                                   2026-01-07T00:00:00Z
...

$ kubectl describe rolebinding developer-binding -n development
Name:         developer-binding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  developer-role
Subjects:
  Kind   Name         Namespace
  ----   ----         ---------
  Group  developers

11. 高度なリソース操作

11.1 wait(リソースの状態を待機)

# Pod が Ready になるまで待機
$ kubectl wait --for=condition=Ready pod/nginx-deploy-6b7f675859-2xj4k --timeout=120s
pod/nginx-deploy-6b7f675859-2xj4k condition met

# 全 Pod が Ready になるまで待機
$ kubectl wait --for=condition=Ready pods --all --timeout=300s

# ラベルセレクタで指定した Pod を待機
$ kubectl wait --for=condition=Ready pods -l app=nginx --timeout=180s

# Pod が削除されるまで待機
$ kubectl wait --for=delete pod/old-pod --timeout=60s

# Job が完了するまで待機
$ kubectl wait --for=condition=Complete job/backup-job --timeout=600s
job.batch/backup-job condition met

# Deployment が Available になるまで待機
$ kubectl wait --for=condition=Available deployment/nginx-deploy --timeout=300s
deployment.apps/nginx-deploy condition met

# jsonpath 条件で待機(Kubernetes 1.31+)
$ kubectl wait --for=jsonpath='{.status.readyReplicas}'=3 deployment/nginx-deploy --timeout=120s

11.2 diff(変更差分の確認)

# 適用前に差分を確認
$ kubectl diff -f deployment.yaml
diff -u -N /tmp/LIVE-123/apps.v1.Deployment.default.nginx-deploy /tmp/MERGED-456/apps.v1.Deployment.default.nginx-deploy
--- /tmp/LIVE-123/apps.v1.Deployment.default.nginx-deploy
+++ /tmp/MERGED-456/apps.v1.Deployment.default.nginx-deploy
@@ -25,7 +25,7 @@
       containers:
       - name: nginx
-        image: nginx:1.25
+        image: nginx:1.26
         ports:
         - containerPort: 80

# ディレクトリ全体の差分を確認
$ kubectl diff -f ./manifests/

# stdin から差分を確認
$ cat updated-config.yaml | kubectl diff -f -

11.3 replace(リソースの置換)

# リソースを完全に置換(リソースが存在する必要がある)
$ kubectl replace -f deployment.yaml
deployment.apps/nginx-deploy replaced

# 強制置換(削除して再作成)
$ kubectl replace --force -f deployment.yaml
deployment.apps "nginx-deploy" deleted
deployment.apps/nginx-deploy replaced

11.4 Kustomize

# kustomization.yaml の例
$ cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: production

commonLabels:
  app: myapp
  env: production

resources:
- deployment.yaml
- service.yaml
- configmap.yaml

patches:
- patch: |-
    - op: replace
      path: /spec/replicas
      value: 5
  target:
    kind: Deployment
    name: myapp

images:
- name: myapp
  newTag: v2.0.0

configMapGenerator:
- name: app-config
  literals:
  - LOG_LEVEL=warn
  - ENVIRONMENT=production

# Kustomize でビルド結果をプレビュー
$ kubectl kustomize ./overlays/production/
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: myapp
    env: production
  name: app-config-abc123
  namespace: production
data:
  ENVIRONMENT: production
  LOG_LEVEL: warn
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
    env: production
  name: myapp
  namespace: production
spec:
  replicas: 5
  ...

# Kustomize で適用
$ kubectl apply -k ./overlays/production/
configmap/app-config-abc123 created
deployment.apps/myapp created
service/myapp created

# Kustomize で削除
$ kubectl delete -k ./overlays/production/

11.5 Dry-run(ドライラン)

# クライアント側ドライラン(サーバーに送信しない)
$ kubectl apply -f deployment.yaml --dry-run=client
deployment.apps/nginx-deploy created (dry run)

# サーバー側ドライラン(バリデーション付き、実際には適用しない)
$ kubectl apply -f deployment.yaml --dry-run=server
deployment.apps/nginx-deploy created (server dry run)

# ドライランで YAML を生成
$ kubectl create deployment test --image=nginx:1.25 --replicas=3 \
    --dry-run=client -o yaml > test-deployment.yaml

# ドライランで差分を確認
$ kubectl apply -f deployment.yaml --dry-run=server -o yaml | diff - <(kubectl get deployment nginx-deploy -o yaml)

11.6 Server-Side Apply(サーバーサイド適用)

# Server-Side Apply(フィールドの所有権管理が改善される)
$ kubectl apply -f deployment.yaml --server-side
deployment.apps/nginx-deploy serverside-applied

# フィールドマネージャーを指定
$ kubectl apply -f deployment.yaml --server-side --field-manager=my-controller
deployment.apps/nginx-deploy serverside-applied

# 競合時に強制適用
$ kubectl apply -f deployment.yaml --server-side --force-conflicts
deployment.apps/nginx-deploy serverside-applied

# マネージドフィールドの確認
$ kubectl get deployment nginx-deploy -o yaml | grep -A 20 managedFields
  managedFields:
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:labels:
          f:app: {}
      f:spec:
        f:replicas: {}
        f:selector: {}
        f:template:
          ...
    manager: kubectl-client-side-apply
    operation: Update
    time: "2026-04-07T03:00:00Z"

12. デバッグとトラブルシューティング

12.1 リソース使用状況の確認 (top)

# ノードのリソース使用状況
$ kubectl top nodes
NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master-1   350m         8%     2048Mi          12%
worker-1   1200m        31%    4096Mi          25%
worker-2   800m         21%    3072Mi          19%
worker-3   600m         15%    2560Mi          16%

# Pod のリソース使用状況
$ kubectl top pods
NAME                              CPU(cores)   MEMORY(bytes)
nginx-deploy-6b7f675859-2xj4k    10m          32Mi
nginx-deploy-6b7f675859-8kl9m    8m           28Mi
redis-master-0                    45m          128Mi

# コンテナごとのリソース使用状況
$ kubectl top pods --containers
POD                               NAME        CPU(cores)   MEMORY(bytes)
nginx-deploy-6b7f675859-2xj4k    nginx       10m          32Mi
multi-pod-xxx                     app         50m          128Mi
multi-pod-xxx                     sidecar     5m           16Mi

# 全 Namespace の Pod リソース使用状況
$ kubectl top pods -A --sort-by=cpu
NAMESPACE     POD                                       CPU(cores)   MEMORY(bytes)
monitoring    prometheus-server-0                       200m         1024Mi
kube-system   kube-apiserver-master-1                   150m         512Mi
default       redis-master-0                            45m          128Mi

# メモリ順でソート
$ kubectl top pods -A --sort-by=memory

12.2 イベントの確認

# 全イベントを表示
$ kubectl get events
LAST SEEN   TYPE      REASON              OBJECT                               MESSAGE
5m          Normal    Scheduled           pod/nginx-deploy-6b7f675859-2xj4k    Successfully assigned default/nginx-deploy-... to worker-1
5m          Normal    Pulling             pod/nginx-deploy-6b7f675859-2xj4k    Pulling image "nginx:1.25"
5m          Normal    Pulled              pod/nginx-deploy-6b7f675859-2xj4k    Successfully pulled image "nginx:1.25"
5m          Normal    Created             pod/nginx-deploy-6b7f675859-2xj4k    Created container nginx
5m          Normal    Started             pod/nginx-deploy-6b7f675859-2xj4k    Started container nginx
2m          Warning   FailedScheduling    pod/resource-heavy-pod                0/3 nodes are available: 3 Insufficient memory.
1m          Warning   Unhealthy           pod/failing-app-xxx                   Readiness probe failed: HTTP probe failed with statuscode: 503
30s         Warning   BackOff             pod/crash-loop-pod                    Back-off restarting failed container

# 時間順にソート
$ kubectl get events --sort-by='.lastTimestamp'

# Warning イベントのみ表示
$ kubectl get events --field-selector type=Warning
LAST SEEN   TYPE      REASON              OBJECT                  MESSAGE
2m          Warning   FailedScheduling    pod/resource-heavy-pod  0/3 nodes are available: 3 Insufficient memory.
1m          Warning   Unhealthy           pod/failing-app-xxx     Readiness probe failed: HTTP probe failed with statuscode: 503
30s         Warning   BackOff             pod/crash-loop-pod      Back-off restarting failed container

# 特定のリソースに関するイベント
$ kubectl get events --field-selector involvedObject.name=nginx-deploy-6b7f675859-2xj4k

# JSON 出力でイベントを分析
$ kubectl get events -o json | jq '.items[] | select(.type=="Warning") | {message: .message, reason: .reason, object: .involvedObject.name}'

12.3 トラブルシューティングのフロー

# ===== Pod が起動しない場合のデバッグフロー =====

# ステップ 1: Pod の状態を確認
$ kubectl get pod failing-pod
NAME          READY   STATUS             RESTARTS      AGE
failing-pod   0/1     CrashLoopBackOff   5 (30s ago)   5m

# ステップ 2: Pod の詳細を確認
$ kubectl describe pod failing-pod
...
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  5m                 default-scheduler  Successfully assigned default/failing-pod to worker-1
  Normal   Pulled     3m (x4 over 5m)    kubelet            Container image "myapp:latest" already present on machine
  Normal   Created    3m (x4 over 5m)    kubelet            Created container myapp
  Normal   Started    3m (x4 over 5m)    kubelet            Started container myapp
  Warning  BackOff    30s (x15 over 4m)  kubelet            Back-off restarting failed container

# ステップ 3: ログを確認
$ kubectl logs failing-pod
Error: DATABASE_URL environment variable is not set
panic: runtime error: invalid memory address or nil pointer dereference

# ステップ 4: 前回のコンテナのログを確認
$ kubectl logs failing-pod --previous
Error: DATABASE_URL environment variable is not set

# ===== ImagePullBackOff のデバッグ =====
$ kubectl get pod image-error-pod
NAME              READY   STATUS             RESTARTS   AGE
image-error-pod   0/1     ImagePullBackOff   0          2m

$ kubectl describe pod image-error-pod
...
Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Normal   Scheduled  2m    default-scheduler  Successfully assigned default/image-error-pod to worker-1
  Normal   Pulling    2m    kubelet            Pulling image "myregistry.com/myapp:v999"
  Warning  Failed     2m    kubelet            Failed to pull image "myregistry.com/myapp:v999": rpc error: code = NotFound
  Warning  Failed     2m    kubelet            Error: ErrImagePull
  Normal   BackOff    90s   kubelet            Back-off pulling image "myregistry.com/myapp:v999"
  Warning  Failed     90s   kubelet            Error: ImagePullBackOff

# ===== Pending Pod のデバッグ =====
$ kubectl get pod pending-pod
NAME          READY   STATUS    RESTARTS   AGE
pending-pod   0/1     Pending   0          10m

$ kubectl describe pod pending-pod
...
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  10m   default-scheduler  0/3 nodes are available: 1 node(s) had untolerated taint
                                                       {node-role.kubernetes.io/control-plane: }, 2 Insufficient cpu.

# ===== Service 接続問題のデバッグ =====

# Endpoints が存在するか確認
$ kubectl get endpoints my-service
NAME         ENDPOINTS   AGE
my-service   <none>      5m
# Endpoints が空 → セレクタが Pod のラベルと一致していない

# Service のセレクタを確認
$ kubectl get service my-service -o jsonpath='{.spec.selector}'
{"app":"myapp","version":"v2"}

# Pod のラベルを確認
$ kubectl get pods --show-labels
NAME         READY   STATUS    RESTARTS   AGE   LABELS
myapp-pod    1/1     Running   0          10m   app=myapp,version=v1
# version ラベルが v1 で、Service は v2 を期待している

12.4 cluster-info dump

# クラスタ全体の診断情報をダンプ
$ kubectl cluster-info dump --output-directory=/tmp/cluster-dump
Cluster info dumped to /tmp/cluster-dump

# 特定の Namespace に限定してダンプ
$ kubectl cluster-info dump --namespaces=default,kube-system --output-directory=/tmp/cluster-dump

# ダンプの内容を確認
$ ls /tmp/cluster-dump/
default/
kube-system/
nodes.json

$ ls /tmp/cluster-dump/kube-system/
coredns-5dd5756b68-4xz7j/
etcd-master-1/
events.json
kube-apiserver-master-1/
pods.json
replication-controllers.json
services.json

12.5 API リソースの探索

# 利用可能な API リソースの一覧
$ kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                        NAMESPACED   KIND
bindings                                       v1                                true         Binding
componentstatuses                 cs           v1                                false        ComponentStatus
configmaps                        cm           v1                                true         ConfigMap
endpoints                         ep           v1                                true         Endpoints
events                            ev           v1                                true         Event
limitranges                       limits       v1                                true         LimitRange
namespaces                        ns           v1                                false        Namespace
nodes                             no           v1                                false        Node
persistentvolumeclaims            pvc          v1                                true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                false        PersistentVolume
pods                              po           v1                                true         Pod
secrets                                        v1                                true         Secret
serviceaccounts                   sa           v1                                true         ServiceAccount
services                          svc          v1                                true         Service
deployments                       deploy       apps/v1                           true         Deployment
replicasets                       rs           apps/v1                           true         ReplicaSet
statefulsets                      sts          apps/v1                           true         StatefulSet
cronjobs                          cj           batch/v1                          true         CronJob
jobs                                           batch/v1                          true         Job
ingresses                         ing          networking.k8s.io/v1              true         Ingress
...

# Namespaced リソースのみ表示
$ kubectl api-resources --namespaced=true

# 特定の API グループのリソース
$ kubectl api-resources --api-group=apps
NAME                SHORTNAMES   APIVERSION   NAMESPACED   KIND
controllerrevisions                apps/v1     true         ControllerRevision
daemonsets          ds           apps/v1      true         DaemonSet
deployments         deploy       apps/v1      true         Deployment
replicasets         rs           apps/v1      true         ReplicaSet
statefulsets        sts          apps/v1      true         StatefulSet

# API バージョンの一覧
$ kubectl api-versions
admissionregistration.k8s.io/v1
apiextensions.k8s.io/v1
apiregistration.k8s.io/v1
apps/v1
authentication.k8s.io/v1
authorization.k8s.io/v1
autoscaling/v1
autoscaling/v2
batch/v1
...
v1

# リソースのスキーマを確認 (explain)
$ kubectl explain pod
KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Pod is a collection of containers that can run on a host. This resource is
    created by clients and scheduled onto hosts.

FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
  kind  <string>
    Kind is a string value representing the REST resource this object represents.
  metadata      <ObjectMeta>
    Standard object's metadata.
  spec  <PodSpec>
    Specification of the desired behavior of the pod.
  status        <PodStatus>
    Most recently observed status of the pod.

# 特定のフィールドを深掘り
$ kubectl explain pod.spec.containers
KIND:       Pod
VERSION:    v1

FIELD: containers <[]Container>

DESCRIPTION:
    List of containers belonging to the pod.

FIELDS:
  args  <[]string>
    Arguments to the entrypoint.
  command       <[]string>
    Entrypoint array.
  env   <[]EnvVar>
    List of environment variables to set in the container.
  image <string>
    Container image name.
  imagePullPolicy       <string>
    Image pull policy. One of Always, Never, IfNotPresent.
  ...

# 再帰的に全フィールドを表示
$ kubectl explain pod.spec --recursive | head -50
KIND:       Pod
VERSION:    v1
FIELD: spec <PodSpec>
  activeDeadlineSeconds <integer>
  affinity      <Affinity>
    nodeAffinity        <NodeAffinity>
      preferredDuringSchedulingIgnoredDuringExecution    <[]PreferredSchedulingTerm>
        preference      <NodeSelectorTerm>
          matchExpressions      <[]NodeSelectorRequirement>
            key <string>
            operator    <string>
            values      <[]string>
  ...

13. 出力フォーマット

13.1 基本的な出力フォーマット

# デフォルト(テーブル形式)
$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h

# ワイド出力(追加カラム)
$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
nginx-deploy-6b7f675859-2xj4k    1/1     Running   0          3h    10.244.1.5   worker-1   <none>           <none>

# YAML 出力
$ kubectl get pod nginx-deploy-6b7f675859-2xj4k -o yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-deploy-6b7f675859-2xj4k
  namespace: default
  labels:
    app: nginx
    pod-template-hash: 6b7f675859
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ...

# JSON 出力
$ kubectl get pod nginx-deploy-6b7f675859-2xj4k -o json
{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "nginx-deploy-6b7f675859-2xj4k",
    "namespace": "default",
    ...
  }
}

# 名前のみ出力
$ kubectl get pods -o name
pod/nginx-deploy-6b7f675859-2xj4k
pod/nginx-deploy-6b7f675859-8kl9m
pod/redis-master-0

13.2 JSONPath

# Pod の IP アドレスを取得
$ kubectl get pod nginx-deploy-6b7f675859-2xj4k -o jsonpath='{.status.podIP}'
10.244.1.5

# 全 Pod の名前と IP を取得
$ kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'
nginx-deploy-6b7f675859-2xj4k    10.244.1.5
nginx-deploy-6b7f675859-8kl9m    10.244.2.8
redis-master-0                     10.244.3.12

# コンテナイメージの一覧を取得
$ kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}'
nginx:1.25 nginx:1.25 redis:7.2

# 改行区切りで表示
$ kubectl get pods -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}'
nginx:1.25
nginx:1.25
redis:7.2

# 条件付きフィルタリング
$ kubectl get nodes -o jsonpath='{.items[?(@.status.conditions[-1].type=="Ready")].metadata.name}'
master-1 worker-1 worker-2 worker-3

# Secret の値をデコード
$ kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
S3cureP@ss!

# ノードの内部 IP を取得
$ kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.addresses[?(@.type=="InternalIP")].address}{"\n"}{end}'
master-1    192.168.1.100
worker-1    192.168.1.101
worker-2    192.168.1.102
worker-3    192.168.1.103

# Pod の全コンテナのリソース要求を表示
$ kubectl get pods -o jsonpath='{range .items[*]}{"Pod: "}{.metadata.name}{"\n"}{range .spec.containers[*]}{"  Container: "}{.name}{" CPU: "}{.resources.requests.cpu}{" Memory: "}{.resources.requests.memory}{"\n"}{end}{end}'
Pod: nginx-deploy-6b7f675859-2xj4k
  Container: nginx CPU: 100m Memory: 128Mi
Pod: redis-master-0
  Container: redis CPU: 200m Memory: 256Mi

13.3 Custom Columns

# カスタムカラムで表示
$ kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName,IP:.status.podIP
NAME                              STATUS    NODE       IP
nginx-deploy-6b7f675859-2xj4k    Running   worker-1   10.244.1.5
nginx-deploy-6b7f675859-8kl9m    Running   worker-2   10.244.2.8
redis-master-0                    Running   worker-3   10.244.3.12

# コンテナイメージとリソース制限
$ kubectl get pods -o custom-columns=\
'NAME:.metadata.name,IMAGE:.spec.containers[0].image,CPU_REQ:.spec.containers[0].resources.requests.cpu,MEM_REQ:.spec.containers[0].resources.requests.memory,CPU_LIM:.spec.containers[0].resources.limits.cpu,MEM_LIM:.spec.containers[0].resources.limits.memory'
NAME                              IMAGE        CPU_REQ   MEM_REQ   CPU_LIM   MEM_LIM
nginx-deploy-6b7f675859-2xj4k    nginx:1.25   100m      128Mi     500m      256Mi
nginx-deploy-6b7f675859-8kl9m    nginx:1.25   100m      128Mi     500m      256Mi

# ファイルからカスタムカラム定義を読み込み
$ cat columns.txt
NAME          STATUS          NODE            IP
.metadata.name   .status.phase   .spec.nodeName   .status.podIP

$ kubectl get pods -o custom-columns-file=columns.txt

13.4 jq との連携

# jq で JSON を加工
$ kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase, restarts: .status.containerStatuses[0].restartCount}'
{
  "name": "nginx-deploy-6b7f675859-2xj4k",
  "status": "Running",
  "restarts": 0
}
{
  "name": "nginx-deploy-6b7f675859-8kl9m",
  "status": "Running",
  "restarts": 0
}

# 特定の条件でフィルタ
$ kubectl get pods -A -o json | jq '.items[] | select(.status.phase != "Running") | {namespace: .metadata.namespace, name: .metadata.name, status: .status.phase}'

# リソース使用量の集計
$ kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cpu: .status.capacity.cpu, memory: .status.capacity.memory}'
{
  "name": "master-1",
  "cpu": "4",
  "memory": "16384Mi"
}
{
  "name": "worker-1",
  "cpu": "4",
  "memory": "16384Mi"
}

# イメージの一覧を重複なしで取得
$ kubectl get pods -A -o json | jq -r '[.items[].spec.containers[].image] | unique[]'
coredns:v1.11.1
etcd:3.5.12
kube-apiserver:v1.30.1
kube-proxy:v1.30.1
nginx:1.25
redis:7.2

# Pod の起動時間順にソート
$ kubectl get pods -o json | jq -r '.items | sort_by(.status.startTime) | .[] | "\(.metadata.name)\t\(.status.startTime)"'

13.5 Go テンプレート

# Go テンプレートで出力
$ kubectl get pods -o go-template='{{range .items}}{{.metadata.name}}{{"\t"}}{{.status.phase}}{{"\n"}}{{end}}'
nginx-deploy-6b7f675859-2xj4k    Running
nginx-deploy-6b7f675859-8kl9m    Running
redis-master-0                     Running

# 条件分岐
$ kubectl get pods -o go-template='{{range .items}}{{if eq .status.phase "Running"}}{{.metadata.name}} is running{{"\n"}}{{end}}{{end}}'
nginx-deploy-6b7f675859-2xj4k is running
nginx-deploy-6b7f675859-8kl9m is running
redis-master-0 is running

# コンテナの詳細を表示
$ kubectl get pods -o go-template='{{range .items}}Pod: {{.metadata.name}}{{"\n"}}{{range .spec.containers}}  Container: {{.name}} Image: {{.image}}{{"\n"}}{{end}}{{end}}'
Pod: nginx-deploy-6b7f675859-2xj4k
  Container: nginx Image: nginx:1.25
Pod: redis-master-0
  Container: redis Image: redis:7.2

14. プラグインと拡張機能

14.1 Krew プラグインマネージャー

# Krew のインストール
$ (
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

# PATH に追加
$ echo 'export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

# プラグイン一覧を検索
$ kubectl krew search
NAME                            DESCRIPTION                                         INSTALLED
access-matrix                   Show an RBAC access matrix for server resources      no
ctx                             Switch between contexts in your kubeconfig           no
images                          Show container images used in the cluster            no
neat                            Remove clutter from Kubernetes manifests             no
ns                              Switch between Kubernetes namespaces                 no
oidc-login                      Log in to the Kubernetes cluster via OpenID Co...    no
resource-capacity               Provides an overview of resource requests, lim...    no
tree                            Show a tree of object hierarchies through owne...    no
view-secret                     Decode Kubernetes secrets                            no
whoami                          Show the subject that's currently authenticated      no
...

# プラグインをインストール
$ kubectl krew install ctx
Updated the local copy of plugin index.
Installing plugin: ctx
Installed plugin: ctx

# インストール済みプラグインの一覧
$ kubectl krew list
PLUGIN   VERSION
ctx      v0.9.5
krew     v0.4.4

# プラグインの更新
$ kubectl krew upgrade
Updated the local copy of plugin index.
Upgrading plugin: ctx

14.2 人気プラグイン

kubectl-ctx(コンテキスト切り替え)

$ kubectl krew install ctx

# インタラクティブにコンテキストを選択
$ kubectl ctx
prod-admin
staging-dev    # 現在のコンテキストがハイライトされる
development

# コンテキストを直接切り替え
$ kubectl ctx staging-dev
Switched to context "staging-dev".

# 前のコンテキストに戻る
$ kubectl ctx -
Switched to context "prod-admin".

kubectl-ns(Namespace 切り替え)

$ kubectl krew install ns

# インタラクティブに Namespace を選択
$ kubectl ns
default
kube-system
monitoring
production
staging

# Namespace を直接切り替え
$ kubectl ns monitoring
Context "prod-admin" modified.
Active namespace is "monitoring".

# 前の Namespace に戻る
$ kubectl ns -
Context "prod-admin" modified.
Active namespace is "default".

kubectl-neat(YAML クリーンアップ)

$ kubectl krew install neat

# 不要なフィールド(managedFields, status など)を除去して表示
$ kubectl get pod nginx-deploy-6b7f675859-2xj4k -o yaml | kubectl neat
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
    pod-template-hash: 6b7f675859
  name: nginx-deploy-6b7f675859-2xj4k
  namespace: default
spec:
  containers:
  - image: nginx:1.25
    name: nginx
    ports:
    - containerPort: 80
    resources:
      limits:
        cpu: 500m
        memory: 256Mi
      requests:
        cpu: 100m
        memory: 128Mi

# Deployment の YAML をクリーンに出力
$ kubectl get deployment nginx-deploy -o yaml | kubectl neat > clean-deployment.yaml

kubectl-tree(リソースツリー表示)

$ kubectl krew install tree

# Deployment のリソースツリーを表示
$ kubectl tree deployment nginx-deploy
NAMESPACE  NAME                                       READY  REASON  AGE
default    Deployment/nginx-deploy                    -              3h
default    └─ReplicaSet/nginx-deploy-6b7f675859       -              3h
default      ├─Pod/nginx-deploy-6b7f675859-2xj4k     True           3h
default      └─Pod/nginx-deploy-6b7f675859-8kl9m     True           3h

# Service のツリーを表示
$ kubectl tree service nginx-svc
NAMESPACE  NAME                                       READY  REASON  AGE
default    Service/nginx-svc                          -              3h
default    └─EndpointSlice/nginx-svc-xxxxx            -              3h

kubectl-images(イメージ一覧)

$ kubectl krew install images

# クラスタ内で使用されているイメージの一覧
$ kubectl images -A
[Summary]: 1 namespace, 5 pods, 6 containers and 4 different images
+---------------------+--------------------------------------------+--------------+
|       Pod Name      |                  Container                 |    Image     |
+---------------------+--------------------------------------------+--------------+
| nginx-deploy-2xj4k  | nginx                                     | nginx:1.25   |
| nginx-deploy-8kl9m  | nginx                                     | nginx:1.25   |
| redis-master-0       | redis                                     | redis:7.2    |
| multi-pod            | app                                       | myapp:v2     |
| multi-pod            | sidecar                                   | fluentd:1.16 |
+---------------------+--------------------------------------------+--------------+

kubectl-whoami(認証情報の確認)

$ kubectl krew install whoami

$ kubectl whoami
kubecfg:certauth:admin
   Issuer: CN=kubernetes
   Subject: O=system:masters,CN=admin-user

14.3 プラグイン開発の基本

kubectl プラグインは kubectl-<name> という名前の実行可能ファイルを PATH に配置するだけで利用できます。

# シンプルなプラグインの例(kubectl-pod-status)
$ cat > /usr/local/bin/kubectl-pod_status <<'EOF'
#!/bin/bash
# kubectl pod-status: 全 Pod のステータスサマリーを表示
echo "=== Pod Status Summary ==="
echo ""
kubectl get pods -A -o json | jq -r '
  [.items[].status.phase] |
  group_by(.) |
  map({status: .[0], count: length}) |
  sort_by(-.count) |
  .[] |
  "\(.status): \(.count)"
'
echo ""
echo "Total: $(kubectl get pods -A --no-headers | wc -l | tr -d ' ') pods"
EOF

$ chmod +x /usr/local/bin/kubectl-pod_status

# プラグインの使用
$ kubectl pod-status
=== Pod Status Summary ===

Running: 25
Succeeded: 3
Pending: 1

Total: 29 pods

# インストール済みプラグインの確認
$ kubectl plugin list
The following compatible plugins are available:

/usr/local/bin/kubectl-pod_status
/home/user/.krew/bin/kubectl-ctx
/home/user/.krew/bin/kubectl-ns
/home/user/.krew/bin/kubectl-neat
/home/user/.krew/bin/kubectl-tree

15. 生産性向上のヒント

15.1 エイリアスの設定

# ~/.bashrc または ~/.zshrc に追加
# 基本エイリアス
alias k='kubectl'
alias kg='kubectl get'
alias kd='kubectl describe'
alias kl='kubectl logs'
alias ke='kubectl exec -it'
alias ka='kubectl apply -f'
alias kdel='kubectl delete'

# リソース別エイリアス
alias kgp='kubectl get pods'
alias kgpa='kubectl get pods -A'
alias kgpw='kubectl get pods -o wide'
alias kgd='kubectl get deployments'
alias kgs='kubectl get services'
alias kgn='kubectl get nodes'
alias kgns='kubectl get namespaces'
alias kgcm='kubectl get configmaps'
alias kgsec='kubectl get secrets'
alias kge='kubectl get events --sort-by=".lastTimestamp"'

# 操作系エイリアス
alias kaf='kubectl apply -f'
alias kdf='kubectl delete -f'
alias kex='kubectl exec -it'
alias klo='kubectl logs -f'
alias kpf='kubectl port-forward'
alias ktn='kubectl top nodes'
alias ktp='kubectl top pods'

# コンテキスト・Namespace エイリアス
alias kcc='kubectl config current-context'
alias kuc='kubectl config use-context'
alias kns='kubectl config set-context --current --namespace'

# 高度なエイリアス
alias kwatch='kubectl get pods -w'
alias kevents='kubectl get events --sort-by=.lastTimestamp'
alias krestartcount='kubectl get pods --sort-by=".status.containerStatuses[0].restartCount"'

# 関数として定義(引数を受け取る)
kexec() { kubectl exec -it "$1" -- "${2:-/bin/sh}"; }
klogs() { kubectl logs -f "$1" --tail="${2:-100}"; }
kscale() { kubectl scale deployment "$1" --replicas="$2"; }

15.2 kubectl ショートカット(リソース短縮名)

# よく使うリソースの短縮名
# po   = pods
# svc  = services
# deploy = deployments
# ds   = daemonsets
# sts  = statefulsets
# rs   = replicasets
# cm   = configmaps
# ns   = namespaces
# no   = nodes
# pv   = persistentvolumes
# pvc  = persistentvolumeclaims
# sa   = serviceaccounts
# ing  = ingresses
# ep   = endpoints
# ev   = events
# cj   = cronjobs
# hpa  = horizontalpodautoscalers
# pdb  = poddisruptionbudgets
# sc   = storageclasses
# limits = limitranges
# quota  = resourcequotas

# 使用例
$ k get po                     # kubectl get pods
$ k get svc                    # kubectl get services
$ k get deploy                 # kubectl get deployments
$ k get no                     # kubectl get nodes
$ k get cm                     # kubectl get configmaps
$ k get ns                     # kubectl get namespaces
$ k describe po nginx          # kubectl describe pod nginx
$ k get pvc                    # kubectl get persistentvolumeclaims
$ k get ev --sort-by='.lastTimestamp'  # kubectl get events

15.3 .kube/config のヒント

# コンテキストごとに異なる色やアイコンを設定(kubectx + kubens との組み合わせ)

# 環境ごとに kubeconfig を分割管理
$ export KUBECONFIG=~/.kube/configs/production:~/.kube/configs/staging:~/.kube/configs/development

# シェルのプロンプトに現在のコンテキストを表示(bash)
$ cat >> ~/.bashrc <<'EOF'
kube_prompt() {
  local ctx=$(kubectl config current-context 2>/dev/null)
  local ns=$(kubectl config view --minify -o jsonpath='{..namespace}' 2>/dev/null)
  if [ -n "$ctx" ]; then
    echo " [k8s:${ctx}/${ns:-default}]"
  fi
}
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(kube_prompt)\$ '
EOF

# プロンプト表示例:
# user@hostname:~/work [k8s:prod-admin/default]$

# kube-ps1 を使う(より高機能)
# macOS
$ brew install kube-ps1
$ echo 'source "/opt/homebrew/opt/kube-ps1/share/kube-ps1.sh"' >> ~/.zshrc
$ echo 'PROMPT='\''$(kube_ps1)'\'' $PROMPT' >> ~/.zshrc

# プロンプト表示例:
# (⎈|prod-admin:default) $

15.4 kubectx / kubens(独立ツール版)

# インストール(Homebrew)
$ brew install kubectx

# kubectx: コンテキスト管理
$ kubectx
prod-admin
staging-dev
development

$ kubectx staging-dev
Switched to context "staging-dev".

$ kubectx -        # 前のコンテキストに戻る
Switched to context "prod-admin".

# kubens: Namespace 管理
$ kubens
default
kube-system
monitoring
production

$ kubens monitoring
Context "prod-admin" modified.
Active namespace is "monitoring".

$ kubens -          # 前の Namespace に戻る
Context "prod-admin" modified.
Active namespace is "default".

15.5 便利な One-Liner

# 全 Namespace の全イメージを一覧(重複なし)
$ kubectl get pods -A -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' | sort -u

# リスタート回数が多い Pod を表示
$ kubectl get pods -A --sort-by='.status.containerStatuses[0].restartCount' | tail -10

# Running でない Pod を表示
$ kubectl get pods -A --field-selector status.phase!=Running | grep -v Completed

# 各ノードの Pod 数を表示
$ kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.nodeName}{"\n"}{end}' | sort | uniq -c | sort -rn
  12 worker-1
  10 worker-2
   8 worker-3
   5 master-1

# リソース要求の合計を計算
$ kubectl get pods -o json | jq '[.items[].spec.containers[].resources.requests.cpu // "0m" | rtrimstr("m") | tonumber] | add'
1500

# 古い ReplicaSet を削除
$ kubectl get rs -o json | jq -r '.items[] | select(.spec.replicas==0) | .metadata.name' | xargs kubectl delete rs

# 全ての Failed/Evicted Pod を削除
$ kubectl get pods -A --field-selector status.phase=Failed -o json | \
    jq -r '.items[] | "\(.metadata.namespace) \(.metadata.name)"' | \
    while read ns name; do kubectl delete pod "$name" -n "$ns"; done

# Secret の値を全てデコードして表示
$ kubectl get secret db-secret -o json | jq -r '.data | to_entries[] | "\(.key): \(.value | @base64d)"'
username: admin
password: S3cureP@ss!

16. 運用ワークフロー

16.1 デプロイメントワークフロー

# ===== 本番デプロイメントの典型的なワークフロー =====

# 1. 現在の状態を確認
$ kubectl get deployment myapp -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES        SELECTOR
myapp   3/3     3            3           30d   myapp        myapp:v1.0    app=myapp

# 2. 変更前の差分を確認
$ kubectl diff -f manifests/deployment-v2.yaml
...
-        image: myapp:v1.0
+        image: myapp:v2.0
...

# 3. 変更理由をアノテーションに記録
$ kubectl annotate deployment myapp \
    kubernetes.io/change-cause="Deploy v2.0: performance improvements and bug fixes (JIRA-1234)"

# 4. Server-side dry-run でバリデーション
$ kubectl apply -f manifests/deployment-v2.yaml --dry-run=server
deployment.apps/myapp created (server dry run)

# 5. 適用
$ kubectl apply -f manifests/deployment-v2.yaml
deployment.apps/myapp configured

# 6. ロールアウトを監視
$ kubectl rollout status deployment/myapp
Waiting for deployment "myapp" spec update to be observed...
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "myapp" successfully rolled out

# 7. 新しい Pod の状態を確認
$ kubectl get pods -l app=myapp
NAME                     READY   STATUS    RESTARTS   AGE
myapp-7c9f8b6d54-abc12   1/1     Running   0          2m
myapp-7c9f8b6d54-def34   1/1     Running   0          90s
myapp-7c9f8b6d54-ghi56   1/1     Running   0          60s

# 8. ログでエラーがないか確認
$ kubectl logs -l app=myapp --tail=20
[2026-04-08 10:00:00] INFO: Application started on port 8080
[2026-04-08 10:00:01] INFO: Health check endpoint ready
[2026-04-08 10:00:02] INFO: Connected to database

# 9. 問題がある場合はロールバック
$ kubectl rollout undo deployment/myapp
deployment.apps/myapp rolled back

# 10. ロールバック後の確認
$ kubectl rollout status deployment/myapp
deployment "myapp" successfully rolled out

$ kubectl get deployment myapp -o jsonpath='{.spec.template.spec.containers[0].image}'
myapp:v1.0

16.2 インシデント対応ワークフロー

# ===== インシデント発生時の初動調査 =====

# 1. クラスタ全体の健全性を確認
$ kubectl get nodes
NAME       STATUS     ROLES           AGE   VERSION
master-1   Ready      control-plane   90d   v1.30.1
worker-1   Ready      <none>          90d   v1.30.1
worker-2   NotReady   <none>          90d   v1.30.1    # 問題あり
worker-3   Ready      <none>          85d   v1.30.1

# 2. ノードの詳細を確認
$ kubectl describe node worker-2
...
Conditions:
  Type                 Status  LastHeartbeatTime                 Reason                  Message
  ----                 ------  -----------------                 ------                  -------
  MemoryPressure       True    Wed, 08 Apr 2026 10:00:00 +0900  KubeletHasMemoryPressure  kubelet has memory pressure
  DiskPressure         False   Wed, 08 Apr 2026 10:00:00 +0900  KubeletHasNoDiskPressure
  PIDPressure          False   Wed, 08 Apr 2026 10:00:00 +0900  KubeletHasSufficientPID
  Ready                False   Wed, 08 Apr 2026 10:00:00 +0900  KubeletNotReady          container runtime is down

# 3. 影響を受ける Pod を確認
$ kubectl get pods -A -o wide --field-selector spec.nodeName=worker-2
NAMESPACE   NAME                        READY   STATUS    RESTARTS   AGE   IP           NODE
default     myapp-7c9f8b6d54-abc12      0/1     Unknown   0          1h    10.244.2.5   worker-2
monitoring  node-exporter-xxxxx         0/1     Unknown   0          30d   10.244.2.3   worker-2

# 4. 全体的な Pod の状態を確認
$ kubectl get pods -A | grep -v Running | grep -v Completed
NAMESPACE   NAME                        READY   STATUS    RESTARTS      AGE
default     myapp-7c9f8b6d54-abc12      0/1     Unknown   0             1h
default     failing-pod-xxxxx           0/1     CrashLoopBackOff   15   30m
monitoring  node-exporter-xxxxx         0/1     Unknown   0             30d

# 5. Warning イベントを確認
$ kubectl get events -A --field-selector type=Warning --sort-by='.lastTimestamp' | tail -20

# 6. リソース使用状況を確認
$ kubectl top nodes
NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master-1   350m         8%     2048Mi          12%
worker-1   3500m        92%    14336Mi         90%    # リソース逼迫
worker-3   600m         15%    2560Mi          16%

$ kubectl top pods -A --sort-by=memory | tail -10

# 7. 問題のある Pod の詳細調査
$ kubectl describe pod failing-pod-xxxxx
$ kubectl logs failing-pod-xxxxx --previous --tail=100

# 8. ノードのデバッグ(必要に応じて)
$ kubectl debug node/worker-2 -it --image=ubuntu:22.04
root@worker-2:/# chroot /host
root@worker-2:/# journalctl -u kubelet --since "30 minutes ago" --no-pager | tail -50
root@worker-2:/# free -h
root@worker-2:/# df -h
root@worker-2:/# exit

# 9. クラスタ情報のダンプ(必要に応じて)
$ kubectl cluster-info dump --output-directory=/tmp/incident-dump-$(date +%Y%m%d-%H%M%S)

16.3 スケーリングワークフロー

# ===== 手動スケーリング =====

# 現在のレプリカ数を確認
$ kubectl get deployment myapp
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
myapp   3/3     3            3           30d

# スケールアップ
$ kubectl scale deployment myapp --replicas=10
deployment.apps/myapp scaled

# 進行状況を監視
$ kubectl rollout status deployment/myapp
Waiting for rollout to finish: 5 of 10 updated replicas are available...
Waiting for rollout to finish: 8 of 10 updated replicas are available...
deployment "myapp" successfully rolled out

# リソース状況を確認
$ kubectl top pods -l app=myapp
NAME                     CPU(cores)   MEMORY(bytes)
myapp-7c9f8b6d54-abc12   50m          64Mi
myapp-7c9f8b6d54-def34   45m          62Mi
...

# ===== HPA を使った自動スケーリング =====

# HPA を設定
$ kubectl autoscale deployment myapp --min=3 --max=20 --cpu-percent=70
horizontalpodautoscaler.autoscaling/myapp autoscaled

# HPA の動作を監視
$ kubectl get hpa myapp -w
NAME    REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
myapp   Deployment/myapp   45%/70%   3         20        3          1m
myapp   Deployment/myapp   85%/70%   3         20        3          2m
myapp   Deployment/myapp   85%/70%   3         20        5          3m    # スケールアップ
myapp   Deployment/myapp   60%/70%   3         20        5          4m
myapp   Deployment/myapp   40%/70%   3         20        5          5m
myapp   Deployment/myapp   35%/70%   3         20        3          10m   # スケールダウン

# スケーリングイベントを確認
$ kubectl describe hpa myapp
...
Events:
  Type    Reason             Age   From                       Message
  ----    ------             ----  ----                       -------
  Normal  SuccessfulRescale  3m    horizontal-pod-autoscaler  New size: 5; reason: cpu resource utilization above target
  Normal  SuccessfulRescale  30s   horizontal-pod-autoscaler  New size: 3; reason: All metrics below target

16.4 証明書管理

# TLS Secret の確認
$ kubectl get secrets --field-selector type=kubernetes.io/tls -A
NAMESPACE   NAME              TYPE                DATA   AGE
default     my-tls-secret     kubernetes.io/tls   2      30d
ingress     ingress-tls       kubernetes.io/tls   2      60d

# 証明書の有効期限を確認
$ kubectl get secret my-tls-secret -o jsonpath='{.data.tls\.crt}' | \
    base64 -d | openssl x509 -noout -dates
notBefore=Jan  7 00:00:00 2026 GMT
notAfter=Apr  7 00:00:00 2027 GMT

# 証明書の詳細を確認
$ kubectl get secret my-tls-secret -o jsonpath='{.data.tls\.crt}' | \
    base64 -d | openssl x509 -noout -text | head -20
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:23:45:67:89:ab:cd:ef
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=R3
        Validity
            Not Before: Jan  7 00:00:00 2026 GMT
            Not After : Apr  7 00:00:00 2027 GMT
        Subject: CN=app.example.com
        Subject Public Key Info:
            ...

# TLS Secret を更新
$ kubectl create secret tls my-tls-secret \
    --cert=./new-server.crt \
    --key=./new-server.key \
    --dry-run=client -o yaml | kubectl apply -f -
secret/my-tls-secret configured

# cert-manager で管理されている証明書の確認
$ kubectl get certificates -A
NAMESPACE   NAME           READY   SECRET         AGE
default     app-cert       True    app-tls        30d
ingress     wildcard-cert  True    wildcard-tls   60d

$ kubectl describe certificate app-cert
Name:         app-cert
Namespace:    default
...
Status:
  Conditions:
    Type:               Ready
    Status:             True
    Reason:             Ready
    Message:            Certificate is up to date and has not expired
  Not After:            2027-04-07T00:00:00Z
  Not Before:           2026-01-07T00:00:00Z
  Renewal Time:         2027-03-08T00:00:00Z

16.5 まとめ:kubectl コマンドのクイックリファレンス

カテゴリコマンド説明
取得kubectl get <resource>リソース一覧を表示
詳細kubectl describe <resource> <name>リソースの詳細を表示
作成kubectl apply -f <file>マニフェストからリソースを作成/更新
削除kubectl delete <resource> <name>リソースを削除
編集kubectl edit <resource> <name>リソースを直接編集
パッチkubectl patch <resource> <name> -p '<json>'リソースを部分更新
実行kubectl run <name> --image=<image>Pod を実行
コマンド実行kubectl exec -it <pod> -- <cmd>Pod 内でコマンドを実行
ログkubectl logs <pod>Pod のログを表示
ポートフォワードkubectl port-forward <pod> <local>:<remote>ポートをフォワード
スケールkubectl scale deployment <name> --replicas=<n>レプリカ数を変更
ロールアウトkubectl rollout status deployment/<name>ロールアウトを監視
ロールバックkubectl rollout undo deployment/<name>前のバージョンに戻す
デバッグkubectl debug <pod> -it --image=<image>デバッグコンテナを追加
差分kubectl diff -f <file>変更差分をプレビュー
待機kubectl wait --for=condition=Ready pod/<name>条件を満たすまで待機
API 探索kubectl api-resources利用可能なリソース一覧
スキーマkubectl explain <resource>リソースのスキーマを表示

本ドキュメントは 2026 年 4 月時点の Kubernetes v1.30 を基準に作成されています。最新の情報は 公式ドキュメント を参照してください。