kubectl patchコマンドでClusterIPからNodePortに変更する

kameneko
penguin-lab
Published in
6 min readMay 14, 2020

こんにちは、かめねこです。
kubectl edit コマンドを使うことでKubernetesのリソースを変更することができますが、あまり使い勝手が良いものではありません。ということで、同様のことを簡単に実現できる kubectl patch コマンドを使って、ServiceをClusterIPからNodePortに変更する手順をご紹介します。

Introduction

Kubernetes上に各種リソースを展開する場合、必要に応じて kubectl edit することがあります。たとえば、表題のようなServiceをClusterIPからNodePortに変更したい場合など。従来は、 kubectl edit で毎回書き換えていたのですが、手順書に記載しづらかったり( kubectl edit でこのフィールドを変更してねみたいな書き方をしていた)、値を間違えたときに毎回やり直しになったりと、使い勝手はよくありませんでした。

そこでもっとスマートなやり方が無いかと調べていたところ、 kubectl patch コマンドで実現できたので、これをご紹介します。

kubectl patch?

kubectl patch コマンドは、JSONまたはYAML形式を使って、Kubernetesのリソースのフィールドを書き換えたり、削除、追加することができるコマンドです。

JSONなどを直接コマンドに書いてフィールドを指定するほかに、 -f オプションを使って kubectl apply -f hoge.yaml のようにファイルから渡すこともできます。

ClusterIPからNodePortに変更するやり方

kubectl patch コマンドで変更する場合の注意点としてリストに対する変更があります。たとえば単にNodePortに変更するだけであれば以下のコマンドで対応できます。

kubectl patch service hoge-service -p '{"spec":{"type": "NodePort"}}'

ただ、 .spec.ports[].nodePort のようにNodePortのポート番号を変更する場合は、対象がリスト内のフィールドです。このリストに対する変更を、上記のやり方でやる方法が見つかりませんでした。そこで、今回は --type=json オプションを使ってjson形式で渡します。

NodePortに変更してPort番号も変更する

次のコマンドでは、NodePortへ変更し、ポート番号を31600として割り当てています。

# update CluserIP -> NodePort
kubectl patch service argocd-server --type='json' -p='[{"op": "replace", "path": "/spec/type", "value": "NodePort"}]'
# update nodePort number
kubectl patch service argocd-server --type='json' -p='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value": 31600}]'

--type=json を利用する場合、以下のフォーマットで指定する必要があります。

-p='[{"op": "${OPERATION}", "path": "${PATH}"}]'

opキーには、オペレーションの内容を指定します。具体的には、以下のオペレーションが利用可能です。今回は replace を利用しています。

  • add : オブジェクトの追加
  • remove : オブジェクトの削除
  • replace : オブジェクトの値の変更
  • move : オブジェクトの移動
  • copy : オブジェクトのコピー
  • test : 渡されたオブジェクトと既存のオブジェクトの比較

公式の該当のドキュメントが見当たらなかったのですが、以下のWebサイトが参考になります。

また、リストを指定する場合は、 path/spec/ports/${NUM}/nodePort のように、0から始まる番号を指定します。もし、複数のportsが存在する場合は、次の様に書けます。

kubectl patch service argocd-server --type='json' -p='[{"op": "replace", "path": "/spec/type", "value": "NodePort"}]'
kubectl patch service argocd-server --type='json' -p='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value": 31600}]'
kubectl patch service argocd-server --type='json' -p='[{"op": "replace", "path": "/spec/ports/1/nodePort", "value": 31700}]'

終わりに

kubectl edit コマンドを使わず、簡単にオブジェクトを変更することができました。今回はServiceTypeでしたが、Kubernetesのリソースであれば基本的に変更できるので、今後もいろいろなところで活用できそうですね。

あと、公式の詳細なドキュメントがほしい…( ˘ω˘)

--

--

kameneko
penguin-lab

PrometheusとかKubernetesとか物理、配信とかが好きなしがないエンジニアです。さくらインターネットという会社であれこれしています。ペンギンがとても、とても好き。