Helm: Adicione o comando 'helm install --app-version' / controle de versão de um gráfico em relação a uma versão do aplicativo

Criado em 22 fev. 2018  ·  118Comentários  ·  Fonte: helm/helm

Pelo que eu sei, helm install atualmente suporta apenas a especificação do sinalizador --version para especificar uma versão do gráfico a ser instalada.

Não tenho certeza de como o campo 'appVersion' em um Chart.yaml deve ser usado, mas parece geralmente útil adicionar suporte para controle de versão de seu aplicativo em relação a uma versão específica (ou conjunto de versões) de um gráfico.

Estou usando incorretamente o campo appVersion aqui? Devo, em vez disso, estar constantemente construindo meu gráfico para ser compatível com versões anteriores, ou de outra forma, como posso inferir aos meus usuários qual versão do gráfico especificar ao executar helm install se eles quiserem uma versão específica (isso se torna ainda mais complexo quando você considera que um usuário também pode alterar a versão implantada com algo como --set image.tag , o que geralmente resulta em uma alteração de versão de um aplicativo).

feature

Comentários muito úteis

Eu não entendo essa discussão de forma alguma. Por que não dar às pessoas a opção de usar a versão do aplicativo da maneira que elas acham que é a mais adequada para elas é um grande problema?

Em um formulário atual para mim, será melhor não ter este APP VERSION todo. Isso está trazendo apenas confusão para as pessoas em nosso projeto. Temos> 80 serviços que estão usando o mesmo gráfico de leme e como não é possível alterar facilmente este APP VERSION no helm upgrade -i ... , vejo que todos os nossos aplicativos ficarão para sempre com 1.0 aqui. E não pretendo reempacotar o gráfico já empacotado apenas para alterar a versão do aplicativo. Por que devo complicar meu CI para se adequar ao seu projeto ???

Também vejo que só preciso dizer a todos que não usem helm list , pois será algo inútil para eles. Para verificar qual versão de nossos aplicativos eles possuem, eles precisarão usar outra coisa.

Eu estava otimista no início da leitura desta conversa, mas depois de chegar ao final vendo como você discute isso e como você luta para forçar os usuários a terem sua maneira de pensar, perdi as esperanças agora :(.

Todos 118 comentários

Eu também corri para isso. Normalmente, quero que a tag da imagem seja especificada no momento de empacotar o gráfico, mas para depurar o aplicativo, queria fazer uma instalação com uma tag diferente.

Os problemas ficam obsoletos após 90 dias de inatividade.
Marque o problema como novo com /remove-lifecycle stale .
Problemas obsoletos apodrecem após 30 dias adicionais de inatividade e, eventualmente, fecham.

Se for seguro encerrar este problema agora, faça-o com /close .

Envie feedback para sig-testing, kubernetes / test-infra e / ou fejta .
/ lifecycle stale

Trazendo isso à tona novamente, pois foi levantado em https://github.com/kubernetes/charts/pull/5919

Copiando partes do meu comentário recente:


Especificamente, escolhemos manter a versão secundária de nosso gráfico alinhada com a versão secundária do aplicativo (embora os números da versão do patch possam, e divirtam-se).

Isso ocorre porque podemos adicionar um novo sinalizador a uma nova versão do cert-manager e, ao adicionar suporte para ele no gráfico do Helm, quebraria a compatibilidade com versões mais antigas do cert-manager, já que eles não suportam o sinalizador. Esta é uma questão bastante fundamental em torno do controle de versão do gráfico do Helm em geral IMO, e para a qual não temos uma boa história.

Eu sei que não é recomendado tentar alinhar appVersion com a versão do gráfico, mas desta forma, um usuário sabe que pode usar a versão 0.3.x do gráfico Helm com qualquer cert-manager 0.3.x, e a versão 0.4.x do gráfico com cert -manager 0.4.x. A compatibilidade é definida na versão secundária.

/ remove-lifecycle stale

Eu gostaria de trazer isso de volta para discussão.

No geral, não vimos muito a favor do controle de versão dos gráficos para nossos aplicativos internos, quando tudo o que está mudando é a tag de imagem usada por alguns componentes. Ao atualizar uma versão, o campo appVersion parece ser o lugar certo para essas informações.

Cópia da minha proposta original mencionada acima:


Nosso fluxo de trabalho atual para implantar gráficos de helm envolve tarefas ansible que chamam o comando da CLI de atualização do helm e seria bom poder passar um sinalizador para definir o appVersion ao revisar uma versão para a mesma versão de gráfico.

Pode ser um pouco estranho conceitualmente porque um appVersion está associado a um gráfico ao invés de liberado, mas em nosso caso, estamos apenas atualizando a tag de imagem usada para alguns contêineres e nosso fluxo de trabalho não passou a incorporar a versão do gráfico e / ou repositórios de gráfico ainda. Isso pode mudar no futuro, mas por enquanto não vejo nenhum problema em adicionar um sinalizador para --app-version na instalação e atualização, pois o campo é puramente informativo.

ao desenvolver nossos próprios aplicativos internos, o próprio aplicativo muda muito mais do que o gráfico que o implementa. Normalmente, nosso comando de implantação contínua é um helm upgrade com nada mais do que --set imageTag=<new_version> (obviamente, usado em outro lugar no gráfico para definir a versão do contêiner). Use outro ponto visual em helm ls para ver quais versões de código são implantadas junto com a versão do gráfico que é implantada.

Para tornar isso mais visível, de outra forma, padronizei a configuração de uma tag de metadados de imageTag que é definida para a imageTag passada na instalação / atualização. Isso me permite usar o painel K8s ou criar facilmente painéis Graphana com imageTag exibida, mas exige que eu saia da linha de comando e clique com o mouse.

Alguma notícia sobre isso?

Obrigado

Alguma atualização disso. Parece que o PR da @Eraac faz o que é pedido. Como o @ TD-4242 mencionou, também executamos helm upgrade --set imageTag=<imagetag> , no entanto, isso não atualiza a VERSÃO do APP listada na saída de helm ls . Ser capaz de --set app-version ou --set version nos permitirá executar helm upgrade forma que helm ls mostre corretamente a versão que está implantada.

Alguma atualização?

Aaaa qualquer momento em breve seria adorável!

será muito útil

Também adoraria a capacidade de definir a versão do aplicativo no momento da instalação, pois usamos gráficos comuns para implantar aplicativos

+1

+1

Seria muito útil

Solicitando o mesmo

Por favor, pare o spam com o +1. Já existe um PR (https://github.com/helm/helm/pull/4961) e as pessoas estão discutindo a proposta. A última resposta foi há 2 dias.

Olá @filipre

Já existe um PR (# 4961) e as pessoas estão discutindo a proposta.

De acordo com aquele PR, isso foi movido para cá:
https://github.com/helm/helm/pull/5492
Este é o PR mais recente para # 4961 e parece que estamos aguardando a fusão de uma revisão ...

@filipre Você poderia dizer: o que acontece com o PR? Parece que o RP não se move na metade do mês

Isso seria muito útil. Encontrei algo em que preciso fixar a versão 0.6.0 de um aplicativo, e a versão do gráfico não tem relação com a versão do aplicativo.

Eu concordo, também acho que isso seria muito útil. Alguma atualização?

Enfrentei esse problema agora, quando percebi que seria um problema ao escrever um gráfico do Helm que planejamos reutilizar para muitos aplicativos. Dada a falta de progresso na resolução desse problema de uma maneira simples (ou seja, com o sinalizador para definir a versão do aplicativo na instalação), eu vim com uma alternativa que deve funcionar por enquanto. Na verdade, é super simples - basta fazer helm fetch primeiro com a opção untar e, em seguida, helm package com o sinalizador --app-version que existe lá e, em seguida, prosseguir com a instalação do gráfico local.

Não é o ideal, mas o resultado final em helm list está correto e é muito simples fazer isso em um servidor de CI. Adoraria ter apenas --app-version disponíveis em helm install e helm upgrade .

O resumo da discussão em # 5492 foi que um comando que envolve a lógica de helm package e helm install resolveria o caso de uso originalmente descrito neste problema.

Em outras palavras, você pode contornar isso executando o seguinte:

$ helm package myapp --app-version 1.0.0
$ helm install myapp-1.0.0.tgz

(Movendo o comentário de relações públicas recentemente fechadas aqui - para que não acabe no Nirvana)

Aqui estão meus 2 centavos sobre isso:
Supondo que tenhamos um leme chart version X implantando um serviço com appVersion Y .

O gráfico do leme é usado para descrever a infraestrutura dentro do Kubernetes em chart version X que é usado para hospedar um serviço de appVersion Y .

Durante o desenvolvimento inicial, tanto X quanto Y mudarão regularmente. No entanto, em algum ponto X ficará mais ou menos estável e Y continuará a mudar (a menos que Y tenha alguns novos requisitos para infraestrutura, o que provavelmente acontece com muito menos frequência no ciclo de desenvolvimento de Y ).

Com a abordagem proposta neste tíquete, pode-se pegar um pacote de gráfico de leme estável na versão X para implantar um appVersion Y , Y+1 , Y+N , etc.

No entanto, não permitir que este sinalizador seja sobrescrito durante a instalação ou atualização do leme e, em vez disso, apenas no pacote, por exemplo, vincularia efetivamente X e Y , forçando-me a sempre criar um novo X+1 por Y+1 . Isso me parece desnecessário e resultaria em uma tonelada de pacotes de leme que efetivamente não mudaram, exceto pelo fato de estarem referenciando um novo appVersion . Do meu ponto de vista, uma versão de um aplicativo e uma versão da infraestrutura que hospeda esse aplicativo têm uma relação, mas devem ou ainda podem ter uma versão independente. A forma como isso está sendo feito deve ser deixada para as respectivas equipes de desenvolvimento.

Resumo:

Essa abordagem definitivamente funciona, mas também resulta em muitos pacotes Helm desnecessários, onde apenas AppVersion mudou:
$ helm package myapp --app-version 1.0.0 $ helm install myapp-1.0.0.tgz

Sim, mas suponho que não seja um grande problema se você seguir a abordagem que mencionei acima. Envie seu gráfico para um repositório gráfico sem conjunto de versão do aplicativo (ou 0.0.0 ou algo assim), então quando quiser usá-lo, use helm fetch , empacote-o com a versão certa do aplicativo e, em seguida, use o local .tgz file e não empurre esse gráfico. Dessa forma, o repo do gráfico permanece limpo e você só tem as alterações reais do gráfico representadas nele.

Sim, funcionaria. Nesse caso, nunca se pode consumir diretamente o artefato de implantação (por exemplo, instalando diretamente do repositório Helm), mas sempre é necessário enviá-lo por meio de uma etapa adicional que altera o artefato.

Onde foi argumentado que Charts.yaml deveria ser imutável, eu argumento que o artefato de implantação deveria ser.

_Resumindo meus pensamentos em https://github.com/helm/helm/pull/5492#issuecomment -520029902_

Há um problema em como a comunidade interpreta o pacote, gráfico e versões. @BenjaminSchiborr , espero que isso faça sentido para você.

Gráfico - é o código-fonte do seu lançamento. Como um código-fonte do seu aplicativo. Consiste em modelos, arquivos de código.
Pacote - é uma compilação de sua versão, artefato. Como um binário, construído a partir de seu código-fonte. Consiste em versões de produção fixas: tanto a versão do gráfico quanto a versão do aplicativo.
Release - é um build, implantado com a configuração especificada.

Não há como você fazer um Release fora do Chart . Simplesmente não funciona dessa maneira!

Antes de implantar seu aplicativo no palco, você precisa ter um gráfico. Então, você precisa empacotar seu aplicativo com um gráfico, corrigindo ambas as versões, usando helm package . Isso resultará em um pacote, implantável em qualquer estágio. Em seguida, você instala este pacote, por exemplo, no estágio de QA, promovendo-o no UA e depois em Produção, usando helm install .

É assim que qualquer software orientado a pacote funciona.

A confusão

helm install precisa de uma fonte, que deve ser instalada. A fonte pode ser:

  1. Nome do pacote, disponível no registro
  2. Caminho do arquivo do pacote, se o pacote já foi baixado ou criado
  3. URL do pacote, se estiver disponível usando HTTP
  4. Caminho do diretório do gráfico

A 4ª abordagem parece uma ovelha negra aqui, não acham? É por isso que o ppl confunde Pacote e Gráfico. E esta é a raiz dos problemas.

Raciocínio

Existem dois tipos de aplicativos disponíveis:

Grande / médio - é aqui que temos tempo, dinheiro e recursos para configurar fluxos detalhados e granulares para melhor introspecção e garantias de qualidade.
Pequeno - um microsserviço, projeto pet, PoC, projetos de baixo custo, projetos sem conhecimento de DevOps ou até mesmo teste de processo de desenvolvimento de leme.

Com pequenos projetos, você não tem tempo ou necessidade de criar ou lidar com embalagens. Você deseja escrever alguns arquivos de modelo e implantá-los com um comando !

É por isso que helm install permite tal uso, como helm package & helm install . Mas não fornece recursos completos de helm package , como --app-version .

helm install pode ser helm package & helm install , mas faria helm install uma bagunça, um inferno para suporte, testes e boas práticas.

Proposta 1

Simplifique helm install . Deve permitir que apenas pacotes sejam fornecidos, para simplificar a base de código, testes e torná-la opinativa, para simplificar a compreensão de helm .

Proposta 2 - helm run

Introduza o novo comando: helm run . Um comando, que deve funcionar . Ideal para pequenos aplicativos. Ou talvez até médio e grande.

Ele deve combinar helm package e helm install , fornecendo recursos de ambos os comandos, excluindo aqueles que não fazem sentido em tal caso de uso.

helm package cria uma construção, assim como go build faz. go run permite iniciar o aplicativo sem o processo de construção, então helm run parece um nome sólido aqui.

Coisas adicionais a serem consideradas:

  • Deve usar upgrade --install vez disso?
  • Deve ter --atomic habilitado por padrão?

@iorlas ,
seus comentários fazem sentido. No entanto, você está assumindo que só pode haver um pacote final que vincula de maneira hereditária a versão da infraestrutura e a versão do software, ao passo que estou assumindo que tenho um pacote para a minha versão do software e um pacote para a minha infraestrutura e quero amarrá-los em uma versão (por exemplo, por meio de uma configuração de estado desejada que faz referência à versão do software e à versão da infraestrutura).

Não vejo por que um processo de desenvolvimento deve ser forçado a esse padrão em que também poderia ser deixado para os grupos de desenvolvimento responsáveis ​​decidir se desejam unir a infraestrutura e a versão do software no nível do pacote de comando ou posterior. Atualmente, um processo de implantação deve sempre utilizar novos pacotes de leme, enquanto apenas a versão do software muda. Isso resulta em milhares de pacotes inúteis em um repositório para mim.

Estou bem se houver alguma vantagem de longo prazo nisso. Eu simplesmente não vejo isso.

@BenjaminSchiborr Ok, deixe-me decifrar um pouco.

Você pode ter seu Chart (== infraestrutura), que possui a versão X .
Você pode ter seu aplicativo, versão Y .

Como helm funciona agora, ele une versões de infraestrutura e aplicativos na etapa helm package . Em seguida, você precisa vinculá-lo ao namespace k8s, produzindo Release.

Portanto, a fórmula é: package(infra + app) + k8s = Release

O que você realmente deseja é pular esta etapa intermediária e unir todos os 3 componentes em uma etapa - Liberar. Assim: infra + app + k8s = Release . Estou correcto?

Isso é o que helm run fará, superficialmente. Sob o capô, será o mesmo.

Mas ... eu sinto que você pode estar perdendo o foco de Helm . Embora qualquer ferramenta possa ser usada como quiser, há sempre uma ideia que influencia a comunidade, cria um "caminho", para que um telescópio não acabe como um hummer com capacidade para fazer cerveja.

Deixe-me tentar descrever como deve ser usado e seria incrível ver isso da sua perspectiva.

O próprio Helm foi criado para abstrair os modelos e a implantação do k8s, unir o aplicativo e a infraestrutura, com suas dependências: em vez de reescrever manualmente os modelos, aplicá-los no K8s e fornecer uma nova marca de imagem, você precisa apenas de um comando - helm upgrade . Como um pacote MSI ou deb.

Quando você precisa instalar uma nova versão do aplicativo ou fazer o downgrade, deve usar o helm para isso. Em vez de gerenciar o aplicativo, você gerencia todo o pacote. Seria muito difícil reverter a versão do aplicativo e a infraestrutura separadamente quando algo der errado - eu já estive lá, não vou sugerir a ninguém.

Então é certo ter muitos pacotes no seu registro, já que o pacote não é a infraestrutura, o pacote é o app, pois o app não significa nada no K8s sem infraestrutura.

Se o seu problema é que você tem muitos pacotes no repo, eu sugeriria usar artefatos em vez de repositórios. Eu faço assim no CI: construir o aplicativo, enviar para o registro do docker, criar o pacote, salvá-lo como artefato para lançamento. CircleCI, Travis, Azure Pipelines suportam a criação de arquivos anexados para construir como artefatos. Voce pode fazer o mesmo?

Talvez eu esteja perdendo o foco de Helm. Talvez Helm tenha perdido um ponto aqui. Acho que este tíquete é para avaliar exatamente isso. E pessoalmente - também sobre como expandir meu horizonte :)

Mas sim, de uma forma abstrata o que você está dizendo está correto. Não quero a versão do software associada ao pacote / lançamento do helm, então basicamente é infra + app + k8s = Release . Da mesma forma que eu não quero as propriedades da minha versão do software vinculadas ao meu pacote / lançamento do helm (exceto talvez pelo padrão normal que eu possa substituir).

Em relação ao exemplo que você fornece mais adiante. Não vejo como isso mostra como essa abordagem é problemática. Você ainda usaria o leme para rolar para trás ou para frente. Se a infraestrutura mudar, você usará uma versão do gráfico do leme alterada. Se a versão do software mudar, você usa uma versão de aplicativo diferente. Se um parâmetro muda, você usa um parâmetro diferente. Seria sempre (uma) chamada de leme por serviço.

Você pode elaborar?

Se o seu problema é que você tem muitos pacotes no repo, eu sugeriria usar artefatos em vez de repositórios.

Eu estava me referindo a muitos gráficos de leme empacotados (que já incluem appVersion). Pense nisso como uma versão de gráfico de leme que é estável e um appVersion que muda centenas de vezes por dia. Então, diariamente, algumas centenas de gráficos de leme empacotados por serviço em um repositório que mais tarde são consumidos por uma automação.

(Meus pipelines geralmente parecem iguais aos seus: Build App -> Docker image (resulta em appVersion) -> gráfico de pacotes (com appVersion atualizado) -> empurra para o repositório?

Acho que este tíquete é para avaliar exatamente isso.

Com certeza! Na minha opinião, já temos muitos níveis de abstração, então ter um leme aqui é um pouco opressor 😄Além disso, há operadores k8s aqui, que são criados para alguns (talvez a maioria?) Dos problemas que o Helm resolve. Mas isso é assunto para outra hora, hehe.

Pense nisso como uma versão de gráfico de leme que é estável e um appVersion que muda centenas de vezes por dia. Então, diariamente, algumas centenas de gráficos de leme empacotados por serviço em um repositório que mais tarde são consumidos por uma automação.

Sim, definitivamente parece demais, mas é intencional. Por exemplo, você tem uma execução de construção, ela deve produzir alguns artefatos e, em seguida, salvá-la para usar para implementar no palco. Tipo ... como podemos ter uma execução de construção que não tem um resultado de construção? Devemos gerar a compilação ao implantar? Seria muito errado. Embora alguns pipelines de CI façam isso para as compilações JS.

O mesmo problema que temos com o docker: cada construção gera uma nova imagem do docker, que vai para o registro do docker. Precisamos salvá-lo, como devemos implantá-lo então, se não o teríamos?

Claro que podemos docker save para economizar espaço no registro e varrer mais tarde na política de retenção de dados de compilação. Mas para que possamos helm package it e mantê-lo como um arquivo.

Mas eu definitivamente entendo seu ponto de vista, podemos ter um "instalador", que pode aceitar uma versão do aplicativo. Como esse instalador possui infraestrutura, você pode mantê-lo igual, apenas alterando a versão do aplicativo. Parece limpo e simples, mas há um problema.

O aplicativo em si não faz sentido em ambiente K8s sem infraestrutura .

E se seu aplicativo depender de alguma infraestrutura? Exemplo básico - configmap.

E se você precisar reverter o aplicativo então?
Você precisaria fazer o downgrade do aplicativo, mas também precisa fazer o downgrade da infraestrutura.

E se você precisar reverter a infraestrutura então?
A infraestrutura anterior não tem ideia de qual versão do aplicativo você precisa instalar, uma vez que não está vinculada a ela. Portanto, você precisaria lembrar qual aplicativo oferece suporte a qual infraestrutura e configurá-lo manualmente.

Realmente, isso seria um inferno. E é um inferno agora, quando você não tem leme. E não está errado. Mas, nesse caso, você tem poucos motivos para usar o leme.

já temos muitos níveis de abstração
Tudo de bom e simples wink

Acho que seu último ponto é muito convincente:

A infraestrutura anterior não tem ideia de qual versão do aplicativo você precisa instalar, uma vez que não está ligada a ela
Isso é definitivamente um problema se você separar essas coisas e tiver o pacote / lançamento do Helm como a fonte da verdade.

No entanto, para muitas pessoas, esse provavelmente não é o caso. Há uma orquestração no topo do Helm (yay, outra camada de abstração) que une vários gráficos de leme (e appVersions) (pense em timoneiro, arreio ou algo parecido). E essa camada em si também é versionada. Nesse caso, o que você descreve não é mais um problema, porque você não iria reverter para uma versão mais antiga de um gráfico de leme, mas para uma versão mais antiga da camada de orquestração (que faz sentido para o aplicativo e a infraestrutura).

Mas o leme sozinho, sim, 100% um problema 💣. Acho que é por isso que a ideia era permitir explicitamente substituir o appVersion e, por padrão, não permitir.

Uma coisa que eu gosto sobre unir a versão do gráfico e a versão do aplicativo é que fica claro qual versão do aplicativo pertence a qual gráfico. Se você precisar reimplantar uma versão específica, não precisa se lembrar qual versão do aplicativo era compatível com qual versão do gráfico. Como eles estão interligados, basta consultar a versão correta do gráfico e ter a certeza de que o aplicativo e o gráfico correspondem. Acho que isso é basicamente o que @iorlas descreveu, certo?

No final, a versão do gráfico atuará como uma "super" versão:

  • qualquer alteração (independentemente de ter alterado o aplicativo ou a infraestrutura, ou seja, gráfico) resultará em uma nova versão do gráfico, ou seja, uma nova versão do aplicativo implicará que a versão do gráfico também mudou
  • uma nova versão do gráfico não significa que a versão do aplicativo mudou

Para fins de documentação (e talvez outras idéias extravagantes), você mesmo poderia introduzir outra versão de "apenas gráfico", que se referirá apenas à própria definição do gráfico.

@filipre
Sim, sim! É assim que Helm deveria funcionar, com base nas decisões atuais de design de arquitetura. Da maneira que eu vejo.

O problema é que às vezes parece estranho - demais para a configuração e a ideia questionável de ter aplicativo e infra-estrutura interligados. Então, é a abordagem certa - essa é uma questão.

@BenjaminSchiborr

No entanto, para muitas pessoas, esse provavelmente não é o caso

Com certeza! Mesmo k8s inteiros, a colocação de contêineres pode ser demais.

Deixe-me tentar decompô-lo de uma perspectiva um pouco diferente, tentando encontrar o leme do problema foi criado para:

  • A instância de infraestrutura é como todo o produto funciona: instâncias de SaaS, pools de VM, configurações de k8s, versões de aplicativos (incluindo bancos de dados, ferramentas de observação, roteadores, sidecars e as instâncias de aplicativos do produto)
  • A instância de infraestrutura precisa de uma fonte de verdade. Agora temos utilitários como o Terraform.
  • Muitas coisas em uma pasta = difícil. Precisamos decompor isso. Olá módulos do Terraform.
  • Plataforma e aplicativo em uma pasta = difícil. Precisamos nos decompor. Olá, plataforma e contêineres. K8s entra em ação.

    1. Portanto, os módulos Terraform podem gerenciar a plataforma, incluindo a criação de camadas de contêineres vazias e prontas para uso

    2. K8s gerencia os contêineres, permitindo a criação de recursos básicos usando YAML

  • Muitos arquivos YAML para muitos aplicativos K8s (incluindo bancos de dados e outras coisas) = ​​difícil. Divida-o em uma pasta por aplicativo.

    1. Portanto, temos algumas pastas como PostgreSQL, Redis, MyPetShop. Cada um deles possui arquivos YAML para os recursos de que dispomos. E ele precisa que suas versões de aplicativo sejam definidas para ser aplicado no K8s.

  • Hello Helm - instrumento, que permite configurar essas pastas (chamadas Charts), mas mais: aplicá-lo juntos, rollback.
  • O gráfico parece sólido. Vamos reutilizá-lo com variáveis ​​de suporte. Agora, o gráfico não é uma infraestrutura, mas um modelo de infraestrutura.
  • O gráfico parece incrível. Vamos compartilhar com amigos. Cada vez que atualizamos o gráfico, precisamos colocá-lo no repositório de arquivos com índice.

Então, é incrível e tudo mais, sem pacotes. Portanto, você precisa aplicar este gráfico e, em seguida, fornecer a versão do aplicativo. E deve ser isso.

Mas surge o problema: ninguém quer lembrar qual gráfico é necessário para qual versão do aplicativo. Qual gráfico é atualizado para fornecer um novo valor de configuração para qual versão do aplicativo.

No final do dia, tudo o que queremos é "Configurar myApp versão 1.4.2 como aplicativo K8s" , que incapsula todos os riscos, dependências, mudanças em um artefato - instalador de aplicativo, que é apps versions + hooks + setup logic + infrastructure to connect it all . É por isso que temos coisas como MSI, Deb, RPM, até mesmo NPM, Go mod, Pip, Gem.

É aqui que Package entra em cena. E o Pacote, por definição, precisa ser criado como uma versão instalável, dentro do fluxo de CI / CD. Portanto, podemos enviá-lo para o registro e / ou configuração em nosso sistema (cluster k8s).

E nenhum outro projeto é diferente. Quando helm install Chart diretamente, sem pacote, fazemos a mesma coisa. Mas, em vez da criação do pacote, nós o criamos em uma etapa diferente. Em vez de construí-lo no processo de construção de aplicativo, nós o construímos na etapa de lançamento. Ainda unimos a infraestrutura e as versões do aplicativo . Implicitamente .

O engraçado é:

  • Dependência atualizada = atualizar a versão do modelo de infraestrutura (gráfico)
  • App atualizado = gerar um fork, subconjunto do template de infraestrutura (gráfico) - Pacote, com sua própria versão

Ainda assim, os operadores k8s devem ser projetados sobre os problemas atuais, então deve haver apenas um instrumento, que deve funcionar como os operadores, mas fornecer um processo de liberação fácil, como o leme.

Alguma ideia? Podemos estar criando algo novo aqui, mas melhor

O que você está descrevendo faz muito sentido para aplicativos que devem ser usados ​​por outras pessoas na infra-estrutura e sobre os quais você não tem controle. No entanto, em cenários empresariais, fazer pacotes torna-se um trabalho árduo: podemos ter dezenas de microsserviços pré-fabricados, que são implantados em ambientes compartilhados ou pré-fabricados, e em virtude da definição de pipeline de CI / CD que vive no próprio repo (pense azure-pipelines.yaml), a "versão do pacote" é apenas uma compilação produzida a partir de uma versão particular do branch master. Ou seja, eu realmente não preciso armazenar o "pacote" em qualquer lugar - minha construção irá produzir o mesmo pacote, com os mesmos bits e as mesmas variáveis ​​usadas em configmaps, etc. Em cenários como este, estarei acelerando o gráfico do leme apenas quando mudanças de infra-estrutura de serviço, o que acontece muito raramente. O leme está nesta foto porque 1) Eu já tenho que usá-lo para implantar algumas peças de infra (por exemplo, nginx), 2) Eu não tenho que reinventar a roda com o template k8s yaml.

@wasker

Vamos projetá-lo, por exemplo, no docker. A imagem do Docker também é um pacote. Ele une binários com a imagem do sistema operacional = infraestrutura. Acredito que o motivo de fazer uma imagem docker cada vez que fazemos uma compilação é o mesmo que fazer um pacote de leme.

Se não houver necessidade de abstrair tudo para as imagens do docker, não será necessário o docker e poderá conviver com a VM simples.

Portanto, se tentarmos projetar o uso do docker no leme, usar o leme apenas como instrumento de infraestrutura seria como usar o docker apenas para criar uma imagem inicial e, em seguida, atualizar essa imagem no próprio host k8s, enviando novos binários. É ruim, o mesmo tipo de ruim que usar o leme e não reembalar todas as vezes.

De qualquer forma, acho que seguimos pelo caminho errado. Alguém usa o helm e atualiza a imagem manualmente? Acredito que temos 3 casos de uso gerais:

  1. helm package chart -> helm install package
  2. helm install chart
  3. helm install -> kubectl set image

@wasker Qual é o seu? Eu acredito, não o terceiro. Mesmo que seja uma separação real de configuração de infraestrutura e controle de versão de aplicativo, seria desagradável de se trabalhar. Pois, isso significaria, quando você precisar atualizar a infraestrutura, perderá todas as versões. Você precisará atualizá-lo no Chart, manualmente, ou kubectl set image para cada implantação.

Então, estamos falando sobre o segundo, helm install chart , "sem a embalagem". Portanto, o leme está sempre na imagem . O problema é que o pacote é construído, mas em tempo de execução - quando implantamos nosso aplicativo. Portanto, a construção do CI é responsável pela criação do pacote, implicitamente, quando precisamos implantá-lo.

E se projetá-lo no golang, tal prática parece enviar o código-fonte e executá-lo como go run na janela de encaixe, em vez de compilá-lo e usar o binário.

Portanto, o verdadeiro motivo para pular a etapa de empacotamento é simplificar todo o quadro para o engenheiro. É isso ?

É aqui que podemos começar a conversar. Aqui https://github.com/helm/helm/issues/3555#issuecomment -529022699 é minha proposta. Adicione helm run e modele-o como go run .

Se realmente precisarmos dividir a infraestrutura e o controle de versão do aplicativo , isso significaria usar o helm apenas para atualizar / propagar a infraestrutura. Mesmo que eu gostaria de ver uma maneira de fazer isso, posso ver uma, que não vai adicionar dor de cabeça nas atualizações. Podemos ignorar as versões de implantações atuais e outras coisas ... mas eu sinto que é tão errado que seria uma perda de tempo para criar.

Vamos projetá-lo, por exemplo, no docker. A imagem do Docker também é um pacote. Ele une binários com a imagem do sistema operacional = infraestrutura. Acredito que o motivo de fazer uma imagem docker cada vez que fazemos uma compilação é o mesmo que fazer um pacote de leme.

Acho que o problema é que, se você está fazendo uma nova imagem do Docker, é porque algo dentro dessa imagem mudou. No cenário que está sendo descrito aqui, o conteúdo do Helm Chart empacotado não mudou além de uma única linha - a versão do aplicativo. Isso afeta o resultado final, mas não altera como o gráfico do Helm se comporta. Ele fará a mesma coisa, da mesma maneira, apenas com valores diferentes - o gráfico do Helm como uma entidade própria não mudou em nada como resultado da alteração da versão do aplicativo; apenas o que é lançado no final dele tem.

Você pode traçar paralelos aqui com a capacidade de fazer coisas como usar a configuração de imagens do Docker. Você passa as variáveis ​​de ambiente para uma imagem do Docker, isso afeta como ela é executada no tempo de execução e você não reconstrói uma imagem para alterar essas variáveis. O conteúdo da imagem não mudou, mas o resultado final mudou - situação muito semelhante lá, mas nesse caso o comportamento é desejável e normal.

E se projetá-lo no golang, tal prática parece enviar o código-fonte e executá-lo enquanto executa no docker, em vez de compilá-lo e usar o binário. [...] Portanto, o verdadeiro motivo para pular a etapa de embalagem é simplificar todo o quadro para o engenheiro. É isso?

Não na minha opinião. Realisticamente, o argumento aqui é se as pessoas consideram ou não a versão do aplicativo "parte do gráfico" e também se consideram um gráfico do Helm diferente das imagens do Docker que são implantadas como resultado do gráfico. Minha opinião sobre isso é o que mencionei acima. É como pegar um binário Go compilado, em uma imagem Docker, e executá-lo com algumas variáveis ​​de ambiente diferentes.

Dito isso, os argumentos que foram apresentados para reempacotar um Helm Chart com uma nova versão do aplicativo e usar a Chart Version como uma espécie de "superversão" são convincentes (principalmente pela vantagem de sempre ter uma versão de aplicativo compatível implantada com um gráfico - desde que a versão do aplicativo não seja personalizável por meio de valores).

Minha pergunta é - _por que não apoiar ambas as abordagens? _ Existem prós e contras em cada abordagem. Fundamentalmente, não oferecer suporte a isso só está dificultando alguns fluxos de trabalho perfeitamente válidos. Por exemplo, usando Flux CD e seu Helm Operator. Se você tiver um gráfico de Helm compartilhado (ou seja, porque você tem um certo tipo de serviço que implanta muitos deles e eles compartilham muitas das mesmas características), para obter uma saída de helm list útil, você precisa ter um novo Helm Gráfico para cada aplicativo, e cada versão também precisa de seu próprio gráfico do Helm. Isso por si só complica os pipelines, porque se o gráfico pudesse ser compartilhado, ele poderia ter seu próprio pipeline que só rodaria quando o gráfico fosse atualizado, e os pipelines do aplicativo nem precisariam executar um único comando Helm (desde que o Flux CD adicionou suporte para uma nova sinalização de versão do aplicativo na instalação / atualização).

Minha pergunta é - por que não apoiar as duas abordagens?

Isso é exatamente o que estou pensando.

No meu caso, a "super versão" não é o gráfico do leme, mas outra camada que usa apenas uma infinidade de gráficos do leme. Para mim, um único gráfico do Helm não tem sentido, pois descreve apenas um pequeno serviço entre muitos outros. Apenas juntos eles formam uma liberação significativa.
Portanto, no meu caso, a "superversão" é o resumo de todos os lançamentos juntos (que é como ele é realmente versionado).

Ainda assim, há um argumento a favor de ter um mapa do Helm como a "superversão" descritiva.

De volta ao ponto de @seeruk : Por que não oferecer suporte a ambos?

Pode ser útil para o debate atual obter uma voz externa. Para um pouco de contexto, tenho usado helm por uma soma total de _11 dias._ Acho que isso me dá uma perspectiva única a ser adicionada, porque não estive envolvido em nenhum aprendizado avançado. Tudo o que recolhi veio de documentação e experimentação.

Como eu vejo o Helm

Até ler este debate atual sobre a instalação de pacotes do Helm em vez de gráficos, eu acreditava que o Helm é principalmente uma interface para descrever recursos relacionados do Kubernetes. Essa crença vem principalmente da documentação do Helm que diz o seguinte:

O Helm instala gráficos no Kubernetes, criando uma nova versão para cada instalação. E para encontrar novos gráficos, você pode pesquisar os repositórios de gráficos do Helm.

Para contexto, a documentação atual do leme estável também afirma:

Um gráfico é um pacote Helm. Ele contém todas as definições de recursos necessárias para executar um aplicativo, ferramenta ou serviço dentro de um cluster Kubernetes. Pense nisso como o equivalente do Kubernetes a uma fórmula Homebrew, um Apt dpkg ou um arquivo Yum RPM.

Portanto, agora há alguma confusão! Os documentos do Helm dizem claramente que "um gráfico é um pacote de leme", mas se for esse o caso, por que diabos helm install aceita repositórios Chart não empacotados?

É esse comportamento que influenciou minha visão atual do que é o leme e como deve funcionar:

O Helm atua como um mapeador entre a estrutura de _o que_ está entrando no cluster e _ quais propriedades_ essas coisas têm.

Portanto, agora a pergunta é: "O que o Helm está implantando?"

O que está implantando o Helm?

Quando executo helm install release-name ./local_chart espero que o helm renderize todos os modelos de gráfico localmente com os valores especificados (por meio de padrões ou substituições) e envie as versões renderizadas para o Kubernetes. Também espero que o Helm mantenha os objetos Kubernetes implantados anteriormente no caso de eu reverter. Este conceito de "uma coleção de modelos renderizados" (que contém alguns metadados) é um lançamento e é um pacote. Todas essas definições de recursos (mesmo que não tenham mudado) precisam estar em _seus estados descritos no pacote_ para que a versão exista (ou ser revertida para).

A partir disso, presumo que o helm sempre implanta pacotes de verdade . Parece ser a única coisa semanticamente correta que você pode dizer; entretanto, o argumento sobre como esses pacotes são distribuídos parece ser a causa raiz desse debate na prática. Especificamente, "atualizar ou alterar a versão do aplicativo constitui um novo pacote?"

Por _minha semântica pessoal_ a resposta a esta pergunta é sim . Indo pelo argumento de que você não alteraria o número da versão a menos que algo mudasse, você só precisaria ajustar o número da versão do seu aplicativo se algumas propriedades subjacentes mudassem. Isso provavelmente envolveria puxar uma imagem docker diferente de um registro ou definir um sinalizador de recurso por meio de uma variável de ambiente ou qualquer número de práticas diferentes que podem ser usadas para alterar o comportamento de algum artefato de código.

É por isso que comecei a limpar nossos registros e nunca a implantar de :latest exceto no desenvolvimento. Usar uma "meta tag" em vez de uma tag de liberação de uma imagem docker torna impossível vincular uma determinada implantação a uma determinada base de código. Aprendemos isso da maneira mais difícil (mas, felizmente, no teste, e não no teste).

Qual padrão deve ser usado?

Isso já é opinado por Helm: pacotes .

Dado que esse padrão é o padrão imposto, mesmo que não seja 100% evidente, parece logicamente consistente que um sinalizador --appVersion seja fornecido. Responder ao "porquê" disso é provavelmente mais importante do que qualquer outra coisa, então deixe-me concluir minha contribuição com essa resposta.

Por que oferecer suporte a --appVersion?

Vamos dar uma olhada em um caso especial de implantação:

Uma empresa possui um aplicativo com duas versões principais. Alguns dos clientes desta empresa não se comprometeram a atualizar para a versão principal mais recente deste aplicativo e estão usando a mais antiga dos dois. Por causa dos contratos de desenvolvimento pagos, o desenvolvimento ao vivo ainda ocorre na versão principal antiga ... mas o produto é o "mesmo". A infraestrutura a ser implementada para ambas as versões deste aplicativo é a mesma; no entanto, a versão do aplicativo será drasticamente diferente entre essas implantações.

O que esta empresa deve fazer?

  1. Faça duas cartas de leme separadas, quase idênticas, que diferem apenas em appVersion ?
  2. Usar um gráfico de leme, mas atualizar constantemente appVersion alternando entre as versões principais do aplicativo?
  3. Substituir appVersion por um sinalizador (atualmente sem suporte) levando a um possível erro do desenvolvedor na linha de comando?
  4. Rescope appVersion de Chart.yaml e em values.yaml ?

A proposta 1 apresenta um pouco mais sobrecarga do que as outras propostas, mas também tem a vantagem de manter os gráficos para essas versões de aplicativo separados, se houver divergência. Ele tem um caso de uso claro e provavelmente seria adotado em muitos casos desse problema.

A proposta 2 tem menos sobrecarga do que a proposta 1, mas introduz alta variabilidade em um gráfico. O que acontecerá se você executar helm install release-name https://remote-repo.com/chart e a versão mais atualizada do gráfico for a versão errada do aplicativo? Opa. Provavelmente não é a melhor abordagem.

A proposta 3 é o que estamos discutindo atualmente. Eu pessoalmente não gosto da opção, mas apenas porque sinto que é a solução errada para o problema. Isso torna o appVersion configurável? Certo. Mas também tem o mesmo problema que você encontra ao executar helm install release-name https://remote-repo/chart : os metadados são efêmeros e mantidos SOMENTE pelo Helm.

Na verdade, estou muito chocado por ninguém ter oferecido a Proposta 4 ou algo parecido ainda. Ele coloca o appVersion em um estado em que pode ser substituído (permitindo algo semelhante a helm run ), pode estar contido no pacote gerado por helm package e realmente desembaraça o conceito de uma versão do aplicativo de uma versão de gráfico, mantendo o conceito de appVersion acoplado a uma implantação de leme (o appVersion tem que estar em algum lugar certo?).

Espero que isso tenha sido útil. 👀 este PR.

@jrkarnes : Em certo sentido 4) já foi proposto e está em uso como uma solução alternativa por muitas pessoas (veja aqui https://github.com/helm/helm/pull/5492#issuecomment-517255692). Você pode usar algo assim em seus modelos de gráfico:

{{ default .Values.appVersion .Chart.AppVersion }}

Isso permitiria a você usar appVersion em Charts.yaml como padrão e substituí-lo por algo em Values.yaml (que pode ser substituído durante as chamadas de instalação / atualização). A desvantagem é que ao fazer, por exemplo, um helm ls ele mostraria não ou um appVersion incorreto.

@BenjaminSchiborr Obrigado por me informar sobre isso. Como eu disse, estive dentro do espaço de trabalho helm por um tempo muito limitado, então qualquer conhecimento é um bom conhecimento neste momento para mim.

Acho que minha quarta proposta foi um pouco mal interpretada. Em vez de ter algo como {{ default .Values.appVersion .Chart.AppVersion}} você usaria {{ .Values.Helm.AppVersion}} e values.yaml contém appVersion vez de Chart.yaml

@jrkarnes
Isso é o que estou pensando agora. Por exemplo, por que a versão do aplicativo deve ser tratada como um floco de neve uniq. É o valor do gráfico.

Raciocinar por trás disso é fácil: tudo faz parte da infraestrutura. Então, infra tem versão. Por que duas versões?

Mas estou muito ocupado para envolver minha cabeça em casos colaterais e projeções. Mas, em geral, essa é a questão: por que precisamos da versão do aplicativo, quando em poucas palavras é toda a infraestrutura? ou Podemos usar a versão do gráfico como versão de infraestrutura quando o gráfico é apenas modelo de infra, e como versão do aplicativo quando o infra inclui a versão do aplicativo?

Vou pensar mais um pouco

@jrkarnes
Isso é o que estou pensando agora. Por exemplo, por que a versão do aplicativo deve ser tratada como um floco de neve uniq. É o valor do gráfico.

Raciocinar por trás disso é fácil: tudo faz parte da infraestrutura. Então, infra tem versão. Por que duas versões?

Fundamentalmente, faz sentido manter a versão do gráfico separada da versão do aplicativo . Um exemplo rápido é provavelmente a melhor maneira de provar que é esse o caso.

Digamos que você tenha um aplicativo implantado que está ver 4.0.0 em execução em seu gráfico com versão ver 1.1.0 . Durante suas operações, você percebe que precisará iniciar a execução de uma tarefa cron para este aplicativo. Em vez de escrever o objeto cronJob e aplicá-lo ao cluster, você percebe que outras pessoas que executam este gráfico provavelmente precisarão da tarefa cron também ... então você a adiciona ao seu gráfico. Seu gráfico agora progrediu para ver 1.2.0 mas não ocorreu nenhuma alteração no aplicativo que o gráfico gerencia, ele ainda está em ver 4.0.0 .

O inverso também é aplicável e já é objeto de debate neste PR.

Mas estou muito ocupado para envolver minha cabeça em casos colaterais e projeções. Mas, em geral, essa é a questão: por que precisamos da versão do aplicativo, quando em poucas palavras é toda a infraestrutura? ou Podemos usar a versão do gráfico como versão de infraestrutura quando o gráfico é apenas modelo de infra, e como versão do aplicativo quando o infra inclui a versão do aplicativo?

Vou pensar mais um pouco

Em vez de pensar em um caso paralelo ou projeção, pense em coisas como MySql, que tem três versões de mecanismo amplamente usadas e suportadas por aí: [5.6, 5.7, 8.0] . Para implantar uma instância mysql em um cluster, você sempre terá:

  • Podes executando uma instância do MySql da versão escolhida
  • Um serviço que permite resolução kube-dns para o pod (ou pods, se executado em HA)
  • Um PV (s) para os pods escreverem seus dados com o (s) PVC (s) que o acompanha

O gráfico para implantação do MySql 5.6, 5.7 ou 8.0 deve ser relativamente o mesmo para todas as versões do Engine (aplicativo). A única diferença real é a versão do aplicativo e a imagem do docker (que provavelmente é marcada semanticamente de acordo com a versão do mecanismo).

Eu vejo o que você quer dizer sobre se perguntar sobre a "necessidade" de uma versão do aplicativo. Acho que isso se resume à conveniência do desenvolvedor ou das operações ao executar helm ls ou helm inspect .

+1 para a última postagem de @jrkarnes . Há muito valor em manter as versões do gráfico e do aplicativo como conceitos separados precisamente porque a versão do gráfico é a "versão da infraestrutura".

Se estou publicando o gráfico para outros consumirem, ele se torna parte da infraestrutura para projetos que dependem dele. No entanto, se eu nunca pretendo que meu aplicativo seja consumido por outras pessoas, tudo que me importa é revisar minha própria versão do gráfico de vez em quando, quando o gráfico em si muda , mas caso contrário, eu só preciso que a versão do meu aplicativo esteja alinhada com o CI / Saída de CD. Neste tipo de gráfico de uso, a rotação é relativamente rara, mas a versão do aplicativo é acelerada em cada ocorrência de CI. Meu repositório de código mantém a relação entre o código e a versão de infra que é aplicável para esta versão do código ser executada. Em outras palavras, em vez de reverter minha implantação com helm install last-known-good-chart-version , simplesmente executo novamente meu pipeline de CD com um ponteiro para um último ID de confirmação válido.

@iorlas Eu li sua proposta para helm run e não tenho problemas com isso. Embora eu ache que não seja necessário ter a dicotomia instalar / executar, se isso deixa os mantenedores do leme à vontade sobre como tornar a versão do aplicativo mutável, tudo bem. :)

@iorlas Você já teve a chance de pensar sobre o que gostaria de fazer com esta proposta?

Acho que não estou entendendo como as funções alternativas que envolvem {{ default .Values.appVersion .Chart.AppVersion}} . Estou recebendo este erro:

Erro: erro ao converter YAML em JSON: yaml: chave de mapa inválida: map [interface {}] interface {} {". Values.appVersion | default \" 0.0.1 \ "": interface {} (nulo)} [

Aqui está meu Chart.yaml:

name: demo-helm
version: 0.0.1
appVersion: {{ .Values.appVersion | default "0.0.1" }}
home: http://example.com
description: Demo Helm

@IRobL Você precisa colocar este trecho em templates/deployment.yaml , onde a versão é usada. Arquivos como values.yaml não são tratados como modelos.

@jrkarnes Não sou um mantenedor, então a palavra final caberá aos outros caras, eu acho. De qualquer forma, estive bastante ocupado nas últimas semanas. Na próxima semana, estarei reavaliando nossa abordagem atual para gerenciar helm e seus packages .

Usamos a abordagem que descrevi:

  • Helm Chart faz parte do repositório de aplicativos
  • A construção do aplicativo produz:

    • Imagem do Docker -> registro do docker

    • Arquivos estáticos -> serviço CDN

    • Pacote Helm -> armazenamento CI

  • Portanto, o pacote Helm é o artefato principal, ligando todos os artefatos do aplicativo juntos
  • Na implantação, install disse pacote

Preocupações atuais:

  • Complexidade do processo de construção.

    • Em vez de imagem docker e arquivos estáticos, um arquivo adicional ( helm package ) é gerado

    • Quais são os principais motivos pelos quais precisamos de algo além do arquivo resultante go build / make install ?

    • Qual o custo?

    • Por que se inscrever?

    • Quando se inscrever?

  • Duração da construção

    • Mesmo se não precisarmos implantá-lo, ainda perdemos algum tempo e dinheiro. 2-5 segundos. Não muito, mas um trabalho sem sentido não tem sentido.

  • Complexidade das atualizações do modelo de infraestrutura

    • Quando o gráfico é atualizado, os valores também devem ser atualizados

    • O gráfico é um repo, os valores são outro, cada atualização dos valores significa uma pequena dor de cabeça

Essa reavaliação pode levar a simplificações e ideias adicionais. Veremos :)
Enviarei uma atualização mais perto da próxima sexta-feira.

Ah, entendo por que esse truque não funcionaria agora que você apontou isso para mim, obrigado. Aqui está um truque que eu acho que funciona bem para muitas pessoas que usam o Helm 2.x, supondo que você se sinta confortável em embrulhar sua ferramenta de elmo com estes tipos de peças aéreas:

APP_VERSION=0.0.7
sed -i.bak "s/^appVersion:.*\\\$/appVersion: $APP_VERSION/" helm/Chart.yaml
helm install --name helm_demo helm/

@IRobL

Em geral, se você estiver envolvendo uma implantação com sed, significa que um mecanismo de modelagem não está fazendo o que você precisa, que é o ponto principal desta discussão.

Quando o gitlab estava em sua infância e não tinha suporte para helm, literalmente instalamos valores em destinos de substituição em um arquivo de manifesto feito à mão.

É uma prática ruim para algo assim e eu recomendaria que você se afastasse, se possível.

Em 7 de outubro de 2019, às 15:33, IRobL [email protected] escreveu:

Ah, entendo por que esse truque não funcionaria agora que você apontou isso para mim, obrigado. Aqui está um truque que eu acho que funciona bem para muitas pessoas que usam o Helm 2.x, supondo que você se sinta confortável em embrulhar sua ferramenta de elmo com estes tipos de peças aéreas:

APP_VERSION = 0.0.7
sed -i.bak "s / ^ a ppVersion :. * \\ $ / appVersion: $ APP_VERSION /" helm / Chart.yaml
helm install --name helm_demo helm /
-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub ou ignore a conversa.

@jrkarnes , quando você diz práticas ruins, está dizendo que a necessidade de envolver o comando helm com o script é indesejável? Se sim, então eu concordo totalmente. Não estou dizendo que sou contra a adição de um sinalizador --app-version ; pelo contrário, acho que seria uma adição muito conveniente ao leme. Claramente com base neste PR, não sou a única pessoa usando o helm que deseja manter a variável appVersion consistente com a construção real sendo implantada. Acontece que estou desenvolvendo uma biblioteca de pipeline de construção reutilizável que reúne várias ferramentas de construção para produzir construções reproduzíveis - essa é uma prática comum para grandes organizações de tecnologia. No meu caso de uso, a biblioteca pipeline constrói os contêineres docker, publica-os e, por fim, os implanta via helm do pipeline de construção do aplicativo (por exemplo, considere a versão do aplicativo 1.0.1-pr-3.1 para a primeira construção do terceiro PR de um aplicativo, que é potencialmente um pré-lançamento da versão 1.0.1).

Mesmo depois que esse problema for resolvido na biblioteca de pipeline de construção da minha empresa, eu definitivamente me sentiria mais confortável com um switch --app-version integrado ao Helm; parece uma forma mais flexível de lidar com implantações. Quero dizer, por que um sistema externo ou um engenheiro teria que ir até o arquivo Chart e atualizar um yaml antes de cada implantação se ele pode ser automatizado por uma plataforma de construção que não pode bagunçar os números acidentalmente? Do meu ponto de vista, a funcionalidade appVersion precisaria ser abandonada inteiramente pela minha organização, ou a solução "desleixada" sed precisaria ser adicionada ao código da biblioteca de pipeline, então pensei em compartilhá-la por qualquer outra pessoa que estivesse resolvendo esse problema.

@IRobL
Em geral, qualquer utilitário deve ser autossuficiente em seu próprio nível de abstração: ele deve abstrair o problema que resolve fornecendo API suficiente. Helm não é exceção. Então, se você precisa customizar como ele se comporta, você precisa primeiro se perguntar: está de acordo com a arquitetura, os princípios do design ou talvez eu esteja perdendo alguma coisa?

É por isso que esse PR não foi tão fácil de resolver. Desde então, consertar é óbvio, mas não está de acordo com o design do Helm. É por isso que poucas soluções temporárias são fornecidas.

E você está certo sobre a bandeira app-version . Você deve fornecê-lo e o Helm deve cuidar de tudo sozinho.

Posso te fazer uma pergunta? Como você utiliza o Helm em seu produto? Quando você usa helm install ? Como exatamente você o usa? Você já pensou em usar helm package ?

Dei outra olhada em helm package ontem à noite. Eu realmente não estava convencido disso. sed existe há muito tempo e é muito estável. Todos esses tiller / package / install subcomandos são relativamente novos e menos estáveis. Para ajudar a articular meu ponto de vista, meses atrás, decidi "com certeza o Tiller poderia funcionar", embora eu tivesse visto o plugin de alguém que contornou a necessidade do Tiller. Eu olhei para o plug-in como algo que deve ter sido menos popular, mas tenho me chutado desde então. Se eu tivesse confiado no plugin, estaria em uma posição muito melhor do que estou agora. Os mantenedores do Helm até confirmaram que concordam que era um design insustentável e que será removido em versões futuras.

Eu acho que seria um erro da minha parte usar helm package para fazer essas operações simples do sed. Qual é o seu caso de uso para package afinal? Eu sinto como se todo o conceito de helm package perdesse o ponto dos lançamentos de controle de versão / web 2.0 ao empacotar em um zip binário em primeiro lugar, quando grupos de tecnologia modernos têm aproveitado o poder da marcação para alcançar o mesmo processo mas de uma forma mais enxuta e auditável.

Para o meu caso de uso, estou permitindo que os desenvolvedores de aplicativos codifiquem seus aplicativos em contêineres e os implantem de forma sustentável, portanto, minimizar a sobrecarga (ops / tiller system admins, gerenciamento de artefatos de liberação redundante, etc.) é de extrema importância. Eu acho que meu uso segue mais de perto a filosofia Unix de ser decidido sobre o uso de uma ferramenta para o que ela faz melhor, e então mudar para outras ferramentas (etc. sed) quando apropriado. Acho que você nunca encontrará uma ferramenta para fazer tudo perfeitamente por você, mas se estiver satisfeito com seu fluxo de trabalho atual, não me deixe dissuadir você de seguir sua própria filosofia.

@IRobL

quando você diz práticas ruins, está dizendo que a necessidade de envolver o comando helm com o script é indesejável?

sim. Isso precisamente.

No meu caso de uso, a biblioteca de pipeline constrói os contêineres docker, publica-os e, por fim, os implanta via helm a partir do pipeline de construção do aplicativo

Isso é exatamente o que estamos fazendo também.

Mesmo depois que esse problema for resolvido na biblioteca de pipeline de construção da minha empresa, eu definitivamente me sentiria mais confortável com um switch --app-version integrado ao Helm

Eu daria um passo adiante e diria que ter appVersion sendo uma propriedade do arquivo Chart.yaml provavelmente está incorreto. Se o valor puder ser alterado em tempo real, ele não deve ser considerado um "conjunto de valores imutável". Acredito ter defendido a mesma coisa em um comentário anterior.

Todos esses subcomandos tiller / package / install são relativamente novos e menos estáveis.

FWIW, Tiller não vai ser uma coisa no Helm 3. Você aludiu a isso mais tarde em sua postagem; no entanto, estou apenas reiterando isso porque mostra que a sintaxe helm package de criar um "binário do kubernetes" e enviá-lo para Tiller é provavelmente uma prática ruim.

Eu acho que seria um erro da minha parte usar o pacote helm para fazer essas operações simples do sed. Qual é o seu caso de uso para o pacote?

Eu provavelmente posso defender a equipe de Helm neste. A sensação que obtive por trás do helm foi um método em que os desenvolvedores de aplicativos especificam como executar seus aplicativos corretamente de dentro do Kubernetes. É por isso que os provedores de aplicativos executam seus próprios repositórios Helm, que você pode adicionar para baixar uma determinada versão de sua implantação. A equipe do Helm provavelmente viu o código do aplicativo e o código da infraestrutura entrelaçados porque as equipes de produção de destino pretendidas não iriam usar o Helm em fluxos de trabalho diários como fazemos em CI / CD. Exemplo: usamos helm upgrade 130 vezes por dia em média. Acho que esse nunca foi o uso pretendido.

Provavelmente era muito mais comum as pessoas dizerem: "Eu só quero instalar o mysql no kubernetes" e o helm era uma maneira (relativamente) fácil de fazer isso para pessoas que sabiam pouco sobre o kubernetes e estavam apenas brincando com ele.

Portanto, helm package tinha como objetivo final ser consumido por _aquela audiência_. A ferramenta está definitivamente vendo muito mais uso em domínios que a equipe (eu acho) ou não acreditava que pegaria a ferramenta, ou nunca teve a intenção de usá-la do jeito que é.

Eu acho que meu uso segue mais de perto a filosofia Unix de ser decidido sobre o uso de uma ferramenta para o que ela faz melhor, e então mudar para outras ferramentas (etc. sed) quando apropriado.

Estou basicamente tratando Helm como awk com um monte de kubectl apply -f s depois disso. É muito mais limpo ter uma ferramenta automatizada que cuida dos valores para evitar erros humanos.

Parece que você e eu temos muitos dos mesmos valores e podemos estar fazendo muitas coisas semelhantes.

@IRobL

leme

Para mim, tiller não é aceitável. Uma vez que adiciona mais um ponto de exposição, riscos de segurança adicionais e, o mais importante, não faz nada, mas cria mais uma maneira de aplicar arquivos yaml, mas com API diferente. O Tiller foi projetado para proteger e alinhar o processo de aplicação dos pacotes Helm, mas com tantos riscos, software adicional (e controle de versão!). É por isso que Helm III não o usa.

Eu acho que seria um erro da minha parte usar o pacote helm para fazer essas operações simples do sed.

Eu acho que você está perdendo o meu ponto. Deixe-me tentar de novo. Para que é feito sed ? Para transformar um fluxo de dados. Ele deve abstrair o problema das transformações, fornecendo a API e o resultado para qualquer entrada fornecida.

E se você fez um script, onde seu comando sed não funciona (ou seja, você tem um erro em seu regex)? Então você fez uma conclusão, não funciona. Você tentará entender por que sed não funciona por conta própria ou adicionaria um canal adicional com script perl?

A mesma coisa acontece com toda solução: ela deve fornecer API, obter entrada e fornecer saída, abstraindo um problema. Você sabe, estilo Unix.

Projetado no Helm, ele foi projetado para criar uma versão do seu lançamento e colocá-lo no K8s. Ele permite personalizar a configuração usando modelos. Então, você está observando um problema, você precisa fornecer uma versão. O Helm fornece um mecanismo simples para gerenciar versões e fornece uma maneira fácil de personalizar a maneira como sua construção funciona. Então, por que não tentar entender como funciona, em vez de adicionar uma solução alternativa com software adicional?

@jrkarnes

Sim, estamos nos aproximando do leme com interesses semelhantes em mente. Eu realmente não tinha percebido que a raiz do comando package estava entrelaçada com os erros pavimentados pelo timão, obrigado por compartilhar esses insights comigo!

Na verdade, eu estava revisando a história de por que esse recurso não foi apenas adicionado e vi dois argumentos sobre o porquê de eles não poderem adicionar esse recurso, um era que, uma vez que já está definido em package eles também não deveriam tem que defini-lo em install / upgrade também. Tenho simpatia por isso, parece um problema de dívida de tecnologia. Não existe software de uso público que não tenha dívidas com a tecnologia. O outro motivo era que o arquivo Chart.yml era metadado e não deveria ser atualizado. Isso me pareceu estranho ... conforme as pessoas desenvolvem gráficos de leme, com certeza elas atualizam esse arquivo manualmente conforme as coisas mudam e, portanto, ele não é imutável. É mais fácil para mim visualizar o arquivo Chart.yml como uma forma de alimentar parâmetros no binário do leme, pois ele cria os objetos de implantação que, em contraste, são realmente imutáveis.

Qual é a sua plataforma de construção btw? O código do pipeline que estou escrevendo foi escrito para o Jenkins como uma biblioteca global do pipeline.

@IRobL O principal problema é: Você está vendo o Helm como um script de implantação. Mas Helm não é assim. Helm é uma camada de abstração. O Helm pega todos os seus artefatos e os aplica como uma unidade de trabalho ao K8s como uma plataforma.

Helm é um empacotador. O Helm foi projetado para facilitar a implantação. Ele cria um "instalador" a partir de seus artefatos, para que você possa "instalá-lo" em seu sistema operacional - K8s.

app-version em install não tem nada a ver com dívida de tecnologia. Não é necessário quando você deseja install ou upgrade it. O mesmo é Chart.yml . Não deve ser alterado de forma alguma, pois é um arquivo de configuração padrão, que contém a versão do gráfico real, mas o gráfico não é o seu software. Você está apenas usando errado.

Desse ponto de vista, por que você não considera o uso de package ? Parece muito complexo para você ou o quê?

Já faz algum tempo que estou fora do circuito com relação a esse problema, mas já vi esse tipo de ponto surgir algumas vezes:

Helm é um empacotador. O Helm foi projetado para facilitar a implantação. Ele cria um "instalador" a partir de seus artefatos, para que você possa "instalá-lo" em seu sistema operacional - K8s.

Fundamentalmente, o Helm _de forma alguma_ cria um instalador. Não cria um "binário". Ele não cria algo semelhante a um arquivo ".deb" ou semelhante. Ele cria um arquivo de alguns modelos de manifestos do Kubernetes, com alguns valores padrão e / ou predefinidos. Seu software real não reside naquele gráfico do Helm. Não é embalado com isso. Não é garantido que seja imutável.

Acho que é justo dizer que, na maioria dos casos, seu Helm Chart vai mudar _muito_ menos do que o software que você está implantando por meio de seu Chart.

Esta é a razão fundamental (pelo menos IMO) para --app-version estar disponível em helm install e helm upgrade . Por que você deve empacotar seu gráfico novamente se literalmente nada mudou?

Vejo um gráfico do Helm como uma descrição com versão dos manifestos do Kubernetes, descrevendo um conjunto de componentes do Kubernetes que executará com êxito um aplicativo, e é tudo o que vejo. Se essas instruções precisarem ser alteradas, é quando eu gostaria de atualizar meu gráfico - nem sempre que meu aplicativo muda e eu só preciso atualizar uma versão da imagem (que você costuma definir por meio de valores de qualquer maneira).

Dê uma olhada no Flux, por exemplo, e como seu Helm Operator funciona. Você pode fazer com que ele atualize automaticamente um valor de tag de imagem - isso não atualiza o gráfico, apenas a tag de imagem que está sendo implantada.

Ele cria um arquivo de alguns modelos de manifestos do Kubernetes, com alguns valores padrão e / ou predefinidos.

Mas o arquivo deb é o mesmo conjunto de arquivos de configuração, comandos, manifestos e / ou valores predefinidos. O mesmo que o instalador MSI ou mesmo, que é o mais próximo, ebuild no sistema de pacotes gento emerge. Além disso, o mesmo que os pacotes de cerveja.

Então, o que é o Helm senão um gerenciador de pacotes para K8s? Qual é a diferença que você vê?

Não é garantido que seja imutável.

Por que não? Se você alterar o pacote após a geração do pacote, isso está errado. Se você fornecer opções adicionais durante o processo de install/upgrade , é intencional, como em todos os sistemas de empacotamento.

Vejo um gráfico do Helm como uma descrição com versão dos manifestos do Kubernetes

Você já tem um - GIT. Então, por que você precisa de um Helm?

Acho que é justo dizer que, na maioria dos casos, o gráfico do Helm vai mudar muito menos do que o software que você está implantando por meio do gráfico.
Esta é a razão fundamental (pelo menos IMO) para --app-version estar disponível na instalação e atualização do helm. Por que você deve empacotar seu gráfico novamente se literalmente nada mudou?

Neste design, appVersion não deve ser tratado como atributo da construção do pacote Helm. Deve ser tratado como parâmetro configuracional, em valores.

Dê uma olhada no Flux, por exemplo, e como seu Helm Operator funciona. Você pode fazer com que ele atualize automaticamente um valor de tag de imagem - isso não atualiza o gráfico, apenas a tag de imagem que está sendo implantada.

Nesse caso, você perderá o acoplamento dos manifestos de infraestrutura do aplicativo e da versão do aplicativo. Já que mudar a tag da imagem não irá disparar uma nova atualização do helm (corrija-me se o pessoal do Flux estiver fazendo de outra maneira). Nesse caso, você terá o Helm como modelo de configuração. Nesse caso, você não precisa de --app-version .

Mas o arquivo deb é o mesmo conjunto de arquivos de configuração, comandos, manifestos e / ou valores predefinidos. O mesmo que o instalador MSI ou mesmo, que é o mais próximo, ebuild no sistema de pacotes gento emerge. Além disso, o mesmo que os pacotes de cerveja.

Sua descrição aqui para .deb e .msi pacotes está faltando um componente chave - a coisa real que está sendo instalada. Se você olhar o conteúdo de um arquivo .deb , encontrará o software desenvolvido - _THE_ software que será instalado. De modo geral (sempre no caso de .deb ?), O aplicativo que está sendo implantado está intrinsecamente vinculado e faz parte desse pacote (não é o caso do brew).

Os pacotes de cerveja são diferentes e não são realmente comparáveis ​​da mesma maneira. O Brew é na verdade muito mais semelhante ao Helm atualmente, pois contém apenas as instruções sobre como ele deve ser instalado e de onde o código-fonte / pacote deve ser baixado.

Para ser absolutamente claro aqui; um Helm Chart _não está intrinsecamente vinculado a uma versão específica do aplicativo_ e não contém o artefato que está sendo implantado (ou seja, a imagem Docker). Ele contém apenas uma referência a ele, e o valor por trás dessa referência pode até mesmo mudar (ou seja, você pode enviar para a mesma tag do Docker, se desejar). Portanto, não importa o que aconteça, um Helm Chart não é uma versão empacotada de um aplicativo e também não está estritamente vinculado a uma versão específica do aplicativo.

Você só precisa dar uma olhada no repositório de gráficos estáveis ​​para obter um exemplo. Quantos aplicativos permitem que você substitua a imagem que está sendo usada por meio de valores? (Muito_)

Então, o que é o Helm senão um gerenciador de pacotes para K8s? Qual é a diferença que você vê?

É uma ferramenta que facilita a modelagem de manifestos do Kubernetes e os distribui e instala facilmente. A chave aqui é isso, isso é tudo com que o Helm lida - os manifestos do Kubernetes.

Isso tudo volta ao meu ponto principal - se esses manifestos mudarem ou se o modelo precisar mudar para esses manifestos por qualquer motivo, então _isso_ é quando um gráfico de leme precisa realmente ser alterado.

A principal complicação que vejo é que existem 2 casos de uso:

  • Implantar aplicativos de terceiros.
  • Implantando aplicativos próprios.

No caso de aplicativos de terceiros, como consumidor do Helm, é desejável que um gráfico do Helm seja lançado com cada nova versão do aplicativo. Uma diferença importante aqui é a frequência dos lançamentos. É provável que um Helm Chart de terceiros para algo como MySQL ou qualquer outra coisa não mude várias vezes ao dia. Nesse caso, você também não deseja usar acidentalmente uma versão antiga de um gráfico com uma nova versão do software - um erro que é muito mais fácil de cometer com software e gráficos que você mesmo não escreveu.

No caso de aplicativos primários, você pode ter uma maneira padrão de implantar uma classe de aplicativos. Na Islândia, por exemplo, escrevemos e implementamos nossos serviços Go praticamente da mesma maneira. Para isso, podemos usar um único gráfico agora para todos os nossos serviços Go implantados no Kubernetes (usamos a solução alternativa helm package agora). Se a abordagem que adotamos para implantar nossos próprios aplicativos mudar, atualizaremos o gráfico. Versamos nosso gráfico com SemVer, de modo que o aplicativo que não foi atualizado não será afetado até que queiramos atualizá-lo.

Apenas nesta nota; nosso gráfico go-service foi atualizado pela última vez há cerca de um mês. Durante esse tempo, provavelmente tivemos dezenas a centenas de implantações - todas sem a alteração do gráfico.

Em um caso, você quer apenas simplicidade. No outro caso, você deseja controle e facilidade de gerenciamento.

Nesse caso, você perderá o acoplamento dos manifestos de infraestrutura do aplicativo e da versão do aplicativo. Já que mudar a tag da imagem não irá disparar uma nova atualização do helm (corrija-me se o pessoal do Flux estiver fazendo de outra maneira). Nesse caso, você terá o Helm como modelo de configuração. Nesse caso, você não precisa de --app-version.

O Flux realmente mudará os valores que usa para atualizar o gráfico e, em seguida, executará a atualização com o novo valor da imagem. Sua opinião sobre a perda do acoplamento de manifestos de infraestrutura e a versão do aplicativo ainda permanece. O que estou argumentando é que é realmente desejável que seja esse o caso em alguns casos de uso. Você está certo, porém, neste caso de uso, eu não preciso de --app-version , ele não seria usado porque não existe agora. Se assim fosse, talvez o Flux pudesse usá-lo. Nesse caso, seria realmente útil.

helm list é um comando útil. Ser capaz de ver quais versões do aplicativo estão implantadas ainda é útil. Para nossos aplicativos atualmente instalados via Helm com a abordagem helm package , apenas definimos a versão do aplicativo (via --app-version em helm package ) para que a saída de helm list seja útil. É por isso que se pudéssemos definir helm install|upgrade , seria mais simples para nós. Não teríamos que buscar o gráfico e reembalá-lo apenas para mudar a versão.

Na verdade, helm list e o tratamento de reversões são provavelmente as únicas razões pelas quais estamos usando o Helm para software original.

Sua descrição aqui para os pacotes .deb e .msi está faltando um componente chave - o que está sendo instalado.

"Instalar" é um processo de configuração dos recursos necessários (pastas, configurações, binários, busca de banco de dados, atualização / migração de dados) na plataforma de destino.

deb trata de tudo isso. O mesmo acontece com o pacote Helm. O que você quer dizer com o pacote Helm não está "realmente instalado"?

Se você olhar o conteúdo de um arquivo .deb, encontrará o software integrado - O software que será instalado.

Falso. Às vezes, você encontrará o próprio software. Às vezes, você encontrará algumas peças de software. Às vezes, você não encontrará nada além de um conjunto de scripts para obter esse software. Portanto, o ponto-chave aqui - não importa , já que Linux e K8s são plataformas para hospedar determinado aplicativo, aceitando um formato de aplicativo universal. E nomes de imagens, parâmetros de configuração - são as partes do pacote.

O Brew é na verdade muito mais semelhante ao Helm atualmente, pois contém apenas as instruções sobre como ele deve ser instalado e de onde o código-fonte / pacote deve ser baixado.

Exatamente. Você está tentando me convencer de que Brew não é um gerenciador de pacotes?

Para ser absolutamente claro aqui; um Helm Chart _não está intrinsecamente vinculado a uma versão específica do aplicativo ...
Quantos aplicativos permitem que você substitua a imagem que está sendo usada por meio de valores? (Muito)

Você está absolutamente certo. O Helm não poderia ser mais do que um mecanismo de modelagem útil para modelos k8s. Não tenho problemas com tal existência de software: ajuda um pouco, não mudará a prática moderna de entrega.

O problema é que o Helm é mais do que um mecanismo de modelagem. É um gerenciador de embalagens, com todas as vantagens e desvantagens. E no ecossistema onde existe o gerenciador de pacotes, é uma má prática ter algo gerenciado por outro gerenciador de pacotes. Pior - trabalhando sem gerenciador de pacotes.

Eu vejo as razões por trás de fazer a versão do aplicativo como argumento de pacote para esses pacotes. E eu vejo razões para você e todos vocês não terem que fazer pacotes. O problema é que é uma abordagem desatualizada, complexa e mais difícil de gerenciar. Engraçado, o custo é pequeno, mas ganho incrível.

O que estou argumentando é que é realmente desejável que seja esse o caso em alguns casos de uso.

Sim, este é o ponto central: é desejável para algum produto?

Seu argumento é que o Helm Chart raramente muda, então por que deveríamos empacotá-lo juntos a cada lançamento. Eu concordo com você, parece redundante. Mas, de qualquer forma, ainda empacotamos alguns arquivos de origem antigos, side-cars antigos (se o Helm consistir em vários aplicativos), configurações antigas, Dockerfile antigo.

Portanto, a questão é: se empacotarmos o Chart inteiro como um artefato, em cada construção, qual será o ganho? Para o Dockerfile é óbvio (mas com certeza não era óbvio quando a conteinerização apareceu no mercado). Para arquivos de origem também.

Antigamente, tínhamos o mecanismo de entrega mais claro possível: envie apenas arquivos alterados por FTP. Agora temos tantas coisas. Precisamos decidir o que é bom, por que é bom, quem deve usar. Não tenho certeza se ficaria feliz com Helm lidando com as duas abordagens ao mesmo tempo - muito complexo.

Implantar aplicativos de terceiros.

Eu ficaria tãããão feliz se pudesse instalar qualquer versão do PSQL / MySQL usando apenas o gráfico Helm. Seria muito mais fácil manter projetos legados, apresentar infraestrutura para iniciantes. É ainda mais fácil ser notificado sobre as atualizações do gráfico. Por que temos tantos arquivos tar.gz para cada versão dos binários, mas não podemos ter o mesmo conjunto de arquivos tar.gz para os pacotes do Helm?

@iorlas Acabei de ler isso e rejeitei o PR e você fez alguns pontos muito bons. Você me convenceu de que preciso começar a empacotar meus gráficos de leme como outro artefato de minha construção / liberação.

Mas gostaria de mencionar que nem sabia que o helm tinha um comando de pacote e acho que não estou sozinho. Provavelmente porque é muito fácil instalar um gráfico do diretório de origem, mas também a documentação não vende realmente o conceito ou mesmo o explica em detalhes.

O comando do pacote está obviamente documentado, mas há apenas algumas menções muito gerais de pacotes no guia de início rápido ; na verdade, a palavra pacote aparece muito no início rápido, mas se refere principalmente a como instalar o Helm e os diferentes pacotes de sistema operacional . A embalagem também não é mencionada nas práticas recomendadas e acho que capturar o que é embalagem e por que ela é útil deve ser incluída aqui. Eu também verifiquei os documentos da

Normalmente eu gostaria de enviar um PR e não apenas parecer que estou reclamando de algo, mas não tenho certeza do que está acontecendo com as alterações na documentação do 3.0.

@jonstelly Definitivamente, há uma lacuna na documentação. Até eu estava pensando no início que --app-version é bom para ir, mas então não poderia faltar sem um motivo.

Os documentos definitivamente precisam de algum esclarecimento e introdução de problemas comuns. Em seguida, introdução ao ciclo de desenvolvimento do Helm. Mas acredito que a equipe está ocupada na 3ª versão. E também estou muito ocupado agora :(

"Instalar" é um processo de configuração dos recursos necessários (pastas, configurações, binários, busca de banco de dados, atualização / migração de dados) na plataforma de destino.

deb trata de tudo isso. O mesmo acontece com o pacote Helm. O que você quer dizer com o pacote Helm não está "realmente instalado"?

Não quero dizer que o próprio Helm Chart não esteja instalado - tudo o que estou dizendo é que o Helm Chart não contém o aplicativo real que você está implantando. Uma imagem Docker não é compactada em um gráfico do Helm. Ele é extraído pelo Kubernetes de alguma fonte externa.

Falso. Às vezes, você encontrará o próprio software. Às vezes, você encontrará algumas peças de software. Às vezes, você não encontrará nada além de um conjunto de scripts para obter esse software. Portanto, o ponto-chave aqui - não importa, já que Linux e K8s são plataformas para hospedar determinado aplicativo, aceitando um formato de aplicativo universal. E nomes de imagens, parâmetros de configuração - são as partes do pacote.

Pelo que eu sei, na verdade você está incorreto aqui. Um arquivo .deb é um arquivo AR. Você pode extraí-lo e ver o conteúdo e, em última análise, são alguns metadados e alguns arquivos. .deb arquivos .deb contiver um script para ir buscar o software, isso significaria que é o script que está sendo instalado pelo arquivo .deb , não o próprio software. É como instalar um instalador.

Se você tiver um exemplo de software Linux empacotado em um .deb onde .deb vai e baixa o software para instalar como parte do processo de instalação do arquivo .deb , então eu realmente gostaria de vê-lo - já que é algo que eu literalmente nunca encontrei antes em muitos anos de uso do Linux.

Exatamente. Você está tentando me convencer de que Brew não é um gerenciador de pacotes?

Não. Tudo o que estou dizendo é que, como o Helm, os scripts fornecidos para instalar o software por meio do Brew são apenas isso - scripts. Os aplicativos são construídos, empacotados e distribuídos separadamente e puxados por esses scripts. Isso não torna o Brew menos um gerenciador de pacotes, assim como o que venho dizendo não torna o Helm menos um gerenciador de pacotes do Kubernetes. Esse não é o ponto desta questão, não estamos debatendo se Helm é ou não um gerenciador de pacotes, estamos tentando decidir se um sinalizador --app-version deve ou não ser adicionado a helm install|upgrade para facilitar um caso de uso comum.

Eu vejo as razões por trás de fazer a versão do aplicativo como argumento de pacote para esses pacotes. E eu vejo razões para você e todos vocês não terem que fazer pacotes. O problema é que é uma abordagem desatualizada, complexa e mais difícil de gerenciar. Engraçado, o custo é pequeno, mas ganho incrível.

Desculpe, não estou certo do que você quer dizer com isso. O que está desatualizado / complexo / mais difícil de gerenciar?

Portanto, a questão é: se empacotarmos o Chart inteiro como um artefato, em cada construção, qual será o ganho? Para o Dockerfile é óbvio (mas com certeza não era óbvio quando a conteinerização apareceu no mercado). Para arquivos de origem também.

Bem, novamente, a diferença é basicamente que todas as coisas que você mencionou estão intrinsecamente ligadas. Você precisa de todo o código-fonte para executar o aplicativo - não apenas o que mudou. Você não empacota o Dockerfile, então não tenho certeza do que se trata - mas você freqüentemente usará o mesmo Dockerfile sem alterá-lo para construir novas versões de imagens (quero dizer, por que se preocupar com a automação se você teve que alterar algo manualmente a cada hora, certo?). Com todo esse tipo de coisa, você está criando algo que encapsula tudo o que você precisa, para que possa ser implantado de forma isolada. Portanto, você pode fazer coisas como girar um novo nó e implantar nele da mesma forma que faria em um nó existente, etc.

Existem _muito_ de vantagens, como tenho certeza de que você já sabe, sobre o uso do upload antigo por FTP.

Enfim, isso está tudo por perto. Acho que, no final das contas, como já mencionei, na minha opinião, tudo isso acontece; os mantenedores do Helm desejam habilitar esse outro caso de uso ou tornar mais difícil para as pessoas usá-lo dessa maneira? No final das contas, não é _realmente_ uma grande diferença de qualquer maneira. Para mim, seria muito bom se eu não pudesse ter que empacotar nosso gráfico interno, que raramente muda, em cada build apenas para definir uma versão do aplicativo, que novamente só é usado para mostrar a versão atual em uma lista. Para aplicativos primários, vou ser honesto, eu questionei se Helm é a abordagem certa de qualquer maneira.

Uma imagem Docker não é compactada em um gráfico do Helm

Na verdade, gostaria que fosse assim. Mas não é agora. Minha visão é, K8s será / deve ser uma plataforma, que irá incorporar Helm (portanto, não haverá Helm) como API para instalar pacotes: você precisará empacotar seu material no arquivo e instalá-lo. De volta à simplicidade dos arquivos deb, mas com isolamento adequado e recursos k8s como cidadãos de primeira classe.

Um arquivo .deb é um arquivo AR
Você pode extraí-lo e ver o conteúdo
e, finalmente, são alguns metadados
e alguns arquivos

Como .... um pacote Helm!

Se você tiver ... um .deb onde o .deb vai e baixa o software para instalar como parte do processo de instalação do arquivo .deb ...
É como instalar um instalador. ...

Sim, seria como um instalador que possui um instalador dentro. Engraçado, certo? Eu usaria um artefato se possível , se fosse o suficiente para configurar a instância do aplicativo. Mas temos diferentes softwares, diferentes fontes de verdade, às vezes é até útil ter várias fontes.

  • Brew tem YAML como um pacote, mas busca binários de armazenamento remoto
  • Emerge (gentoo) tem ebuild como definição, que baixa até clones git

O Debian tenta empacotar tudo dentro. E é a coisa certa a fazer, se possível. Mas, para provar meu ponto, metapacotes servirão. Você já ouviu falar sobre isso? É um pacote que instala alguns outros pacotes. Não é um pacote?

Mas, por favor, não perca o ponto principal: Não importa ! Mesmo a embalagem vazia, que tem apenas referência dentro, é uma embalagem. Talvez você aceite outro termo, instalador?

O que estou dizendo é que, como o Helm, os scripts fornecidos para instalar o software via Brew são apenas isso - scripts
Os aplicativos são construídos, empacotados e distribuídos separadamente e puxados por esses scripts

E todos nós temos o mesmo pipeline - para construir uma imagem docker.

estamos tentando decidir se um sinalizador --app-version deve ou não ser adicionado ao helm install | upgrade para facilitar um caso de uso comum.

Essa é uma chave. Mas como podemos decidir? Devemos fazer duas perguntas:

  • É possível? sim
  • É a coisa certa a se fazer? Sim? Não?

Se houver pessoas fazendo algo, isso significa que é uma coisa boa? Para progredir, precisamos questionar tudo.

Desculpe, não estou certo do que você quer dizer com isso. O que está desatualizado / complexo / mais difícil de gerenciar?

vamos projetar no Brew, já que o Brew está bem próximo do Helm e já é amplamente usado com sucesso. Você pode projetar em Gentroo Ebuilds ou deb, a imagem não mudará.

  • Desatualizado. Quando foi a última vez que você instalou o MySQL / PSQL manualmente? Por que mudamos disso? Essas razões, amigo.
  • Complexo. Este é um dos "motivos": você precisa configurar a infraestrutura de forma independente, precisa saber qual funciona melhor com quais versões de software. Às vezes, você precisará personalizar a infraestrutura para executar determinada versão do software. Porque se importar? Por que você não delega toda a questão?
  • Mais difícil de gerenciar. Você precisará gerenciar as versões da infraestrutura e do aplicativo quando poderia ter apenas um artefato. Por que tornar sua vida mais difícil?

Desculpe, estou meio preguiçoso agora para descrever todos os casos de uso, como rollbacks limpos, upgrades elegantes, de qualquer forma, esses são os principais bônus.

Bem, novamente, a diferença é basicamente que todas as coisas que você mencionou estão intrinsecamente ligadas.

Nem sempre. Por exemplo, a imagem docker pode ter SSR BE e referência a CDN.

Dockerfile, então não tenho certeza do que se trata - mas você geralmente usará o mesmo Dockerfile sem alterá-lo para construir novas versões de imagens (quero dizer, por que se preocupar com a automação se você teve que alterar algo manualmente todas as vezes, certo?).

Essa é a questão. Mesmo quando o Dockerfile não é alterado, você cria uma nova imagem. Se o seu código-fonte não foi alterado, mas o Dockerfile foi, você construiu uma nova imagem. Portanto, em poucas palavras, o Dockerfile também é um pacote. O mesmo vale para Helm. Você não acha?

Com todo esse tipo de coisa, você está criando algo que encapsula tudo o que você precisa, para que possa ser implantado de forma isolada. Portanto, você pode fazer coisas como girar um novo nó e implantar nele da mesma forma que faria em um nó existente, etc.

Mas acontece que a imagem do docker não é suficiente para executar um aplicativo. Precisamos de uma instância de configuração, precisamos de definições de serviço. Por que não empacotar tudo?

No final das contas, não é uma grande diferença de qualquer maneira.

Eu acredito que sim. Talvez não seja muito importante na base de código, mas estagnará a evolução da conteinerização.

Uma imagem Docker não é compactada em um gráfico do Helm

A imagem em si não é empacotada, mas a referência (leia como: pin) está. Claro, podemos ser pedantes e saber se a imagem literal de vários tamanhos (de MBs a GBs) está incluída no artefato de helm package (spoiler: não é), mas a essência da declaração "Uma determinada versão do código de um aplicativo está incluída em um pacote de leme" ainda é fundamentalmente correta. Se você deseja ou não ser pego no como é irrelevante.

Voltando à terra dos exemplos, digamos que você tenha um aplicativo que tenha versionado internamente como 1.9.9 rodando em um gráfico versionado 1.2.5 . Para que não haja confusão, a imagem do Docker sha para o contêiner do aplicativo é fakeshaA .

Sua equipe decide que na versão 2.0.0 de seu aplicativo, haverá uma versão do sistema de arquivos local de um arquivo que você costumava ter como referência em HTTP. A razão para isso não é importante, mas a consequência para você é bastante severa. Agora você precisa de pv e pvc para suas implantações, para que esses arquivos agora locais não sejam perdidos entre as atualizações. Vendo a necessidade, você vai em frente e atualiza seu gráfico do Helm para ter este pv e pvc para que a mudança para 2.0.0 não seja muito perturbadora.

Antes de alterar o gráfico, você tem Artifact A vinculando a versão do aplicativo 1.9.9 à versão de infraestrutura 1.2.5 . Agora você altera o gráfico ... _seu gráfico de leme agora é v. 1.3.0 _ e você produzirá um artefato ligando 1.9.9 à versão de infraestrutura 1.3.0 . Chamaremos isso de Artifact B

Quando a implantação do código para 2.0.0 for ativada com a imagem do Docker sha fakeShaB , você criará outro artefato vinculando 2.0.0 à versão de infra-estrutura 1.3.0 . Este é Artifact C

Agora, digamos que haja um problema que você não entende totalmente com a versão 2.0.0 e você precisa reverter. Você reverte usando Artifact B ... mas isso não resolve o problema, então você reverte novamente para Artifact A e o problema está resolvido.

O único problema que você encontra é se o Docker Registry ao qual seus artefatos fazem referência ainda tem a imagem referenciada nesses artefatos.

Não importa o que aconteça, você ainda tem uma ligação entre uma versão de um aplicativo e uma versão de infraestrutura . Este é o propósito de Helm. Argumentar o contrário é tolice.

@iorlas :

Vamos deixar de lado as .deb comparações. Acho que somos apenas nós sendo desviados.

Nem sempre. Por exemplo, a imagem docker pode ter SSR BE e referência a CDN.

Isto é uma grande verdade. Mais sobre isso mais tarde.

Essa é a questão. Mesmo quando o Dockerfile não é alterado, você cria uma nova imagem. Se o seu código-fonte não foi alterado, mas o Dockerfile foi, você construiu uma nova imagem. Portanto, em poucas palavras, o Dockerfile também é um pacote. O mesmo vale para Helm. Você não acha?

Você faz, mas isso é porque o produto no final desse processo de construção (ou seja, uma imagem do Docker) depende _both_ do Dockerfile e do que você está colocando nele. Uma imagem não pode existir sem esses dois componentes.

Por outro lado, um Helm Chart pode existir antes mesmo de um aplicativo ser construído - literalmente antes de uma única linha de código ser escrita. Você poderia construir um imaginário que não conseguiria instalar - mas, mesmo assim, o gráfico do Helm poderia existir inteiramente sem qualquer outra coisa. Como eu disse, isso seria inútil, mas estou apenas tentando ilustrar meu ponto de vista de que eles não estão de forma alguma vinculados.

Meu ponto aqui, e como isso está relacionado a esse problema específico, é apenas que os Gráficos do Helm nem sempre estão intrinsecamente vinculados aos aplicativos que estão sendo implantados pelo Gráfico. Não acho que seja uma afirmação ousada, acontece - já é um fato. Estou fazendo isso agora com aplicativos de produção, assim como outros que comentaram sobre esse problema. Então, como eu disse antes, tudo isso se resume a; os mantenedores do Helm desejam habilitar esse caso de uso ou não - não há mais nada a fazer.

Mas acontece que a imagem do docker não é suficiente para executar um aplicativo. Precisamos de uma instância de configuração, precisamos de definições de serviço. Por que não empacotar tudo?

Na verdade, gostaria que fosse assim. Mas não é agora.

Se fosse esse o caso, e um Helm Chart empacotasse realmente tudo o que implantou (você mencionou o CDN antes, mas não o implantará no Kubernetes então, então não iria para seu Chart ainda), então acho que esta conversa não estaria acontecendo. Seu Helm Chart _seria_ intrinsecamente vinculado à versão do aplicativo que está sendo implantado - assim como construir uma imagem Docker. Para construir um Helm Chart nesse cenário, você seria obrigado a reconstruí-lo quando seu aplicativo fosse alterado, momento em que não há dúvidas. Você não poderia usar o Helm da maneira que estou usando hoje - seria muito mais claro dessa forma.

Essa não é a realidade embora. Não é assim que Helm funciona, e não sei se algum dia vai acabar sendo também. Mas nunca diga nunca, certo?


@jrkarnes :

A imagem em si não é empacotada, mas a referência (leia como: pin) está.

Claro, mas um caso de uso comum é usar valores para substituir esse valor. Usei-o com gráficos de terceiros e primários. Não seria uma opção se não fosse algo que as pessoas usassem.

Claro, podemos ser pedantes e ficar presos se a imagem literal de tamanho variável (de MBs a GBs) está incluída no artefato do pacote do leme (spoiler: não é),

Não acho que estejamos sendo pedantes sobre nada - como você já observou, seria factualmente incorreto dizer que a imagem do Docker está empacotada dentro do Helm Chart "construído".

"Uma determinada versão do código de um aplicativo está incluída em um pacote de leme" ainda é fundamentalmente correta.

Mas não realmente, como meu primeiro ponto argumentaria contra. Você pode alterar o que está sendo implantado. Inferno, você pode alterar a maioria dos gráficos para executar a imagem hello-world se quiser. Isso seria inútil, mas prova bem o meu ponto - o gráfico do Helm não está vinculado ao seu aplicativo. Há uma _expectativa_ de que você o usará com a imagem certa e provavelmente por padrão funcionará, mas certamente _não precisa_ - e _de maneira nenhuma_ o código do aplicativo está incluído em um gráfico do Helm, empacotado de outra forma.

Voltando à terra dos exemplos, [...] e o problema está resolvido.

Você fez parecer que isso não seria possível sem usar o Helm da maneira que aparentemente é pretendida. Mas, na realidade, você pode ter apenas 2 versões do gráfico (ou seja, suas duas versões de infraestrutura) e 3 versões de seu aplicativo. Se você deseja reverter, faça isso, você pode escolher facilmente qual gráfico e imagem (ns) deseja implantar. Execute o Helm com seu gráfico, defina seus valores de acordo com a imagem e está tudo pronto.

Não importa o que aconteça, você ainda tem uma ligação entre uma versão de um aplicativo e uma versão de infraestrutura. Este é o propósito de Helm. Argumentar o contrário é tolice.

Acho que argumentar (idealmente discutir) como as coisas podem mudar muitas vezes leva a melhorar as coisas. Não acho que o "propósito" do Helm seja vincular um gráfico e uma versão do aplicativo. Acho que o objetivo é tornar mais fácil e seguro implantar aplicativos em um cluster Kubernetes, mantendo seus manifestos Kubernetes DRY e reutilizáveis. Em nenhum lugar você exige que um gráfico e uma versão do aplicativo estejam estritamente vinculados (como na realidade agora, você não precisa que eles estejam).

Então, novamente, como eu disse a @iorlas , a questão é: Helm deve se adaptar? Qual é o motivo para não ativar esse caso de uso? Se a razão for apenas "porque não funciona atualmente", então essa é uma razão muito pobre, se você me perguntar. Nada desta discussão até agora parece ter respondido a esta pergunta.

... o produto no final desse processo de construção (ou seja, uma imagem do Docker) depende do Dockerfile e do que você está colocando nele. ... Uma imagem não pode existir sem esses dois componentes.

Então ... O pacote Helm precisa da versão do gráfico e do aplicativo (= imagem do Docker) e não pode existir sem ele.

um Helm Chart pode existir antes mesmo de um aplicativo ser construído - literalmente antes de uma única linha de código ser escrita. ... o gráfico de leme poderia existir inteiramente sem qualquer outra coisa. Como eu disse, isso seria inútil

O engraçado é que em um projeto usamos imagens stub do docker para criar uma arquitetura de protótipo. Literalmente, usamos gráficos sem escrever uma única linha de código. Além disso, é sempre um caso viável ter um gráfico que consiste apenas em sub-gráficos.

Portanto, minha hipótese é : o pacote Helm é quase inútil sem uma imagem Docker. A imagem do Docker é quase inútil sem um código-fonte. A diferença é um nível de abstração. Ambas as coisas são objetos semelhantes a pacotes .

mas estou apenas tentando ilustrar meu ponto de vista de que eles não estão de forma alguma vinculados.

Sim, sim! Isso é muito bom, temos pessoas prontas para discutir tudo nos detalhes. Sem você, sem projeções e afirmações, não teremos uma vida futura de mosto 😃

Não acho que seja uma afirmação ousada, acontece - já é um fato. ... Então, como eu disse antes, tudo isso se resume a; os mantenedores do Helm desejam habilitar esse caso de uso ou não - não há mais nada a fazer.

Facto. Para fazer e aceitar tal mudança, deve-se avaliar: é certo fazer ?

Deixe-me te contar uma historia. O Martini era um framework da Web muito usado e ótimo. O motivo não foi a falta de horas para investir, o motivo não foram algumas travessuras com licenciamento. Portanto, a única maneira de tornar o futuro mais brilhante era depreciar todo o framework, deixando alguns caras com raiva, deixando alguns projetos órfãos, forçando alguns caras a reavaliar as coisas que fazem.

Então, eu não sou contra essa abordagem. Eu vejo como ele pode viver (veja minha proposta com helm run ). Mas embora tenhamos a chance de fazer uma intervenção e, possivelmente, consertar toda a indústria enquanto não for tarde demais, eu avaliaria cada uso, discutia quaisquer desvantagens e problemas.

Para construir um Helm Chart nesse cenário, você seria obrigado a reconstruí-lo quando seu aplicativo fosse alterado

Sim. Mesmo agora, pode ser um caso. Temos um pipeline em que, em vez de push , estamos fazendo save / load da imagem do docker. E funciona muito bem. Não estou com vontade agora, mas fundamentalmente é uma maneira muito mais limpa. O problema é que os K8s ainda precisarão do registro docker remoto como um barramento para transferir a imagem "inicial" do docker.

Vamos estreitar nosso foco, pessoal

Seu Helm Chart estaria intrinsecamente vinculado à versão do aplicativo sendo implantado - assim como construir uma imagem Docker.

Esta é uma diferença fundamental aqui. E @seeruk acertou em cheio . E podemos nos concentrar nisso. Deixe-me parafrasear os fatos:

  1. A imagem do Docker não está vinculada ao pacote Helm. Apenas referência a ele.
  2. Isso dá oportunidade de liberar esses caminhos de forma independente.

Questões-chave:

  1. Quais são os riscos da abordagem independente? (ou seja, o que aconteceria se algum devops o usasse, quais argumentos diremos contra ele)
  2. Como a abordagem de embalagem resolve isso?
  3. Qual o custo?
  4. Como vemos o futuro da conteinerização nesta questão em particular?

@seeruk :

Então, novamente, como eu disse a @iorlas , a questão é: Helm deve se adaptar? Qual é o motivo para não ativar esse caso de uso? Se a razão for apenas "porque não funciona atualmente", então essa é uma razão muito pobre, se você me perguntar. Nada desta discussão até agora parece ter respondido a esta pergunta.

Você faz muitos esclarecimentos e pontos importantes. Pessoalmente, acho que Helm deve se adaptar. CI / CD é o futuro de como o software será desenvolvido e, honestamente, com vantagens como --atomic helm já está se tornando mais flexível como uma ferramenta de implantação confiável. Porém, este problema é muito antigo, então acho que a fusão desse PR não é "o próximo passo" no processo.

A criação de um plugin, digamos helm-ci-cd seria viável para este recurso específico de --app-version ( @jrkarnes provavelmente pode falar com este como um contribuidor de RP)? Acho que as necessidades da comunidade em relação à liberação do Tiller só foram realmente reconhecidas depois que o plugin decolou. Existem vários outros problemas com o Helm que são facilmente contornados que podem ser outros bons candidatos para helm-ci-cd veja a dualidade install/ upgrade que nós CI / CD ppl já unificamos via embalagem.

Mesmo se a opção --app-version não for um valor agregado direto para os usuários finais que estão tentando instalar um aplicativo k8s sem ter que olhar os arquivos de modelo (que, aliás, nunca realmente funcionou para devido à necessidade de adicionar políticas de rede para ser compatível com minha infraestrutura de trabalho k8s), o usuário final ainda está obtendo mais valor porque a pessoa que construiu aquele gráfico teve mais facilidade para fazê-lo por causa dos recursos do helm ci / cd que tornam a construção estável e software confiável mais fácil.

Acabamos de ler o Chart.yaml com groovy, em seguida, definir a versão do aplicativo e substituir o arquivo durante o tempo de implantação. Em seguida, faça a atualização do leme. Seria bom se fizesse parte do leme, mas não contaria com isso.

Encontrei isso através do Google'ing. O mesmo barco, na verdade.

Se verison: for a versão do gráfico, isso implica que essa versão muda quando os YAMLs do gráfico mudam. Como um gráfico é um modelo com valores configuráveis, é seguro supor que você pode usar o Gráfico 1.3 para implantar aplicativos de várias versões, 1.2, 1.3, 1.6, 1.8, etc., sem qualquer modificação dos arquivos YAML do gráfico.

Agora vem appVersion: codificado em Chart.yaml - forçando você a editar um arquivo de gráfico para atualizar (e refletir) a versão do aplicativo implementado.

Definitivamente, há uma necessidade de uma opção --app-version CLI que possamos usar nos modelos de gráfico para fazer referência à versão do _aplicação_ para implantar versões diferentes com o mesmo version: 1.3.0 Chart.

@seeruk

Não acho que o "propósito" do Helm seja vincular um gráfico e uma versão do aplicativo. Acho que o objetivo é tornar mais fácil e seguro implantar aplicativos em um cluster Kubernetes, mantendo seus manifestos Kubernetes DRY e reutilizáveis.

Este é o nosso ponto de discórdia e não acho que nenhum de nós vai convencer o outro. Às vezes, em um ambiente profissional, é _tudo_ haver diferenças irreconciliáveis ​​no que diz respeito a uma questão de opinião. Certamente não concordo com tudo o que Stallman diz e se fôssemos entrar nas trincheiras sobre tudo o que ele e eu discordamos, morreríamos antes de chegar a um consenso.

Eu disse isso mais adiante na discussão e acho que vale a pena repetir:

[...] eu suponho que o helm sempre implanta pacotes. Parece ser a única coisa semanticamente correta que você pode dizer; entretanto, o argumento sobre como esses pacotes são distribuídos parece ser a causa raiz desse debate na prática. Especificamente, "atualizar ou alterar a versão do aplicativo constitui um novo pacote?"

Um gráfico de leme de primeira parte (eu gosto de usar MySQL, então vou continuar usando) sem configuração deve instalar um recurso em um cluster como o criador do gráfico o descreveu e pretendia . Olhando para o gráfico real para o mysql, existem duas propriedades que são configuráveis ​​envolvendo o mecanismo real do mysql:

  • image (padrão mysql )
  • imageTag (padrão 5.7.14 )

Então, em seu arquivo Chart.yaml :

apiVersion: v1
name: mysql
version: 1.4.0
appVersion: 5.7.27

Observe que appVersion e o padrão imageTag não correspondem . Se eu executar helm list , vou obter um relatório de que a "versão do aplicativo" (ler; versão do mecanismo) é um estado _que não reflete a versão real do aplicativo instalada no cluster_.

Em nenhum lugar você exige que um gráfico e uma versão do aplicativo estejam estritamente vinculados (como na realidade agora, você não precisa que eles estejam).

Isto está certo; e na minha opinião, uma falha de design.

Então, novamente, como eu disse a @iorlas , a questão é: Helm deve se adaptar?

sim. Vou abordar algumas sugestões em um momento.


@IRobL

A criação de um plug-in, digamos helm-ci-cd, seria viável para esse recurso --app-version específico ( @jrkarnes provavelmente pode falar com este como um contribuidor de relações públicas)?

Você responde sua própria pergunta com:

Mesmo se a opção --app-version não for um valor agregado direto para os usuários finais que estão tentando instalar um aplicativo k8s sem ter que olhar os arquivos de modelo, o usuário final ainda está obtendo mais valor porque a pessoa que Construir aquele gráfico teve mais facilidade por causa dos recursos do helm ci / cd que tornam a construção de software estável e confiável mais fácil.

Se tivermos que fazer isso como um plugin para obter a função correta, eu recomendaria essa abordagem; no entanto, acho que isso está resolvendo o problema errado. Como eu disse antes para @seeruk , acho que ter appVersion sendo uma propriedade intrínseca no arquivo Chart.yaml imutável é uma falha de design. appVersion é uma propriedade de image que está sendo instalada no cluster por meio do gráfico e é derivada de alguma forma da imagem referenciada com seu tag .

Ao pensar em um plug-in helm-ci , que outros recursos ou suplementos você espera que existam? Não acho que simplesmente alternar appVersion das propriedades Chart.yaml imutáveis ​​seja suficiente para agregar valor para garantir ser um plug-in.


@IRobL e @seeruk juntos:

Acho que nossas opiniões divergentes vêm de quem consideramos o usuário final mais comum do leme. Se o usuário final é suposto ser alguém que não vai fazer muitas configurações ou se aprofundar em modelos, helm ls pode não ser particularmente útil e a questão é discutível.

No entanto ... se você estiver usando o Helm como uma ferramenta administrativa e assistente para gerenciar um cluster OU se estiver utilizando o Helm em um contexto mais de CI / CD, então o switch --appVersion acaba sendo muito mais útil e, portanto, um ponto de preocupação (e configuração),

Em um mundo perfeito, eu diria que appVersion deveria ser uma propriedade derivada e vir de metadados de imagem do docker; isso não é viável para o leme fazer, portanto, a falta de contenção.

Ao que eu disse sobre

sim. Vou abordar algumas sugestões em um momento ...
... ao pensar em um plug-in helm-ci , que outros recursos ou suplementos você espera que existam?

Tenho uma lista pessoal que pode ser um bom ponto de partida:

  • Executar helm no modo CICD não compararia _apenas_ o estado de pacotes lançados anteriormente com o que está sendo aplicado atualmente. . Em vez disso, cada implantação de uma versão aplicaria totalmente todos os manifestos modelados quando upgrade for executado.
  • helm-cicd deve envolver os comandos básicos do kubernetes. Não consigo contar quantas vezes tentei executar helm describe ou helm logs .
  • helm-cicd deve permitir que eu veja quais são os resultados dos comandos quando executados por um usuário diferente. Se estivermos usando RBAC, gostaria de ver o que acontece quando um usuário não autenticado tenta fazer algo.
  • helm-cicd deve ser capaz de decompor um namespace em uma coleção de manifestos para editar posteriormente.
  • helm-cicd deve ser capaz de _transplantar_ uma versão em um namespace.

Esses são os maiores ... mas discutir um plugin helm-ci completo está fora do escopo deste PR / edição (atualmente).

Eu leio tudo o que vocês digitam e agradeço o discurso. Eu estou ansioso por suas respostas.

Estou muito ocupado com meu tempo agora, mas quero corrigi-lo em alguns pontos. @jrkarnes

Eu acho que ter appVersion sendo uma propriedade intrínseca no arquivo imutável Chart.yaml é uma falha de design

Não é. Quando algo é feito desta maneira e não de outra, sempre há uma razão, mesmo que seja a selvagem . Neste caso, é a ideologia que defendo: um pacote = uma compilação, gráfico = modelo para as compilações, pacote = app + infra.

O Helm foi projetado em torno dessa ideologia, para tratar K8s como sistema operacional e empacotar como instalador / atualizador para seu aplicativo. Tem alguns problemas, às vezes parece demais, mas com certeza é um futuro.

_Por que eu acho que é assim? Mesmo helm list está definido para exibir as versões atuais dos pacotes instalados._

Ok, nós temos muitos gráficos (públicos como mysql e local, como você provavelmente tem) que não são construídos para criar um pacote cada vez que uma nova versão aparece. E admiro essa necessidade, já que a migração para uma solução de alto nível exige um certo tempo. Além disso, alguém precisa construir pacotes e seria difícil convencer os mantenedores do mysql a criar um pacote Helm para cada construção.

Com o gráfico MySQL, há um problema adicional. Você tem razão, seria melhor ver a versão do MySQL instalada em helm list , mas é apenas uma parte da versão, já que também existe uma tag Image, que provavelmente faz parte da versão aqui.

Então, novamente, como eu disse a @iorlas , a questão é: Helm deve se adaptar?
sim. Vou abordar algumas sugestões em um momento.

Novamente, houve uma proposta para adicionar helm run , que é o que todos vocês estão procurando. Pretende-se usar o Chart como pacote instantaneamente, permitindo fornecer versões de aplicativos e tudo.

Em um mundo perfeito, eu diria que appVersion deveria ser uma propriedade derivada e vir de metadados de imagem docker; isso não é viável para o leme fazer, portanto, a falta de contenção.

Você está vendo a imagem do Docker como produto final, como o último pacote, que é a última fonte da verdade. Não é. Quando você não tem nada além de uma imagem Docker, pode ser enganado e acreditar que é o seu software. Quando você está escrevendo um módulo em seu código, é levado a acreditar que este módulo é o seu software.

O problema é que não é. É apenas uma parte, artefato. De produtos pequenos a grandes, você terá muitos artefatos interligados. Às vezes, você passará versões no arquivo docker dentro do processo de compilação, às vezes terá um ConfigMap, que une vários artefatos. E você não terá um arquivo docker que terá tudo.

Eu tenho uma lista pessoal que pode ser um bom ponto de partida

Eu acredito que você tem muitas sugestões, mas parece mais ao vivo um fork do Helm do que um plugin selvagem. Eu diria que não tem nada a ver exclusivamente com CI de CD. Eu diria para não construir tal fork / plugin, mas discutir e propor soluções adequadas. Ninguém precisa de 3 garfos Helm, considerando que a comunidade atual não é tão grande no momento.

Atenção por FAVOR!

Ok, temos muitos pensamentos aqui e ali. Acredito que o melhor cenário seria ter:

  • Capacidade de alterar a versão do aplicativo, sem precisar criar pacotes primeiro
  • Capacidade de ver a versão adequada do aplicativo em helm ls
  • Permitir que qualquer API (como o operador Helm) especifique / atualize a versão do aplicativo sem o estado intermediário

Temos duas abordagens fornecidas:

  1. helm install é criado para instalar um pacote. Ele também suporta a instalação do Chart, mas é limitado. Vamos simplificar helm install e deixá-lo servir ao seu propósito - instalar pacotes. Em segundo lugar, vamos adicionar helm run , cuja intenção é fornecer um fluxo simplificado: combine helm package e helm run , forneça os argumentos de ambos os comandos, mas filtre aqueles que não fazem sentido nesse caso .
  2. Adicione app-version em helm install cmd. Isso vai inchar essa API e esconder a ideia de usar pacotes, vai esconder (como faz agora) a ideologia de usar pacotes como instaladores, o que faz total sentido pelo menos para alguns, senão para a maioria dos projetos.

Podemos concordar que essas duas abordagens resolverão todas as lutas que temos agora?

Um plug-in é uma solução alternativa para um recurso ausente que os desenvolvedores principais não desejam ou não têm tempo para oferecer, então não me importaria se fosse um plug-in.

O Helm foi projetado em torno dessa ideologia, para tratar K8s como sistema operacional e empacotar como instalador / atualizador para seu aplicativo.

Oooh. Entendo. Um gráfico de leme [pacote] deve ser um "rpm" [por palavra] para Kubernetes. Não foi totalmente a impressão que tive: o helm usa gráficos para implantar um aplicativo. O gráfico / pacote é o aplicativo "formatado para k8s".

Eu estou bem com isso. Faz sentido - agora precisamos atualizar nosso servidor de compilação para fazer o appVersion conforme construímos novos contêineres:

  • Build Container - tag "v1.2"
  • Atualize Chart.yaml - appVersion: "v1.2" --- Vejo que já existe até um comando helm package --app-version .
  • Gráfico de pacotes: helm package --app-version v1.2 => pacote [gráfico] -v1.2.tgz (ou seja, um "pacote [gráfico] -v1.2.rpm")
  • Implantar pacote usando servidores de implantação, pacote de instalação helm [gráfico] -v1.2 (por exemplo, apt install [email protected])

Agora, estou errado no entendimento de nada disso? Se package-v1.2 não é v1.2 appVersion, por que não? Não seria essa a intenção? por exemplo, rpm é a versão do aplicativo, não do pacote (gráfico).

Editar:

Se package-v1.2 não é v1.2 appVersion, por que não? Não seria essa a intenção?

Agora eu vejo porque as pessoas estão comentando sobre Chart.version e Chart.appVersion estarem em uníssono. Os argumentos podem ir para os dois lados aqui ... um aplicativo com uma construção de "gráfico" estável, você esperaria que o pacote v1.2 alterasse seus números de versão. Mas você também pode argumentar que package-v1.2 seria o número da versão do gráfico - quando os arquivos yaml mudam.

Como você gerencia uma versão estável do Chart (1.2), diferenciando-se de uma versão crescente do aplicativo (1.6)? package-[version] será 1,2? ou 1,6? Digamos que você implemente um Chart versão 1.2, mas o appVersion mudou na embalagem: helm package --app-version 1.6 ?

➜  chart git:(master) ✗ helm package --app-version 1.5 nginx
Successfully packaged chart and saved it to: /Users/Documents/source/docker/nginx/chart/nginx-0.1.0.tgz

:(

.... Tão confuso.

Um gráfico de leme [pacote] deve ser um "rpm" [por palavra] para Kubernetes

Exatamente! Mas às vezes parece muito estrito ou muito incômodo, é aqui que o atalho é necessário.

Agora, estou errado no entendimento de nada disso? Se package-v1.2 não é v1.2 appVersion, por que não? Não seria essa a intenção? por exemplo, rpm é a versão do aplicativo, não do pacote (gráfico).

Este é um problema para outra discussão, mas atualmente o pacote terá o nome da versão do gráfico, não da versão do aplicativo. Não sei o motivo, sinto que deveria ser o contrário. Acho que é uma questão histórica, mas na minha cabeça, como na sua, deveria ser package-{app-version}.tgz .

De acordo com minhas mensagens anteriores, existem 4 componentes para a versão:

  • Gráfico
  • Aplicativo
  • Pacote
  • Lançamento

É uma dor de cabeça criar versões de todas essas coisas de forma independente, mas é assim que funciona agora. Com uma exceção: o pacote tem uma versão após a versão do gráfico.

Se escolhermos uma ideologia de empacotar o aplicativo, a versão do aplicativo faria todo o sentido, uma vez que o mesmo processo produz o aplicativo, a imagem e o pacote. Então, quando entrarmos na etapa de entrega, será óbvio como os arquivos são chamados, qual arquivo instalar. No momento, temos que codificar o nome do pacote em pipelines> _ <

@iorlas

Você está vendo a imagem do Docker como produto final, como o último pacote, que é a última fonte da verdade. Não é. Quando você não tem nada além de uma imagem Docker, pode ser enganado e acreditar que é o seu software. Quando você está escrevendo um módulo em seu código, é levado a acreditar que este módulo é o seu software.

Levei algumas semanas para pensar sobre essa afirmação e estou 100% de acordo com você. Além disso, agora entendo de onde vem nossa diferença de opiniões ...

Eu sigo uma filosofia de desenvolvimento e implantação de que você deve construir um sistema a partir de pequenos componentes que fazem um conjunto de coisas incrivelmente bem (pense no UNIX); no entanto, os sistemas modernos podem tratar um "aplicativo" como um agrupamento dessas pequenas ferramentas. Como você deve marcar a "versão" de um aplicativo quando ele depende não apenas do artefato do docker, mas também de outros subcomponentes (que também podem ser artefatos do docker)? Não é uma resposta tão direta quando você começa a usar esse tipo de acoplamento.

Responder a esta pergunta está muito além do escopo desta questão / solicitação. Para voltar à raiz do problema, gostaria de fazer uma diferenciação entre install e run . Com base na semântica, install só deve operar em pacotes, e run deve "executar" o helm através do processo de geração de modelos e aplicá-los _sem manter o estado_.

Embora muitas vezes devamos usar helm template para ver como um gráfico prospectivo será implantado, é muito útil observar isso acontecer vi-ca-vi run que tem um propósito duplo de ser uma estrela em pipelines de desenvolvimento (onde não queremos necessariamente manter um pacote porque ele não tem valor se a velocidade for muito alta).

Com o gráfico MySQL, há um problema adicional. Você tem razão, seria melhor ver a versão do MySQL instalada na lista do helm, mas é apenas uma parte da versão, já que também existe uma tag de imagem, que provavelmente faz parte da versão aqui.

Como eu disse, em um universo perfeito, a versão de um objeto instalado seria introspectada. No entanto, isso me dá uma ideia.

Se mantivermos o que eu disse desde o início sobre como os gráficos são implantados, e se tivéssemos a capacidade de exibir todos os subcomponentes com um sinalizador em helm describe ? Isso não corrige a necessidade de especificar a versão do aplicativo, mas deixa mais claro exatamente o que está instalado (o que é parte da força motriz por trás do desejo de ajustar a versão do aplicativo com uma bandeira).

Li todos os comentários e não tenho uma opinião totalmente qualificada sobre o assunto.

Cheguei aqui porque minha empresa mantém um repositório Helm privado e 90% dos nossos gráficos são principalmente uma implantação que tem uma especificação de contêiner. Nestes casos, se pudéssemos usar appVersion para listar a tag da imagem, evitaríamos duplicar uma variável e poderíamos ver esta versão executando helm version .

Depois de ler este tópico, parece-me que isso seria uma conveniência, embora um muito bom que eu usaria se ele fosse mesclado.

Conforme solicitado, vou incluir minha última resposta do tópico anterior para que outros vejam


Hum. É aqui que as coisas começam a se desentender quando você começa a amarrar appVersion a uma tag Docker (uma associação lógica). É aqui que estamos tendo problemas, ou seja, o cenário de desenvolvimento que mencionei acima. Como version deve ser um SemVer, simplesmente não podemos usar as tags Docker como um Gráfico version .

Como criamos uma diferença de versão visual para os desenvolvedores quando appVersion não está aparente nos gráficos?

Por causa de como o k8s funciona com os aplicativos de TI: em um mundo de desenvolvimento, deve haver alguma maneira de permitir versões de tag em todo o quadro.

Ele não poderia fazer coisas como o SemVer em termos dos operadores ~ ou ^, porque a versão era puramente ordenada, sem semântica.

Por que não? Fazemos isso o tempo todo com php composer . Podemos usar SemVer ou podemos usar versões de strings que são simplesmente analisadas ou ignoradas no esquema de controle de versão, ou seja, se version não for um número SemVer, não o inclua em ~ e ^ correspondência de padrões.

Já que você está citando meu comentário sobre o nº 7299 , vou esclarecer "Não poderia" como "Não fez" (e talvez ainda não o faça).

Para pacotes .deb e .rpm, a string de versão é dividida de maneiras específicas (por hífens), mas eles não têm um significado semântico como "Isso é compatível com a API" e, portanto, você não pode gerar uma expressão como "Dê me a versão compatível com a API mais recente "ou" Dê-me a versão mais recente com uma API inalterada ", como você pode com SemVer.

Lembro que tanto o Debian quanto o RedHat usaram aliases de pacote para atingir esses casos de uso (e compatibilidade ABI) geralmente com base em números de versão. Isso permitiu um comportamento razoavelmente consistente usando apenas nomes de pacotes e comparações apenas de pedidos.

No tópico geral, a maneira como estamos usando os gráficos do Helm para nosso produto é para empacotar nossos vários serviços. As imagens do Docker são, no entanto, um mero artefato e sua nomenclatura é orientada pela versão do serviço, para a qual adotamos o SemVer porque oferecem APIs.

Nosso pipeline de CI transforma repositórios git de código e scripts relacionados e produz gráficos Helm que podem ser instalados e fazem referência a imagens Docker. As marcas nas imagens do Docker não são interessantes para nossos usuários. Em seguida, marcamos com o git SHA de onde eles vieram e, em seguida, marcamos novamente as imagens usadas em um lançamento. O principal benefício da retagging é que nunca devemos desmarcá-los, embora possamos desmarcar as versões git-SHA após um curto período.

Portanto, estou muito feliz com a forma como o Helm funciona para nós, porque version contém a versão exata do nosso software e appVersion contém a mesma coisa, mas como uma string, e ninguém olha em nosso repositório Docker.

Estou um pouco menos satisfeito com a forma como os gráficos são versionados em https://github.com/helm/charts/ , pois lá o gráfico é versionado, não o software, levando a um gráfico menor (estável) ocasional version de um gráfico da versão das coisas que ele contém.

Temos um problema semelhante com o gráfico do operador estável / prometheus , em nossa página interna "Bibliotecas e artefatos consumidos externamente". Ele contém vários softwares diferentes, então a pergunta "Qual versão estamos usando?" e, particularmente, "É seguro atualizar?" são muito mais difíceis de responder do que para Agones, cujas versões são da mesma maneira que nós.

@jrkarnes

Se mantivermos o que eu disse desde o início sobre como os gráficos são implantados, e se tivéssemos a capacidade de exibir todos os subcomponentes com um sinalizador no leme descrever? Isso não corrige a necessidade de especificar a versão do aplicativo, mas deixa mais claro exatamente o que está instalado (o que é parte da força motriz por trás do desejo de ajustar a versão do aplicativo com uma bandeira).

Eu adoraria ver isso. Há uma solicitação de recurso relacionada em # 6932, por exemplo.

Tendo acabado de voltar à discussão, a ideia de que appVersion está relacionado a metadados de imagem Docker definitivamente não se encaixa em nosso caso de uso, como pelo menos alguns de nossos gráficos (aqueles com os quais nossos usuários lidam principalmente) se encaixam não contém imagens Docker, sendo principalmente hosts para recursos compartilhados (por exemplo, chaves públicas JWT, values.yaml ) mais requirements.yaml para extrair outros gráficos.

a ideia de que appVersion está relacionado aos metadados de imagem do Docker definitivamente não se encaixa em nosso caso de uso, pois pelo menos alguns de nossos gráficos

Não estou dizendo que esse era _o_ uso pretendido. Eu apenas declarei que é uma associação lógica. Você ainda está usando appVersion como um "recipiente lógico" de seus yamls internos.

Ainda não sei como bloquear version para a SemVer tem algum benefício. O Helm poderia apenas analisar e testar version (e appVersion ) e prosseguir a partir daí?

Acho que meu ponto é que não estamos usando appVersion , geralmente não está presente em nosso Chart.yaml e, quando está presente, é idêntico a version .

A vantagem de bloquear version no SemVer é que você pode usar os vários operadores SemVer nele e analisá-lo de forma confiável para produzir pedidos e correspondências por instalação.

Os sistemas de empacotamento RPM e DEB têm a mesma coisa, exceto que seus sistemas de versionamento usam uma sintaxe diferente, mas ainda são uma sintaxe restrita por razões de análise semântica. Eles também têm diferentes semânticas com as quais se preocupam.

Dado como o repositório de leme / gráficos foi executado, acho que um único campo version com uma versão de estilo DEB ou RPM teria sido uma escolha melhor do que SemVer mais appVersion string. No entanto, esse é um navio completamente diferente, já navegado. E tendo sido um fornecedor upstream e empacotador Debian em minha juventude, eu aprecio não ter que fazer malabarismos "Qual dos números de versão precisa ser alterado aqui?" em nossos pacotes " version é a única verdade".

O problema com "às vezes é SemVer" é que SemVer se parece muito com um analisador indistinguível de algo que você pode escrever à mão ou encontrar em outro lugar, como uma versão de pacote Debian que não tem uma época, com resultados desastrosamente confusos .

Oi. Não há novidades sobre esse recurso.

Depois de ler todos os comentários, posso ver que seria muito útil.

Na verdade, em nossa empresa, como temos vários aplicativos que usam as mesmas tecnologias e são implantados da mesma forma, temos um gráfico para diferentes aplicativos para evitar duplicações.
Nós empacotamos um novo gráfico somente quando há mudanças estruturais.
E é apenas quando atualizamos ou instalamos uma versão que aplicamos valores específicos como tag, variáveis ​​env ...

Consideramos que o helm chart empacotado é a camada de abstração que representa os recursos e a estrutura do kubernetes esperados para um tipo de aplicativo e é apenas durante a implantação que dizemos "ok, quero que esse tipo de aplicativo seja implantado naquele env com esses valores específicos"

Como a lista do leme deve exibir informações sobre a versão, devemos ser capazes de ver a versão do aplicativo implantada nesta versão.

Deixei o comentário em questão semelhante https://github.com/helm/helm/issues/7517
Podemos adicionar a capacidade de substituir isso em values.yaml?
Então, temos a opção de linha de comando gratuitamente --set

Se tentarmos usar o helm para qualquer aplicação, isso será uma merda. Ninguém usa controle de versão semântico para aplicativos de produção.

Eu concordo. No momento, estamos bloqueados para usar o Chart Museum para gráficos imutáveis ​​com base em _aplicação_. Chart version! = Versão do aplicativo, tornando impossível para nós o lançamento através do Chart Museum.

Eu li um monte (não toda) da discussão acima, desculpe se estou repetindo alguns pontos / visões. Estou tentando apresentar uma resposta mais ponderada.

Gosto de ver a versão do app quando faço helm ls e, conceitualmente, mudar de .Values.image.tag foi uma boa, MAS não ser capaz de configurá-la no momento da implantação é um verdadeiro obstáculo e é algo que já tive para reverter para.

Estou firmemente convencido de que (chart) version é a versão do gráfico e appVersion é a tag docker. Em nosso processo de CI, a tag docker também é uma tag git.
Também temos vários microsserviços e desejamos manter as coisas o mais SECAS possível. Temos gráficos genéricos em um repositório de gráficos local porque a grande maioria dos aplicativos java-springboot são os mesmos. A maior parte dos aplicativos do tomcat são os mesmos (mas diferentes dos do springboot). Enxágue e repita para outras tecnologias. Em seguida, temos valores ambientais à medida que a implantação percorre vários ambientes
Cada um desses microsserviços faz uso do gráfico genérico por meio de CI / CD
por exemplo, helm upgrade release-name private-repo/generic-chart --values <environment>.yaml --set image.tag=<docker tag from build step> --namespace <environment> --install Eu preferiria usar .Chart.AppVersion vez de .Values.image.tag mas PRECISO ser capaz de implantar de uma forma eficiente para nossa organização.

Se eu fizer um helm ls , tenho CHART e APP VERSION portanto, toda a versão do gráfico deve corresponder à versão do aplicativo. Continuar por esse caminho vai apenas alienar as pessoas e em algum ponto o projeto será bifurcado porque essa mentalidade é muito rígida e não é o que muitas pessoas procuram. Também está começando a tomar o caminho de "Vamos remover image.* , nameOverride & fullnameOverride . Image. * Pode ser codificado em deployment.yaml etc." por razões MUITO semelhantes.

Um último ponto é que muitos gráficos públicos não corresponderão exatamente à versão do docker container que eles usam. Dê uma olhada nos contêineres docker mais conhecidos, por exemplo, alpine ou nginx, onde as versões principais e secundárias são etiquetas rotativas com apenas versões de patch não rotativas. Ter um mapeamento 1: 1 para cada versão de patch introduz uma sobrecarga bastante significativa com pouco ou nenhum benefício.
Não é incomum que ambientes de produção não consigam atualizar para a versão mais recente por uma infinidade de razões. Nem fale com a maioria dos lugares sobre versões contínuas em produção.

O resultado de todos os itens acima levanta a questão "Por que o Helm pode usar um repositório gráfico?".
Não ser capaz de sobrescrever appVersion no momento da instalação / atualização significa que você já precisa baixar e descompactar o gráfico, editar appVersion por instalação / atualização ou pode também empacotar os contêineres docker necessários em o gráfico.
A exceção é quando uma instalação completamente padrão está acontecendo, e já há muito debate em torno da geração automática de senhas e coisas do gênero.
Eu sei que os últimos parágrafos pareciam que eu estava entrando em uma toca de coelho e me encurralando, mas é aí que "appVersion é a tag docker E não é possível definir appVersion por meio da linha de comando ou dos valores" nos leva.

@timothyclarke : O que você pode querer fazer, para o caso de uso helm upgrade que você descreveu aqui, é helm package primeiro, que permite definir --version e --app-version , e então você pode helm install o tarball e mantê-lo como um artefato CI, o que aumenta sua reprodutibilidade para a instalação, já que não será necessário adicionar nenhum parâmetro --set . É para isso que mudamos, embora sem o aspecto de "gráfico genérico", já que nossos gráficos não são genéricos.

Também é uma boa chance de adicionar metadados de construção a Version , com algo como +g<shortCommitSHA> .

De acordo com o # 7517, isso me permitiu remover um monte de sed chamadas que estavam reescrevendo image.tag antes de instalar em nosso cluster de teste de CI, e novamente quando empacotado posteriormente.

Essa abordagem pode realmente resolver os problemas que a maioria das pessoas encontra aqui, se estiverem construindo seus próprios gráficos e, particularmente, se estiverem instalando a partir da origem do gráfico em seu checkout. Realmente não ajuda se eles precisarem dessa funcionalidade para um gráfico proveniente de um repo, mas acho que é um problema diferente do que a maioria das pessoas aqui está enfrentando.

Para mim, o risco de substituir uma versão do aplicativo (ou versão) no momento da instalação é que não é tão claramente visível para alguém que está tentando recriar o gráfico, que isso foi feito. A menos que seja de alguma forma hackeado no suporte de valores, ele não estará lá quando alguém extrair a configuração atual do gráfico usando helm get values -o yaml , então se torna _uma coisa a mais_ que torna a implantação de seu gráfico ao vivo diferente do que você obtém com helm install <some way to specify a particular package> --values <values from helm get values> , por exemplo, ao tentar reproduzir um problema visto na produção em uma configuração de teste.

Para mim, o risco de substituir uma versão do aplicativo (ou versão) no momento da instalação é que não é tão claramente visível para alguém que está tentando recriar o gráfico, que isso foi feito. A menos que seja de alguma forma hackeado no suporte de valores, ele não estará lá quando alguém extrair a configuração atual do gráfico usando helm get values -o yaml

Você acerta o prego na cabeça. Isso deve começar em values.yml desde o primeiro dia.

Embora eu entenda os argumentos filosóficos contra esse recurso, a prática de campo mostra que ajudaria muito as pessoas - incluindo nós.

Existem muitos gráficos que permitem definir a versão do aplicativo por meio de values.yml , especificamente porque ele não pode ser definido aqui.

Não tenho certeza se isso foi discutido (deu um rápido CTRL + F e não conseguiu encontrar nenhum vestígio), mas que tal remover appVersion todos juntos como uma solução alternativa? Parece-me que evitaria toda a confusão.

No momento appVersion é tratado como uma espécie de valor "especial". Presumo que esteja lá para fornecer a visibilidade, por exemplo, posso ter a versão do gráfico 123.5.6 do Prometheus, mas terá appVersion: 2.17.1, então eu sei qual é a versão do patch de segurança e quais recursos do Prometheus devo esperar e eu pode pesquisar usando helm ls .

Acho que isso poderia ser fornecido de uma maneira diferente. Talvez por meio de rótulos de lançamento? Ou talvez jsonPath consulta em todas as versões, semelhante ao que é possível com kubectl por exemplo:

kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

Então, o suporte disso seria transferido para as melhores práticas, em vez de ser imposto pela própria helm . Também pode ter fiapos.

Por outro lado, pode ser que muitas pessoas confiem na implementação existente de appVersion , que também precisa ser considerada.

Talvez dar um passo atrás e entender por que exatamente appVersion foi adicionado ajude a resolver esse problema?

@bokysan Estava anteriormente em values.yaml e foi movido para Chart.yaml estou supondo que para todo o helm ls mostre o gráfico e a tag docker em vez de executar um comando como Como
kubectl get deployment <release name> -o jsonpath='{.spec.template.spec.containers[0].image}'

@TBBle Eu abordaria cada um de seus pontos, mas tornaria este post tão longo quanto o anterior. Acho que toda a questão se resume a alguém decidir que um gráfico genérico não é um caso de uso válido apenas olhando para os gráficos no repo público.

Toda a premissa do appVersion cai por terra assim que você precisa começar a usar initContainers e sidecars. Para dar um exemplo do mundo real, um dos projetos que atualmente preciso gerenciar tem o nginx com um sidecar php. As tags nginx e php não mudam com frequência. O contêiner / versão php é muito importante para os desenvolvedores que escrevem o código. O contêiner que muda com mais frequência é o initContainer que fornece o conteúdo.
Defino appVersion para initContainer , para o contêiner php ou é nginx e, ao escolher apenas um desses, quais informações foram perdidas?

Se for importante para seus usuários, então deveria ser a versão PHP, certo? É isso que você está anunciando. Você também pode colocar todos os três em seu appVersion, afinal é um campo de texto livre.

Se você deseja forçar appVersion == tag de imagem de contêiner, então você vai achar isso desafiador com gráficos não triviais, ou seja, gráficos com mais de um contêiner ou sem contêineres. No entanto, esse não é realmente o objetivo, ou seria imageVersion . Se você estiver empacotando um único aplicativo upstream, use sua versão. Se você estiver construindo um pacote de vários aplicativos upstream, escolha um, por exemplo, gráfico do operador prometheus, ou ignore appVersion, pois é um campo opcional.

Se a origem do gráfico for _parte da_ aplicação, por exemplo, Agones, deixe appVersion branco ou copie-o de version se você tiver ferramentas que dependem dele.

Nenhuma dessas coisas precisa ser helm install -decisões em tempo real. Como mencionei anteriormente, helm package está atrasado o suficiente para todos os fluxos de trabalho, exceto "trocar uma versão upstream diferente no momento da instalação para um gráfico de terceiros" e que deve estar em --values ou --set como todas as outras ações "alterar X no momento da instalação".

Honestamente, o recurso que está faltando é provavelmente "passar appVersion por tpl ", então você pode ler .Values.image.tag ou o que funcionar para você.

Se você deseja forçar appVersion == tag de imagem de contêiner

Então provavelmente estamos em https://github.com/helm/helm/issues/7517 Isso talvez seja de onde tudo isso se origina.

Eu não entendo essa discussão de forma alguma. Por que não dar às pessoas a opção de usar a versão do aplicativo da maneira que elas acham que é a mais adequada para elas é um grande problema?

Em um formulário atual para mim, será melhor não ter este APP VERSION todo. Isso está trazendo apenas confusão para as pessoas em nosso projeto. Temos> 80 serviços que estão usando o mesmo gráfico de leme e como não é possível alterar facilmente este APP VERSION no helm upgrade -i ... , vejo que todos os nossos aplicativos ficarão para sempre com 1.0 aqui. E não pretendo reempacotar o gráfico já empacotado apenas para alterar a versão do aplicativo. Por que devo complicar meu CI para se adequar ao seu projeto ???

Também vejo que só preciso dizer a todos que não usem helm list , pois será algo inútil para eles. Para verificar qual versão de nossos aplicativos eles possuem, eles precisarão usar outra coisa.

Eu estava otimista no início da leitura desta conversa, mas depois de chegar ao final vendo como você discute isso e como você luta para forçar os usuários a terem sua maneira de pensar, perdi as esperanças agora :(.

Ter duas saídas diferentes "TABELA (versão)" e "VERSÃO APP" em helm list , helm history e semelhantes é muito útil e evita a necessidade de se aprofundar nas opções de linha de comando e análise de saída para obter os fatos mais importantes.

Se "CHART (version)" e "APP VERSION" estiverem empatados no momento da construção ("helm package"), todo o benefício de ter dois valores diferentes é um pouco perdido. Construir um gráfico e atualizar a VERSÃO do APP sem incrementar / atualizar a VERSÃO DO GRÁFICO resultará em grandes problemas, pois a mesma VERSÃO DO GRÁFICO fornecerá resultados muito diferentes. : - <

Então, por enquanto, somos forçados a construir o pacote com cada lançamento e incrementar "CHART (versão)" e "APP VERSION" em sincronia para não entrar em uma situação insana / obscura.

Como acabei de saber, poderíamos descartar "APP VERSION", pois é opcional e usar algum valor personalizado e usá-lo em vez de {{Chart.appVersion}} para nossa imagem ... mas então helm list ser bem menos informativo. : - <

Da perspectiva dos usuários (desenvolvedores):

  • capacidade de definir alguma propriedade / sinalizador / valor de versão no momento da instalação
  • capacidade de ver a propriedade / sinalizador / valor da versão na lista do leme / saída do histórico com o rótulo "versão XX"

Alguma chance de fazermos isso?

Se "CHART (version)" e "APP VERSION" estiverem empatados no momento da construção ("helm package"), todo o benefício de ter dois valores diferentes é um pouco perdido.

Acho que esse é o ponto crucial do desalinhamento. O benefício da versão do aplicativo conforme eu o uso, e como parece ser pretendido pela configuração atual, é que você conhece a versão de um aplicativo empacotado _ para essa versão do gráfico_, porque a versão do gráfico é a versão de todo o gráfico, não o versão dos modelos no gráfico. Eu odiaria ter todas as declarações como "Exigimos a versão ~ XY do gráfico do Helm" para exigir "Oh, e não mexa com a AppVersion" adicionado ao final.

Este benefício é perdido da versão do aplicativo (e a versão real do aplicativo) é alterada no momento da instalação, porque agora a versão do gráfico não informa qual aplicativo você está usando e você perde a capacidade de usar o SemVer para garantir, por exemplo, você tem a versão mais recente, mas compatível com a API.

Para o caso de uso que @pniederlag está descrevendo, ser capaz de ter appVersion um modelo que aponta para uma entrada de Valores faria com que helm list fizesse o que é desejado, desde que o Gráfico suporte a sua a versão do aplicativo (provavelmente uma tag de contêiner) mudou no momento da instalação, por meio de --set ou --values como todas as outras opções de configuração "alteradas no momento da instalação".

Aqui é onde tenho um problema com AppVersion .

Estamos usando a versão de lançamento e AppVersions.

Para defini-los agora - eu tenho que chamar helm package explicitamente antes de helm upgrade --install para criar um arquivo tar local com ambas as versões sendo definidas.

Agora estou adicionando o suporte de helm-secrets e ...
E seu invólucro não pode funcionar com helm package !

E agora?
Abandonar o suporte e o fluxo de todas as nossas versões?
Desistir usando segredos?
Alguma ideia?

Na verdade, é mais um problema para helm-secrets , mas está relacionado à capacidade --set app-version discutida aqui também, porque se eu pudesse usá-la desta forma - não preciso chamar helm package em tudo.

UPD Oh, espere ... Ainda consigo usar helm secrets upgrade chart.tgz -f secrets.yaml ...
OK.
Mas ainda assim, +1 para adicionar --set app-version .

E agora?
Abandonar o suporte e o fluxo de todas as nossas versões?
Desistir usando segredos?
Alguma ideia?

Construímos dois pacotes: um pacote helm apenas com os gráficos, sem os valores env e o arquivo segredos. Renomeamos este pacote para chart-{app-version}.tgz pois a versão do gráfico não significa nada para nós, nem a versão do gráfico oferece suporte à sintaxe da versão do aplicativo. Nossas atualizações de aplicativo incluem qualquer atualização de gráfico potencial (mesmo repo, usando marcação git).

Então temos um segundo tgz que é específico do ambiente, chart-{app-version}-{env}.tgz que inclui o gráfico tgz, valores yaml e arquivo secrets criptografado. Este arquivo também inclui um "package.yaml" que contém valores como tag, app e nome do ambiente para nossos scripts automatizados implantarem usando helm-secrets .

Estamos acostumados a identificar as versões de nossos aplicativos, ou a maioria deles, com um número de versão semântica. Em seguida, use este número na versão do aplicativo para identificá-lo facilmente na lista helm history para reversões ou outras operações.
Como o sistema não permite injetá-lo automaticamente no momento da implantação, executamos este comando simples automaticamente em nosso pipeline de CI / CD antes do comando de implantação:

sed -i -E "s/^appVersion: (.*)/appVersion: ${deploy.project.version}/" ${chartPath}/Chart.yaml

É complicado, mas funciona conforme o esperado.

@bvis
O problema com sua solução alternativa é que você precisa editar o gráfico em seu pipeline de CI / CD.
Se você usar um repo gráfico centralizado, será forçado a helm pull repo/chart --untar

Algum progresso adicional com a injeção programática de Chart.yaml / appVersion? Existem soluções alternativas? Isso daria um grande impulso ao CI / CD Helm.

@jakovistuk , pelo que posso dizer, os gráficos que usam appVersion para mostrar a versão do contêiner fazem isso diretamente via Chart.yaml, como visto em nginx-ingress / Chart.yaml por exemplo ...

Eu não tenho pensado muito sobre esse problema há algum tempo, então esta pode ser uma pergunta realmente estúpida, mas há uma maneira de usar a CLI do Helm para substituir appVersion?

Parece que muitas pessoas aqui estão pedindo uma maneira de substituir o campo 'appVersion'. A intenção / solicitação original neste problema é permitir —app-version como um substituto para —version, para que um usuário possa executar 'helm fetch —app-version = v0.15.0' e Helm descobrir qual é a última versão do gráfico mais

Em nosso projeto / gráfico (cert-manager), queremos deixar o mais claro possível para os usuários finais qual versão eles estão instalando, portanto, permitir que eles instalem pela versão do aplicativo em vez da versão do

Dito isso, esse problema foi aberto há 2 anos e, desde então, optamos por apenas manter os dois números de versão sincronizados / bloqueados. Depois de alguns anos fazendo isso, foi surpreendentemente fácil e sem dor, embora os usuários às vezes tenham que esperar algumas semanas por um novo lançamento oficial se houver alterações em nossos manifestos de implantação.

Dada a idade deste problema, seu comprimento, a enorme variedade de portas de recursos ligeiramente diferentes e as mudanças no projeto Helm desde então (Helm 3, gráficos OCI etc), não acho que este problema esteja em um bom estado para ser encaminhado como uma solicitação de recurso em sua forma atual. Vou encerrar este problema, mas qualquer outra pessoa que tenha uma solicitação de recurso semelhante é melhor abrir um novo problema e criar um link para qualquer outro comentário relevante neste problema para fornecer evidências. Esperançosamente, isso funcionará melhor para o processo de triagem da equipe do Helm, para que suas solicitações tenham a visibilidade de que precisam!

Também acho que esse tipo de funcionalidade poderia ser, e provavelmente é melhor, implementado como uma ferramenta externa ou wrapper
Helm, especialmente quando se leva em consideração as mudanças de OCI que eu acho que tornariam isso mais complicado de implementar.

Até que isso seja resolvido (ou não). Aqui está como resolvi isso no meu CI / CD (GitLab):

empacote o gráfico com a versão do aplicativo e, em seguida, implante-o.
Eu sei que a versão do gráfico não deve ser igual à appVersion, mas, em nosso caso, é uma solução alternativa.

deploy:
  image: alpine/helm:3.2.4
  stage: deploy
  environment:
    name: ${ENV}
  script:
    - helm package --app-version=${CI_COMMIT_TAG} --version=${CI_COMMIT_TAG} ${NAMESPACE}
    -  | 
       helm upgrade -i --wait ${CI_PROJECT_NAME} ./${NAMESPACE}-${CI_COMMIT_TAG}.tgz \
       --set image.repository="${CI_REGISTRY_IMAGE}" \
       --set image.tag="${CI_COMMIT_TAG}" \
       --set-string ingress.enabled="${INGRESS}" \
       --set service.port="${CONTAINER_PORT}" \
       --set service.targetPort="${CONTAINER_PORT}" \
       --set dc="${CI_ENVIRONMENT_NAME}" \
       --set project="${CI_PROJECT_NAME}" \
       --namespace ${NAMESPACE}
    - helm history ${CI_PROJECT_NAME} -n ${NAMESPACE}
  tags:
    - kubernetes
  only:
    - tags

Se você padronizar seu image.tag para {{ .Chart.AppVersion }} , você não precisará --set durante a instalação, ele já estará correto. Isso também funciona bem para compilações automáticas, quando suas imagens do Docker são marcadas com SHA1, de forma que AppVersion corresponda à marca da imagem do Docker e a versão seja um SemVer de autocriação.

Não há problema em Version ser igual a AppVersion se sua AppVersion for SemVer.

Para pacotes produzidos por minha equipe, estamos mudando para coisas que procuram AppVersion, por exemplo, image.tag, padronizando para Version se AppVersion não estiver definido. Não é uma grande diferença, apenas um argumento a menos para helm package para lançamentos marcados, mas só faz sentido se seu gráfico for construído a partir do mesmo SCM que o que você está empacotando.

@TBBle que não funcionará se você estiver usando um

Você quer dizer que a image.tag está em um subchart, mas você está tentando usar a versão de um gráfico pai? Nesse caso, sim, isso é muito estranho e não será fácil de gerenciar. Acabei de sair exatamente desse layout nos https://github.com/googleforgames/open-match/ gráficos do Helm. Eu sugiro rolar os subgráficos em questão de volta para o gráfico principal neste caso.

Os gráficos devem ser unidades isoladas / utilizáveis ​​de forma independente, sem depender dos comportamentos do gráfico-pai para funcionar. O subchart tem sua própria versão, _esta_ é a que suas imagens deveriam estar usando, caso contrário, por que é um subchart?

No caso do Open Match, os subcharts parecem ser usados ​​de forma que XXX.enable possa ser usado como um atalho em values.yaml para desabilitar um monte de coisas de uma vez, mas então ele introduz um monte de problemas estruturais como este . Todos os subcharts do Open Match usam intensamente o gráfico pai chamado templates, e também têm uma versão local de 0.0.0-dev , então já há dois códigos de que algo não está bem estruturado.

Ou talvez eu tenha entendido mal a observação que você está fazendo.

@haimari Infelizmente, não está funcionando (relacionado a https://github.com/helm/helm/issues/6921?):

> helm package $DIR/deployment/chart --app-version="1111e8" --version="3454e5" --namespace stage
Error: Invalid Semantic Version

Mas, isso funciona:

> helm package $DIR/deployment/chart --app-version="0.0.0-1111e8" --version="0.0.0-3454e5" --namespace stage
Successfully packaged chart and saved it to: /Users/aws/service-0.0.0-3454e5.tgz

e mesmo isso (mas parece sujo):

> helm package $DIR/deployment/chart --app-version="0-1111e8" --version="0-3454e5" --namespace stage
Successfully packaged chart and saved it to: /Users/aws/service-0-3454e5.tgz

helm version version.BuildInfo {Version: "v3.4.0", GitCommit: "7090a89efc8a18f3d8178bf47d2462450349a004", GitTreeState: "dirty", GoVersion: "go1.15.3"}

Acho que a solução da @haimari no estado em que se encontra só funciona porque eles usam tags compatíveis com semver em seu pipeline de CI (ou seja, este será um exemplo de execução de trabalho para lançamentos com tag, não executado em cada commit)

@ a0s : Geralmente sugiro:

helm package $DIR/deployment/chart --app-version="<container image tag>" --version="<semver version>"

Em seguida, faça com que o valor da tag da imagem do contêiner seja algo como {{ Values.image.tag | default .Chart.AppVersion | default .Chart.Version , para que você não precise alterá-lo imediatamente, como faz @haimari .

Em seus exemplos, você tem o que parecem ser duas versões diferentes do git, certo? Um é para a imagem do contêiner e outro para o gráfico?

Com SemVer, você não pode realmente colocar um SHA do git commit na parte significativa do semver, porque semver implica ordenação e os SHAs do git commit não são classificáveis.

Portanto, você desejará usar uma versão algo como 0.0.1-alpha.<build-id>+g<gitcommitsha> que <build-id> é algo parecido com o pipeline ou ID de trabalho de seu sistema de CI, então está sempre subindo quando você se compromete com seu projeto. Dessa forma, você sempre obtém a compilação mais recente quando a solicita.

No SemVer, usar - significa que é um pré-lançamento para aquela versão, então 0.0.1-<anything> está entre os lançamentos 0.0.0 e 0.0.1. A parte depois de + é a informação de construção e é ignorada para classificação, portanto, um bom lugar para colocar SHAs git ou nomes de branch ou outras informações de rastreamento não classificáveis.

Assim, com o que você usou aqui, 0-3454e5 parecerá ser mais recente que o próximo commit, se seu SHA começar com 2 , por exemplo, 0-2764e1 .

Em seus exemplos, você tem o que parecem ser duas versões diferentes do git, certo? Um é para a imagem do contêiner e outro para o gráfico?

Sim, o aplicativo e o gráfico - existem dois softwares independentes.

Dessa forma, você sempre obtém a compilação mais recente quando a solicita.

E se eu não quiser (e nem imaginar) pedir o último.

0.0.1-alpha.<build-id>+g<gitcommitsha>

Esta string (após a interpolação) parece muito longa para caber em uma coluna de saída helm list padrão :)

Eu sempre sei qual versão (sha hash) do aplicativo que desejo instalar (passe-o com --set args). E eu sempre sei qual versão do gráfico eu uso (como @haimari descreveu, eu sempre usarei git checkout chart && helm pack && helm upgrade .tar.gz localmente em meu ci / cd)

O que poderia dar errado?
1) Um erro durante helm upgrade normal. Ok, vou consertar o erro e tentar novamente (com outro sha commit do aplicativo - 99%) (ou usando --atomic lugar)
2) Rollback manual: helm rollback <RELEASE_NAME> ou implantação anterior sha commit por CI / CD.

O que sinto falta?

PS: Para ser honesto, eu quero usar uma pequena parte do sha na versão e na versão do aplicativo apenas para fins informativos (durante helm list )

Se for apenas para fins informativos, ele vai atrás de + em um SemVer, não - . Se você _nunca_ se preocupa com a ordem de lançamentos ou com a distribuição de gráficos do Helm para qualquer pessoa, e seu gráfico ou aplicativo ainda não está SemVer, então 0+g<commitsha> é um SemVer válido (equivalente a 0.0.0).

Isso é o que os gráficos construídos automaticamente pelo Helm da Open Match fazem, por exemplo; todos eles são atualmente 0.0.0-dev , e começamos a pensar em fazer aquele 0.0.0-dev+g<commitsha> para que, se você estiver olhando o que instalou, possa pelo menos dizer _qual_ construção mestre que possui.

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