Helm: 嵌套的“ null”值不会按预期删除键

创建于 2019-01-18  ·  36评论  ·  资料来源: helm/helm

https://github.com/helm/helm/pull/2648允许通过在values.yaml文件中设置null值来删除密钥。 但是,它不适用于嵌套值,例如:

web:
  livenessProbe:
    httpGet: null
    exec:
      command:
      - curl
      - -f
      - http://localhost:8080/api/v1/info

不会从原始值中删除web.livenessProbe.httpGet ,而只是用null覆盖该值并显示警告:

2019/01/18 11:30:07 Warning: Merging destination map for chart 'concourse'. Cannot overwrite table item 'httpGet', with non table value: map[path:/api/v1/info port:atc]

具有讽刺意味的是,以上是文档中给出的示例的一个小变体,我敢肯定,它实际上并没有真正实现它声称的功能: https :

我怀疑由于模板呈现似乎在空值和未指定的值之间没有太大区别,因此该警告被忽略并且没有太大作用。

helm version

Client: &version.Version{SemVer:"v2.12.1", GitCommit:"02a47c7249b1fc6d8fd3b94e6b4babf9d818144e", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.12.1", GitCommit:"02a47c7249b1fc6d8fd3b94e6b4babf9d818144e", GitTreeState:"clean"}

kubectl version

Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.1", GitCommit:"eec55b9ba98609a46fee712359c7b5b365bdd920", GitTreeState:"clean", BuildDate:"2018-12-13T10:39:04Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"11+", GitVersion:"v1.11.5-eks-6bad6d", GitCommit:"6bad6d9c768dc0864dab48a11653aa53b5a47043", GitTreeState:"clean", BuildDate:"2018-12-06T23:13:14Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}

云提供商/平台(AKS,GKE,Minikube等):

埃克斯

最有用的评论

我们还遇到了此问题(类似于@vbuciuc所描述的问题),当在3.2.x的requirements.yaml中子图表被列为依赖项时,值覆盖不起作用,因此无法工作为“空”。 以前的版本(3.1.x)可以正常工作。

所有36条评论

@scottrigby ,您是否有幸要成为这个人的

根据原始作者的说法,将其标记为问题/支持,直到确认这确实是个错误为止。

我在2.12.3上也看到了这一点。 我在尝试同时通过-f和--set将值设置为null时看到。 无论哪种方式,它都只是将其设置为字符串的“空”(不带引号),而不是删除默认值。
我的情况:

> helm get values grafana
admin:
  existingSecret: ""
chownDataImage:
  pullPolicy: null
  repository: null
  tag: null
<...>

> helm upgrade grafana stable/grafana --tls --reuse-values --set chownDataImage.pullPolicy=null
<output indicating it works>

> helm get values grafana
admin:
  existingSecret: ""
chownDataImage:
  pullPolicy: null
  repository: null
  tag: null
<...>

用例是将这些值重置为使用模板中的默认值,而不是现在陷入困境的默认值。

稳定/文件拍

使用nullnil我看到的是同一件事...密钥未被删除...它被覆盖为null/nil但未被删除,并且在更换时它具有不同的键会导致问题:

---values.yml in the Chart
output.file:
  path: /var/log/foo.log

``yaml
---我的替代
output.elasticsearch:
主持人:
-'http:// localhost :9200'
output.file:空

or
```yaml
---my overrides
output:
  elasticsearch:
     host:
      - 'http://localhost:9200'
  file: null

或者

---my overrides
output:
  elasticsearch:
     hosts:
      - 'http://localhost:9200'
output.file: null
» k get secret filebeat -o jsonpath="{.data.filebeat\.yml}" | base64 -D
    filebeat.config:
      modules:
        path: ${path.config}/modules.d/*.yml
        reload.enabled: false
      prospectors:
        path: ${path.config}/prospectors.d/*.yml
        reload.enabled: false
    filebeat.prospectors:
    - enabled: true
      fields:
        apenv: dev
        app: kubernetes
        log_category: kubernetes
      fields_under_root: true
      paths:
      - /var/log/*.log
      - /var/log/messages
      - /var/log/syslog
      type: log
    - containers.ids:
      - '*'
      fields:
        apenv: dev
        app: kubernetes
        log_category: kubernetes
      fields_under_root: true
      processors:
      - add_kubernetes_metadata:
          in_cluster: true
      - drop_event:
          when:
            equals:
              kubernetes.container.name: filebeat
      type: docker
    http.enabled: true
    http.port: 5066
    output:
      elasticsearch:
        hosts:
        - http://localhost9200
    output.file: null
    processors:
    - add_cloud_metadata: null

广告连播错误如下:

Exiting: error unpacking config data: more than one namespace configured accessing 'output' (source:'filebeat.yml')

我也遇到了Filebeat图表的确切问题。

@cdenneen您可以使用config.output.file.enabled=false来绕过文件输出。

我遇到一个问题,我想使用新的inputs键进行文件拍,但无法删除prospectors键。

现有值:

config:
  filebeat.prospectors:
    - type: log
      enabled: true
      paths:
        - /var/log/*.log
        - /var/log/messages
        - /var/log/syslog

我的替代: --set config.filebeat.prospectors=null

结果:(使用config来设置Secret值)

filebeat:
  prospectors: null

我还遇到了stable/kibanastable/filebeat的问题,即使指定了!!null ,键也将默认为图表值。

@aeijdenberg认为您的PR仅要求更新标签才能进行审核

@bacongobbler对不起,我在https://github.com/helm/helm/issues/5184#issuecomment -456138448中错过了您的问题。 我可以验证这是一个错误。 在#2648中,我确实应该添加一个与记录的示例相匹配的测试。 我本来想回到这个话题,但#5185看起来很有前途! 👏会在那儿回应

@scottrigby 。 我可以知道哪个版本包含#5185的修复程序吗? 尝试删除istio图表上的资源定义时,我刚遇到此问题。

这应该在2.14.2中-但我无法使它正常工作。

我正在跟踪一个与问题顶部的示例非常相似的示例-我可以看到的唯一区别是,我正在尝试删除子图中的一个值集(在我的情况下为logstash)。

我试过了:

  • 在主图表的values.yaml或命令行中,将logstash.livenessProbe.http设置为null~{} 。 在这两种情况下,“ helm template”显示原始值仍然存在(即,我仍在设置httpGet)-这与我看到的“ helm install”是一致的
  • 将logstash.livenessProbe.httpGet设置为“ nil”-在这种情况下,该值的确会被覆盖,但字符串“ nil”不能在此处使用,因此无效,因此kubernetes拒绝了该模板。

我是否误解了,而这并没有使它成为2.14.2-还是还有问题?

(显示此图: demo.zip

根据发行说明,该补丁已精选到2.14.2中,因此应该可以使用。

在那种情况下,我不确定该错误是否已解决-应该重新打开它还是创建新问题? 其他人可以看看我所附的图表,看看他们是否有所不同?

@ cc-stjm @ bacongobbler-我能够重现该问题,并且我认为此测试证明了这一点:

func TestSubchartCoaleseWithNullValue(t *testing.T) {
    v, err := CoalesceValues(&chart.Chart{
        Metadata: &chart.Metadata{Name: "demo"},
        Dependencies: []*chart.Chart{
            {
                Metadata: &chart.Metadata{Name: "logstash"},
                Values: &chart.Config{
                    Raw: `livenessProbe: {httpGet: {path: "/", port: monitor}}`,
                },
            },
        },
        Values: &chart.Config{
            Raw: `logstash: {livenessProbe: {httpGet: null, exec: "/bin/true"}}`,
        },
    }, &chart.Config{})
    if err != nil {
        t.Errorf("Failed with %s", err)
    }
    result := v.AsMap()
    expected := map[string]interface{}{
        "logstash": map[string]interface{}{
            "global": map[string]interface{}{},
            "livenessProbe": map[string]interface{}{
                "exec": "/bin/true",
            },
        },
    }
    if !reflect.DeepEqual(result, expected) {
        t.Errorf("got %+v, expected %+v", result, expected)
    }
}

就我所知,问题是CoalesceValues()导致对合并值的基础函数的多个调用:
https://github.com/helm/helm/blob/e04fa72f6f211cae68c362f9b7c62f06dc51493e/pkg/chartutil/values.go#L164 -L180

例如,上面的第173行在httpGet设置为null被调用,但是它返回的值已从映射中删除了该键(按预期方式)。 但是随后,该输出将第二次作为输入传递给第二组合并(第179行),然后由于键不再存在,因此默认为图表中的值。

不幸的是,我不太可能在不久的将来有时间去做进一步的工作-我已经更换了角色,并且目前没有使用Helm,而且解决方法的答案对我来说并不明显。 希望以上内容对解决问题有所帮助。

实际上,我刚刚升级了2.14.0 => 2.14.2。 null ed键不仅仍然存在,而且还包含以前的值。 以前的行为只是将其设为null,因此我认为这实际上已经退步了。

@aeijdenberg您可以调查@sgillespie的询问吗? 如果存在回归,那么除非确定修复方法,否则将PR撤回可能更安全。 如果您无法提供帮助,则还原提交并返回第1方块可能更安全。让我知道您想如何进行。

@bacongobbler ,虽然我尚未明确测试2.14.0,但@sgillespie与我在https://github.com/helm/helm/issues/5184#issuecomment-517059748中提到的行为相匹配。 可悲的是,我认为这是单元测试通过的情况,但是端到端失败-因为单个组件被串联使用,这使得在较早的阶段删除密钥使其在以后的阶段没有效果(这就是为什么原始值将通过)。

我同意这是一种回归,尽管支持它对于依赖新行为的任何人也是一种回归。

我快速浏览了一个相对较小的补丁,我认为它将减少#6146中的影响(并修复我在上面添加的测试)-很抱歉,我们在最后一次尝试中遇到了这个错误。

这可能已在https://github.com/helm/helm/pull/6080中修复

如果是这样,是否可以关闭#6146,还是尝试解决其他问题? 我试图在这里围绕问题空间把握住自己的头,但是目前尚不清楚这些PR正在尝试解决什么问题。 对不起。

确实确实可以解决此问题。 快速的天真测试:

子图表值:

prop:
  nested:
    val: true

父图表值:

sub:
  prop:
    nested: null

预期的输出为{}

你好,

我正在使用头盔2.15.0 ,但我仍然遇到了这个问题。

给定一个带有值的子图表:

securityContext:
  runAsUser: 65534
  fsGroup: 65534

这些值与toYaml

并在父图表中的值:

sub:
  securityContext:
  runAsUser: null

那么实际输出为:

securityContext:
  runAsUser: 65534
  fsGroup: 65534

虽然应该是:

securityContext:
  fsGroup: 65534

不想在您的游行中下雨,但我仍然在头盔v3.0.1中看到了这一点

version.BuildInfo {版本:“ v3.0.1”,GitCommit:“ 7c22ef9ce89e0ebeb7125ba2ebf7d421f3e82ffa”,GitTreeState:“干净”,GoVersion:“ go1.13.4”}

尝试安装稳定/点火时,我必须取消设置一个值,但是掌舵似乎只是将值设置为null / nil,从而导致k8s在验证步骤中不起作用。

要重现,请将其另存为bug5184-ignite.yaml (以覆盖图表默认值:https://github.com/helm/charts/blob/master/stable/ignite/values.yaml):

persistence:
  enabled: true   # <-- without this, the keys in question are ignored
  persistenceVolume:
    provisionerParameters:
      type: null  # <-- I want to unset this key
  walVolume:
    provisionerParameters:
      type: null  # <-- I want to unset this key

然后将其用作值文件进行点火安装:

helm install runtimedb stable/ignite --version 1.0.1 --values bug5184-ignite.yaml --debug --dry-run | less

我得到的结果是此错误消息,表明我要取消设置的值已设置为nil

install.go:148: [debug] Original chart version: ""
install.go:165: [debug] CHART PATH: /home/creinig/.cache/helm/repository/ignite-1.0.1.tgz

Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: unknown object type "nil" in StorageClass.parameters.type
helm.go:76: [debug] error validating "": error validating data: unknown object type "nil" in StorageClass.parameters.type
helm.sh/helm/v3/pkg/kube.scrubValidationError
        /home/circleci/helm.sh/helm/pkg/kube/client.go:520
helm.sh/helm/v3/pkg/kube.(*Client).Build
        /home/circleci/helm.sh/helm/pkg/kube/client.go:135
helm.sh/helm/v3/pkg/action.(*Install).Run
        /home/circleci/helm.sh/helm/pkg/action/install.go:229
[...]

我也尝试过的是:

  • 将值设置为其他值/根本不覆盖它

    • => PersistentVolumeClaim卡在“待处理”中,因为提供程序不支持额外的“类型”选项

    • =>绝对是导致问题的价值

  • 通过--set将值设置为null --set

    • 与在文件中设置时的行为相同

当仅通过命令行将单个值设置为null时,同时保持点燃持久性处于禁用状态(这样就不会生成storageclass模板,并且所讨论的参数将被忽略)...

helm install myignite stable/ignite --version 1.0.1 --set persistence.persistenceVolume.provisionerParameters.type=null --debug --dry-run | less

...有适当的调试输出而不是错误,但是它表明该值仅设置为null (我添加的评论):

NAME: myignite
LAST DEPLOYED: Tue Dec 10 09:43:40 2019
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
persistence:
  persistenceVolume:
    provisionerParameters:
      type: null   # <-- Set via the command line

COMPUTED VALUES:
affinity: {}
dataStorage:
  config: ""
env:
  IGNITE_QUIET: "false"
  JVM_OPTS: -Djava.net.preferIPv4Stack=true
  OPTION_LIBS: ignite-kubernetes,ignite-rest-http
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: apacheignite/ignite
  tag: 2.7.6
nameOverride: ""
nodeSelector: {}
peerClassLoadingEnabled: false
persistence:
  enabled: false
  persistenceVolume:
    provisioner: kubernetes.io/aws-ebs
    provisionerParameters:
      fsType: ext4
      type: null  # <-- Set to null instead of removed
    size: 8Gi
  walVolume:
    provisioner: kubernetes.io/aws-ebs
    provisionerParameters:
      fsType: ext4
      type: gp2  # <-- This is what the default looks like
    size: 8Gi
rbac:
  create: true
replicaCount: 2
resources: {}
serviceAccount:
  create: true
  name: null
tolerations: []

我已经使用3.0.1遇到了完全相同的问题,重新打开此问题可能会很好?

从头盔v2.16.1移至v3.0.2之后。 我遇到了无法设置注释和cpu限制的问题。

我只是在2.14.13.0.2遇到了这个问题。 这事有进一步更新吗?

如果我知道舵图只是在使用,如果测试则为true / false,我将使用非表值(如0)覆盖该值。我收到很多警告,如Overwriting table item 'x', with non table value: 0 ,但至少我得到了在我不希望包含节的情况下的解决方法。 我的首选是使null起作用,但这是一个丑陋的解决方法。

我已将值设置为null(并在我的值文件中将其保留为null),并且忽略了很长的表警告列表,目前这还可以,但是我真的想一次性清除存储在其中的旧的不正确的值kubernetes。 在修复此值删除错误之前,是否有手动方法可以在不停机的情况下编辑现有部署中的值?

使用livenessreadiness探针遇到相同的问题。
从模板指南中删除默认密钥无效。

请尝试#7743。 似乎对Helm 2所做的提交未移植到Helm 3中,这就是为什么许多用户在那里看到这种行为的原因。

仍然在头盔2.16.3上仍然看到此问题,但仅在有requirements.yaml将该子图作为依赖项列出时才出现。

boo是子图表,而foo是父图表:

vibu@item-ax35755:~/work$ cat boo/values.yaml 
object:
  fromSubchart:
    hello: from boo
vibu@item-ax35755:~/work$ cat foo/values.yaml 
boo:
  object:
    fromParent:
      hello: from foo
    fromSubchart: null
vibu@item-ax35755:~/work$ cat boo/templates/test.yaml 
{{ toYaml .Values.object }}
vibu@item-ax35755:~/work$ cat foo/requirements.yaml 
dependencies:
- name: boo
  repository: file://../boo
  version: 0.1.0
vibu@item-ax35755:~/work/foo$ helm version -c
Client: &version.Version{SemVer:"v2.16.3", GitCommit:"1ee0254c86d4ed6887327dabed7aa7da29d7eb0d", GitTreeState:"clean"}
vibu@item-ax35755:~/work/foo$ helm dep up
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "incubator" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.
Saving 1 charts
Deleting outdated charts

vibu@item-ax35755:~/work/foo$ helm template .
---
# Source: foo/charts/boo/templates/test.yaml
fromParent:
  hello: from foo
fromSubchart:
  hello: from boo


vibu@item-ax35755:~/work/foo$ mv requirements.yaml{,.bak}
vibu@item-ax35755:~/work/foo$ helm template .
---
# Source: foo/charts/boo/templates/test.yaml
fromParent:
  hello: from foo

此处的两个图表:

helm_5184.zip

@bacongobbler是否打算在2.x中进一步解决此问题?

我们还遇到了此问题(类似于@vbuciuc所描述的问题),当在3.2.x的requirements.yaml中子图表被列为依赖项时,值覆盖不起作用,因此无法工作为“空”。 以前的版本(3.1.x)可以正常工作。

@bacongobbler @technosophos我也遇到了Helm 3.3.4这个问题,请您重新打开;

我可以确认它可以在3.1.2工作,并且在3.2.x之后停止工作,如@paleg所述。 目前,看来@ tuzla0autopilot4将其设置为非地图值(如false将产生预期的行为,但在完成时会给出输出警告。

@ Chili-Man,我刚刚尝试了3.1.3 ,它似乎不起作用。 它将与null但是我得到警告,但它什么也没做。 与其他任何东西( false0[] )一起拒绝(例如)

```coalesce.go:196:警告:无法用非表覆盖资源表(map [requests:map [cpu:250m memory:256Mi]])
错误:升级失败:值不符合下表中的架构规范:
PostgreSQL的:

  • 资源:无效的类型。 预期:对象,给定:布尔值
    `` (or what the type that I try that is not a dict/hash). With 3.3.4 I get just silence and it does nothing with null`,同样,其他所有内容均不适用。 最烦人的...

我仍然在3.4.2中遇到此问题。

该问题在3.4.2中仍然存在,但仅在某些情况下才存在。
我有一个带有多个子图的图表。
将默认值放入子图表值时, null覆盖无效。 如果将相同的值移动到父图表值中,它将按预期工作。
这仅在子图中可以重现。 当您将其放在单个(平面)图表中时,一切正常。

使用子图表时,我在3.4.2中遇到相同的问题(如上述@BohdanKalytka所述)。
就我而言,我想在OpenShift集群中使用ElasticSearch掌舵图时覆盖securityContext。
是要重新打开此问题,还是我们应该创建一个新的问题?

引发#9136

此页面是否有帮助?
0 / 5 - 0 等级