Skip to main content

k3s のデータストアとして RDS を使う

僕は自宅で k3s クラスタを運用しています。このブログもおうち k3s で動作しています。

ホビーユースですが、かなりヘビーに活用しており、できれば 24/365 で運用したいところです。

そのために実施した内容をいくつかのチャプタに分けてお送りします。

現状

まず、変更を施す前の環境は、以下のとおりでした。

  • Master: Raspberry Pi 4 Model B 4GB * 2
  • Worker: x86 サーバ * 3 + Raspberry Pi 3 Model B+ * 1

また、k3s は kine という etcd shims を利用することにより、バックエンドデータストアを色々選ぶことができます。

https://rancher.com/docs/k3s/latest/en/installation/datastore/

その中で MySQL 5.7 を利用して運用していました。

MySQL の運用は、ノードの一台に Docker Compose で上げておくという非常に簡素なもので、冗長化を行なっていないためノードのメンテもしづらく、ノード故障によるデータ消失の危険性を常に抱えていました。

バックエンド DB をクラスタ外部に移行すれば、Master も Worker もステートレスにできるため、運用も楽になります。

バックエンド DB の分離

バックエンド DB を分離しよう!そう決意した僕は、移行先を検討しました。

MySQL といえば DBaaS を利用することが鉄板です。真っ先に検討しました。

ただ、鉄板である AWS RDS を含む DBaaS は非常に高い。できる限りコストを抑えたかったのです。

東京リージョンは大体どのパブリッククラウドでも高いので、東京リージョン以外のリージョンを利用した際はどのくらい品質が劣化するのか調査しました。

調査方法

  1. AWS 各リージョンに RDS を起動する
  2. RDS を向く k3s をコンテナで起動する
  3. 各種操作の時間を計測する
  4. 1~3 を繰り返す

インスタンスタイプは全て共通で db.t3.micro を利用しました。

us-east-1 を使ってみる

まず、低コストの代表 us-east-1 を使ってみました。

結果はこんな感じ。

% time kubectl --kubeconfig output/kubeconfig.yaml get node --v=10 2>&1 |grep GET
I0327 14:32:10.563803 2597482 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1be
ta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.19.4 (linux/amd64) kubernetes/d360454" -H "Authorization: Basic YWRtaW46ZmVmNDcyNGQ5MGQwMGE5OTM1O
TJiOTk3YTQxNzI4NTA=" 'https://127.0.0.1:6443/api/v1/nodes?limit=500'
I0327 14:32:11.084269 2597482 round_trippers.go:443] GET https://127.0.0.1:6443/api/v1/nodes?limit=500 200 OK in 520 milliseconds
kubectl --kubeconfig output/kubeconfig.yaml get node --v=10 2>&1  0.08s user 0.02s system 18% cpu 0.573 total
grep GET  0.00s user 0.00s system 0% cpu 0.572 total

kubectl get node のレイテンシとして、500ms くらいでした。片道250ms と思うと健闘している。

試しに ingress-nginx を apply したらこんな感じ。22s と、非常に時間がかかったことが分かります。

% time kubectl --kubeconfig output/kubeconfig.yaml apply -f ingress-nginx
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
daemonset.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
service/ingress-nginx created
kubectl --kubeconfig ~/.dev/kubeconfigs/k3d.kubeconfig apply -f ingress-nginx  0.22s user 0.06s system 1% cpu 22.417 total

色々なリージョンで調査

他リージョンだとどうなのか?調査しました。

対象は以下。

  • us-east-1 (バージニア州)
  • ap-southeast-1 (シンガポール)
  • ap-northeast-1 (東京)

ベンチマークとして、 cert-manager のマニフェストを apply してみました。

以下結果です。まずは us-east-1

% time kubectl --kubeconfig ~/.dev/kubeconfigs/k3d.kubeconfig apply -f cert-manager
...snip...
kubectl --kubeconfig ~/.dev/kubeconfigs/k3d.kubeconfig apply -f cert-manager  0.32s user 0.11s system 0% cpu 59.807 total

ap-southeast-1

% time kubectl --kubeconfig ~/.dev/kubeconfigs/kubeconfig.yaml create -f cert-manager
...snip...
kubectl --kubeconfig ~/.dev/kubeconfigs/kubeconfig.yaml create -f cert-manage  0.31s user 0.08s system 2% cpu 16.561 total

ap-northeast-1

% time kubectl --kubeconfig ~/.dev/kubeconfigs/kubeconfig.yaml apply -f cert-manager
...snip...
kubectl --kubeconfig ~/.dev/kubeconfigs/kubeconfig.yaml apply -f cert-manager  0.31s user 0.12s system 14% cpu 2.988 total

結果をまとめると、以下のようになりました。

  • us-east-1 … 59s
  • ap-southeast-1 … 16s
  • ap-northeast-1 … 2.9s

参考:

  • k3s master と同じホストで DB を起動した場合 … 0.69s
  • k3s master と別ホストで DB を起動し LAN 越しにアクセスした場合 … 1.6s

ap-southeast-1 は健闘していますが、ちょっと耐えられないかな?くらいもっさり。ap-northeast-1 は、体感ローカル DB と遜色ない反応です。

RDS 東京リージョンを選択

まともに使えるのは東京リージョンのみということが分かりました。

そのため、シュッと東京リージョンに RDS を作成、データ移行して切り替えました。

インスタンスは、 db.t3.micro で作成しました。

月間のコストは大体 $18 くらい。Netflix くらいでおうち k3s が可用性高く運用できます。

稼働後の CPU 利用率が大体 6% 前後

Freeable Memory が250MB くらいありました。

問題なし!ということで、めでたしめでたし。ところが。。。

謎の重課金発生

なぜか課金額が $130 を超えるという事態に。。。

$18 だったはずなのになぜ!?!?!?

ということで、重課金との戦い編に続きます。