Reiniciar pods quando o configmap for atualizado no Kubernetes?

120

Como reinicio automaticamente os pods do Kubernetes e os pods associados às implantações quando seu configmap é alterado / atualizado?


Sei que tem falado sobre a capacidade de reiniciar pods automaticamente quando um mapa de configuração muda, mas que eu saiba, isso ainda não está disponível no Kubernetes 1.2.

Então, o que (eu acho) eu gostaria de fazer é uma "reinicialização contínua" do recurso de implantação associado aos pods que consomem o mapa de configuração. É possível e, em caso afirmativo, como forçar uma reinicialização contínua de uma implantação no Kubernetes sem alterar nada no modelo real? Esta é atualmente a melhor maneira de fazer isso ou existe uma opção melhor?

João
fonte
$ kubectl set env deployment my deployment --env="LAST_RESTART=$(date)" --namespace ...faça o trabalho por mim
maciek

Respostas:

60

A sinalização de um pod na atualização do mapa de configuração é um recurso em desenvolvimento ( https://github.com/kubernetes/kubernetes/issues/22368 ).

Você sempre pode escrever um pid1 personalizado que percebe que o confimap mudou e reinicia seu aplicativo.

Você também pode, por exemplo: montar o mesmo mapa de configuração em 2 contêineres, expor uma verificação de integridade de http no segundo contêiner que falha se o hash do conteúdo do mapa de configuração mudar e empurrá-lo como a prova de atividade do primeiro contêiner (porque os contêineres em um pod compartilhar o mesmo namespace de rede). O kubelet reiniciará seu primeiro contêiner para você quando o probe falhar.

É claro que, se você não se importa com os nós dos pods, pode simplesmente excluí-los e o controlador de replicação os "reiniciará" para você.

Prashanth B
fonte
Com "deletar pods" você quer dizer: Coletar todos os nomes de pods, deletar um, esperar até ser substituído, deletar o segundo, esperar até ser substituído etc. Correto?
Torsten Bronger
6
usando uma implantação, eu diminuiria e aumentaria. Você ainda terá aquele pequeno tempo de inatividade. Você pode fazer isso em uma linha para reduzir isso ... kubectl scale deployment/update-demo --replicas=0; kubectl scale deployment/update-demo --replicas=4;
Nick H
Se você não deseja encontrar todos os pods e não se preocupa com o tempo de inatividade - apenas remova o RC e recrie o RC.
Desenhou em
1
Isso significa que o volume em que está montado está atualizado e você só precisa reler o arquivo no pod sem reiniciar todo o pod?
Matt Williamson
@NickH Rápido e sujo, felizmente o tempo de inatividade foi aceitável no meu caso e funcionou muito bem, obrigado!
ChocolateAndCheese
129

A melhor solução atual para este problema (referenciado profundamente em https://github.com/kubernetes/kubernetes/issues/22368 vinculado na resposta do irmão) é usar Implantações e considerar seus ConfigMaps imutáveis.

Quando você quiser mudar sua configuração, crie um novo ConfigMap com as mudanças que deseja fazer e aponte sua implantação para o novo ConfigMap. Se a nova configuração for interrompida, a implementação se recusará a reduzir o seu ReplicaSet de trabalho. Se a nova configuração funcionar, seu antigo ReplicaSet será dimensionado para 0 réplicas e excluído, e novos pods serão iniciados com a nova configuração.

Não tão rápido quanto apenas editar o ConfigMap no local, mas muito mais seguro.

Simétrico
fonte
2
Esta é a abordagem que adotamos também
Johan
4
Vale a pena mencionar que a nova ferramenta experimental kustomizeoferece suporte à criação automática de um hash de configmap determinístico, o que significa que você não precisa criar manualmente um novo configmap: github.com/kubernetes-sigs/kustomize/blob/…
Simétrico
Isso é o que o Spinnaker faz nos bastidores, portanto, se você usá-lo, não precisará se preocupar com isso.
Gus
32

A melhor maneira que encontrei de fazer isso é correndo Reloader

Ele permite que você defina configmaps ou segredos para observar, quando eles são atualizados, uma atualização contínua de sua implantação é realizada. Aqui está um exemplo:

Você tem uma implantação fooe um ConfigMap chamado foo-configmap. Você deseja lançar os pods da implantação sempre que o configmap for alterado. Você precisa executar o Reloader com:

kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

Em seguida, especifique esta anotação em sua implantação:

kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap"
  name: foo
...
George Miller
fonte
Reloader é compatível com kubernetes> = 1,9
jacktrade de
31

https://github.com/kubernetes/helm/blob/master/docs/charts_tips_and_tricks.md#user-content-automatically-roll-deployments-when-configmaps-or-secrets-change

Freqüentemente, configmaps ou segredos são injetados como arquivos de configuração em contêineres. Dependendo do aplicativo, uma reinicialização pode ser necessária caso sejam atualizados com um subsequente helm upgrade, mas se a própria especificação de implantação não mudou, o aplicativo continua em execução com a configuração antiga, resultando em uma implantação inconsistente.

A sha256sumfunção pode ser usada junto com a includefunção para garantir que uma seção de modelo de implantação seja atualizada se outra especificação for alterada:

kind: Deployment
spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
[...]

No meu caso, por alguns motivos, $.Template.BasePathnão funcionou, mas $.Chart.Namefunciona:

spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: admin-app
      annotations:
        checksum/config: {{ include (print $.Chart.Name "/templates/" $.Chart.Name "-configmap.yaml") . | sha256sum }}
quanta
fonte
8
Não aplicável ao uso geral do Kubernetes, aplicável apenas ao Helm
Emii Khaos de
2
A resposta é útil, mas provavelmente não é relevante para esta pergunta
Anand Singh Kunwar
helm3 foi lançado recentemente. Portanto, o link está desatualizado. Ele aponta para um masterramo. O URL a seguir levará aos helm2 documentos (atualmente) mais recentes : github.com/helm/helm/blob/release-2.16/docs/…
Marcel Hoyer
Solução legal. Mudei para sha1sum, pois no meu caso sha256sum tinha 65 caracteres que resultaram em Deployment.apps "xxx" is invalid: metadata.labels: Invalid value: "xxx": must be no more than 63 characters. A alternativa seria | trunc 63, mas sha1sum deve ser "mais exclusivo".
iptizer
11

Você pode atualizar um rótulo de metadados que não seja relevante para sua implantação. isso irá desencadear uma atualização contínua

por exemplo:

metadata:
  labels:
    configmap-version: 1
Maoz Zadok
fonte
Estou procurando documentos sobre metadados: labels: configmap-version: 1
c4f4t0r
7
alterações no rótulo de metadados não acionam a reinicialização dos pods
dan carter
Esta resposta tem upwotes, então preciso perguntar. Se atualizarmos os metadados, o cluster do Kubernetes acionará uma atualização contínua? @ maoz-zadok
titus
1
Acredito que isso funcione contanto que o rótulo de metadados esteja abaixotemplate.spec
Saikiran Yerram
1

Tive esse problema onde a implantação estava em um subgráfico e os valores que a controlavam estavam no arquivo de valores do gráfico pai. Isso é o que usamos para acionar o reinício:

spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ tpl (toYaml .Values) . | sha256sum }}

Obviamente, isso irá disparar o reinício em qualquer alteração de valor, mas funciona para nossa situação. O que estava originalmente no gráfico filho só funcionaria se o config.yaml no gráfico filho mudasse:

    checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
Bryji
fonte
0

Eu faço a solução de quanta "se funciona perfeitamente. Mas o que eu não entendo é que o pod na verdade não está reiniciando ... O pod continua o mesmo, mas a mudança está aí!

Por exemplo: O pod está rodando há 50min e eu mudo algo e a mudança está online posso ver no meu navegador e o pod ainda está rodando + 50min !! Estou usando o Helm3 ... Você sabe o que torna isso possível sem reiniciar a atualização do configmap?

Ibrahim Yesilay
fonte
1
Está bem! Eu descobri ... Porque montamos nosso configmap como um volume e atualizamos dinamicamente ... É por isso que quando eu faço essa "'soma de verificação' ', meu pod não reinicia, mas as mudanças estão lá! Eu sugiro como um boa solução :)
Ibrahim Yesilay
-1

Outra maneira é colocá-lo na seção de comando da implantação:

...
command: [ "echo", "
  option = value\n
  other_option = value\n
" ]
...

Alternativamente, para torná-lo mais parecido com o do ConfigMap, use uma implantação adicional que hospedará apenas essa configuração na commandseção e executará kubectl createenquanto adiciona uma 'versão' exclusiva ao seu nome (como calcular um hash do conteúdo) e modificar todos os implantações que usam essa configuração:

...
command: [ "/usr/sbin/kubectl-apply-config.sh", "
  option = value\n
  other_option = value\n
" ]
...

Provavelmente irei postar kubectl-apply-config.shse acabar funcionando.

(não faça isso; parece muito ruim)

Velkan
fonte