2022-02-08

Kubernetesのkubectl runでdeploymentやjobが作れなくなっているのは仕様変更のため、v1.18 2020-03以降のバージョンにて

唐突ですが、仮想化技術の流れの中、Kubernetes (K8s) をいじくっている、初心者の私です。

Dockerやpodmanからステップアップしてきて、一番最初に使うコマンドは

$ kubectl run NAME --image=IMAGE

だと思います。
Docker/podmanと同じように、指定したイメージを実行するのですが、多くの、というかほとんどの解説書には、

$ kubectl run NAME --image=IMAGE --restart=[Always | Never | OnFailure]

のコマンドを使用すると

  • Deploymentが作成される、--restartを指定しないか、デフォルトのAlwaysを指定した場合
  • Podが作成される、--restart=Neverを指定した場合
  • Jobが作成される、--restart=OnFailureを指定した場合

のように書いてあると思います。
でも、実際試してみたら、何度やっても、どうやっても、Podしか作成できません。
これ、自分の環境か、はたまた理解が間違っているんじゃないかって、悩んじゃいますよね。
でも大丈夫、そんなことはありません。

よくよく調べてみると2020年3月リリースのK8s v1.18でkubectl runの仕様が変更(複雑さを排除するため)されていて、kubectl runはPod実行専用になっていました(腹腹開発さんの記事で気付きましたありがとうございます、K8sのchangelogでも確認しました)。
この件、偉い人もあまり取り上げていないようです。
おそらくkubectl runは初心者しか使わなくて、少し専門的になってくるともっぱらYamlでIaC (Infrastructure as Code) しかやらなくなるから、kubectl runの変更は些細な事なんだろうな、と想像しています。

では、Deploymentはどうやって作成・実行するのかと言うと、素直に

$ kubectl create deployment NAME --image=IMAGE

で大丈夫です。
ならば、Podの作成もkubectl create podに統一した方が良いのか、と思いましたがこういうコマンドは残念ながらありません。

また、従来、kubectl run --dry-run -o yamlのコマンドで、DeploymentのYamlを簡易的に生成していたと思いますが、これもv1.18で一緒に仕様が変わっていて、

$ kubectl create deployment NAME --image=IMAGE --dry-run=client -o yaml

となります。
この --dry-run は、--dry-run=[client | server | none] の形式で、clientを指定するとkubectlのコマンド内のロジックのみで処理、serverを指定するとサーバ側で生成される内容を取得、noneはdry-runではなくて実際に実行した内容を表示(つまりdry-run指定しないのと同じ)、となります。
同様にPodのYamlの生成コマンドは、

$ kubectl run NAME --image=IMAGE --dry-run=client -o yaml

となります。
作成済み、実行済みのDeploymentやPodのYamlを取得・逆生成するには、

$ kubectl get deployment NAME -o yaml
$ kubectl get pod NAME -o yaml

です。
サーバ側のYamlは余計な管理情報が付いてきますが、追加のkubectl-neatと言うツールを使えば、ある程度まできれいにできるようです。

なお、作成済み、実行済みのPodやDeploymentの一覧を一発で表示するには、

$ kubectl get all

が便利ですね。

kubectl runで最初の取っつきでつまずいてしまい、あわやK8sを毛嫌いしそうになったわたしの顛末を、あえて共有させていただきました。