これは、k8sクラスタを個人で運用する際に行った構成要素の技術選定の記録である。 技術選定の理由を書くのも見るのも楽しい、という心情のもとにここに公開する。
前提知識
以前、こんなエントリを書いた。
bitcoinのfull nodeをAWSでなるべく安く運用してみる - でこてっくろぐ ねお
上記の通り、個人でbitcoinのfull nodeという、状態をバリバリもつサービスを、AWSでのコスト面で最安を狙って作り運用を行っていた。 しかしその後、Oracle Cloudで運用したほうが安くなることに気づいたため引っ越した。 Oracle CloudではARMのVMが4台無料で使えて複数台構成が組め、AWSやGCP同様k8sのマネージドサービスもあり、また仕事でk8sを扱う部署に異動したのもあり、勉強のためk8sクラスタ上で運用することにした。
構成要素
以下の構成要素を選択している。以下の中でも"☆"のついたものについて詳細を掘り下げる。
- ☆ クラウド
- Oracle Cloud
- マネージドk8sサービス
- OKE(Oracle Container Enginer for Kubernetes)
- ☆ ソースコード管理
- マニフェスト管理
- Helm
- ☆ CI
- CD
- ArgoCD
- ☆ 秘密情報の管理
- ☆ 監視
- イメージ管理
- docker hubのpublic image
クラウドにOracle Cloudを採用
Oracle クラウドが私のユースケースではコスト的に最安だったため選択。 以下がすべて無料で使えるため、結構な範囲の個人ユースには価格的には最適なのではないかと思っている。
- ARMインスタンスを4コア・メモリ合計24GB
- AMDインスタンスを2台
- ブロックストレージ 合計 200GB
- NAT Gateway
- Outboundのデータ転送、月に10TB
- bitcoinのfull nodeはブロックデータをpeerとやり取りするため意外とデータ転送量を食う
- Network Load Balancer
詳細: Oracle Cloud Free Tier | Oracle 日本
ソースコード管理
ソースコードの管理(主にマニフェスト)にはgithub の public リポジトリを採用している。
privateにするという判断もあったかと思われるが、publicリポジトリだとGithub Actionsが無料で使えて大変便利であり、publicにしておくと"ちゃんとしないといけない"圧力が自分で自分にかかって勉強になるという利点もある。 また、発表の場やブログなどで実例を社内外にリンクで紹介できて楽というのも見逃せないポイントとしてある。このエントリ内でもいくつかリンクを便利に使っている。
CI
マニフェストを適用しないとエラーが発覚しないのはたいへんダルいので、CIも整備してある。
pull requestに対してGithub Actionsが発火する形のCIとなっている。
CIでは以下のチェックを行っている
マニフェストの差分の検知にはjestのsnapshot testを実施している。helm template
を実施してマニフェストを出力し、差分があるとテストが落ちる。また、差分があった際に変更行が出力されるため、意図しない変更が行われていないかを検知するのに役立つ。
snapshot testについては、マニフェスト管理のためというよりはもともとViewのテストを行うために作られたという認識だが、ここで行っているマニフェストの差分検知のように、なんらか文字列を出力するものをテストするのに非常に優れている。詳細は以下のエントリを読むと良い。
ただ、jestを使わなくてもhelm templateの結果をgit commitしておくだけでも十分な気もしているのでそうしてもいいかなとは考えている。
CIの設定の詳細はGithub Actionsのファイルを見てください: crypt-manifest/ci.yaml at main · dekokun/crypt-manifest · GitHub
依存関係の更新補助
依存関係の更新の補助にRenovateを採用している。 Renovateがhelm chartの更新を検知してpull requestを作成し、github actionsがそれに対してsnapshotのupdateを行ってコミットし、人間はただその差分を眺めて良さそうであればmergeを行えばArgoCDが自動的にデプロイしてくれる世界になっている。
renovateからのpull requestに自動的にsnapshotのupdateを行ってくれるgithub actionの設定: crypt-manifest/auto-snapshot-update-for-renovate.yaml at main · dekokun/crypt-manifest · GitHub
機械が差分を出してくれるので人間はこのようにdiffを見るだけで良い: Update Helm release sealed-secrets to v2.1.3 by renovate · Pull Request #37 · dekokun/crypt-manifest · GitHub
この世界は非常に便利だったため、仕事にも輸出した。
秘密情報の管理
例えば、監視に使っているMackerelのapi keyをどのようにk8sに伝えるかは考えないといけない。 github の public リポジトリを使っている以上、平文でマニフェスト内にベタ書きすると、バージョン管理に含められなくなってしまって運用が面倒になってしまう。
最初に検討したのが、クラウド上のsecret manager的なものと連携するというものであったが、Oracle Cloudでかんたんに連携できるCSI Driverはパット見なさそうだったのと、あまりクラウドに依存したくないのと個人クラスタ管理には大げさに感じたので見送った。
そこで、初期はhelm secretsのhelm wrapperを使ってhelmのデプロイ時にhelmの変数として突っ込むようにしていたが、ArgoCD導入時に調べたところArgoCDとの連携が面倒くさく思えたのでhelm secretsの継続は諦めた。
また、helm secretsを使う場合は手元のマシンの中や、AWS の secret manager等自分で秘密鍵の管理方法を考えて管理しなくてはいけなかったのもネックである。
その際にKubernetes完全ガイドを読んでいたところ、"sealed-secrets"というツールが紹介されており、上記欠点を完全に解決していたので採用した。
このツールは暗号化したマニフェストファイルをデプロイするとk8s内で復号しSecretを生成してくれる。
秘密鍵の管理はクラスタ内に閉じており、マニフェストファイルの暗号化の際も手元に秘密鍵は渡らないため安心して使うことができる。
監視
普段仕事で使ってるMackerelでどうするとより良いk8sの監視ができるのかを探るために採用。 コンテナのサイドカーとしてmackerel-container-agentを動かしている。
上記の通り、Oracle Cloudを無料で使うためにARMインスタンスを使用しているが、Mackerelも最近container-agentの公式イメージがARM対応したためパッと入れられた。
ついでにbitcoin向けのMackerel pluginも作ったのでよければどうぞ。
また、cronJobを使用して bitnodesからbitcoin fullnode の自分の順位の取得を行ってMackerelへの投稿もしている。順位の変動が可視化され、"この日full nodeが落ちから順位が下がってるな"などがわかって便利。
感想
久しぶりに個人で手を動かして何かを作ってるけど楽しいな〜〜〜