1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HelmでConfigMap生成に失敗する罠:値が「文字列」ではなく「構造」として解釈されてしまう

1
Last updated at Posted at 2026-03-08

Rook CephのHelmチャートで、PodのnodeAffinityに関するvalueを指定したところ、マニフェストのレンダリングに失敗してしまいました。原因は、 rook-ceph-operator-config のテンプレートの書き方にありました。

本記事では、問題が発生した箇所のみをピックアップしたHelmチャートを作り、どのようにして解決したかを記載します。Rook Ceph以外のHelmチャートでも発生し得る問題なので、ご参考になれば幸いです。

発生した問題の再現

以下は、Rook CephのHelmチャートで問題が起きた箇所のみをピックアップしたものの構成です。

.
├── Chart.yaml
├── templates
│   └── configmap.yaml
└── values.yaml

ConfigMapは以下のような内容になっています。

configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: rook-ceph-operator-config-snippet
  namespace: {{ .Release.Namespace }}
data:
  CSI_RBD_PLUGIN_RESOURCE: {{ .Values.csi.csiRBDPluginResource | quote }}
  CSI_RBD_PLUGIN_NODE_AFFINITY: {{ .Values.csi.rbdPluginNodeAffinity }}

CSI_RBD_PLUGIN_RESOURCE には、あるPodのリソースに関する情報(CPU, memoryのrequest/limit)が格納され、Helmの csi.csiRBDPluginResource を介して値が渡されます。
また CSI_RBD_PLUGIN_NODE_AFFINITY は、同じPodのnodeAffinityに関する情報が入り、 csi.rbdPluginNodeAffinity のvalueが渡されます。

両方とも、YAMLやJSON等で表される構造を持ったデータを値として渡す必要があり、values.yamlには次のように書きました。

values.yaml
csi:
  csiRBDPluginResource: |
    - name : csi-provisioner
      resource:
        requests:
          memory: 100Mi
          cpu: 100m
  rbdPluginNodeAffinity: |
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - antarctica-east1
          - antarctica-west1

Helmチャートをインストール可能かどうかlintコマンドで確認すると、エラーになってしまいます。

$ helm lint .
==> Linting .
[INFO] Chart.yaml: icon is recommended
[ERROR] templates/configmap.yaml: unable to parse YAML: error converting YAML to JSON: yaml: line 8: mapping values are not allowed in this context

Error: 1 chart(s) linted, 1 chart(s) failed

ConfigMapの CSI_RBD_PLUGIN_NODE_AFFINITY に、許容されていない mapping values を格納しようとしていることが原因のようです。

一方 CSI_RBD_PLUGIN_RESOURCE はエラーが出ていません。現時点では確認できませんが、仮にlintに成功したとしてその値を確認すると、次のような値がレンダリングされています。

  CSI_RBD_PLUGIN_RESOURCE: "- name : csi-provisioner\n  resource:\n    requests:\n      memory: 100Mi\n      cpu: 100m\n"

valueの値を変えてレンダリング結果を確認

このような違いがでるのはなぜなのでしょうか?
原因を探るため、両方のvalueに1行のシンプルな文字列を入れてみます。

values-simple.yaml
csi:
  csiRBDPluginResource: "hogehoge"
  rbdPluginNodeAffinity: "fugafuga"

lintが通るようになりました。

$ helm lint . -f values-simple.yaml
==> Linting .
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

helm templateも通りますが、一方だけダブルクォートされていますね。

$ helm template . -f values-simple.yaml
---
# Source: helm-chart-value-one-liner-test/templates/configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: rook-ceph-operator-config-snippet
  namespace: default
data:
  CSI_RBD_PLUGIN_RESOURCE: "hogehoge"
  CSI_RBD_PLUGIN_NODE_AFFINITY: fugafuga

values.yamlを使った場合のエラーの原因

Helmのテンプレートを見ると、以下のように CSI_RBD_PLUGIN_RESOURCE だけ | quote が追加されており、これがレンダリング結果の違いを生んでいるようです。

  CSI_RBD_PLUGIN_RESOURCE: {{ .Values.csi.csiRBDPluginResource | quote }}
  CSI_RBD_PLUGIN_NODE_AFFINITY: {{ .Values.csi.rbdPluginNodeAffinity }}

最初のhelm lintのエラーでもわかるように、values.yaml に記載した値をHelmチャートでそのまま参照すると、文字列ではなくて「mapping(YAMLの構造)」と解釈されてしまいます。2つ目の変数 CSI_RBD_PLUGIN_NODE_AFFINITY がそのケースです。

一方、CSI_RBD_PLUGIN_RESOURCE ではテンプレートの最後に | quote をつけることで、mapping 全体がダブルクォートされて文字列(string)に変換されています。helm templateが成功すると、以下のようにダブルクォートして出力されます。

  CSI_RBD_PLUGIN_RESOURCE: "- name : csi-provisioner\n  resource:\n    requests:\n      memory: 100Mi\n      cpu: 100m\n"

ということは、 CSI_RBD_PLUGIN_NODE_AFFINITY にも | quote をつければ解決するのですが、外部Helmチャートを修正するにはそれなりのエネルギーが必要です。

Helmチャートのテンプレートは変えずに、valueの指定方法を工夫して解決できないでしょうか?

この問題はRook Cephのv1.18.3 で解決されており、このバージョンにアップデートすれば、元の values.yaml の指定方法でも問題なく動作します。

解決策

次のように書くと解決します。

values-solved.yaml
csi:
  csiRBDPluginResource: |
    - name : csi-provisioner
      resource:
        requests:
          memory: 100Mi
          cpu: 100m
  rbdPluginNodeAffinity: |
    |-
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: topology.kubernetes.io/zone
              operator: In
              values:
              - antarctica-east1
              - antarctica-west1

ポイントは、 rbdPluginNodeAffinity 配下の元の記述の間に |- の行を追記して、元の記述の各行に適切にスペースを開けることです。

このようにすると、lintが通ります。

$ helm lint . -f values-solved.yaml
==> Linting .
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

helm templateすると、次のように出力されます。

$ helm template . -f values-solved.yaml
---
# Source: helm-chart-value-one-liner-test/templates/configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: rook-ceph-operator-config-snippet
  namespace: default
data:
  CSI_RBD_PLUGIN_RESOURCE: "- name : csi-provisioner\n  resource:\n    requests:\n      memory: 100Mi\n      cpu: 100m\n"
  CSI_RBD_PLUGIN_NODE_AFFINITY: |-
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - antarctica-east1
          - antarctica-west1

CSI_RBD_PLUGIN_NODE_AFFINITY: の後に、 |- がついているのが鍵です。記号の説明は割愛しますが(こちらの記事がわかりやすいです!)、Helmチャートからマニフェストをレンダリングした後に requiredDuring... 以降の記述がYAMLの構造ではなくて、文字列として解釈されるようになりました。ConfigMapの各キーに対応する値の型は string の必要があり、その要件を満たしているのでエラーが発生しなくなりました。

尚、quote が入っている CSI_RBD_PLUGIN_RESOURCE: の値は、 "- name : csi-provisioner\n resource:\n requests:\n memory: 100Mi\n cpu: 100m\n" のように一行で記述されていますが、HelmチャートをインストールしてConfigMapの中身を確認すると、次のように改行で表示されているのを確認できました。

helm install cm-test . -f values-solved.yaml -n default
$ kubectl get cm rook-ceph-operator-config-snippet -oyaml
apiVersion: v1
kind: ConfigMap
data:
  CSI_RBD_PLUGIN_RESOURCE: |
    - name : csi-provisioner
      resource:
        requests:
          memory: 100Mi
          cpu: 100m
  CSI_RBD_PLUGIN_NODE_AFFINITY: |
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - antarctica-east1
          - antarctica-west1

上と同じことをRook CephのHelmチャートでも実施すれば、nodeAffinityの設定が効いてやりたいことをできるはずです。

おわりに

Helmチャートを扱う場合はHelmだけでなく、YAMLの知識が必要なことを痛感させられました。。。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?