谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

Dapr Advent Calendar 17日目 - Dapr + k8sの環境が壊れたので作り直し

こんにちは Dapr Advent Calendar 17日目です。今日はもともと分散トレーシングの話を書くつもりだったのですが、その前に環境でトラブってしまったので、その辺りの経緯や対策などを書きたいと思います。

TL;DR

「私はminikubeをメモリ割り当て2GBで動かそうとしていました」

  • Daprの環境が壊れた時は、dapr unintall -k minikube stop Dockerの再起動 minikube start dapr init -k という手順で復旧できる
  • minikubeはデフォルトで2CPU、2GBのメモリで環境を作るが、Javaアプリケーションを5〜6つくらい作成するだけでメモリが足りなくなる
  • minikube start--cpus--memory オプションで、割り当てるリソースを指定ができる
    • ただし既に作成したminikubeはリソース割り当てを変更できないため、一度 minikube delete してから再作成する必要がある
  • docker container stats でDockerのリソース状況を確認できる
  • eval $(minikube docker-env)docker container stats でminikubeのリソース状況を確認できる

問題の経緯

問題が起きる前

数日前ですが、このAdvent Calendarの連載を書くために、ローカル環境のminikubeに色々とアプリケーションをデプロイしたり何だりしていたら、急にkubectlコマンドの反応が極端に遅くなったことがありました。その時はMacのCPU使用率が200%になっていて、2CPUを使いきって遅くなっていたため、「podが無限ループでもしたかなぁ?」などと思い、とりあえず kubectl delete -f k8s で順番にpodを削除しようとしました。

ただpodの削除も途中で止まったので minikube stop コマンドでk8sごと停止させ、改めて minikube start コマンドで起動して、残ったpodなどを削除などしてから作業を続けていました。

その後は特に問題なくminikubeを使うことができたので、まぁそんなこともあるのかなと思い、あまり気にしていませんでした。

なぜかpodを4つ以上起動できない!

昨晩、またブログを書くためにminikube上にアプリケーションをデプロイしていたら、3つか4つ以上のアプリケーションをデプロイしたところで、なぜか「アプリケーションのpodのうち1つがランダムにERRORになる」という問題が起きました。kubectl describe pod で詳細を見ると、Liveness ProbeとReadiness Probeが500エラーを返しているようです。

何かDapr関連のポートが被って通信エラーが起きているのか、サンプルのアプリケーションに問題があるのか、複数のServiceを起動しているのが問題なのか、などいくつか仮説を立て、とりあえず問題切り分けのためにHello WorldアプリケーションをServiceなしで5つほど起動してみたところ、1つは必ず同じエラーが起きるようになっていました。

Daprをダウングレードしてみようとしたものの

いま仕事でAmazon EKS上でDaprを使ってもっとたくさんのアプリケーションを運用しているので、ポートが被って通信エラーが起きるというのも、ちょっと考えにくい話です。ただ、いま運用はDapr 1.4系を使っているのですが、このブログはDapr 1.5を使って書いているので、1.5の問題かも知れないと思い、一度バージョンを落とそうと思いました。

dapr uninstall -k
dapr install -k --runtime-version 1.4.4

これでバージョンがどうなったかなと思い、dapr status -k コマンドを実行したところ、何かおかしい。

  NAME                   NAMESPACE    HEALTHY  STATUS                       REPLICAS  VERSION  AGE  CREATED              
  dapr-placement-server  dapr-system  False    Waiting (ContainerCreating)  1         1.5.1    5d   2021-12-11 21:08.30  
  dapr-sidecar-injector  dapr-system  False    Waiting (ContainerCreating)  2         1.5.1    5d   2021-12-11 21:08.30  
  dapr-operator          dapr-system  False    Terminated                   2         1.5.1    5d   2021-12-11 21:08.30  
  dapr-dashboard         dapr-system  False    Terminated                   2         0.9.0    5d   2021-12-11 21:08.30  
  dapr-sentry            dapr-system  False    Waiting (ContainerCreating)  2         1.4.4    7s   2021-12-16 23:15.34  

1.4.4のコンテナを作れていないだけでなく、1.5.1のコンテナもまだ残っている、、というか作成途中で止まっていて、まともに動いていません。どうやらminikube上のDapr環境が壊れているようです。おそらく、冒頭に書いたCPU使用率が上がった時に、環境の一部が壊れてしまったのでしょう。

環境の再構築

これはもうDaprのバージョンの問題ではなく、Dapr環境が壊れているせいだと確信したので、環境を再構築することにしました。

dapr uninstall -k
minikube stop

この後、Docker Desktopを再起動して、また環境を構築しました。

minikube start
dapr init -k

そしてまたHello Worldアプリケーションを5つほどデプロイすると、今度は5つともきちんと起動できたので、問題解決。無事にトラブルシューティングが完了しました。さすが俺!

またCPU使用率が200%になる問題が発生

環境が治ったので、とりあえず全アプリケーションをデプロイすることにしました。

kubectl apply -f k8s

そして起動するのを待っていると、、、またkubectlの反応がなくなり、CPU使用率が200%になる問題が起きました。えぇぇ、なんで。。。

Javaエンジニアの経験と勘から、これはリソースが足りていなくてメモリ不足になってフルGCでも起きているのかなと思い、とりあえずDockerのリソース状況を確認することにしました。

docker container stats
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT    MEM %     NET I/O          BLOCK I/O       PIDS
cbe04e02f2d1   minikube   202.36%   1.894GiB / 1.94GiB   97.60%    691kB / 2.11MB   102GB / 168MB   1100

いやー、もう完全に足りてないですね。メモリの割り当て2GBを完全に使いきっています。そりゃ中のアプリケーションもフルGCを頻発するでしょうよ。そもそもメモリ2GBでminikubeを運用しようとするなんて無茶、誰がしたんだよ。。。まぁ僕なんですが。

そんなわけで、環境をすべて作り直すことにしました。

環境の再構築

そんなわけで、ここから環境の再構築手順を説明します。このブログを読んで手を動かしていた人は、この手順に従って環境を作り直してください。

minikubeの削除

minikubeはstartする際の引数でCPU数やメモリ割り当て量を変えることできるのですが、既に作成してあるminikubeに対して変更することはできないため、まずminikubeそのものを削除する必要があります。

次のコマンドで削除します。

minikube stop
minikube delete

これでDaprのコンテナや、作成したイメージなどもすべて削除されます。

minikubeとDapr環境の再構築

続いて環境の再構築です。次のコマンドで構築します。

minikube start --cpus=4 --memory=4096

環境が構築できたら、念のためリソース状況を確認します。

docker container stats

メモリのLIMITが4GiBになっていることを確認してください。

続いて、Dapr環境の構築です。

dapr init -k

環境が構築できたら、念のためpodが正常に動いていることを確認します。

dapr status -k

5つのpodのHEALTYがTRUEになっていて、STATUSがRunningになっていればOKです。

イメージの再作成

これまでのブログで作ってきたアプリケーションのイメージは、minikubeをdeleteした際に一緒に削除されてしまったので、すべて作り直す必要があります。

eval $(minikube docker-env)
cd (GitHubのディレクトリパス)/dapr-advent-2021
./mvnw spring-boot:build-image

これですべてのアプリケーションのイメージが再作成されます。

ちなみに最後に親モジュールのイメージも作ろうとしてmavenビルドがエラーになりますが、その時点で子モジュールのイメージはすべて作成されているためヨシとします。

アプリケーションのデプロイ

イメージの作成が完了したら、アプリケーションをまとめてデプロイしてしまいましょう。

kubectl apply -f k8s

デプロイする順番など気にせず、一気にデプロイしても特に問題などは起きません。

念のため kubectl get pods コマンドで、起動に成功していることを確認しておきましょう。

NAME                                READY   STATUS    RESTARTS   AGE
hello-app-fb644cd5d-j2z7b           2/2     Running   0          1m
invoke-app-745b5f4bf6-2hf6l         2/2     Running   0          1m
postgresql-deploy-658df4946-lm6gp   1/1     Running   0          1m
publish-app-5b4c66c9-mhj67          2/2     Running   0          1m
rabbitmq-5d474484f5-rhjzd           1/1     Running   0          1m
state-app-849f6d6944-2mtr5          2/2     Running   0          1m
subscribe-app-cdc58446-n82px        2/2     Running   0          1m

問題ありませんね。

minikubeのリソース確認

最後に、minikubeのリソースを確認しておきましょう。

新しいコンソールを開いて、docker container stats コマンドを実行します。

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O          BLOCK I/O        PIDS
079bf48016ec   minikube   53.21%    2.339GiB / 4GiB     58.48%    1.56GB / 250MB   106MB / 9.87GB   1062

メモリは4GiB中、2.3GiBほど使っているようです。そりゃ2GBしか割り当ててなければ、メモリが足りなくて止まっちゃいますよね、、、

なお、minikube内部のpodごとのリソース状況は、次のコマンドで確認できます。

eval $(minikube docker-env)
docker container stats

次のような結果が出るはずです。

CONTAINER ID   NAME                                                                                                                  CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
bb2650777c7a   k8s_daprd_state-app-849f6d6944-2mtr5_default_fa0cc253-ddab-4026-9328-fc3a29d2151e_0                                   0.14%     15.75MiB / 7.773GiB   0.20%     1.59MB / 1.51MB   0B / 0B           11
e51e7d17a744   k8s_daprd_publish-app-5b4c66c9-mhj67_default_9f1de14f-0498-4f12-ab17-931771d7f0b3_0                                   0.21%     15.68MiB / 7.773GiB   0.20%     1.59MB / 1.51MB   0B / 0B           12
b9c2c68edd1b   k8s_daprd_hello-app-fb644cd5d-j2z7b_default_114f279b-313b-4763-b779-3a1128986b9e_0                                    0.09%     15.74MiB / 7.773GiB   0.20%     1.59MB / 1.5MB    8.19kB / 0B       12
3d7590c40e30   k8s_daprd_invoke-app-745b5f4bf6-2hf6l_default_852d6fd1-582d-44ea-b06f-cbaa95a7af2b_0                                  0.08%     15.69MiB / 7.773GiB   0.20%     1.59MB / 1.51MB   0B / 0B           12
52769d846edb   k8s_subscribe_subscribe-app-cdc58446-n82px_default_b0d3ebfa-8a4f-4dec-ad6e-4296c9dfaa74_0                             0.12%     172.4MiB / 7.773GiB   2.17%     1.59MB / 1.52MB   0B / 1.29MB       32
5daf791beb83   k8s_state_state-app-849f6d6944-2mtr5_default_fa0cc253-ddab-4026-9328-fc3a29d2151e_0                                   0.14%     164.7MiB / 7.773GiB   2.07%     1.59MB / 1.51MB   16.4kB / 1.32MB   32
9c162e211125   k8s_publish_publish-app-5b4c66c9-mhj67_default_9f1de14f-0498-4f12-ab17-931771d7f0b3_0                                 0.12%     180.6MiB / 7.773GiB   2.27%     1.59MB / 1.51MB   8.19kB / 1.3MB    32
4652afb3deef   k8s_postgresql_postgresql-deploy-658df4946-lm6gp_default_f080e2f5-f9ec-41f3-a8b3-752b59445d8b_0                       0.00%     52.89MiB / 7.773GiB   0.66%     12.5kB / 12kB     32.7MB / 55MB     12
39ba4e76702f   k8s_POD_subscribe-app-cdc58446-n82px_default_b0d3ebfa-8a4f-4dec-ad6e-4296c9dfaa74_0                                   0.00%     212KiB / 7.773GiB     0.00%     1.59MB / 1.52MB   0B / 0B           1
6b06c40a04b6   k8s_POD_state-app-849f6d6944-2mtr5_default_fa0cc253-ddab-4026-9328-fc3a29d2151e_0                                     0.00%     208KiB / 7.773GiB     0.00%     1.59MB / 1.51MB   0B / 0B           1
2f3b07bc26e6   k8s_rabbitmq_rabbitmq-5d474484f5-rhjzd_default_f39f8fcd-47af-420a-aebd-d4dbf4385d8d_0                                 0.25%     126.4MiB / 7.773GiB   1.59%     2.5kB / 354B      33.8MB / 819kB    33
b2bc5b2bcd5c   k8s_POD_publish-app-5b4c66c9-mhj67_default_9f1de14f-0498-4f12-ab17-931771d7f0b3_0                                     0.00%     208KiB / 7.773GiB     0.00%     1.59MB / 1.51MB   0B / 0B           1
78778711254e   k8s_POD_rabbitmq-5d474484f5-rhjzd_default_f39f8fcd-47af-420a-aebd-d4dbf4385d8d_0                                      0.00%     208KiB / 7.773GiB     0.00%     2.5kB / 354B      0B / 0B           1
90754eca8f01   k8s_hello_hello-app-fb644cd5d-j2z7b_default_114f279b-313b-4763-b779-3a1128986b9e_0                                    0.20%     194.5MiB / 7.773GiB   2.44%     1.59MB / 1.5MB    0B / 1.56MB       32
0ccbd01ea780   k8s_POD_postgresql-deploy-658df4946-lm6gp_default_f080e2f5-f9ec-41f3-a8b3-752b59445d8b_0                              0.00%     204KiB / 7.773GiB     0.00%     12.5kB / 12kB     0B / 0B           1
986d6f27779d   k8s_invoke_invoke-app-745b5f4bf6-2hf6l_default_852d6fd1-582d-44ea-b06f-cbaa95a7af2b_0                                 0.11%     179.7MiB / 7.773GiB   2.26%     1.59MB / 1.51MB   143kB / 1.64MB    32
0361dd7cf5bb   k8s_POD_hello-app-fb644cd5d-j2z7b_default_114f279b-313b-4763-b779-3a1128986b9e_0                                      0.00%     208KiB / 7.773GiB     0.00%     1.59MB / 1.5MB    0B / 0B           1
1f374ad3ef7c   k8s_POD_invoke-app-745b5f4bf6-2hf6l_default_852d6fd1-582d-44ea-b06f-cbaa95a7af2b_0                                    0.00%     204KiB / 7.773GiB     0.00%     1.59MB / 1.51MB   0B / 0B           1
6d1ef557c15a   k8s_dapr-placement-server_dapr-placement-server-0_dapr-system_677cb5fd-ae57-41eb-918c-58d42e6c7652_0                  0.33%     7.207MiB / 7.773GiB   0.09%     6.06MB / 6.09MB   0B / 0B           11
23acf6a45fe2   k8s_dapr-operator_dapr-operator-5b4b68b5c5-mptxp_dapr-system_c9d399ef-c82c-4781-9ae4-624a6933abc5_0                   0.17%     18.25MiB / 7.773GiB   0.23%     27.1MB / 14.1MB   0B / 0B           13
9ff28f354a81   k8s_dapr-sidecar-injector_dapr-sidecar-injector-6f749dbf87-9vn96_dapr-system_0ab8e63d-8073-411c-9c87-d9abd03083b7_0   0.11%     8.184MiB / 7.773GiB   0.10%     1.55MB / 1.37MB   0B / 0B           12
116fb67e12ec   k8s_dapr-sentry_dapr-sentry-c6b746cdf-hp2n9_dapr-system_e30b08ca-9060-4853-8c26-a37351e41c26_0                        0.06%     7.883MiB / 7.773GiB   0.10%     1.53MB / 1.39MB   0B / 0B           14
9ef9efefb9c2   k8s_dapr-dashboard_dapr-dashboard-57b4db56fc-pr62l_dapr-system_4ba3a32e-afe9-4c7e-a8c2-ba2ac4745da9_0                 0.00%     5.734MiB / 7.773GiB   0.07%     2.89kB / 0B       0B / 0B           8
9bc3f4edc295   k8s_POD_dapr-placement-server-0_dapr-system_677cb5fd-ae57-41eb-918c-58d42e6c7652_0                                    0.00%     200KiB / 7.773GiB     0.00%     6.06MB / 6.09MB   0B / 0B           1
db607d3df442   k8s_POD_dapr-sidecar-injector-6f749dbf87-9vn96_dapr-system_0ab8e63d-8073-411c-9c87-d9abd03083b7_0                     0.00%     204KiB / 7.773GiB     0.00%     1.55MB / 1.37MB   0B / 0B           1
2f2426091427   k8s_POD_dapr-operator-5b4b68b5c5-mptxp_dapr-system_c9d399ef-c82c-4781-9ae4-624a6933abc5_0                             0.00%     208KiB / 7.773GiB     0.00%     27.1MB / 14.1MB   0B / 0B           1
351e4b9d4e76   k8s_POD_dapr-sentry-c6b746cdf-hp2n9_dapr-system_e30b08ca-9060-4853-8c26-a37351e41c26_0                                0.00%     204KiB / 7.773GiB     0.00%     1.53MB / 1.39MB   0B / 0B           1
292b25653234   k8s_POD_dapr-dashboard-57b4db56fc-pr62l_dapr-system_4ba3a32e-afe9-4c7e-a8c2-ba2ac4745da9_0                            0.00%     204KiB / 7.773GiB     0.00%     2.89kB / 0B       0B / 0B           1
da405d04f18f   k8s_storage-provisioner_storage-provisioner_kube-system_3526d87b-7f1f-4e57-a5c4-6a9f054e7ec2_1                        0.05%     9.297MiB / 7.773GiB   0.12%     0B / 0B           0B / 0B           8
4d7fe3d17eb4   k8s_coredns_coredns-558bd4d5db-t4gxq_kube-system_ec6ebffa-abce-45b9-9978-b3349311791f_0                               0.36%     11.11MiB / 170MiB     6.53%     2.23MB / 719kB    0B / 0B           12
7e4d83af4783   k8s_kube-proxy_kube-proxy-tmzwt_kube-system_29295269-e286-48b4-84e0-eb2583132419_0                                    0.02%     12.56MiB / 7.773GiB   0.16%     0B / 0B           0B / 16.4kB       10
52cab24b1823   k8s_POD_coredns-558bd4d5db-t4gxq_kube-system_ec6ebffa-abce-45b9-9978-b3349311791f_0                                   0.00%     204KiB / 7.773GiB     0.00%     2.23MB / 719kB    0B / 0B           1
1ec5d319864e   k8s_POD_kube-proxy-tmzwt_kube-system_29295269-e286-48b4-84e0-eb2583132419_0                                           0.00%     280KiB / 7.773GiB     0.00%     0B / 0B           0B / 0B           1
23e447125876   k8s_POD_storage-provisioner_kube-system_3526d87b-7f1f-4e57-a5c4-6a9f054e7ec2_0                                        0.00%     148KiB / 7.773GiB     0.00%     0B / 0B           0B / 0B           1
d0b6da913375   k8s_etcd_etcd-minikube_kube-system_be5cbc7ffcadbd4ffc776526843ee514_0                                                 1.65%     39.15MiB / 7.773GiB   0.49%     0B / 0B           0B / 235MB        19
094635d3e682   k8s_kube-apiserver_kube-apiserver-minikube_kube-system_cefbe66f503bf010430ec3521cf31be8_0                             3.95%     314.8MiB / 7.773GiB   3.96%     0B / 0B           0B / 0B           12
4c8cac060a66   k8s_kube-scheduler_kube-scheduler-minikube_kube-system_a2acd1bccd50fd7790183537181f658e_0                             0.20%     16.75MiB / 7.773GiB   0.21%     0B / 0B           0B / 0B           11
a638324aa7b6   k8s_kube-controller-manager_kube-controller-manager-minikube_kube-system_a5754fbaabd2854e0e0cdce8400679ea_0           1.61%     48.86MiB / 7.773GiB   0.61%     0B / 0B           0B / 0B           10
a21fdf45e9ab   k8s_POD_etcd-minikube_kube-system_be5cbc7ffcadbd4ffc776526843ee514_0                                                  0.00%     144KiB / 7.773GiB     0.00%     0B / 0B           0B / 0B           1
4983ebfc71a4   k8s_POD_kube-scheduler-minikube_kube-system_a2acd1bccd50fd7790183537181f658e_0                                        0.00%     144KiB / 7.773GiB     0.00%     0B / 0B           0B / 0B           1
ffa6824f6939   k8s_POD_kube-controller-manager-minikube_kube-system_a5754fbaabd2854e0e0cdce8400679ea_0                               0.00%     140KiB / 7.773GiB     0.00%     0B / 0B           0B / 0B           1
6e78a62d73d0   k8s_POD_kube-apiserver-minikube_kube-system_cefbe66f503bf010430ec3521cf31be8_0                                        0.00%     140KiB / 7.773GiB     0.00%     0B / 0B           0B / 0B           1
19977ecb1ab2   k8s_daprd_subscribe-app-cdc58446-n82px_default_b0d3ebfa-8a4f-4dec-ad6e-4296c9dfaa74_0                                 0.21%     15.47MiB / 7.773GiB   0.19%     1.59MB / 1.52MB   0B / 0B           12

何やよく分かりませんけど、わりとたくさんpodが動いてるんですね(今さら)

JVM系のpodは、たとえばこんな感じです。

90754eca8f01   k8s_hello_hello-app-fb644cd5d-j2z7b_default_114f279b-313b-4763-b779-3a1128986b9e_0                                    0.20%     194.5MiB / 7.773GiB   2.44%     1.59MB / 1.5MB    0B / 1.56MB       32

アプリケーション1つで200MiBほどメモリを使うのですから、そりゃ5つも6つも立ち上げれば2GBでは足りませんね。

そんなわけで、無事に環境を作り直すことができました。

ドキュメントはちゃんと読もうね

ちなみにDaprのminikube環境構築のドキュメントを見ると、、、

docs.dapr.io

minikube startのコマンドは、このようになっています。

minikube start --cpus=4 --memory=4096

ドキュメントで、メモリ4GiBにしろって書いてあるんですから、それをきちんと守れって話ですよね・・・。

いや、別にオプションなしで実行しても問題ないんだったら、それに越したことはないのかなって、、、(言い訳)

まとめ

ということで今回のまとめです。

  • Daprの環境が壊れた時は、dapr unintall -k minikube stop Dockerの再起動 minikube start dapr init -k という手順で復旧できる
  • minikubeはデフォルトで2CPU、2GBのメモリで環境を作るが、Javaアプリケーションを5〜6つくらい作成するだけでメモリが足りなくなる
  • minikube start--cpus--memory オプションで、割り当てるリソースを指定ができる
    • ただし既に作成したminikubeはリソース割り当てを変更できないため、一度 minikube delete してから再作成する必要がある
  • docker container stats でDockerのリソース状況を確認できる
  • eval $(minikube docker-env)docker container stats でminikubeのリソース状況を確認できる

いやぁ、こういうことを経験して、使いこなしレベルって上がっていくもんですよね!

それでは、また明日!