LoginSignup
1
0

More than 3 years have passed since last update.

kubernetes-clientを経由してpatch

Posted at

何がしたかった?

全ての Pod を一発でリロードさせる方法
↑をJavaからkubernetes-client/javaを使ってやりたかった。
これができるとpodリロードをAPI化してwebから蹴ったりできるのでは?と画策。

ExampleがExampleじゃない気がするんだ。
めっちゃ500とか400で怒られるけど全然わからなくて泣いた。bodyがなってねえんだよとひたすら言われた。

壁崩壊

て思ったらなんかいつの間にかUPDATEされたExampleがあったので、あの夜の私の汗と涙を返してほしい。嘘ですメンテありがとう。
できることなら君と一ヶ月前に会いたかった。
:tada: \\ PatchExample.java // :tada:
もうこの記事書く意味なくなったけど悔しいので備忘録兼日記的に残します。

環境

  • SpringBoot2.0.2

準備

ライブラリをbuild.gradeleに追加

compile('io.kubernetes:client-java:4.0.0')

実行前

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

これにpatchを実行します。

おれおれコード

@RequiredArgsConstructor
public class SampleClient {

    private final AppsV1Api appsV1Api;

        public V1Deployment patchDeploymentSample() throws ApiException {

            String namespace = "namespace";
            String name = "deployment_name";

            ArrayList<JsonObject> body = new ArrayList<>();
            String jsonStr = "{"
                            + "\"op\":\"add\", "
                            + "\"path\":\"/spec/template/spec/sample/reload\","
                            + "\"value\":\"update-test-20190624\""
                            + "}";
            body.add(((JsonElement) this.deserialize(jsonStr, JsonElement.class)).getAsJsonObject());

            return appsV1Api.patchNamespacedDeployment(name, namespace, body, true, null);
        }

        private Object deserialize(String jsonStr, Class<?> targetClass) {
            return (new Gson()).fromJson(jsonStr, targetClass);
        }
}

実行後

上記コードを実行すると以下のdeploymentに変わっていました。
bodyで指定した項目が追加されています!
valueを変えて再度実行すると、keyはそのままでvalueだけ更新されています。
もちろんpodも再起動がかかっています。

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
      sample:
        reload: update-test-20190624

JSON Patch

Json Patchなるものはこの記事がとてもわかり易かったのでどうぞ。
自分はoperationにaddではなくreplaceを指定していますが、

  • add -> 指定の項目追加。既にあれば置き換える。
  • remove -> 指定の項目削除。項目がなければエラー。
  • replace -> remove + add。つまり置き換える項目がなければエラー。

という仕様なので、今回の用途ならaddです。なければinsert、あればupdateという動きをします。
むしろreplaceを使いたいのってどういうときでしょうか :thinking:

公式ドキュメントとの違い

DI部分とかはさておき、自分でdeserializeしてJsonElementのObjectを渡しているところがV1Patchというものに入れて渡してますね。
PatchExampleの更新とソースの更新日が同じなので新しく追加されたObjectなのかも。
V1Patchのドキュメントも空。

Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.

JsonのStringを渡すとPATCHのための具体的な名前と型に落とし込んでくれるものらしい。
こっち使った方が良いですね。便利って大事。

気になる

patchNamespacedDeploymentの第4引数のprettyがよくわかっていません。

If true, then the output is pretty printed. (optional)

……何を? ログとかエラー? :thinking::thinking:

多謝

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0