環境
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…