怪しいやつ!何者じゃ!
-
あの時助けていただいたカエル弥富豪宏と申します- twitter: https://twitter.com/umegaya
- github: https://github.com/umegaya
- 技術的に難易度の高いサービスのバックエンドの設計、開発、運用をまとめて得意としています
- 数千人がリアルタイムで対戦するMMOG(大規模オンラインゲーム)のゲームサーバー
- googleのサービスを使わない位置情報ゲーム用の地図配信バックエンド
- NFTゲーム用のethereumのprivate chainのクラスタ on kubernetes
cordaとの関わり
- cordaを使った電子契約サービス(以下Tと呼びます)の構築
- IaaS的なcorda プライベートネットワークの設計、開発、運用を担当しました
- プログラム的にcordaノードを追加/削除/更新などの管理可能
- ユーザーに見えるような大きな障害もなく、現在プロダクション環境で元気に動いています
本日のお品書き
- Tのプロダクション環境におけるcorda関係のシステム構成
- 発生したトラブルと原因
- 得られた教訓
本日のお品書き
- Tのプロダクション環境におけるcorda関係のシステム構成
- 発生したトラブルと原因
- 得られた教訓
Tのプロダクション環境におけるcorda関係のシステム構成
Tの開発の様子(2020/12)cnat🤔
-
cordaのprivate networkを、抽象化されたリソースとして、各種サービスを構成するモジュールが扱うことができるようにするための内部サービス。以下のような理由から筆者が開発した
- 当初の構想では企業単位でサービスに参加してもらい、その企業毎にcorda nodeを提供する予定であった
- 参加企業の数は多くなることが予想されたため、構築の自動化が必要とされた
- ユーザーはcordaの特別な知識がないため、corda nodeのメンテナンスやスペックの変更、ソフトウェアの更新などの管理もサービスとして提供したかった
-
詳細は今回は割愛いたします
azure🤔
-
わかってます
-
これは技術的負債となっている
- 構築当時cordaのサポートはazureでしか提供されておらず、また自力で全てなんとかできるという目処も立っていなかったため、azure(aks)を利用した
- 結果論だが、発生した障害の質や後で得られたサポートの量などを考えると、eksで最初からやっていればという気持ちもある(今は公式にeksでもいける)
azure側のaksクラスタの詳細
- cordaクラスタ
- cenmクラスタ
- jpaクラスタ
cordaクラスタ
- 各会社用と、個人利用者用のcorda nodeを動かしているaksクラスタ
- velero https://velero.io/ corda nodeのファイルシステム上のデータを格納するpersistent volumeのバックアップのために利用
cenmクラスタ
- cordaクラスタが利用するnotary/id-manager/network-map/signerなどのCENMコンポーネントを動かしているaksクラスタ。
- 公開されているhelm chartを元に、ha-notaryとして指定した台数のnotaryを起動できるようにしたソフトウェアを使って構築している
- cordaクラスタと分割している理由としては、外部のcorda nodeがTのprivate networkに参加するという構想があったため、障害範囲を分離したかったことが大きい
jpaクラスタ
- cockroach dbを動かしているクラスタ
- cenmのenterprise notaryがレコードを記録するDBについて、我々の構築時点ではcockroachdb/oracle RACをバックエンドとしたJPAを利用することが推奨されていた
- oracleは使いたくなく、azureはcockroach cloudのサポート外であったため、自前でcockroach dbを運用する必要があった
本日のお品書き
- Tのプロダクション環境におけるcorda関係のシステム構成
- 発生したトラブルと原因
- 得られた教訓
発生したトラブルと原因
人為的なミスによるTの障害発生の瞬間(2021/01)発生したトラブル
- 2つ紹介します
- 通信障害
- cordapp更新に伴うステートのマイグレーションのエラー
通信障害
通信障害
- corda nodeをソフトウェア更新のため再起動した際に発生する
- notary => corda nodeでnotarizeのための通信が行えなくなる
- corda node => notaryは通信できている
- TCPレベルの接続失敗により、AMQP接続がリトライを中止している
No targets have presented acceptable certificates ... Halting retries
- corda nodeの再起動にはかなり時間がかかっていたため、corda nodeが起動できない間にnotaryが接続を行おうとしてtimeoutしていることが強く疑われた
タイムアウトが短すぎるんじゃない?
って思うじゃろ?
タイムアウトが短すぎるんじゃない?
- corda node / notaryのSSL handshake timeoutやamqpのリトライ関連の設定を調整したが効果なし
通信障害:一時対応
- notaryを再起動すると問題が解決した
- notaryを再起動したタイミングではcorda nodeの再起動がかかっておらず、すぐ接続できるためだと考えられた
- そのため毎日3つのnotaryを自動で順番に再起動することで停止時間を設けず問題を復旧する一時的な対応を行なった
- その間に根本的な原因の究明を開始
通信障害:原因究明
- すでに述べたように、当初の運用方針として、外部のcorda nodeがTのprivate networkに参加する想定だった
- そのためTがcnatで起動するcorda nodeのP2Pポートにも外部IPを割り当てる必要がある
- 大量のユーザーがTを利用した時のことを考えて、azureのglobal IPのquotaを超えないように、corda nodeごとに別にglobal IPを割り当てないで欲しいという要件があった
通信障害:原因究明
- global IPを節約する
- kubernetesのnginx ingress controllerを使い、1つのglobal IPへの異なるポートへのアクセスを別々のcorda nodeのP2P portに転送するという形で使い回してこの要件を達成した
- つまり、corda node => notaryと異なり、notary => corda nodeの経路にはnginx serverが挟まっていた
通信障害:原因究明
- このnginxがcorda node / notaryの設定とは異なるSSL handshake timeoutの設定を持っていたことが原因
- nginxが切断を行なっていたため、corda node / notaryの設定変更では効果がなかった
- global IPを節約するのは原因が判明した状況ではそれほど重要ではなかったため、それぞれのcorda nodeに割り当てるようにして解決した
cordapp更新に伴うステートのマイグレーションのエラー
cordapp更新に伴うステートのマイグレーションのエラー
- ステートに新規に追加されたシンボルを型として持つ変数を追加した
- 我々のcordappは署名されているため、こう言ったケースで古いcordappで作成されたstateもsignature constraintによって正常に新しいcordappで動くようにマイグレーションされるはずだった
- しかしhash constraintで動いている時と同じエラーが発生しマイグレーションできなかった
- よくあるパターンのソフトウェア更新ができず運用に支障があった
cordapp更新に伴うステートのマイグレーションのエラー:原因究明
- signature constraintはminimumPlatformVersion >= 4でないと有効ではなかった
- このことはあまり明示的にcordaのドキュメントには書いていない(見つからない)。「corda 4」が必要だとは書いてあるが
- 我々がCENMの構築に利用したhelm chartはデフォルトでminimumPlatformVersion = 1を利用していた
- 今もcenmのhelm chartのデフォルトは3になっているので注意 https://github.com/corda/cenm-deployment/blob/master/k8s/helm/notary/values.yaml#L62
- network parameter updateをgitopsで行えるようにし、minimumPlatformVersionを7に上げることで解決した
本日のお品書き
- Tのプロダクション環境におけるcorda関係のシステム構成
- 発生したトラブルと原因
- 得られた教訓
得られた教訓
cordaのステートは手動では書き換えられないと聞いた時のTのPM(2021/03)得られた教訓
- 実際に全ての主要なコンポーネントを連携させて動作テストを行う
- cordaノードやデータベースなどをいくつも立ち上げテストするのは、リソースを非常に食うため、ユニットテストに頼りがち
- しかしモジュールの境界面に予想していない落とし穴があり、それらは単体のソフトウェアテストでは発見できない、あるいはそこまでテストを作り込めない、ようなことが多い
得られた教訓
- ログやソースコードを恐れずよく読む
- ログはTRACEレベルまで出せるようにしておく => 量が多いのでlog4j2.xmlにmonitoringIntervalを設定しておいて必要な時に出すのが有用
- ログで見られたメッセージでcordaのソースを見ていくことでヒントが得られることがある
得られた教訓
- 最初からnetwork parameter minimumPlatformVersionは4以上にしておく🤗
- private networkをhelmで作る場合には、未だデフォルトではこの状態でないようなので注意
えーこんなの罠多すぎ。。。マヂ無理。。。
ですよね!
そんな困ったあなたに
株式会社トリックトラック
- https://www.trictrac.co.jp/
-
アジャイルをはじめとした最新の開発手法を駆使するPMと、最先端の技術を身につけた開発チームがあなたのビジネスの成功をお約束します!
- 私もcorda関連を担当させていただいております
-
cordaなど技術面のお悩みはトリックトラックに任せ、お客様はビジネスの課題にご集中ください!
- we develop, you profit👍