TT Lab
はじめる
学ぶ 学習パス コース

CBA — Backstage認定アソシエイト

カタログは登録時ではなく、時間とともに腐る

TT Labで続きを見る

一言でいうと

カタログが崩れるのは、最初に登録するときではなく、半年後です。腐敗は、ほぼいつも3つの形で現れます。必須フィールドが欠けたエンティティ、存在しない対象を指す参照、そして互いを指し合う依存関係です。3つとも、ポータルを起動しなくても、静的に見つけられます。

なぜ必要なのか

ポータルをはじめて開くときは、たいていきれいです。人が手で入れて、入れた人がまだそのサービスを覚えているからです。問題は、そのあとです。

ここで重要なのは、Backstageがこれらをエラーとして知らせてくれないという点です。スキーマに違反したエンティティは、カタログがエラーとして表示しますが、存在しない対象を指す参照は、ただ「関係が計算されなかった」ことになります。画面には空白が見えるだけで、赤い文字はありません。

そして、カタログが死ぬ経路は、いつも同じです。参照が切れ、グラフが断片化し、画面が空に見え、人々が見なくなり、誰も直しません。空の画面は障害のように見えないので、誰も報告しません。

どう動くのか

診断すべきことは4つ

1つ目は、必須フィールドの欠落です。必須フィールドは、kindごとに違います。ComponentとAPIは、spec.type、spec.lifecycle、spec.ownerがすべてある必要があり、Resourceはspec.typeとspec.owner、SystemとDomainはspec.ownerが必要です。ここに、すべてのkindに共通して、apiVersion、kind、metadata.nameが必要です。「必須フィールド3つ」とまるごと暗記すると、kindが変わったときに間違えます。

2つ目は、切れたオーナーです。最も高くつく欠陥です。オーナーが切れると、障害時のページ、脆弱性のチケット、コストの帰属、廃止の判断のすべてが、行き場を失います。そして、原因がエンティティのファイルではない場合が多いです。組織データの同期が止まって、Group自体がカタログに入ってこなかったのです。ファイルだけを直すと、来週、同じことがまた起きます。

3つ目は、切れた参照です。spec.system、spec.domain、spec.dependsOn、spec.providesApisが対象です。オーナーと分けて見る理由は、対応が違うからです。オーナーは組織の問題で、残りはたいてい、名前が変わったか、エンティティをまだ作っていないかです。

4つ目は、依存の循環です。A dependsOn Bで、B dependsOn Aという状態です。こうなると、影響度分析が意味を失います。「これを止めたら何が壊れるか」と問うたときに、答えが自分自身に戻ってきます。原因は、たいてい誤解です。AがBを呼び出すから、B側にもAを書く必要があると考えることですが、関係は、片側の宣言で、カタログが双方向を計算します。

比較する前に、参照を正規化する

これを抜かすと、検査ツールが、問題のない参照を欠陥として報告します。

team-orders                    →  group:default/team-orders
group:team-orders              →  group:default/team-orders
group:default/team-orders      →  group:default/team-orders

3つは、同じものを指しています。kindはフィールドごとにデフォルト値が決まっていて、ネームスペースのデフォルト値はdefaultです。文字列をそのまま比べると、3つの表記がすべて別のものになってしまいます。正規化してから比べることが、この作業の最初の段階です。

直す順序がある

  1. 先に組織データ: 存在しないGroupとUserを埋めます。
  2. その次にまとまり: 存在しないSystemとDomainを作るか、移った先の名前に参照を直します。
  3. 個別のエンティティは最後: 欠けた必須フィールドを埋めて、残った参照を整理します。

順序をひっくり返すと、同じエラーを2回直すことになります。個別のエンティティのオーナーを1つずつ直しておいてからGroupを作ると、直したばかりの値が、また不自然になります。

そして、必ず守るべきことが1つあります。欠陥のあるエンティティを削除して、一覧をきれいにすることは、直したことではありません。カタログの目的は、私たちが持っているものを、漏れなく見せることです。見えないようにしたサービスも、午前3時には壊れます。

ゲートで止める

catalog-info.yamlがコードのリポジトリにあるので、検査をPRで動かせます。ファイルがマージされる前に止めれば、カタログが腐る速度が大きく下がります。ゲートは、きれいな入力には0を、欠陥のある入力には0以外の値を出す必要があります。

現場での姿

このリポジトリには、ゲートに関する痛い記録があります。「ドキュメントに平文のパスワードがない」という検査項目が、長い間緑のままでしたが、実は1つの形しか見ていませんでした。その間、複数のツールの管理者パスワードが、2つのドキュメントに平文で存在し、3つともそれぞれ違う形だったので、どのパターンにも引っかかりませんでした。

教訓は、正規表現ではありませんでした。ゲートを作ったら、止めたいものを実際に入れてみて、赤信号が点くかを確認する必要があります。通過するものだけを確認すると、そのゲートは、何でもないまま数か月が過ぎます。カタログのlintも、まったく同じです。きれいなディレクトリで0が出ることだけを見て満足すると、欠陥が入っても0を出すゲートを、デプロイすることになります。

同じ感覚が、このクラスターで繰り返し得た教訓である、「状態がReadyであることと、実際に動作することは別の命題」とつながります。カタログの画面が正常に見えることと、その中の関係が実際につながっていることは、別の事実です。後者は目で見られないので、必ず計算して確かめる必要があります。

次のラボですること

/root/cba-audit/incoming/に、引き継いだカタログの8件を、そのまま再現します。その中には、欠陥の4つの種類が、わざと入っています。そのあと、必須フィールドの欠落、切れたオーナー、切れた参照、依存の循環を、それぞれ診断して一覧に取り出し、直したコピーを作って、4つの診断がすべて0になるようにします。最後に、同じ検査を行うlintスクリプトを書いて、きれいな入力と欠陥のある入力の両方でテストし、監査の結果をクラスターに記録します。