[k8s] kubectl apply コマンドの使い方(実例付)

kubectl applyコマンド解説

 本記事はkubectlコマンド v1.22.2の環境で確認しています。

 kubectl apply コマンドは、Kubernetesのマニフェストを記載したファイルを読み込んでリソースの作成、更新を行うことが可能です。

 マニフェストファイルの指定方法は、ファイル名を指定するだけでなく、ファイルが格納されているディレクトリを指定することもできます。ディレクトリを指定した場合は、ディレクトリ内のマニフェストファイル(複数ファイル可能)を自動的に読み込みKubernetesに反映してくれます。

 またマニフェストを、標準入力やネット上にあるファイルをhttpsなどでアクセスして読み込むことも可能です。

kubectl apply コマンドのフォーマットとオプション

フォーマット

kubectl apply -f <ファイル名 or ディレクトリ名> [オプション]

主なオプション

 kubectlコマンドのオプションには、kubectl apply コマンド固有のオプションとkubectlコマンド共通のオプションがあります。

kubectl apply コマンド固有のオプション

 オプションの中で主なものを挙げます。

 「kubectl apply -h」コマンドで確認可能なオプションです。

オプション概説
-f, --filenameマニフェストファイル、またはマニフェストファイルが
格納されているディレクトリを指定する
-R「-f」の値にディレクトリを指定した際、下位階層内の
ファイルも読み込み対象にする

kubectlコマンド共通のオプション

 kubectlコマンド共通のオプションは、以下のコマンドで確認できます。

$ kubectl options

 その中で主なものを挙げます。

オプション概説
-n, --namespace=''指定した名前空間内のリソース情報を取得する
-s, --server=''指定したAPI serverに接続する

コマンド例

$ kubectl apply -f web-app-deployment.yaml
$ kubectl apply -f ./database-deployment
$ cat web-app03.yaml | kubectl apply -f -

kubectl apply コマンドの主な使い方

 以下で、実例をまじえたコマンドの使い方を解説していきます。

本記事内のコマンド実行で使用しているユーザは、rootではなく、kubectlコマンドを利用可能にする設定を行った一般ユーザです。

一般ユーザ(例えばadminkube)がkubectlを使えるようにするには、対象ユーザでログインした後、以下のコマンドを実行してください。

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

※出典:Kubernetes公式サイト

基本事項の解説

 kubectl apply コマンドは、マニフェストを使用してリソースの作成や設定内容の更新を行うために使用します。

 kubectl apply コマンドの基本動作は、マニフェスト内に存在しないリソースは新規に追加し、既に存在するリソースに関しましては設定内容が更新されます。

 マニフェストの設定内容をうまく利用することによって、設定内容を削除したり初期値(デフォルト値)に戻したりすることも可能です。

 kubectl apply コマンドの内部処理に関する詳細はボリュームが大きいので、別記事の作成を予定しております。(2021年11月時点 未作成)

 なお、以下の実例では、YAML形式のマニフェストファイルを使用しています。

マニフェストファイルを指定してリソースを追加・更新する

 以下の内容のマニフェストファイルを用意しました。

 ファイル名はweb-app01.yamlとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-test
spec:
  selector:
    matchLabels:
      app: web-pods
  replicas: 3
  template:
    metadata:
      labels:
        app: web-pods
    spec:
      containers:
      - name: test-pod
        image: k8s.gcr.io/echoserver:1.4

 Deploymentリソースdeploy-testと、その管理下で動くPodの定義になります。

 現在Kubernetes内ではPodとDeploymentは空の状態です。

$ kubectl get pod,deploy
No resources found in default namespace.

 kubectl apply コマンドでマニフェストファイルを読み込んでみましょう。

$ kubectl apply -f web-app01.yaml
deployment.apps/deploy-test created

 Podが3つとDeploymentが1つ動き始めました。

$ kubectl get pod,deploy
NAME                               READY   STATUS    RESTARTS   AGE
pod/deploy-test-64988f78fc-dkrp6   1/1     Running   0          3m43s
pod/deploy-test-64988f78fc-jftrh   1/1     Running   0          3m43s
pod/deploy-test-64988f78fc-lhr52   1/1     Running   0          3m43s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-test   3/3     3            3           3m43s

 追加したDeplynmentの定義を更新してみます。

 マニフェストファイル(web-app01.yaml)のreplicasの値を3から5に変更してください。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-test
spec:
  selector:
    matchLabels:
      app: web-pods
  replicas: 5      ←5に変更
  template:
    metadata:
      labels:
        app: web-pods
    spec:
      containers:
      - name: test-pod
        image: k8s.gcr.io/echoserver:1.4

 再度kubectl apply コマンドでマニフェストファイルを読み込んでみます。

$ kubectl apply -f web-app01.yaml
deployment.apps/deploy-test configured

 先ほどkubectl apply コマンドを実行した際は「created」と表示されていましたが、今度は「configured」と表示されました。

 マニフェストに記述されているリソースが既に存在する場合で、設定値になんらかの更新があったときは「configured」と表示されます。

 replicasの値を5に変えましたので、稼働中のPodの数が5つになりました。

$ kubectl get pod,deploy
NAME                               READY   STATUS    RESTARTS   AGE
pod/deploy-test-64988f78fc-79zd5   1/1     Running   0          27s
pod/deploy-test-64988f78fc-dkrp6   1/1     Running   0          11m
pod/deploy-test-64988f78fc-jftrh   1/1     Running   0          11m
pod/deploy-test-64988f78fc-lhr52   1/1     Running   0          11m
pod/deploy-test-64988f78fc-ps4b9   1/1     Running   0          27s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-test   5/5     5            5           11m

(補足)

 マニフェストファイルが複数ある場合はkubectl applyコマンドを複数回実行すれば良いのですが、以下のように「-f」を複数個並べて記述することも可能です。

$ kubectl apply -f web-app10.yaml -f web-app20.yaml

 本節で作成したリソースは、以下のコマンドで削除できます。

$ kubectl delete -f web-app01.yaml

ディレクトリ内にあるマニフェストファイルでリソースを追加・更新する

 以下の内容の2つのマニフェストファイル(web-app02.yaml、web-service02.yaml)をディレクトリ/home/work/contents02内に用意しました。

$ pwd
/home/work/contents02
$ ls -l
total 8
-rw-rw-r-- 1 test01 users 291 Nov  5 01:40 web-app02.yaml
-rw-rw-r-- 1 test01 users 164 Oct 18 06:56 web-service02.yaml

 web-app02.yamlにはDeploymentとPodの定義、web-service02.yamlにはPodを外部に公開するNodeportを使用するためのサービスの定義が記述されています。

web-app02.yamlの内容

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-test
spec:
  selector:
    matchLabels:
      app: web-pods
  replicas: 3
  template:
    metadata:
      labels:
        app: web-pods
    spec:
      containers:
      - name: test-pod
        image: k8s.gcr.io/echoserver:1.4

web-service02.yamlの内容

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web-pods2
  ports:
    - port: 8080
      nodePort: 30808

 では、オプション「-f」の値として2つのファイルが存在するディレクトリを指定して実行してみましょう。

$ ls -l
-rw-rw-r-- 1 test01 users 295 Nov  5 02:51 web-app02.yaml
-rw-rw-r-- 1 test01 users 161 Nov  5 02:52 web-service02.yaml
$ kubectl apply -f .
deployment.apps/deploy-test2 created
service/web-service created

 2つのマニフェストが正常に読み込まれました。内容を確認してみます。

$ kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/deploy-test2-76c54dd5f7-slzfm   1/1     Running   0          4m39s
pod/deploy-test2-76c54dd5f7-z9rwz   1/1     Running   0          4m39s

NAME                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/kubernetes    ClusterIP   10.96.0.1      <none>        443/TCP          32d
service/web-service   NodePort    10.110.2.130   <none>        8080:30808/TCP   4m39s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-test2   2/2     2            2           4m39s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-test2-76c54dd5f7   2         2         2       4m39s

 マニフェストの内容が正しく反映されています。

 実行したコマンド「kubectl apply -f .」ではカレントディレクトリを指定しましたが、もちろん1つ上の階層に移動してディレクトリ名を指定することも可能です。

$ cd ..
$ kubectl apply -f contents02

 ディレクトリ名を指定する方法の場合、ディレクトリ内に存在する以下の拡張子のファイルが読み込み対象となります。

形式拡張子
YAML形式.yml .yaml
JSON形式.json

 前節の補足欄に書きましたように、1つのコマンドに複数のマニフェストファイルを並べて記述することも可能です。

Webサービスで公開されているマニフェストファイルを指定してリソースを追加・更新する

 これまでの例では「-f」の値としてマニフェストファイルの名前やマニフェストファイルが格納されているディレクトリの名前を指定しました。

 場合によっては、マニフェストを多くのユーザと共有したいこともあるかもしれません。

 その際は、マニフェストをWebサービスで公開するのが手っ取り早いと思います。

 kubectlコマンドはWebサービスも利用できます。

 「-f」の値としてマニフェストファイルのURLを指定するだけです。

$ kubectl apply -f https://git.io/vPieo

※上記コマンド内で使用しているURLは、Kubernetesの公式ドキュメント内のkubectl applyコマンドの解説内でサンプルとして利用されていたものです。

 内容は、イメージとしてbusyboxを使用し、内部でsleepコマンドを実行するPodのマニフェストです。

 以下のコマンドで状態を確認してみます。

$ kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
busybox0   1/1     Running   0          56m

 busybox0という名前でPodが起動されていることがわかります。

 以下のコマンドでPodを削除できます。

$ kubectl delete -f https://git.io/vPieo
pod "busybox0" deleted

※私の環境では削除が完了するまで30秒ほどかかりました

標準入力からリソースを追加・更新する

 以下のマニフェストファイルを作成します。

 ファイル名はweb-app03.yamlとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-test3
spec:
  selector:
    matchLabels:
      app: web-pods3
  replicas: 3
  template:
    metadata:
      labels:
        app: web-pods3
    spec:
      containers:
      - name: test-pod3
        image: k8s.gcr.io/echoserver:1.4

 ファイルがあるので「-f」オプションの値として指定すればよいのですが、catコマンドで出力した結果を、kubectlコマンドへ標準入力を使って読み込んでみます。

$ cat web-app03.yaml | kubectl apply -f -
deployment.apps/deploy-test3 created

 「-f」オプションに「-(ハイフン)」を指定することで、標準入力から読み込みます。

 Kubernetes公式ドキュメントでは、ヒアドキュメントを使用した例が掲載されていました。

 それを参考にして、上の内容をヒアドキュメントを使用する場合は以下のコマンドになります。

$ cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-test3
spec:
  selector:
    matchLabels:
      app: web-pods3
  replicas: 3
  template:
    metadata:
      labels:
        app: web-pods3
    spec:
      containers:
      - name: test-pod3
        image: k8s.gcr.io/echoserver:1.4
EOF

おわりに

  以上でkubectl apply コマンドのご紹介を終わります。

 本記事では、kubectl apply コマンドのフォーマットをメインに解説しました。

 でも実は、kubectl apply コマンドで重要なのは、本記事の基本事項の解説の節で解説しましたとおり、既に存在するリソースを更新する処理になります。

 マニフェストによってリソースを更新しますと、基本的には上書きで設定されるのですが、設定値を削除したりデフォルト値に戻したりすることも可能なのです。

 そのためには、マニフェストの定義内容と実行中のリソースの設定内容、前回設定した内容の3つを利用する必要があります。

 これに関しましては別記事(2021年11月時点 未作成)で解説させてください。

 ご利用ありがとうございました。

k8s
その他のおすすめ記事
その他のおすすめ記事

コメント