ここで噛む動作は、偶発的なものではなく指定されています YAML 1.2 仕様 引用符で囲まれていないスカラーを型にどのように解決するかを定義します。
サービスをバージョンに固定する展開を出荷したことがあります 1.1 構成ファイルがはっきり言っていたとき 1.10。 タイプミスではありません。 検索と置き換えは悪くありません。 私が 4 回読んだ YAML ファイルには、次のように書かれています。
image_tag: 1.10
そしてパーサーは私のデプロイスクリプトに番号を渡しました 1.1。 だってさ 1.10 isn' T は YAML へのバージョン文字列 - it's a フロート文字と、浮動小数点数は末尾にゼロを維持しません。 10 は 1 点 1 になります。 ファイルは 100% 有効な YAML でした。 リンターは幸せでした。 CI は緑色でした。 間違ったコンテナが出てきました。
YAML 検証について誰も教えてくれないのは、次のとおりです。 「有効」は「正しい」と同じではありません。 Yes/no だけに答える構文チェッカーは、簡単な質問に答えることです。 hard question - 実際に deploys を壊す質問 - は、 私の YAML は何に変わりましたか? YAML は構成形式ではないため、構成形式の服を着た型推論エンジンであり、データについての決定を下して、ユーザーが作成するように要求したことはありません。
ザ・ YAML バリデータ on Toolz.dev は両方の質問に答えます。ドキュメントが解析するかどうかを教えてくれます。その後、解析された結果を JSON として示します。ツーリングが受け取る実際のデータ構造です。その後半が私を救ってくれたでしょう。 "image_tag": 1.1 出力ペインで読み誤りはありません。
tl;dr: YAML に貼り付けます。 YAML バリデータ そして読んで JSON 出力、緑色のチェックマークだけではありません。 タイプの強制がそれ自体を示す場所:
1.10→1.1、0123→123、引用符なしの値は、静かに数値、ブール値、または null になります。 JS-YAML (YAML 1.2) で完全にブラウザーで実行されるため、Kubernetes シークレットとデータベースの資格情報は決してマシンから離れません。 文字列のままにしなければならないものはすべて引用します。 結果を JSON 構成と比較する必要がある場合、 JSON フォーマッタ あんど json 差分 そこから拾う。
YAML バリデーターは実際に何をチェックしますか?
2 つの異なることですが、失敗するので、それらを分ける価値があります。
構文検証 質問: このテキストを解析できますか? スペースが属するタブ、コロンの後に欠けているスペース、ボディがインデントされていないブロック スカラー、クローズされていない引用符。 これらは うるさ 失敗。 パーサーがスローし、パイプラインが赤くなり、2 分で修正します。 面倒くさい、危険ではありません。
セマンティック検査 質問: 何を解析したのですか に? ここに静かな失敗があります。 ドキュメントは有効です。 パイプラインは緑色です。 値は、あなたが書いたと思っていたものとはまったく異なります。 プロダクションが奇妙に動作するまで誰も知りません。それまでは、構成ファイルが「問題」であるため、誰も構成ファイルを調べていません。
ほとんどのオンラインYAMLチェッカーは最初のものだけを行います。 Toolz.devバリデータは最初のものを行い、次に2 番目のものをあなたに渡します - 解析されたドキュメント、JSONとしてレンダリングされ、入力のすぐ隣にある そのペインを読む習慣をつけましょう。 It& #39; s " the difference between " the file is well-formed" and " the file means what I meant."
ビルドを実際に壊す YAML エラーはどれですか?
これが本当に現れたもので、それぞれの人生でどれだけの犠牲を払ったかでランク付けされています。 以下のすべての行動は、私が確認したことに対して確認しました JS-YAML 4、これは、Toolz.dev バリデータが実行し、 ヤムル 1.2 スペック
1. タブ。 常にタブ。
YAMLはインデントのタブ文字を禁止します。 "discourages" - forbidsではありません。 specは明示的で、エラーメッセージはさわやかに直接的です:
tab characters must not be used in indentation
これが発生し続ける理由は、タブが非表示にするためです。 エディターは、整列したファイルを表示します。パーサーは、コントロール文字を表示します。 ソースで修正してください: エディターでスペースを挿入するように設定し、YAML ファイルの [空白をレンダリング] をオンにします。 レベルごとに 2 つのスペース。これは、すべての主要な YAML エコシステムが定着した慣習です。
2. キーの重複
database:
host: localhost
port: 5432
host: production-db.example.com
host 2回登場。 何が起こる? これは完全にパーサーに依存します。これは、構成形式について書くのは恐ろしい文です。
JS-YAML 投げる: duplicated mapping key。良い. That's the behavior you want, and it's what the Toolz.dev validator will show you.しかし、PyYAML - これは Ansible と多くの Python ツールが置かれているものです - は静かに受け取ります 最後の 価値を持ち、先に進みます。 警告なし。 データベース ホストは、最後の複製が言ったものをすべて、長いファイルでは、あなたが探している場所から 300 行離れている可能性があります。
これは、プロダクション ツールがそれらを受け入れたとしても、厳密なバリデータを介して構成を実行するための唯一の最良の引数です。 のバリデーター より厳格 ランタイムよりもバグを見つけるバリデーターです。
3.タイプ強制 - 私を得たもの
YAML は、引用符で囲まれていないスカラーからタイプを推測します。 それは非常に自信があり、あなたの意図については間違っていることがよくあります。
| あなたが書いた | あなたはそういうつもり | YAML 1.2 が提供します |
|---|---|---|
version: 1.10 |
文字列「1.10」 | フロート 1.1 |
pin: 0123 |
文字列「0123」 | 整数 123 |
port: "8080" |
8080という数字 | 文字列 "8080" |
enabled: true |
ブール | ブール true ー正解 |
value: |
空の文字列かも? | null |
value: ~ |
チルダ | null |
あれか 0123 行は1 です I& #39; d タトゥー 人々. zip codes, PINs, アカウント番号, ゼロパッド入りID - すべての先頭のゼロは、あなたが理由のために書いた食べられて取得します。
一度も私を失望させたことのないルール: 値が識別子、バージョン、コード、または絶対に演算を行わないものである場合は、引用符で囲んでください。 ポートとレプリカの数は、むき出しのままにすることができます。 ただのすべて 見ている 数値は "quoted"。
4. バージョンに依存するブール (別名ノルウェー問題)
これは本当に悪名高いもので、詳細はミームよりも重要です。
で YAML 1.1、ブール型は受け入れます yes、 no、 on、 off、 y、 n、およびその大文字に加えて、 true あんど false。 そー country: NO - ノルウェー' s ISO 国コード - ブール値として解析します 偽。 で ヤムル 1.2、これをクリーンアップしただけです true あんど false ブール値です。 NO ただの文字列ですか "NO"。
つまり、同じファイルです さまざまなツールで異なることを意味します:
country: NO
feature_flag: on
- JS-YAML 4 (YAML 1.2 と、このバリデーターの使用方法):
{"country": "NO", "feature_flag": "on"}ー ストリングス. - Pyyaml (YAML 1.1):
{"country": False, "feature_flag": True}ー booleans.
同じバイト。 別のデータ。 ノード サービスが消費する構成で CI が Python リンターを実行している場合、2 つのパーサーが自分のファイルについて意見が合わないので、どちらも間違っていません。
これが GitHub アクションの起源でもあります。 on: すべてのワークフローが開始されるキーは、 ブール YAML 1.1 パーサーに、Python でリンクするワークフロー ファイルをリントするスクリプトは、次のようなキーを見つけます。 True 代わりに on。 引用 ("on":) は合法であり、それを修正します。
防御的な動きは、前と同じです。 引用してください。 country: "NO" という意味 "NO" これまでに存在したすべてのパーサーに。
5. スカラーのインデントをブロックする
description: |
This is not indented
ザ・ | (文字通り) そして > (折りたたみ) ブロック スカラーは、キーに対してインデントされたコンテンツが必要です。 インデントされていないコンテンツはすぐにブロックを終了し、パーサーは YAML キーとしてあなたの散文を読み始めます。これにより、実際のミスとは何の関係もないように見えるエラー メッセージが生成されます。
あなたがここにいる間、むしゃむしゃむしゃのインジケーターを知っておく価値があります。 | 後続の改行を 1 つにします。 |- それを剥がして、 |+ それらすべてを保持します。 秘密鍵またはスクリプトを埋め込んでいて、下流の何かが後続の改行について不平を言うなら、これはあなたのノブです。
6. 引用符で囲まれていない特殊文字
引用符で囲まれていない値内のコロン空間は、値を終了し、新しいキーを開始します。 これは、エラー メッセージと URL を噛み合わせます。
message: Error: file not found # parse error
regex: [a-z]+ # parsed as a LIST, not a string
time: "22:22" # quote it — in YAML 1.1 this was base-60!
[、 {、 #、 &、 *、 !、 |、 >、 %、 @ スカラーの開始時には、すべて何か意味があります。 最初に引用して、後で質問してください。
Toolz.dev で YAML を検証するにはどうすればよいですか?
- を開きます YAML バリデータ。 アカウントもアップロードもありません。
- ドキュメントを貼り付けます。 Helm の値ファイル、docker-compose、ワークフロー - 何であれ' s の不正動作。
- 検証を押します。 エラーは正確に戻ってきます 行と列 パーサーから、さらにパーサー独自の理由文字列 (
bad indentation of a mapping entry、duplicated mapping keyなど)。 - JSON 出力ペインを読みます。 これが、人々がスキップするステップであり、重要なのはそのステップです。 気になる値をスキャンします。 です
image_tag文字列か数字か? そのポートは引用されていますか? 空の値はありましたかnull? - 修正、再検証。 エラーは互いにマスクすることができます - パーサーはそれができる最初の1 で停止します& #39; tから回復するので、1 を修正すると、時々さらに2 つが現れます。 That& #39; s normal, not a sign things are getting worse.
1 つの既知の制限、はっきりと述べています
バリデーターは現在、 単一の YAML ドキュメント。 multi-document ファイルを貼り付ける場合 - で区切られたいくつかの Kubernetes マニフェスト --- 1 つのファイルでは、非常に一般的なパターンです - それは報告します:
expected a single document in the stream, but found more
ファイルが壊れているのではなく、パーサーが正しいのです。 今日の回避策は、各ドキュメントを個別に検証することです。その上にすべてを貼り付けます。 ---を確認してから、次のチャンクを貼り付けます。 マルチ ドキュメントのサポートは、私のリストにあります。これは、Kubernetes ユーザーがすぐにこれを達成したためです。ただし、インシデントの途中で発見するよりも、ギャップについてお話ししたいと思います。
YAML と JSON: いつ使うべきですか?
YAML 1.2 は JSON の厳密なスーパーセットです。有効な JSON ドキュメントはすべて有効な YAML であるため、バリデーターは JSON 出力をまったく渡すことができます。ただし、フォーマットは反対の性格を持っています。
| ヤムル | json | |
|---|---|---|
| によって定義された構造 | インデント (空白 - 重要) | 中括弧とブラケット (明示的) |
| コメント | はい(#) |
いやー |
| 型推論 | 攻撃的 - 数値、ブール値、ヌル、日付を推測します | なし - 引用符は常に文字列を意味します |
| 複数ドキュメント | はい(--- セパレーター) |
いやー |
| 再利用 | アンカー (&)、別名 (*)、マージキー (<<) |
なし |
| 障害モード | 黙って誤解する | 大音量の解析エラー |
| 最高に | ファイルの人間の書き込みと編集 | データマシン交換 |
取引は本物であり、双方向に進みます。 YAML' sの可読性とコメントは、まさにインフラストラクチャ構成がそこに住んでいる理由です - 誰もコメントなしでJSONで400 行のKubernetesマニフェストを維持したくありません。 JSON' sの賢さの完全な欠如は、APIがそれを使用するまさに理由です: "1.10" です "1.10" そして、議論することは何もありません。
私のルール: yaml はファイルを編集し、JSON はデータ マシンを通過させます。 そして、YAML ファイルが人によって入力されるのではなくプログラムによって生成されると、その ' s 機械によって生成された匂い設定は、YAML' の利点とそのすべてのリスクを一切得ません。
2 つの間を移動している場合、 JSON から YAML へのコンバータ 変換を処理し、 JSON フォーマッタ 反対側を片付けます。
アンカーとエイリアスとは何ですか?それらを使用する必要がありますか?
YAML では、ブロックを一度定義して再利用できます。 とアンカー &、参照 *、地図にマージして <<:
defaults: &defaults
adapter: postgres
host: localhost
port: 5432
development:
<<: *defaults
database: myapp_dev
test:
<<: *defaults
database: myapp_test
両方 development あんど test アダプター、ホスト、ポートがマージされた状態で出てきます。it's は本当に便利で、js-yaml がそれを処理します。マージが正しく解決されることを確認しました。
2 つの警告ですが。
まずは、 マージ キーは YAML 1.1 拡張機能です、YAML 1.2 コアの一部ではありません。 サポートは広く普及していますが、普遍的ではなく、そして - 人々を捕まえるもの - GitHub アクションはサポートされていません。 ワークフロー ファイルのアンカーは、必要な機能を実行しません。 これに頼る前に、消費者を確認してください。
次に、アンカーは次の人がファイルを読みにくくします。構成では、次の人は通常午前 2 時にあなたです。私は、それらを真に繰り返されるブロックに使用し、巧妙さを保つためには使用しません。
YAML の危険な側にいる間: この形式は、一部のパーサーが任意のオブジェクトを構築するために使用するカスタム タグをサポートします。 yaml.load() このように悪用されたことで有名なのですが、そのためです yaml.safe_load() が存在し、なぜあなたがそれを使用する必要があります - 常に - あなたのチームの外から来た任意のYAML上で。 js-yaml& #39; s load() V4 はデフォルトで安全です (任意の型は構築できません)。これは、ここで心配する必要がありません。
そもそも壊れた YAML を書くのをやめるにはどうすればよいですか?
予防は検証に勝るものであり、そのほとんどはエディター構成です。
- 2 つのスペース、決してタブではありません。 ファイルタイプごとに設定して、忘れないようにします。
- 空白のレンダリングをオンにする のため
.yml/.yaml。 タブが表示されている場合、タブはコミットしません。 - YAML 言語サーバーをインストールします。 Kubernetes、GitHub アクション、および Docker-Compose スキーマに対するリアルタイムのスキーマ検証は、構文検証がスペルミスのあるキーで有効な YAML であるというエラーのクラス全体をキャッチします。
- デフォルトで、疑わしい場合は引用します。 不要な見積もりのコストはゼロです。 欠落しているもののコストは展開です。
- プッシュする前に検証する、CI が失敗した後ではありません。 ブラウザー タブに貼り付けるには 8 秒かかります。失敗したパイプラインには 8 分かかります。
- Kubernetes の場合は、チェックをレイヤ化します。 構文検証は構造をキャッチします。
kubectl apply --dry-run=clientスキーマをキャッチします。 彼らは異なるバグを見つけ、あなたは両方を望んでいます。
そして、実際に私にとって物事を変えた習慣: 構成駆動型デプロイが説明のつかないことを行う場合、 他のものを見る前に、解析された出力を確認してください。 ファイルではありません。 解析された出力。 ファイルは、あなたが何を意味するかについてのストーリーです。 解析された出力は、実際に起こったことです。
それは私のすべてを支配するのと同じ本能です API デバッグ ワークフロー ー コードではなくデータを読みます ー そしてそれはレスポンスと同じように コンフィグにも適用されます そのツールボックスに他に何があるか もっと広いツアーをしたいなら コーディング ツール ガイド それをカバーします。
よくある質問
YAML が検証しても、展開が壊れるのはなぜですか?
構文の妥当性と意味の正しさは別物だからです。 YAML は引用符なしの値から型を推測します。 1.10 フロートになります 1.1、 0123 整数になります 123、空の値が null ーすべて完全に有効なドキュメントで。 pass/fail の結果だけでなく、解析された JSON 出力を読み、文字列のままにする必要がある値を引用します。
YAML が私のバージョン番号を別の番号に変換するのはなぜですか?
1.10 は、YAML のリテラルであり、浮動小数点は末尾のゼロを保持しないため、次のように解決します。 1.1。 バージョン、ビルド番号、またはゼロ パッド付きの識別子は、引用する必要があります。 version: "1.10"。 ファイルが正しく見え、解析が成功するため、これは YAML の最も高価なミスの 1 つです。
YAML のノルウェーの問題は何ですか?
YAML 1.1 では、値 no、 NO、 off、そして yes ブール人なので、ノルウェーの国コード NO として解析します false。 YAML 1.2 はこれを修正しました - のみ true あんど false はブール値です - しかし、多くのツール (特に Ansible が使用している PyYAML) はまだ 1.1 を実装しています。したがって、同じファイルでも、異なるツールでは異なる意味を持つ可能性があります。 (値)を引用しますcountry: "NO") はどこでも文字列になります。
YAML でインデントするタブを使用できますか?
いいえ、YAML 仕様ではインデント内のタブ文字が禁止されており、パーサーは " などのエラーでタブ文字を拒否します。タブ文字はインデントで使用してはなりません。" YAML ファイルのスペースを挿入するようにエディターを設定します。レベルごとに 2 つのスペースが標準規則です。
Toolz.dev Yaml Validator は複数ドキュメント ファイルをサポートしていますか?
現在はありません。 単一のドキュメントを検証するため、複数の Kubernetes マニフェストを含むファイルが、 --- 「ストリーム内の単一のドキュメントを期待しています。」を返します。回避策として、各ドキュメントを個別に検証します。 複数のドキュメントのサポートが計画されています。
YAML では重複キーを使用できますか?
仕様書では、マッピングキーは一意でなければならないと書かれていますが、実際にはパーサーの意見が異なります。 js-yaml - このバリデーターが使用する - は " duplicated mapping key" エラーを投げます。 PyYAML は最後の値を静かに保持します。つまり、重複しても警告なしで設定を静かにオーバーライドできます。 strict validator を介してコンフィグを実行すると、ランタイムがサイレントに受け入れる前にこれがキャッチされます。
Kubernetes の秘密と資格情報をオンラインで検証しても安全ですか?
Toolz.dev バリデータを使用すると、はい - 解析は完全に JavaScript 経由でブラウザ内で行われ、どのサーバーにも何も送信されません。検証中にブラウザ' s ネットワーク タブを開き、リクエストが行われていないことを確認することで、ご自身でこれを確認できます。インフラストラクチャ構成を貼り付ける前に、同じチェックをオンライン ツールに適用します。
.yml と .yaml はどう違いますか?
何も機能しません - 両方の拡張機能はすべての YAML パーサーによって認識されます。公式の推奨事項は次のとおりです .yaml; .yml 3 文字の拡張機能の時代から生き残り、非常に一般的なままです (Docker の構成と GitHub の両方のアクションは、デフォルトでそれに基づいています)。 1 つを選択して、プロジェクト内で一貫性を保ちます。
YAML を JSON に変換するにはどうすればよいですか?
YAMLをバリデータに貼り付け、出力ペインを読み込みます - 解析されたドキュメントをJSONとしてレンダリングします これは変換です YAML 1.2 はJSONのスーパーセットであるため、有効なYAMLドキュメントはすべてJSON相当のものがありますが、型推論が最初に適用されるため、引用符で囲まれていません 1.10 として到着します 1.1 あんど 0123 のように 123。 文字列として保持する必要がある場合は、最初にこれらの値を引用してください。
YAML をスキーマに対して検証するにはどうすればよいですか?
このバリデータは構文をチェックし、解析された結果を表示しますが、スキーマに対してバリデーションしません - つまり、キーと値の型が Kubernetes や GitHub Actions のようなツールが期待するものと一致することを確認する別のスキーマバリデーションには、エディターの YAML 言語サーバー、または、などのスキーマ対応の CLI を使用します kubeconform クベルネテスの場合、または kubectl apply --dry-run=client。 構文とスキーマの検証では、異なるバグが発生するため、両方を実行します。



