Ritolabo
  1. Home
  2. Kubernetes
  3. kubectl で Kubernetes のクラスタを操作する

kubectl で Kubernetes のクラスタを操作する

  • 公開日
  • カテゴリ:Kubernetes
  • タグ:Kubernetes,学習メモ
kubectl で Kubernetes のクラスタを操作する

Kubernetes のクラスタは、kubectl というコマンドで操作する。Pod を作るのも、状態を見るのも、消すのも kubectl で行う。

この記事では、kubectl がクラスタとどうやりとりしているかを確かめたうえで、よく使う操作をローカルのクラスタで試して整理する。Pod の作り方そのものは「Kubernetes の Pod とは?コンテナを動かす最小単位を整理する」を参照。

この記事でやること:

  • kubectl の操作対象のクラスタ(context)の確認
  • kubectl が送っている HTTP リクエストの確認
  • kubectl get の出力の切り替え(-o yaml、-n、-A)
  • kubectl explain によるフィールドの意味の確認
  • kubectl exec によるコンテナ内でのコマンド実行
  • YAML を書き換えて kubectl apply し直したときの動き

contents

  1. 環境
  2. kubectl とは
    1. 操作対象のクラスタ:context
    2. 送っているリクエストを見る
  3. kubectl get の出力を切り替える
    1. -o yaml
    2. -n と -A:namespace
    3. RESTARTS 列
  4. kubectl explain:フィールドの意味を調べる
  5. kubectl exec:コンテナの中でコマンドを実行する
  6. kubectl apply し直す:変更の反映
    1. image を書き換えて apply する
    2. 変更せずに apply する
    3. create との違い
    4. 消す
  7. 用語メモ
  8. 参考 URL

環境

kind で作ったクラスタ(Control Plane 1台 + Worker 2台)を使う。作り方は「Kubernetes の Pod とは?コンテナを動かす最小単位を整理する」に書いている。

kubectl get nodes
NAME                      STATUS   ROLES           AGE   VERSION
k8s-study-control-plane   Ready    control-plane   23h   v1.37.0
k8s-study-worker          Ready    <none>          22h   v1.37.0
k8s-study-worker2         Ready    <none>          22h   v1.37.0
  • 環境: macOS(Apple Silicon)、Docker Desktop 29.8.0、kind v0.33.0、Kubernetes v1.37.0、kubectl v1.36.1

操作の題材には、nginx のコンテナを1つ入れた Pod を使う。

# nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.14.2
      ports:
        - containerPort: 80

kubectl とは

公式ドキュメントでは、kubectl は「Kubernetes API を使って、Kubernetes クラスタのコントロールプレーンと通信するためのコマンドラインツール」とされている。

Mac                                    クラスタ
kubectl get pods ──── HTTP で要求 ───▶ kube-apiserver(Control Plane の窓口)
                 ◀─── 答え ───────────
  • kubectl はクラスタの窓口である kube-apiserver にリクエストを送り、返ってきた答えを表示する
  • Pod を作る、Node を決める、コンテナを起動するといった実際の処理は、クラスタ側が行う

操作対象のクラスタ:context

kubectl がどのクラスタを操作するかは、context で決まる。今の context は次のコマンドで確かめられる。

kubectl config current-context

# => kind-k8s-study
kubectl config get-contexts

CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
*         kind-k8s-study   kind-k8s-study   kind-k8s-study
  • * が付いているのが今使っている context。kind はクラスタを作るときに kind-<クラスタ名> という名前で登録する
  • context は、クラスタ・ユーザー・namespace の組み合わせに名前を付けたもの
  • この情報は ~/.kube/config(kubeconfig ファイル)に書かれていて、kubectl は実行のたびにこのファイルを読む
  • 複数のクラスタ(開発用、本番用など)を扱うと、この一覧に複数の行が並ぶ

送っているリクエストを見る

-v=6 を付けると、kubectl が送ったリクエストが表示される。

kubectl get nodes -v=6

いつもの表に加えて、次の行が出る。

I0927 10:39:41.995110    5543 round_trippers.go:632] "Response" verb="GET" url="https://127.0.0.1:52024/api/v1/nodes?limit=500" status="200 OK" milliseconds=15
  • https://127.0.0.1:52024 が kube-apiserver の住所。kind が Mac のポートにつないでいる(番号は環境ごとに違う)
  • /api/v1/nodes に対する GET が「Node の一覧をください」というリクエスト
  • status="200 OK" は、答えが正常に返ってきたという意味

kubectl get nodes の表は、この答えの一部の項目を並べたもの。表にする前のデータは、--raw で見られる。

kubectl get --raw /api/v1/nodes

長い JSON が出る。その中から表の列にあたる部分を抜き出すと、次のようになっている(値は1台目の Node のもの)。

表の列JSON の中の場所値
NAMEmetadata.namek8s-study-control-plane
STATUSstatus.conditions の type: Ready の statusTrue(表では Ready)
ROLESmetadata.labels の node-role.kubernetes.io/control-planeラベルがあるので control-plane
AGEmetadata.creationTimestamp2026-09-26T02:40:30Z(ここからの経過時間)
VERSIONstatus.nodeInfo.kubeletVersionv1.37.0

表に出ていない情報(Node の IP、OS、CPU の数など)も、このデータには含まれている。

kubectl get の出力を切り替える

以降は nginx-pod.yaml の Pod を作った状態で試す。

kubectl apply -f nginx-pod.yaml

-o yaml

-o yaml を付けると、リソースの全体が YAML で出る。

kubectl get pod nginx -o yaml

自分で書いた nginx-pod.yaml は 10 行ほどだが、出力は 100 行を超える。中身は大きく2つに分かれる。

場所中身
spec:自分が書いた内容。書いていない項目(restartPolicy: Always など)も既定値で埋められている
status:Kubernetes が書き足した今の状態。phase: Running、podIP、コンテナの restartCount など

kubectl get pods の表や kubectl describe は、この中から一部を抜き出して見やすくしたもの。-o json にすると同じ内容が JSON で出る。

-n と -A:namespace

Kubernetes のリソースは namespace という区画に分けて置かれる。何も指定しないと default という namespace を見ている。

クラスタ自身の部品が置かれている kube-system を指定すると、次のようになる。

kubectl get pods -n kube-system
NAME                                              READY   STATUS    RESTARTS      AGE
coredns-559f6c778d-9jtk8                          1/1     Running   1 (10m ago)   23h
coredns-559f6c778d-rf79d                          1/1     Running   1 (10m ago)   23h
etcd-k8s-study-control-plane                      1/1     Running   0             10m
kindnet-ds92d                                     1/1     Running   1 (10m ago)   23h
kindnet-m7w6c                                     1/1     Running   1 (10m ago)   23h
kindnet-s5vkj                                     1/1     Running   1 (10m ago)   23h
kube-apiserver-k8s-study-control-plane            1/1     Running   0             10m
kube-controller-manager-k8s-study-control-plane   1/1     Running   1 (10m ago)   23h
kube-proxy-qx648                                  1/1     Running   1 (10m ago)   23h
kube-proxy-sgqwh                                  1/1     Running   1 (10m ago)   23h
kube-proxy-vfdhm                                  1/1     Running   1 (10m ago)   23h
kube-scheduler-k8s-study-control-plane            1/1     Running   1 (10m ago)   23h

kubectl がリクエストを送っている kube-apiserver も、etcd や kube-scheduler も、ここに Pod として並んでいる。

そのため、kubectl get pods で No resources found in default namespace. と出ても、クラスタに Pod が1つもないわけではない。-A(all namespaces)を付けると、すべての namespace の Pod が NAMESPACE 列付きで出る。

kubectl get pods -A
NAMESPACE            NAME                                              READY   STATUS    RESTARTS        AGE
default              nginx                                             1/1     Running   1 (3m40s ago)   3m53s
kube-system          coredns-559f6c778d-9jtk8                          1/1     Running   1 (35m ago)     23h
...

RESTARTS 列

上の一覧で RESTARTS が 1 (10m ago) になっているのは、「Pod の中のコンテナを1回起動し直した。最後に起動し直したのは 10 分前」という意味。

  • 起動し直すのはコンテナで、Pod はそのまま残る。そのため RESTARTS が増えても AGE(Pod を作ってからの時間)は続く

kubectl explain:フィールドの意味を調べる

YAML に書くフィールドの意味は、kubectl explain で調べられる。nginx-pod.yaml の image なら次のように指定する。

kubectl explain pod.spec.containers.image
KIND:       Pod
VERSION:    v1

FIELD: image <string>


DESCRIPTION:
    Container image name. More info:
    https://kubernetes.io/docs/concepts/containers/images This field is optional
    to allow higher level config management to default or override container
    images in workload controllers like Deployments and StatefulSets.

先頭の pod が YAML の kind: Pod にあたり、そこから YAML の階層を . でつないでいく。

kind: Pod               # pod
spec:                   # .spec
  containers:           # .containers
    - name: nginx
      image: nginx:1.14.2   # .image

kubectl explain pod.spec.containers のように途中までにすると、その下に書けるフィールドの一覧が出る。

kubectl exec:コンテナの中でコマンドを実行する

kubectl exec は、Pod のコンテナの中でコマンドを実行する。docker exec にあたる。

kubectl exec nginx -- nginx -v

# => nginx version: nginx/1.14.2
  • -- より後ろが、コンテナの中で実行するコマンド
  • -- は「ここから先は kubectl のオプションではない」という区切り

シェルに入るときは -it を付ける。

kubectl exec -it nginx -- sh
# hostname
nginx
# exit
  • -i はキーボード入力をつなぐ、-t は端末として扱う指定。docker exec -it と同じ
  • hostname は Pod の名前になっている

kubectl apply し直す:変更の反映

image を書き換えて apply する

nginx-pod.yaml の image を書き換える。

      image: nginx:1.16.1   # 1.14.2 から変更
kubectl apply -f nginx-pod.yaml

# => pod/nginx configured

最初に作ったときは created だったのが、今回は configured になる。同じ名前(metadata.name: nginx)の Pod がすでにあるので、新しく作るのではなく、今ある Pod を YAML に合わせて変更している。

kubectl get pods
NAME    READY   STATUS    RESTARTS      AGE
nginx   1/1     Running   1 (12s ago)   25s
kubectl exec nginx -- nginx -v

# => nginx version: nginx/1.16.1
  • 中の nginx が 1.16.1 に変わった
  • RESTARTS が 1 (12s ago) になった。新しいイメージで、コンテナが起動し直された
  • AGE は 25s で、起動し直した 12 秒前より古い。Pod は作り直されず、中のコンテナだけが入れ替わった

kubectl describe pod nginx の Events: にも、その経緯が残る。

Events:
  Type    Reason     Age                From               Message
  ----    ------     ----               ----               -------
  Normal  Scheduled  46s                default-scheduler  Successfully assigned default/nginx to k8s-study-worker
  Normal  Pulling    46s                kubelet            spec.containers{nginx}: Pulling image "nginx:1.14.2"
  Normal  Pulled     42s                kubelet            spec.containers{nginx}: Successfully pulled image "nginx:1.14.2" in 4.581s (4.581s including waiting). Image size: 41901077 bytes.
  Normal  Created    34s (x2 over 42s)  kubelet            spec.containers{nginx}: Container created
  Normal  Started    34s (x2 over 42s)  kubelet            spec.containers{nginx}: Container started
  Normal  Killing    34s                kubelet            spec.containers{nginx}: Container nginx definition changed, will be restarted
  Normal  Pulled     34s                kubelet            spec.containers{nginx}: Container image "nginx:1.16.1" already present on machine and can be accessed by the pod
  • Killing の行は「コンテナ nginx の定義が変わったので、起動し直す」という kubelet の記録
  • Created / Started の (x2 over 42s) は、同じ Pod の中でコンテナを2回作って2回起動したことを示す(1.14.2 と 1.16.1)
  • Scheduled(Node の決定)は1回だけ。Pod を作り直していないので、Node も決め直していない
  • nginx:1.16.1 は Pulling がなく already present on machine になっている。この Node には 1.16.1 のイメージがすでにあった

動いている Pod で変更できるフィールドは、image など一部に限られている。それ以外のフィールドを変えるには、Pod を作り直す必要がある。

変更せずに apply する

YAML を変えずにもう一度 apply すると、何も変わらない。

kubectl apply -f nginx-pod.yaml

# => pod/nginx unchanged

apply は「このファイルのとおりにする」操作なので、なければ作り、あれば合わせ、同じなら何もしない。

create との違い

kubectl create -f でも Pod は作れるが、同じ名前のものがすでにあるとエラーになる。

kubectl create -f nginx-pod.yaml
Error from server (AlreadyExists): error when creating "nginx-pod.yaml": pods "nginx" already exists

create は新規作成だけを行う。YAML を書き換えながら反映していく使い方には apply が合う。

消す

作ったときのファイルを指定して消せる。

kubectl delete -f nginx-pod.yaml

nginx-pod.yaml は、作る・変える・消すのすべてに使っている。このファイルは「nginx という名前の Pod はこうあってほしい」という定義で、Kubernetes が見ているのはファイル名ではなく、中の kind と metadata.name。

用語メモ

用語読み方意味
kubectlキューブシーティーエル(公式の英語読みは「キューブコントロール」)クラスタを操作するコマンド
kube-apiserverキューブ エーピーアイサーバークラスタの窓口。kubectl のリクエストを受け付ける
contextコンテキストkubectl が操作するクラスタ(とユーザー・namespace)の組み合わせ
kubeconfigキューブコンフィグcontext などを書いた設定ファイル。既定は ~/.kube/config
namespaceネームスペースリソースを分けて置く区画。指定しなければ default

まとめ

  • kubectl は kube-apiserver に HTTP でリクエストを送るコマンド。操作するクラスタは context で決まり、kubectl config current-context で確かめられる
  • kubectl get の表は、kube-apiserver から返ってきたデータの一部。-o yaml で全体が見え、spec は自分が書いた内容と既定値、status は Kubernetes が書き足した今の状態
  • リソースは namespace に分けて置かれる。指定しなければ default。-n で指定、-A ですべて
  • kubectl explain で YAML のフィールドの意味を調べられる
  • kubectl exec でコンテナの中でコマンドを実行できる
  • YAML を書き換えて apply し直すと、同じ名前のリソースが変更される(configured)。Pod の image を変えた場合は、Pod はそのままで中のコンテナが起動し直される

参考 URL

Author

rito

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級