何がしたかった?
全ての Pod を一発でリロードさせる方法
↑をJavaからkubernetes-client/javaを使ってやりたかった。
これができるとpodリロードをAPI化してwebから蹴ったりできるのでは?と画策。
壁
ExampleがExampleじゃない気がするんだ。
めっちゃ500とか400で怒られるけど全然わからなくて泣いた。bodyがなってねえんだよとひたすら言われた。
壁崩壊
て思ったらなんかいつの間にかUPDATEされたExampleがあったので、あの夜の私の汗と涙を返してほしい。嘘ですメンテありがとう。
できることなら君と一ヶ月前に会いたかった。
\\ PatchExample.java //
もうこの記事書く意味なくなったけど悔しいので備忘録兼日記的に残します。
環境
- SpringBoot2.0.2
準備
ライブラリをbuild.gradeleに追加
compile('io.kubernetes:client-java:4.0.0')
実行前
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も再起動がかかっています。
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を使いたいのってどういうときでしょうか
公式ドキュメントとの違い
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)
……何を? ログとかエラー?