環境
Kubernetes 1.15
]# kubectl version Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.3", GitCommit:"2d3c76f9091b6bec110a5e63777c332469e0cba2", GitTreeState:"clean", BuildDate:"2019-08-19T11:13:54Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.3", GitCommit:"2d3c76f9091b6bec110a5e63777c332469e0cba2", GitTreeState:"clean", BuildDate:"2019-08-19T11:05:50Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}
困りごと
こんな yaml を用意して
pod.yaml
apiVersion: v1 kind: Pod metadata: name: sample-pod spec: containers: - name: x image: nginx - name: y image: redis
apply するとエラーになる。
]# kubectl apply -f pod.yaml Error from server (BadRequest): error when creating "pod.yaml": Pod in version "v1" cannot be handled as a Pod: v1.Pod.Spec: v1.PodSpec.Containers: []v1.Container: v1.Container.Name: ReadString: expects " or n, but found t, error found in #10 byte of ...|","name":true}]}} |..., bigger context ...|age":"nginx","name":"x"},{"image":"redis","name":true}]}} |...
なんで?
y(文字列のつもりで書いた) が true(真偽値) になっていた。
kubectl apply -f pod.yaml --v=8
を実行して送信したリクエストを抜き出すと、その様子がわかる。
{ "apiVersion": "v1", "kind": "Pod", "metadata": { "annotations": { "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"sample-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx\",\"name\":\"x\"},{\"image\":\"redis\",\"name\":true}]}}\n" }, "name": "sample-pod", "namespace": "default" }, "spec": { "containers": [ { "image": "nginx", "name": "x" }, { "image": "redis", "name": true <- これ } ] } }
YAML 1.1 の仕様だと Boolean は y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
が許可されている。そのため y(文字列のつもりで書いた) が true(真偽値) に評価された。
参考 Boolean Language-Independent Type for YAML™ Version 1.1
回避策
シングルクオートで囲って明示的に文字列だと示せばよい。
apiVersion: v1 kind: Pod metadata: name: sample-pod spec: containers: - name: 'x' image: nginx - name: 'y' image: redis
]# kubectl apply -f pod.yaml pod/sample-pod created
YAML の Boolean ハマるんですけど
YAML 1.2 の仕様だと Boolean は true/false だけに修正されている。
参考 YAML Ain’t Markup Language (YAML™) Version 1.2
そのため Kubernetes でも YAML 1.2 に準拠してほしいところ。しかし、当分は YAML 1.1 とお付き合いする必要がありそう。(『 kubectl / kubernetes not 100% compatible with YAML 1.2』 という Issue が 2016 年からオープンのままになっている。対応されない理由は、後方互換性がなくなることや、Kubernetes が利用している YAML パーサ(go-yaml) が YAML 1.1 と 1.2 のサポートを謳っているため。go-yaml の v3 からはデフォルトを YAML 1.2 にするらしい。)
最後に go-yaml でのやり取りを紹介して締めの言葉とする。
引用元 Boolean support inconsistent with the YAML 1.2 spec · Issue #214 · go-yaml/yaml · GitHub
Welcome to YAML…