Helm: --set analisa os valores numéricos apenas como float64

Criado em 17 dez. 2016  ·  68Comentários  ·  Fonte: helm/helm

Acabei de notar que algo como helm install --set tag=20161216 termina em notação científica no modelo e isso porque {{ typeOf .Value.tag }} produz float64 .

Isso é verdade até para pequenos inteiros como helm install --set tag=1 -> float64 .

Isso está acontecendo com o helm 2.1.0

help wanted

Comentários muito úteis

Compatibilidade com versões anteriores? De um recurso que é simplesmente 'WTF' e provavelmente muitos não o querem ou usam? Em uma ferramenta que está sob intenso desenvolvimento e não foi realmente adotada de forma ampla? Eu sugiro repensar isso e consertar antes que seja muito tarde.

Todos 68 comentários

Funciona de forma diferente se você fizer --set tag=\"1\" ?

Graças a @chancez , conhecemos o problema exato: durante as conversões de e para JSON feitas por ghodss/yaml , inteiros estão sendo convertidos em float64s para representar o tipo numérico do Javascript. Isso está fazendo com que todos os inteiros acima de um determinado valor sejam representados em notação científica.

Eu fui mordido pelo mesmo problema. A maneira de superar o obstáculo (ou o bug) é fazer o seguinte:

--set bignumber=\\"a185576882739235744\\"

Outra solução alternativa que usamos é fazer coisas como esta:

--set port=":1234567"

Em seguida, no modelo:

{{ .Values.port | replace ":" "" }}

Que nojo! 😷

Isso é um inferno, e a solução alternativa de @ipedrazas não parece funcionar para mim, ou qualquer outra combinação de citar / escapar que eu tentei.

Ainda não estou disposto a engolir meu orgulho e tentar o hack feio de @technosophos ...

Por enquanto, estou alterando isso expandindo meu script de implantação para gravar os dados como yaml em um arquivo temporário e usar isso como um argumento -f .

De vez em quando, enfrento o mesmo problema com a tag de imagem.
Vou tentar usar uma dessas soluções alternativas. Espero que seja corrigido em breve :)

No meu caso, vendo isso abaixo em --set image.tag=5997578 :

$ kubetctl describe po msj-treasure-map-msj-treasure-map-192172122-dnb80
...
Events:
  Type     Reason         Age               From                                    Message
  ----     ------         ----              ----                                    -------
  Normal   Scheduled      1m                default-scheduler                       Successfully assigned msj-treasure-map-msj-treasure-map-192172122-dnb80 to ip-10-253-13-113.ec2.internal
  Warning  InspectFailed  15s (x9 over 1m)  kubelet, ip-10-253-13-113.ec2.internal  Failed to apply default image tag "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06": couldn't parse image reference "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06": invalid reference format
  Warning  InspectFailed  15s (x9 over 1m)  kubelet, ip-10-253-13-113.ec2.internal  Failed to apply default image tag "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06": couldn't parse image reference "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06": invalid reference format
  Warning  FailedSync     15s (x9 over 1m)  kubelet, ip-10-253-13-113.ec2.internal  Error syncing pod, skipping: [failed to "StartContainer" for "msj-treasure-map-uwsgi" with InvalidImageName: "Failed to apply default image tag \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06\": couldn't parse image reference \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06\": invalid reference format"
, failed to "StartContainer" for "msj-treasure-map-nginx" with InvalidImageName: "Failed to apply default image tag \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06\": couldn't parse image reference \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06\": invalid reference format"
$ helm version                                                                                                                                                                             
Client: &version.Version{SemVer:"v2.5.1", GitCommit:"7cf31e8d9a026287041bae077b09165be247ae66", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.5.1", GitCommit:"7cf31e8d9a026287041bae077b09165be247ae66", GitTreeState:"clean"}

Também estou tendo o mesmo problema no leme 2.6.2.

Client: &version.Version{SemVer:"v2.6.2", GitCommit:"be3ae4ea91b2960be98c07e8f73754e67e87963c", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.6.2", GitCommit:"be3ae4ea91b2960be98c07e8f73754e67e87963c", GitTreeState:"clean"}
  • 1

A redução de YAML para JSON remove muitas informações, a maioria relacionada ao tipo. Significa que você não pode digitar os valores de verificação pré-implantação.

Acho que isso pode ser resolvido mudando para uma biblioteca yaml diferente. Talvez este aqui: https://github.com/go-yaml

Enquanto lutava com esse problema hoje, descobri que o filtro toString pode ajudar com isso:

dockerPort: {{ .Values.dockerPort | toString }}

Então consegui passar a porta na linha de comando ( --set dockerPort=2376 ) e interpretá-la corretamente.

Acabamos de ver isso no 2.7.2 e a maioria das soluções alternativas não funcionam para nós, exceto escrever todas as --set opções para um arquivo local e passar isso por meio de helm -f locals.yml .

Eu também vi isso em 2.7.2 (e arquivado # 3246 como resultado), portanto, +1 sobre este problema. Como em https://github.com/kubernetes/helm/issues/3001 , eu também estava usando o git SHAs para minhas tags de imagem do docker. Minha solução por enquanto, FWIW, é sufocar tags de imagem com -gitsha

1 para mim também.

$ helm version                                                                                                                                    ⏎
Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}

$ git rev-parse --short HEAD
6180689

$ helm upgrade foobar \
    -i charts/foobar \
    --set image.tag=$(git rev-parse --short HEAD) \
    --reuse-values

Após a implantação, recebo o seguinte:

Failed to apply default image tag "gcr.io/foobar/foobar:6.180689e+06": couldn't parse image reference "gcr.io/foobar/foobar:6.180689e+06": invalid reference format
Error syncing pod

Eu também ganho InvalidImageName ao executar kubectl get pods .

Anexar | toString não parece fazer diferença para mim.

você pode apenas fazer:

{{ .Values.tag | int64 }}

@laverite em gráficos absolutamente, mas isso está usando o analisador --set. Este problema existe apenas para o analisador --set. os valores passados ​​por meio de values.yaml são analisados ​​corretamente. :)

Parece que isso está relacionado a # 3155

sim, acredito que sim @jesselang

O mesmo problema aqui com o helm 2.8.0.

@bacongobbler ou @technosophos Eu tenho uma correção para este problema no # 3599, já existe uma aprovação, só preciso de outra. Obrigado!

resolvido via # 3599

obrigado pelo ping @ arturo-c :)

Também vendo esse bug com o Helm 2.9.1

Eu me pergunto por que helm lint não pega isso? Veja # 4099

Estou curioso para saber por que isso foi resolvido adicionando --set-string , em vez de corrigir o que me parece ser um bug óbvio em --set .

É provável que alguém pretenda que os números sejam coagidos à notação científica em seus arquivos yaml?

duas palavras: Compatibilidade com versões anteriores :)

Podemos alterar a forma como o analisador --set coage os valores inteiros no Helm 3, mas, de modo geral, optamos por evitar a alteração do comportamento esperado da funcionalidade principal como --set pois há tantos usuários executando o Helm em produção. Também não podemos forçar todos os valores em --set para strings, pois isso quebrará o comportamento existente, como o comportamento esperado em torno de valores nulos e verdadeiros em arquivos de valores, então --set-string foi aceito como viável solução por enquanto.

Compatibilidade com versões anteriores? De um recurso que é simplesmente 'WTF' e provavelmente muitos não o querem ou usam? Em uma ferramenta que está sob intenso desenvolvimento e não foi realmente adotada de forma ampla? Eu sugiro repensar isso e consertar antes que seja muito tarde.

@technosophos thanks.
Exemplo:

kind: Secret
data:
  some_db_port: {{ .Values.dbInfo.db_port | replace ":" "" | b64enc }}

é trabalho para mim.

@OndraZizka, obrigado pelo feedback (muito apaixonado). Definitivamente, estamos tentando resolver alguns desses problemas comportamentais instáveis ​​que o analisador --set tem para o Helm 3, provavelmente substituindo-o por algo semelhante ao novo analisador --set-string .

Eu concordo plenamente que o comportamento de --set é muito estranho neste caso (e até mesmo totalmente errado), mas não podemos esperar substituir uma biblioteca de análise inteira por outra e ter certeza de que não haverá outra coerção bugs no novo sistema. A troca de bibliotecas de coerção seria considerada uma alteração incompatível com versões anteriores.

Por enquanto, --set-string é um ótimo recurso e eu o recomendo para qualquer pessoa que esteja enfrentando esse bug que use --set-string tanto quanto possível quando você não depende da coerção de tipo. Dessa forma, os valores são forçados a serem coagidos como uma string, e não como um float.

Infelizmente, quando o Ansible formata um dict para yaml (que é meu values.yaml), ele não adiciona aspas, o que é um grande problema para mim. Não acredito que preciso usar este maldito hack: replace ":" ""

se você precisar de uma solução que funcione sem prefixar a tag com : e removê-la mais tarde, você pode usar este (tl; dr: quando a tag for um número, use printf para imprimi-lo, caso contrário, imprima o corda que você tem)

{{- $tag :=  .Values.image.tag }}
{{- $type := printf "%T" $tag }}
image: "{{ .Values.image.repository }}:{{if eq $type "float64"}}{{ printf "%.0f" $tag }}{{ else }}{{ $tag }}{{ end }}"

O bug também acontece com helm ... -f myval.yaml

Para sua informação, isso foi corrigido em https://github.com/helm/helm/pull/6010.

@bacongobbler ainda está acontecendo comigo com o helm versão v2.14.3

Você pode abrir um novo problema? Obrigado.

reabrindo devido à necessidade de reverter # 6010 em # 6749.

Qualquer hora prevista de chegada quando a correção estaria disponível?

consulte # 6888.

@sagarkal para ter certeza de que estamos na mesma página: a correção mencionada visa apenas alcançar o Helm v3, não v2 (estou declarando isso como um contribuidor aleatório, a decisão real sempre é da equipe). A mudança é relativamente grande e não deve ser considerada 100% segura para ser mesclada no branch 2.x, que agora é somente patch. Nesse ínterim, se você tiver uma chance, seria ótimo se você pudesse testar o ramo de RP em relação ao seu caso de uso e nos informar se as coisas funcionam conforme o esperado. Isso ajudaria bastante!

Usar --set-string image.tag=6599236 funcionou para mim com um modelo simples como este

  ...
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          env:
  ...

Correndo para isso com um grande valor inteiro especificado no arquivo de valores do gráfico. Ele é implicitamente convertido em um float com notação científica. Apenas lançar o valor para int consertou isso e parece muito mais limpo do que algumas das outras soluções alternativas que vi:

# values.yaml

tomcat:
  maxPostSize: 2097152
# Cast to int when used

{{ .Values.tomcat.maxPostSize | int }}

Isso foi testado com Helm v3.1.1.

É bom saber! Essa é definitivamente uma solução fácil em comparação com muitas das que já vi. Obrigado!

@Rathgore Casting para um int é perfeito ao lidar com ints o tempo todo, mas no meu caso o valor de entrada precisa ser tratado como uma string, mas vem na forma de dígitos (às vezes). Por exemplo, o hash github commit de 7 comprimento reduzido, às vezes é uma string e às vezes é apenas uma string de dígitos. Neste caso, passar o valor com a opção --set-string funciona sempre.

@ m0rganic Eu não testei isso, mas você pode tentar usar toString vez de int ou definir explicitamente o tipo usando !!str . Isso não é necessário se você estiver usando apenas --set-string mas também precisamos desse comportamento para os valores definidos no gráfico.

@ m0rganic Eu não testei isso, mas você pode tentar usar toString vez de int ou definir explicitamente o tipo usando !!str . Isso não é necessário se você estiver usando apenas --set-string mas também precisamos desse comportamento para os valores definidos no gráfico.

toString não funciona e, em alguns casos, não posso usar !!str .

Existe um plano para corrigir esse comportamento? Este problema está aberto há um bom tempo ...

Veja # 6888. Caso contrário, não. Documentamos muitos padrões para usar. Mas não encontramos uma solução que resolva mais problemas do que causa. Sinta-se à vontade para tentar sua sorte em um PR.

Obrigado pela resposta rápida! Não tenho certeza de que alguma das soluções alternativas propostas resolva meu caso de uso, mas tentarei novamente.

Funciona de forma diferente se você fizer --set tag=\"1\" ?

no meu caso eu usei "" nos valores int, float e bool e funcionou, obrigado

Com base neste comentário , pode parecer que este não é mais um problema para o Helm 3, apenas para o Helm 2. Eu adoraria saber quem ainda está enfrentando esse problema, como e com quais versões do Helm.

Para usuários do Helm 2, estamos aceitando apenas patches de segurança neste momento, portanto, não procuraremos corrigir esse bug para o Helm 2. No entanto, se isso ainda for relevante para o Helm 3, gostaria de receber mais informações da comunidade no este bug em particular.

para o leme 2, você pode lançar para o que quiser entre () como no exemplo abaixo

{{- range $i := until (int .Values.deployment.numberofracks) }}
  - name: rack{{$i}}
{{- end}}

Vou assumir que isso foi corrigido para o Helm 3, pois já se passaram 3 semanas desde a última vez que postei que isso parece ter sido corrigido. Se ainda houver outras pessoas enfrentando esse problema com o Helm 3, sinta-se à vontade para discutir isso e podemos reabrir o problema. Obrigado!

Isso ainda é um problema; Estou em 3.3.0 e ainda estou tendo isso.

Você pode fazer uma demonstração?

Feliz, mas não tenho certeza de como fazer isso; Eu tenho um gráfico que tem em seu values.yaml um campo parecido com este:

customEnv:
  SOME_ENV_VAR: 10000000

e então em templates/deployment.yaml , eu tenho este:

    ...
    containers:
      - name: someContainer
        env:
           {{- range $key, $value := .Values.customEnv }}
            - name: {{ $key | quote }}
              value: {{ $value | quote }}
          {{- end }}
    ...

Quando executo helm template , obtenho este valor na saída renderizada:

    ...
    containers:
      - name: someContainer
        env:
            - name: "SOME_ENV"
              value: "1e+07"
   ...

e então meu aplicativo implantado falha ao tentar analisar o valor de SOME_ENV como um número.

OK. Consegui reproduzir o mesmo problema seguindo suas instruções com o Helm 3.3.1. Obrigada. Reabrindo.

Estou atingindo o mesmo problema por um ângulo ligeiramente diferente. Meu appVersion é 8482e77 , se eu fizer referência a appVersion qualquer lugar, ele será renderizado como +Inf . É divertido depurar, BTW.

Editar:
alterar appVersion de appVersion: 8482e77 para appVersion: "8482e77" corrigiu meu problema

Isso era de se esperar. Sem aspas, YAML analisa esse valor como notação científica (como 8482e77 significa “8482 * 10 ^ 77”). Se você quiser que um valor seja tratado como uma string, coloque-o entre aspas.

Eu tive esse problema com a tag de imagem contianer. O problema foi resolvido ao criar o auxiliar abaixo:

+{{/* Generate Image Name */}}
+{{- define "helpers.image" }}
+{{- $tag := printf "%f" .Values.app.image.tag -}} 
+{{- if regexMatch "^[0-9]+\\.[0-9]+$" $tag }}
+{{ .Values.image.repository }}:{{ .Values.image.tag | int }}
+{{- else }}
+{{ .Values.image.repository }}:{{ .Values.image.tag }}
+{{- end }}
+{{- end }}

E então, no manifesto de implantação:

   containers:
       - name: {{ template "helpers.fullname" . }}
         image: {{ template "helpers.image" . }}

este problema foi corrigido? se não, eu gostaria de consertar isso.

Não. Veja acima . Por favor, certifique-se de ler o tópico e testar você mesmo. :)

Este problema foi marcado como obsoleto porque esteve aberto por 90 dias sem atividades. Este tópico será encerrado automaticamente em 30 dias se nenhuma atividade ocorrer.

colisão, ainda é um problema

Estou usando esta solução alternativa quando encontro este problema em IDs de commit talvez numéricos:

{{- define "numericSafe" -}}
{{- if . | toString | contains "e+" -}}
{{ . | toString | replace "." "" | regexFind "^\\d+" }}
{{- else -}}
{{ . }}
{{- end -}}
{{- end -}}

então use com

{{ include "numericSafe" .Values.git.commitID }}

Isso resolve os problemas se sua string original nunca contiver ponto e e+ , embora eu não saiba se é uma string de número muito longa, nada será omitido.

@urakagi infelizmente, isso não funciona se o seu valor for: 1800000

Existe uma solução planejada para este problema?

Alguma atualização?

@bacongobbler a reprodução de @edobry é, na verdade, um problema diferente. Este era originalmente sobre valores sendo passados ​​com --set , que agora foi corrigido e a opção --set-string foi adicionada.

A reprodução é sobre um número dentro de values.yaml sendo transformado em notação científica. A reprodução pode ser corrigida citando o número em values.yaml , se for tratado como uma string. Se for usado como um número, as notações não devem ser um problema.

Eu olhei para o código e acho que seria capaz de mudar o comportamento para números de saída em notação padrão em vez de números de até 20 dígitos decimais. Depois disso, parece haver algum limite de implementação no analisador yaml subjacente que arredonda números muito grandes e / ou os transforma em notação científica.

Eu também tentei encontrar outro problema que lidaria com o problema conforme descrito no repro de @edobry e encontrei # 9162 onde a resolução parece ser essa pretendida, pois o analisador analisa os valores como achar adequado e dentro os limites da especificação yaml.

Então, quando alguém usa, por exemplo, tags numéricas, que não têm nenhum valor numérico (nenhuma aritmética é definida nelas), elas devem ser citadas em values.yaml para serem tratadas como strings e isso deve resolver o problema:

# values.yaml
foo: "10000000"
# template
foo: {{ .Values.foo | quote }}



md5-aba98a385ca8fe457cb1f98967ed3bf1



# Source: foo/templates/x.yaml
foo: "10000000"



md5-265ed31678f08bdbd76c259b974f5398



# Source: foo/templates/x.yaml
foo: "1e+07"



md5-3df6a1bc5fe8f474ded5c2033aaf11a3



# Source: foo/templates/x.yaml
foo: "10000000"

Portanto, acho que isso pode ser encerrado e um novo problema pode ser aberto se alguém pensar que a análise de números não cotados deve seguir algumas outras regras do que já faz.

Esta página foi útil?
0 / 5 - 0 avaliações