Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

State の内部構造

State は、Tazuna が「自分が入れたリソース」を追跡するための記録です。 クラスタ内の ConfigMap に保存され、tazuna state list / tazuna state diff / tazuna state sync の起点になります。

このページでは State の保存形式と、それを支える State key / ContentHash / Diff type の 仕様をまとめます。

保存場所

State は クラスタ内 に保存されます。Tazuna のローカルファイルやリモートストレージは使いません。

要素
Namespacetazuna(無ければ自動作成される)
ConfigMap 名tazuna-state-<manifest-name>
形式ConfigMap.data に key/value で 1 リソース 1 エントリ

1 つの Manifest が 1 つの ConfigMap に対応します。 includes 展開後の各 Manifest 名はユニーク(tazuna.yamlname 参照)なので、 ConfigMap 名は衝突しません。

State key

State key は、ConfigMap 内の 1 エントリを指す識別子です。 構造体としては manifestName / group / version / kind / namespace / name を持ち、 文字列化のフォーマットは次の 2 通りです。

リソースのスコープ形式パート数
namespaced{manifest}/{group}/{version}/{kind}/{namespace}/{name}6
cluster-scoped{manifest}/{group}/{version}/{kind}/{name}5

group は core group("")の場合は空セグメントになります。 例: core/v1 の ConfigMap(namespaced)であれば、my-manifest//v1/ConfigMap/default/my-cm のように 2 つ目のスラッシュ間が空になります。

ConfigMap data key へのエンコード

Kubernetes の ConfigMap.data の key は [-._a-zA-Z0-9]+ しか許さず、/ を含められません。 そのため Tazuna は ConfigMap への書き込み時に State key 文字列の /__ に置換します。 読み込み時には逆変換します。

state key:    nginx/apps/v1/Deployment/default/nginx
data key:     nginx__apps__v1__Deployment__default__nginx

Kubernetes の DNS-1123 名(manifest 名 / group / namespace / name)に _ は含まれないため、 __ は安全なセパレータとして使えます。

State エントリ (StateEntry)

各エントリは ConfigMap 上 1 つの value として、次の JSON 形で書き込まれます。

{"contentHash":"<hex sha256>"}
フィールド説明
contentHashstringリソースの内容に対する SHA-256 ハッシュ。詳細は ContentHash 参照。

_metadata キー

ConfigMap には予約キー _metadata がもう 1 つ入ります。 これは State エントリではなく、State 全体のメタ情報です。

{"gitCommitHash":"<sha>","lastSyncedAt":"<rfc3339>"}
フィールド説明
gitCommitHashstring同期時に記録された git commit hash。
lastSyncedAtstring同期時刻。

Manifest の name には _metadata は使えません (tazuna.yamlname で予約語として扱われています)。 この衝突を避けるためのガードです。

ContentHash

ContentHash は、各リソースの YAML 表現から計算される SHA-256 の hex 文字列です。 Tazuna は server-side で付与される fieldstatus を除いて計算します。

除外するフィールド:

フィールド除外理由
metadata.resourceVersionクラスタの世代管理用、適用ごとに変動するため
metadata.uidクラスタ採番、適用ごとに変動するため
metadata.creationTimestampクラスタ採番、適用ごとに変動するため
metadata.generationクラスタ採番、適用ごとに変動するため
metadata.managedFieldsserver-side apply の追跡情報
metadata.selfLinkクラスタ採番
statusコントローラが書く動的フィールド

計算手順:

  1. オブジェクトを JSON マーシャル / アンマーシャルして deep copy する。
  2. 上記の除外対象フィールドを削除する。
  3. 残りを JSON マーシャルする。
  4. SHA-256 を取り hex 文字列化する。

status を含めると Pod の再起動などで毎回ハッシュが変わってしまうので、 tazuna.yaml から見て同じ状態か」 を判定できる粒度に絞っています。

Diff type

tazuna state difftazuna state sync は、Build 結果と既存 State の比較結果を Diff type で分類します。

Diff type意味state sync の挙動
addedBuild 結果に存在し、State に無い反映する
modified両方に存在するが、ContentHash が異なる反映する
removedState に存在し、Build 結果に無いデフォルトはスキップ。TAZUNA_STATE_SYNC_DELETE=true のときだけ削除
always-sync差分計算をスキップし、常に同期扱いとする反映する

state diff の出力は addedmodifiedremovedalways-sync の順、 同 Diff type 内は State key 昇順で安定ソートされます。

always-sync の対象

現バージョンでは、type: genesissecret 由来の Secret が always-sync 分類になります。 これらは Provider 側を真実の源として毎回同期する性質を持ち、ContentHash で差分判定できる対象ではありません。 詳細は GenesisSecret スキーマ - State と always-sync を参照してください。

関連