k8sに入門した(その3)「ConfigMapとsecretを理解する」
これ https://kubernetes.io/docs/tutorials/configuration/configure-java-microservice/ をやる。
バージョンを確認して、k8s環境が動いていることを確認
kubectl version
/root/sample-kubernetes-config
にチュートリアル用の設定ファイルが入ってるからそこに移動
cd /root/sample-kubernetes-config/start/
JAVAのマイクロサービスを動かすらしい。
2つのPod('system' と 'inventory')が疎結合したシステムを動かす。
JavaはMaven
とかいうツールでビルドするらしい。その方法は
mvn package -pl system
mvn package -pl inventory
Java使ったことないから良くわからん。Log見てるとmvnはdockerを呼び出してビルドしてるようだ。
ビルドできたらそれをk8sにdeployする。そのコマンドは
kubectl apply -f kubernetes.yaml
どうやらk8s上でビルドまではしないらしい。
マイクロサービスの状態を確認する。
kubectl wait --for=condition=ready pod -l app=inventory
kubectl wait --for=condition=ready pod -l app=system
waitはreadyな状態になるまで待機するというコマンド。(https://kubernetes.io/ja/docs/reference/kubectl/overview/)
condition metと表示されたら状態がreadyになったということ。
deploy出来たのでcurlでリクエストを送信する
その前にdeployしたapplicationがどんな感じでportを公開してるか確認する。
kubectl get services
どうやらinventoryが32000でsystemが31000らしい。
早速、curlでsystemとinventoryにリクエストを送る。
curl -u bob:bobpwd http://$( minikube ip ):31000/system/properties
curl http://$( minikube ip ):32000/inventory/systems/system-service
あっさりリクエストが送れてる。
systemはX-App-Name:
をsystemとなるようにハードコードされている。
curl -# -I -u bob:bobpwd -D - http://$( minikube ip ):31000/system/properties | grep -i ^X-App-Name:
これを書き換えるらしい。
javaのコードを書き換える。
/sample-kubernetes-config/start/system/src/main/java/system/SystemResource.java
を開く。
この辺を変更
@Inject
@ConfigProperty(name = "APP_NAME")
private String appName;
.header("X-App-Name", appName)
こうするとX-App-NameをMicroProfile Configで書き換えれるようになる?
次に
/sample-kubernetes-config/start/inventory/src/main/java/inventory/client/SystemClient.java
を開いて
// Basic Auth Credentials
@Inject
@ConfigProperty(name = "SYSTEM_APP_USERNAME")
private String username;
@Inject
@ConfigProperty(name = "SYSTEM_APP_PASSWORD")
private String password;
を書き換える。
こうすることで、-u bob:bobpwdをMicroProfile Configで書き換えれるようになる?
たくさんあるコンテナの環境変数を書き換えるためにKubernetes ConfigMapやKubernetes secretなどがある。(確かにこういう課題あるからシステムをk8sに乗せるためにはシステムそのもののコードを書き換える必要あるなぁ、ロステクしたシステムとかだとk8sに乗せるには最初から作り直した方が楽そう。)
とりあえず、ConfigMap
ってのを使って辞書的なのを作る。
kubectl create configmap sys-app-name --from-literal name=my-system
sys-app-nameが辞書の名前、--from-literal name=my-systemがnameというキーにmy-systemという値を設定する。
他にも--from-fileとか--from-env-fileとかで辞書を指定できるらしい。
つぎにsecret
ってのを使ってusernameとpasswordを設定する。
kubectl create secret generic sys-app-credentials --from-literal username=bob --from-literal password=bobpwd
ConfigMap
との違いは隠すべき値を設定できることらしい。
genericは入れる値の種類を示してるらしいけど良くわからん。
これらを実際のシステムで使えるようにkubernetes.yaml
を設定する。
env:
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: sys-app-name
key: name
env:
- name: SYSTEM_APP_USERNAME
valueFrom:
secretKeyRef:
name: sys-app-credentials
key: username
- name: SYSTEM_APP_PASSWORD
valueFrom:
secretKeyRef:
name: sys-app-credentials
key: password
これで ConfigMapとsecretを設定できたので、システムをbuildしなおす。
mvn package -pl system
mvn package -pl inventory
build時間長くない?
build終わったら変更を反映させる。
kubectl replace --force -f kubernetes.yaml
Readyになるまで待つ
kubectl get --watch pods
反映されてることがわかる。
curl -# -I -u bob:bobpwd -D - http://$( minikube ip ):31000/system/properties | grep -i ^X-App-Name:
curl http://$( minikube ip ):32000/inventory/systems/system-service
確かにdockerにはこういう機能ない気がする。
便利かも。