Anhang: YAML-Techniken
Der Großteil dieser Anleitung hat sich auf das Schreiben der Template-Sprache konzentriert. Hier werden wir uns das YAML-Format ansehen. YAML hat einige nützliche Funktionen, die wir als Template-Autoren nutzen können, um unsere Templates weniger fehleranfällig und leichter lesbar zu machen.
Skalare und Collections
Laut der YAML-Spezifikation gibt es zwei Arten von Collections und viele skalare Typen.
Die zwei Arten von Collections sind Maps und Sequences:
map:
one: 1
two: 2
three: 3
sequence:
- one
- two
- three
Skalare Werte sind einzelne Werte (im Gegensatz zu Collections).
Skalare Typen in YAML
In Helms YAML-Dialekt wird der skalare Datentyp eines Wertes durch einen komplexen Satz von Regeln bestimmt, einschließlich des Kubernetes-Schemas für Ressourcendefinitionen. Bei der Typinferenz gelten jedoch in der Regel die folgenden Regeln.
Wenn eine Ganzzahl oder Fließkommazahl ein nicht in Anführungszeichen gesetztes Wort ist, wird sie typischerweise als numerischer Typ behandelt:
count: 1
size: 2.34
Wenn sie jedoch in Anführungszeichen gesetzt sind, werden sie als Strings behandelt:
count: "1" # <-- string, not int
size: '2.34' # <-- string, not float
Dasselbe gilt für Booleans:
isGood: true # bool
answer: "true" # string
Das Wort für einen leeren Wert ist null (nicht nil).
Beachten Sie, dass port: "80" gültiges YAML ist und sowohl durch die
Template-Engine als auch den YAML-Parser läuft, aber fehlschlägt, wenn
Kubernetes erwartet, dass port eine Ganzzahl ist.
In einigen Fällen können Sie eine bestimmte Typinferenz mit YAML-Node-Tags erzwingen:
coffee: "yes, please"
age: !!str 21
port: !!int "80"
Im obigen Beispiel teilt !!str dem Parser mit, dass age ein String ist, auch
wenn es wie ein Integer aussieht. Und port wird als Integer behandelt, obwohl
es in Anführungszeichen steht.
Strings in YAML
Ein Großteil der Daten, die wir in YAML-Dokumenten platzieren, sind Strings. YAML hat mehr als eine Möglichkeit, einen String darzustellen. Dieser Abschnitt erklärt die verschiedenen Wege und zeigt, wie einige davon verwendet werden.
Es gibt drei "inline" Möglichkeiten, einen String zu deklarieren:
way1: bare words
way2: "double-quoted strings"
way3: 'single-quoted strings'
Alle Inline-Stile müssen in einer Zeile stehen.
- Bare Words (unquotierte Wörter) sind nicht in Anführungszeichen gesetzt und werden nicht escaped. Aus diesem Grund müssen Sie darauf achten, welche Zeichen Sie verwenden.
- Strings in doppelten Anführungszeichen können bestimmte Zeichen mit
\escapen. Zum Beispiel"\"Hello\", she said". Sie können Zeilenumbrüche mit\nescapen. - Strings in einfachen Anführungszeichen sind "literale" Strings und verwenden
nicht
\zum Escapen von Zeichen. Die einzige Escape-Sequenz ist'', die als einzelnes'dekodiert wird.
Zusätzlich zu den einzeiligen Strings können Sie mehrzeilige Strings deklarieren:
coffee: |
Latte
Cappuccino
Espresso
Das obige Beispiel behandelt den Wert von coffee als einen einzelnen String,
der Latte\nCappuccino\nEspresso\n entspricht.
Beachten Sie, dass die erste Zeile nach dem | korrekt eingerückt sein muss.
Wir könnten das obige Beispiel also durch Folgendes ungültig machen:
coffee: |
Latte
Cappuccino
Espresso
Da Latte falsch eingerückt ist, würden wir einen Fehler wie diesen erhalten:
Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key
In Templates ist es manchmal sicherer, eine "erste Zeile" als Platzhalter in einem mehrzeiligen Dokument zu setzen, um den obigen Fehler zu vermeiden:
coffee: |
# Commented first line
Latte
Cappuccino
Espresso
Beachten Sie, dass diese erste Zeile in der Ausgabe des Strings erhalten bleibt. Wenn Sie diese Technik beispielsweise verwenden, um den Inhalt einer Datei in eine ConfigMap einzufügen, sollte der Kommentar dem Typ entsprechen, der von dem erwartet wird, was diesen Eintrag liest.
Kontrolle von Leerzeichen in mehrzeiligen Strings
Im obigen Beispiel haben wir | verwendet, um einen mehrzeiligen String
anzuzeigen. Beachten Sie jedoch, dass dem Inhalt unseres Strings ein
abschließendes \n folgte. Wenn wir möchten, dass der YAML-Prozessor das
abschließende Newline entfernt, können wir ein - nach dem | hinzufügen:
coffee: |-
Latte
Cappuccino
Espresso
Jetzt wird der coffee-Wert sein: Latte\nCappuccino\nEspresso (ohne
abschließendes \n).
In anderen Fällen möchten wir vielleicht, dass alle abschließenden Leerzeichen
erhalten bleiben. Wir können dies mit der |+-Notation tun:
coffee: |+
Latte
Cappuccino
Espresso
another: value
Jetzt wird der Wert von coffee sein: Latte\nCappuccino\nEspresso\n\n\n.
Die Einrückung innerhalb eines Textblocks wird beibehalten und führt auch zur Beibehaltung von Zeilenumbrüchen:
coffee: |-
Latte
12 oz
16 oz
Cappuccino
Espresso
Im obigen Fall wird coffee sein: Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso.
Einrückung und Templates
Beim Schreiben von Templates möchten Sie möglicherweise den Inhalt einer Datei in das Template einfügen. Wie wir in vorherigen Kapiteln gesehen haben, gibt es zwei Möglichkeiten, dies zu tun:
- Verwenden Sie
{{ .Files.Get "FILENAME" }}, um den Inhalt einer Datei im Chart zu erhalten. - Verwenden Sie
{{ include "TEMPLATE" . }}, um ein Template zu rendern und dann dessen Inhalt in das Chart einzufügen.
Beim Einfügen von Dateien in YAML ist es gut, die obigen mehrzeiligen Regeln zu verstehen. Oft ist der einfachste Weg, eine statische Datei einzufügen, folgender:
myfile: |
{{ .Files.Get "myfile.txt" | indent 2 }}
Beachten Sie, wie wir die Einrückung oben durchführen: indent 2 weist die
Template-Engine an, jede Zeile in "myfile.txt" mit zwei Leerzeichen
einzurücken. Beachten Sie, dass wir diese Template-Zeile nicht einrücken. Das
liegt daran, dass andernfalls der Dateiinhalt der ersten Zeile doppelt
eingerückt würde.
Gefaltete mehrzeilige Strings
Manchmal möchten Sie einen String in Ihrem YAML mit mehreren Zeilen darstellen,
aber möchten, dass er bei der Interpretation als eine lange Zeile behandelt
wird. Dies wird "Folding" (Falten) genannt. Um einen gefalteten Block zu
deklarieren, verwenden Sie > anstelle von |:
coffee: >
Latte
Cappuccino
Espresso
Der Wert von coffee oben wird Latte Cappuccino Espresso\n sein. Beachten
Sie, dass alle außer dem letzten Zeilenvorschub in Leerzeichen umgewandelt
werden. Sie können die Leerzeichen-Kontrollen mit dem Folded-Text-Marker
kombinieren, sodass >- alle Newlines ersetzt oder entfernt.
Beachten Sie, dass in der Folded-Syntax das Einrücken von Text dazu führt, dass Zeilen erhalten bleiben.
coffee: >-
Latte
12 oz
16 oz
Cappuccino
Espresso
Das obige Beispiel ergibt Latte\n 12 oz\n 16 oz\nCappuccino Espresso.
Beachten Sie, dass sowohl die Leerzeichen als auch die Zeilenumbrüche noch
vorhanden sind.
Einbetten mehrerer Dokumente in einer Datei
Es ist möglich, mehr als ein YAML-Dokument in einer einzigen Datei zu
platzieren. Dies geschieht, indem ein neues Dokument mit --- eingeleitet und
das Dokument mit ... beendet wird.
---
document: 1
...
---
document: 2
...
In vielen Fällen kann entweder --- oder ... weggelassen werden.
Einige Dateien in Helm können nicht mehr als ein Dokument enthalten. Wenn
beispielsweise mehr als ein Dokument in einer values.yaml-Datei bereitgestellt
wird, wird nur das erste verwendet.
Template-Dateien können jedoch mehr als ein Dokument haben. In diesem Fall wird die Datei (und alle ihre Dokumente) beim Template-Rendering als ein Objekt behandelt. Aber dann wird das resultierende YAML in mehrere Dokumente aufgeteilt, bevor es an Kubernetes übergeben wird.
Wir empfehlen, mehrere Dokumente pro Datei nur dann zu verwenden, wenn es unbedingt notwendig ist. Das Vorhandensein mehrerer Dokumente in einer Datei kann das Debugging erschweren.
YAML ist eine Obermenge von JSON
Da YAML eine Obermenge von JSON ist, sollte jedes gültige JSON-Dokument auch gültiges YAML sein.
{
"coffee": "yes, please",
"coffees": [
"Latte", "Cappuccino", "Espresso"
]
}
Das obige ist eine andere Art, dies darzustellen:
coffee: yes, please
coffees:
- Latte
- Cappuccino
- Espresso
Und die beiden können (mit Vorsicht) gemischt werden:
coffee: "yes, please"
coffees: [ "Latte", "Cappuccino", "Espresso"]
Alle drei sollten zur gleichen internen Darstellung geparst werden.
Obwohl dies bedeutet, dass Dateien wie values.yaml JSON-Daten enthalten
können, behandelt Helm die Dateiendung .json nicht als gültiges Suffix.
YAML-Anker
Die YAML-Spezifikation bietet eine Möglichkeit, eine Referenz auf einen Wert zu speichern und später auf diesen Wert per Referenz zu verweisen. YAML nennt dies "Anchoring":
coffee: "yes, please"
favorite: &favoriteCoffee "Cappuccino"
coffees:
- Latte
- *favoriteCoffee
- Espresso
Im obigen Beispiel setzt &favoriteCoffee eine Referenz auf Cappuccino.
Später wird diese Referenz als *favoriteCoffee verwendet. So wird coffees zu
Latte, Cappuccino, Espresso.
Obwohl es einige Fälle gibt, in denen Anker nützlich sind, gibt es einen Aspekt, der subtile Bugs verursachen kann: Wenn das YAML zum ersten Mal eingelesen wird, wird die Referenz aufgelöst und dann verworfen.
Wenn wir also das obige Beispiel dekodieren und dann wieder kodieren würden, wäre das resultierende YAML:
coffee: yes, please
favorite: Cappuccino
coffees:
- Latte
- Cappuccino
- Espresso
Da Helm und Kubernetes oft YAML-Dateien lesen, modifizieren und dann neu schreiben, gehen die Anker verloren.