Kubernetes: Reinicialização contínua de pods

Criado em 2 set. 2015  ·  108Comentários  ·  Fonte: kubernetes/kubernetes

kubectl rolling-update é útil para implantar incrementalmente um novo controlador de replicação. Mas se você tiver um controlador de replicação existente e quiser fazer uma reinicialização contínua de todos os pods que ele gerencia, será forçado a fazer uma atualização autônoma para um RC com um novo nome e a mesma especificação. Seria útil poder fazer uma reinicialização contínua sem precisar alterar o RC ou fornecer a especificação RC, então qualquer pessoa com acesso a kubectl poderia iniciar facilmente uma reinicialização sem se preocupar em ter a especificação local, certificando-se de que seja a mesma / atualizado, etc. Isso pode funcionar de algumas maneiras diferentes:

  1. Um novo comando, kubectl rolling-restart que recebe um nome RC e exclui incrementalmente todos os pods controlados pelo RC e permite que o RC os recrie.
  2. O mesmo que 1, mas em vez de excluir cada pod, o comando itera por meio dos pods e emite algum tipo de comando "reiniciar" para cada pod incrementalmente (isso existe? Esse é um padrão que preferimos?). A vantagem desse aqui é que os pods não seriam rebalanceados desnecessariamente para outras máquinas.
  3. kubectl rolling-update com um sinalizador que permite especificar apenas um RC antigo e segue a lógica de 1 ou 2.
  4. kubectl rolling-update com um sinalizador que permite especificar apenas um RC antigo e gera automaticamente um novo RC com base no antigo e prossegue com a lógica de atualização contínua normal.

Todas as opções acima precisam das opções MaxSurge e MaxUnavailable recentemente introduzidas (consulte # 11942) junto com verificações de prontidão ao longo do caminho para garantir que a reinicialização seja feita sem derrubar todos os pods.

@nikhiljindal @ kubernetes / kubectl

areapp-lifecycle kinfeature lifecyclfrozen prioritbacklog siapps

Comentários muito úteis

OK, kubectl rollout restart fundiu!

Todos 108 comentários

cc @ironcladlou @ bgrant0607

Qual é o caso de uso para reiniciar os pods sem nenhuma alteração nas especificações?

Observe que não haverá nenhuma maneira de reverter a alteração se os pods começarem a falhar quando forem reiniciados.

Sempre que os serviços entrarem em algum estado bloqueado ou indesejável (conexões esgotadas e agora paralisadas, mau estado interno, etc.). Normalmente, é uma das primeiras etapas da solução de problemas se um serviço apresentar problemas graves.

Se o primeiro pod falhar ao ser reiniciado, espero que ele pare de continuar ou continue tentando iniciar o pod novamente.

Além disso, uma reinicialização contínua sem alteração nas especificações realoca os pods entre os
cacho.

No entanto, também gostaria de poder fazer isso sem reagendar o
vagens. Isso poderia ser uma mudança de rótulo rotativo, mas pode pegar uma nova dinâmica
configurar ou limpar o estado do arquivo local.

Na quarta-feira, 2 de setembro de 2015 às 12:01, Sam Ghods [email protected] escreveu:

Sempre que os serviços entrarem em algum estado bloqueado ou indesejável (limite máximo
conexões e agora estão travadas, mau estado interno, etc.). Geralmente é
uma das primeiras etapas de solução de problemas se o serviço for sério
comportando-se mal.

Se o primeiro pod falhar ao ser reiniciado, espero que ele pare
continuar ou continuar tentando iniciar o pod.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/kubernetes/kubernetes/issues/13488#issuecomment -136931790
.

Clayton Coleman | Engenheiro-chefe, OpenShift

@smarterclayton Essa é a minha opção 2 listada acima? Porém, por que os rótulos seriam alterados?

Ré. wedged: É para isso que servem as sondas de vivacidade.

Ré. rebalanceamento: ver # 12140

Se nós suportássemos isso, eu agruparia com # 9043 - o mesmo mecanismo é necessário.

Suponho que isso seja mais para uma situação em que o pod está ativo e respondendo a verificações, mas ainda precisa ser reiniciado. Um exemplo é um serviço com um cache na memória ou estado interno que é corrompido e precisa ser limpo.

Acho que pedir a reinicialização de um aplicativo é um caso de uso bastante comum, mas talvez eu esteja incorreto.

A corrupção seria apenas um pod, que poderia ser eliminado e substituído pelo RC.

O outro caso mencionado offline foi para reler a configuração. É perigoso fazer isso implicitamente, porque reinicializações por qualquer motivo fariam com que os contêineres carregassem a nova configuração. Seria melhor fazer uma atualização contínua para enviar uma nova referência de configuração com versão (por exemplo, em um env var) para os pods. Isso é semelhante ao que motivou # 1353.

@ bgrant0607 decidimos que não queremos fazer isso?

@gmarek Nada, por enquanto. Muitas coisas já estão em andamento.

Podemos ter um marco post v1.1 (ou algo assim) para as coisas que consideramos importantes, mas não temos pessoas para consertá-las imediatamente?

Eu também seria um fã desse recurso, você não quer ser forçado a trocar de tags a cada atualização menor que deseja lançar.

Sou fã desse recurso. Caso de uso: atualize facilmente todos os pods para usar uma imagem docker recém-enviada (com imagePullPolicy: Always ). Atualmente, uso um pouco de uma solução hacky: Rolling-update com ou sem a tag :latest no nome da imagem.

Outro caso de uso: Atualizando segredos.

Eu realmente gostaria de ver esse recurso. Executamos aplicativos de nó em kubernetes e, atualmente, temos certos casos de uso em que reiniciamos pods para limpar o pseudo-cache do aplicativo.

Aqui está o que estou fazendo agora:

kubectl get pod | grep 'pod-name' | cut -d " " -f1 - | xargs -n1 -P 10 kubectl delete pod

Isso exclui pods 10 por vez e funciona bem em uma configuração de controlador de replicação. Ele não aborda questões como alocação de pods ou falha no início de novos pods. É uma solução rápida quando necessário.

Eu realmente gostaria de poder fazer uma reinicialização contínua.
O principal motivo é que alimentaremos as variáveis ​​ENV nos pods usando o ConfigMap e, se alterarmos a configuração, precisaremos reiniciar os consumidores desse ConfigMap.

Sim, há muitos casos em que você realmente deseja reiniciar o pod / contêiner sem alterações internas ...
Configs, armazenar em cache, reconectar a serviços externos, etc. Eu realmente espero que o recurso seja desenvolvido.

Pequena solução alternativa (eu uso implantações e quero mudar as configurações sem ter mudanças reais na imagem / pod):

  • criar configMap
  • crie a implantação com a variável ENV (você vai usá-la como indicador para a sua implantação) em qualquer contêiner
  • atualizar configMap
  • atualização de implantação (altere esta variável ENV)

k8s verá que a definição da implantação foi alterada e iniciará o processo de substituição de pods
PS:
se alguem tiver melhor solução, por favor compartilhe

Obrigado @paunin

@paunin Esse é exatamente o caso em que precisamos atualmente - temos que alterar os valores do ConfigMap que são muito importantes para os serviços e precisam ser implementados nos contêineres em minutos até algumas horas. Se nenhuma implantação acontecer nesse meio tempo, os contêineres falharão todos ao mesmo tempo e teremos um tempo de inatividade parcial de pelo menos alguns segundos

from (kinda-related # 9043): uma linha de abordagem de RESTART_ é a variável de ambiente e está definida para um carimbo de data / hora ISO:

kubectl patch deployment mydeployment \
-p'{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"RESTART_","value":"$(date -uIseconds)"}]}]}}}}'

(observe que, por alguma razão, as variáveis ​​de ambiente começando com _ parecem simplesmente desaparecer, e env value s numérico causam erros, eles precisam ser strings)

@paunin @rcoup Fazemos algo muito semelhante hoje em dia, temos um env var literalmente chamado "DUMMY_VAR_FOR_NO_OP_DEPLOYMENT".

Parece que a solução certa aqui permitiria que você reiniciasse uma implantação e reutilizasse a maioria dos parâmetros de implantação para implantações como MinReadyCount, enquanto permite substituições de linha de comando, como aumentar o paralelismo para situações de emergência em que você precisa que tudo seja devolvido imediatamente.

algum progresso nisso?

Acho que essa adição é um inchaço desnecessário da API CLI. Isso pode ser facilmente alcançado atualizando os valores das variáveis ​​do ambiente de implementação, conforme sugerido por @paunin .

Também gostaríamos de ver isso para implantações como kubectl restart deployment some-api

O Kubernetes pode reiniciar pods por todos os motivos, mas o administrador do cluster não pode.
Eu entendo a posição moral de que 'desligar e ligar novamente' pode não ser uma forma desejada de operar ... mas também acho que não deveria haver problema em permitir que as pessoas que desejam reiniciar uma implantação sem recorrer ao intervalo de truques menos apetitosos como:

  • excluindo pods
  • rótulos fictícios
  • variáveis ​​de ambiente fictícias
  • mapas de configuração fictícios mapeados para a variável de ambiente
  • reinicializar os nós de trabalho
  • cortando a energia do data center 😄

'Não, não estou reiniciando nada, apenas corrigindo um erro de digitação neste rótulo aqui' 😛

Este recurso será útil em par com kubectl apply : apply atualizará as configurações, incluindo controladores de replicação, mas os pods não serão reiniciados.

Portanto, precisamos de um método para reiniciar esses pods de maneira azul-verde.

@DmitryRomanenko, que tal mudar de ReplicationControllers para Deployments? Isso permitirá que você execute atualizações de ReplicaSets (sucessor de ReplicationController).

@kargakis não é possível: as implantações atualizam apenas conjuntos de réplicas e pods.
Com kubectl apply , também atualizamos ConfigMaps, serviços, etc.

@DmitryRomanenko se o problema for "Eu quero reiniciar pods quando o ConfigMap / Secret for atualizado", a solução possível é ter versões para seu ConfigMap e Secrets e tornar essa versão parte de sua especificação de implantação. Portanto, com kubectl apply ing, a especificação de implantação é alterada e os pods são recriados.
Em outras situações, não vejo por que os pods devem ser reiniciados (quero dizer Service / Ingress / update etc).

@tyranron , obrigado! Qual é a melhor maneira de criar a versão ConfigMap s? Devo criar um novo mapa de configuração com um nome diferente para uma nova implantação?

@DmitryRomanenko você realmente pode, por que não? Mas, neste caso, você deve tomar cuidado ao remover os antigos. Por outro lado, pode ser útil para reversão. Mas na maioria dos casos, especificar a versão por meio de rótulos é o suficiente.

Eu acredito que a melhor solução aqui poderia ser algum tipo de observador ou verificador de soma hash no objeto configmap . O que deve acionar o reinício de objetos / pods relacionados (qualquer coisa usa aquele configmap , secret ). Não tenho certeza se é algo acessível na arquitetura k8s embora ...

Eu também acho que é melhor ter controle de configmap|secret object para acionar o reinício nas alterações ou não.

@tyranron ,

Portanto, com kubectl, a aplicação das especificações de implantação é alterada e os pods são recriados.

Você poderia explicar? Devo apenas usar kubectl apply -f new_config.yml com implantações atualizadas e essas implantações serão reiniciadas sem interrupção?

@DmitryRomanenko sim, exatamente.

@DmitryRomanenko com a aplicação de novas especificações, você está atualizando a implantação e, na atualização da implantação, a reinicialização é acionada se a especificação for alterada.

Por padrão, a estratégia de reinicialização é RollingUpdate , mas você também pode especificar outra explicitamente.

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.

Evite que os problemas sejam fechados automaticamente com um comentário /lifecycle frozen .

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

Uma pequena mudança na solução do @rcoup : certifique-se de que date seja avaliado dentro do shell:

kubectl patch deployment mydeployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"RESTART_","value":"'$(date +%s)'"}]}]}}}}'

/ remove-lifecycle stale
/ ciclo de vida congelado

Uso o modo Swarm há algum tempo, considerado menos flexível do que o Kubernetes, posso reiniciar tarefas de serviço (leia-se: pods de implantação), simplesmente fazendo uma atualização forçada (sem alteração nas especificações) como em docker service update --force <service-name> . Eu esperaria que o Kubernetes também fizesse isso.
Quanto aos configmaps e segredos, o swarm não permite que você os edite; em vez disso, você precisa girá-los. Você faz isso criando novos configmaps / segredos, atualizando as especificações de serviço para usar os novos e, em seguida, excluindo os mais antigos. Vejo que isso é normalmente o que é recomendado acima, criando versões de seus configmaps / secerts e atualizando as implantações que os usam. Para ser honesto, esse comportamento de rotação é uma das principais razões pela qual deixei o swarm! É muito inconveniente ter uma cópia local, atualizar e criar novos recursos e, finalmente, atualizar os recursos dependentes. Adicione a isso, segredos em swarm não podem ser lidos da api, você tem que montá-los dentro de qualquer contêiner (ou exec dentro de um contêiner que os usa), então cat seus arquivos.
Por falar no assunto, usei o openshift por algum tempo e acredito que ele reinicia automaticamente os pods em env / configmap / mudança secreta. Eu estou corrigido, no entanto.

deve ser responsabilidade do aplicativo observar as mudanças no sistema de arquivos, como mencionado, você pode usar somas de verificação no configmap / secret e forçar reinicializações dessa maneira

mas se você não quiser alterar a configuração e apenas reiniciar com uma pausa arbitrária, um pipeline simples faz o trabalho (este dorme 30 segundos entre o pod encerrado)

kubectl get po -l release=my-app -o name | cut -d"/" -f2 | while read p;do kubectl  delete po $p;sleep 30;done

Observe que se você pressionar ctrl + c, não é fácil reiniciar de onde você parou

@ so0k , comando alternativo:

kubectl get pods|grep somename|awk '{print $1}' | xargs -i sh -c 'kubectl delete pod -o name {} && sleep 4'

Dois anos e meio depois, as pessoas ainda estão criando novas soluções alternativas, com variáveis ​​de env fictícios, rótulos fictícios, arquivos secundários do ConfigMap e do inspetor secreto, dimensionamento para zero e scripts de shell de atualização direta para simular a capacidade de acionar uma atualização contínua. Isso ainda é algo que os administradores de cluster não deveriam ter permissão para fazer honestamente, sem os truques?

27081 # 33664 https://github.com/kubernetes/helm/issues/2639

https://stackoverflow.com/questions/41735829/update-a-deployment-image-in-kubernetes

kubectl scale --replicas=0 deployment application
kubectl scale --replicas=1 deployment application

https://stackoverflow.com/questions/40366192/kubernetes-how-to-make-deployment-to-update-image

Outro truque é executar inicialmente:

kubectl set image deployment/my-deployment mycontainer=myimage:latest

e então:

kubectl set image deployment/my-deployment mycontainer=myimage

Na verdade, ele acionará a atualização contínua, mas certifique-se de que também definiu imagePullPolicy: "Always".

outro truque que descobri, em que você não precisa alterar o nome da imagem, é alterar o valor de um campo que acionará uma atualização contínua, como terminationGracePeriodSeconds. Você pode fazer isso usando kubectl edit deployment your_deployment ou kubectl apply -f your_deployment.yaml ou usando um patch como este:

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'

http://rancher.com/docs/rancher/v1.4/en/cattle/upgrading/

# Force an upgrade even though the docker-compose.yml for the services didn't change
$ rancher-compose up --force-upgrade

@ so0k @KIVagant excluir pods significa tempo de inatividade, mesmo quando várias instâncias são executadas. Quando alguém executa um único pod com strategy.rollingUpdate.maxUnavailable = 0 uma implantação regular primeiro cria um novo pod antes de encerrar o existente. O truque kubectl patch deployment dispara esse comportamento, mas a exclusão de pods não. Eu realmente gostaria de uma maneira não hacky de acionar esse comportamento sob demanda.

Por exemplo, ao executar imagens de hub.docker.com, a mesma tag pode ser corrigida para atualizações de segurança. Eu realmente gostaria de "obter as imagens mais recentes" e realizar uma atualização contínua para qualquer imagem desatualizada.

O lançamento das atualizações do ConfigMap / Secret é # 22368
O lançamento mais fácil de novas imagens é # 1697
As atualizações contínuas no local são # 9043

Reinicie nas compilações de imagem: https://github.com/GoogleCloudPlatform/freshpod
Apresentação do Helm Summit de um truque usando um modelo de anotação para acionar lançamentos de implantação: https://www.youtube.com/watch?v=dSw0w1x96ak

@ bgrant0607 Acho que o caso de uso importante que não é coberto por outros tíquetes é este: https://github.com/kubernetes/kubernetes/issues/13488#issuecomment -136946912

@ghodss escreveu:
Suponho que isso seja mais para uma situação em que o pod está ativo e respondendo a verificações, mas ainda precisa ser reiniciado. Um exemplo é um serviço com um cache na memória ou estado interno que é corrompido e precisa ser limpo.

Acho que pedir a reinicialização de um aplicativo é um caso de uso bastante comum, mas talvez eu esteja incorreto.

Eu gostaria de forçar uma reinicialização contínua para limpar todo o estado do aplicativo sem truques manuais.

Eu tenho uma linha semelhante baseada na abordagem que @rcoup e @paunin descreveram, mas deve funcionar para o caso mais geral. Ele depende da saída JSON e usa jq para análise. Eu carreguei isso no meu bashrc como uma função, então posso chamá-lo de qualquer lugar

kubectl-restart() {
  kubectl get deploy $1 -o json | jq \
    'del(
      .spec.template.spec.containers[0].env[]
      | select(.name == "RESTART_"))
    | .spec.template.spec.containers[0].env += [{name: "RESTART_", value: now|tostring}]' | kubectl apply -f -
}

Isso me permite apenas dizer: kubectl-restart my-deployment-name e ele "atualizará" o RESTART_ env var no primeiro contêiner para o carimbo de data / hora atual. Estou longe de ser um especialista em jq, então pode haver uma maneira melhor de fazê-lo, mas basicamente ele exclui o antigo RESTART_ env var da saída (se existir) e o adiciona de volta com o hora atual.

Parece muito estranho para mim que não haja uma maneira nativa de fazer isso ... Certamente uma sala cheia de engenheiros concordaria que a capacidade de "desligar e ligar novamente" é algo que gostaríamos de ter.

Esse é um bom hack e tudo, mas tem uma grande desvantagem. Na próxima vez que você implantar, usando kubectl apply -f , esse componente será reiniciado se tiver um RESTART_xxx env var, mesmo que nada mais mude. Em outras palavras, ele causa reinicializações espúrias na próxima implantação, se já tiver sido reiniciado entre a última implantação e esta implantação. Não é ideal...

É por isso que a funcionalidade de reinicialização contínua deve ser incorporada ao controlador de implantação, e não incorporada.

Eu escrevi uma função bash para realizar a estratégia de "implantação de patch de terminationGracePeriodSeconds " @whereisaaron citado em seu comentário acima (fonte: https://stackoverflow.com/a/40368520/90442).

# $1 is a valid namespace
function refresh-all-pods() {
  echo
  DEPLOYMENT_LIST=$(kubectl -n $1 get deployment -o json|jq -r .items[].metadata.name)
  echo "Refreshing pods in all Deployments"
  for deployment_name in $DEPLOYMENT_LIST ; do
    TERMINATION_GRACE_PERIOD_SECONDS=$(kubectl -n $1 get deployment "$deployment_name" -o json|jq .spec.template.spec.terminationGracePeriodSeconds)
    if [ "$TERMINATION_GRACE_PERIOD_SECONDS" -eq 30 ]; then
      TERMINATION_GRACE_PERIOD_SECONDS='31'
    else
      TERMINATION_GRACE_PERIOD_SECONDS='30'
    fi
    patch_string="{\"spec\":{\"template\":{\"spec\":{\"terminationGracePeriodSeconds\":$TERMINATION_GRACE_PERIOD_SECONDS}}}}"
    kubectl -n $1 patch deployment $deployment_name -p $patch_string
  done
  echo
}

Comente / atualize-o por meio da essência aqui . Vou repetir os comentários de outros de que seria melhor se isso não fosse necessário.

Apenas por meio de uma justificativa mais especificamente relacionada ao kube, reiniciar também permite a reexecução de um contêiner init, que pode ser usado para rolar chaves, atualizar a configuração ou qualquer outra coisa para a qual você use contêineres init.

@ kubernetes / sig-apps-feature-requests @ kow3ns @janetkuo

@gjcarneiro Você tinha um RESTART_xxx env var na configuração que aplicou, ou não? Caso contrário, esperaria que o apply ignore o env var extra no estado ativo.

cc @apelisse

@gjcarneiro Sim, o problema com o script @mattdodge é que ele está usando aplicar, então a alteração será salva na anotação lastApplied. O script pode ser corrigido usando patch ou outro método para atualizar a implantação.

Adoraria ter esse recurso. Parece muito básico e necessário.

Nenhum progresso aqui nem em # 22368, le suspiro :-(

Alguém pode recomendar uma solução rápida e suja para reiniciar um DaemonSet após o ConfigMap montado ter sido atualizado (o nome ainda é idêntico)?

Obrigado pela dica :-)

O Openshift tem o conceito de gatilhos de implantação, que acionam um lançamento na mudança de imagem, webhook ou mudança de configuração. Seria muito bom ter um recurso no Kubernetes. Bem como lançamentos manuais, é claro.

Além disso, o repositório Docker tem um histórico, então não há razão para que o rollback não funcione - o pod gerado a partir de .spec.template pode usar o formato image-tag:@digest ao puxar imagens para contêineres. A reversão usaria o ID de resumo da implementação anterior.

Não tenho certeza se estou entendendo corretamente. Apenas no caso de ajudar alguém.

Parece que se você atualizar o valor de um rótulo em pod> modelo> metadados, uma atualização contínua ocorrerá depois de kubectl apply -f file.yaml

Assim, você sempre pode ter um rótulo para sua versão e sempre que quiser fazer uma atualização contínua, altere a versão e aplique o arquivo.

Claro, a desvantagem é que da próxima vez que você quiser fazer uma implantação, você faz kubectl apply -f some.yaml , certo? Normalmente, se nada mudar em some.yaml , nada será reiniciado, essa é uma das coisas mais legais do Kubernetes.

Mas imagine o que acontece depois que você altera um rótulo para reiniciar uma implantação. Na próxima implantação normal de software, você faz kubectl apply -f some.yaml como de costume, mas como o arquivo yaml não contém o mesmo rótulo, a implantação será reiniciada desnecessariamente.

@gjcarneiro Se você não fizer apply quando fizer uma alteração, a anotação kubectl.kubernetes.io/last-applied-configuration não será atualizada, então o próximo apply não causará outro reinício.

Sou fortemente a favor de adicionar um comando de reinicialização contínua ao kubectl, mas enquanto isso estou usando o seguinte (com base nas soluções acima):

kubectl patch deployment mydeployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"RESTART_","value":"'$(date +%s)'"}]}]}}}}'

Parametrize isso e adicione-o como uma função em seu .bashrc e é uma boa solução provisória.

Ah, legal, eu não sabia disso, obrigado!

Não preciso do alias bash, na minha empresa fizemos minha própria interface web para gerenciar Kubernetes usando Python + aiohttp e já usa patch. Eu pensei em abrir o código, apenas fui preguiçoso ...

Parece que as pessoas estão repetindo as mesmas soluções alternativas neste tópico - por favor, leia o tópico completo antes de postar aqui

@joelittlejohn Eu executei sua macro e ela DID

@Macmee Depende da configuração de sua implantação. O comando acima apenas altera a implantação. Os pods são então atualizados de acordo com a implementação strategy definida por sua implantação. Isso é como qualquer outra alteração na implantação.

A única maneira de substituir todos os pods ao mesmo tempo é se seu .spec.strategy.rollingUpdate.maxUnavailable permitir.

Também precisamos desse recurso. Um caso de uso também do nosso lado é que usamos spring-cloud-config-server apoiado por e scm, para nosso aplicativo spring-boot. Quando alteramos uma propriedade de configuração, o aplicativo spring-boot precisa ser reiniciado para poder buscar a nova alteração de configuração, portanto, também precisamos desse tipo de gatilho de reinicialização normal sem ter que fazer uma reimplantação.

@japzio Conforme sugerido por Helm , uma soma de verificação do configmap nas anotações é uma boa maneira de lidar com esse caso.

Houve alguma atualização sobre isso? Queremos ter esse recurso também. @ bgrant0607 @nikhiljindal

@ bholagabbar-mt Qual é o seu caso de uso?

cc @ kow3ns @janetkuo

@ bgrant0607 @ kow3ns @janetkuo O caso de uso de nossos sistemas é multifacetado.

  1. Atualização de segredos - tenho certeza de que você percebeu que existem muitas empresas como a minha, que criaram suas próprias abstrações sobre o kubernetes. Temos nosso próprio sistema de gerenciamento de contêineres orquestrado por kubernetes. Portanto, o comentário de sugestão de segredo do

  2. Isso é um pouco complicado, mas o escopo geral, como alguém sugeriu, é corrigir o comportamento anormal. Temos de 4 a 5 aplicativos Java pesados ​​em execução no framework Play. Estamos encontrando uma situação em que o consumo de memória de nossos pods java aumenta linearmente e, em seguida, reinicia os pods quando o limite de memória é atingido. Este é um problema Java documentado com um problema de stackoverflow e um Kubernetes associado a ele. A reinicialização contínua de todos os pods em um período de 3 a 4 horas redefiniria o consumo de memória e permitiria que nossos aplicativos funcionassem sem problemas, sem picos.

Esperançosamente, isso foi convincente o suficiente e esse recurso pode ser usado por alguém para desenvolvimento.

@ bholagabbar-mt apenas altere uma variável de ambiente e isso acionará uma implantação contínua:

kubectl patch deployment mydeployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"LAST_MANUAL_RESTART","value":"'$(date +%s)'"}]}]}}}}'

@montanaflynn Isso é perfeito. Integramos essa mudança em nossos próprios sistemas hoje e ela funciona bem. Muito obrigado!

cc @huzhengchuan

Outro caso de uso para isso: devido a um problema de segurança no containerd, gostaria de reiniciar todos os pods. https://seclists.org/oss-sec/2019/q1/119 O cluster fica completamente inativo ou faz uma reinicialização contínua. Ter um comando de reinicialização faria uma grande diferença!

atualização , solução alternativa:

kubectl set env --all deployment --env="LAST_MANUAL_RESTART=$(date +%s)" --namespace=...
kubectl set env --all daemonset --env="LAST_MANUAL_RESTART=$(date +%s)" --namespace=...

@realfresh vocês são as melhores práticas. adicione annotation:{creatTime: 12312312} em rancheiro!

kubectl set env deployment mydeployment --env="LAST_RESTART=$(date)" --namespace ...

parece ser um comando mínimo que faz o trabalho para uma implantação. É um exemplo de uso de configuração imperativa.

cc @monopole @apelisse

~ Dois ~ Três anos e meio depois, e as pessoas ainda estão criando novas soluções alternativas, com variáveis ​​de env fictícios, rótulos fictícios ,

As atualizações contínuas ainda são uma atividade bastante popular para algo aparentemente sem caso de uso 😄

problema de longo prazo (nota para mim)

  1. Não vejo uma maneira de fazer isso sem permitir que a lógica imperativa se transforme em uma API declarativa, quebrando assim nossa convenção de manter as APIs declarativas e implementar o comportamento imperativo nos controladores, e introduzindo incompatibilidades com a maioria das práticas de CI / CD.
  2. Eu poderia imaginar uma API RollingRestart e um controlador em que a criação de um recurso RollingRestart fizesse com que o controlador reiniciasse os pods 1 por 1 por meio de despejo (respeitando assim os orçamentos de interrupção), mas tal controlador poderia ser implementado como um CRD (ou seja, vejo o motivo pelo qual temos que fazer isso na árvore).
  3. A abordagem declarativa, por exemplo, adicionar uma anotação lastRestartedAt = TIMESTAMP não parece um hack para mim.
  4. Se alguém quiser oferecer um design declarativo e uma contribuição para implementar esse recurso (em árvore ou de outra forma), considere a criação de um PR KEP em relação ao repo de aprimoramentos . Se uma implementação declarativa e integrada puder ser projetada, eu ficaria feliz em revisar / acompanhar as APIs de cargas de trabalho. Se um controlador CRD como [2] for oferecido, poderíamos patrociná-lo no SIG Apps como uma extensão patrocinada pela comunidade.

A abordagem declarativa, por exemplo, adicionar uma anotação lastRestartedAt = TIMESTAMP não parece um hack para mim.

Não é um hack, deve haver apenas uma linha de comando abreviada para ele.

Alguém poderia construir um plugin do krew que envia o patch. kubectl restart-deployment <deployment_name> ?

kubectl rollout restart que corrige um deployment / daemonset / statefulset para acionar um novo 'lançamento'?

Isso está de acordo com a abordagem de @ kow3ns (3) e faz algum sentido, já que você pode assistir / pausar / retomar a implementação que acabou de iniciar com os outros comandos kubectl rollout .

@whereisaaron vou ver se posso enviar um patch para isso (trocadilho não intencional)

Para lançar novos segredos e configmaps, minha recomendação ainda é # 22368: crie novos. Isso fornece um meio para controlar a implementação e também reverter. Precisamos apenas terminar o GC de objetos antigos:
https://github.com/kubernetes/community/pull/1163
https://github.com/kubernetes/community/pull/2287

No entanto, documentar e / ou oferecer suporte (em kustomize, kubectl ou um plug-in kubectl) a maneira recomendada de fazer uma reinicialização contínua com a API existente é razoável.

cc @monopole

Quanto a novas imagens, CI / CD ou um controlador que resolve tags para digerir: # 1697.

A movimentação de pods infelizes deveria ser realizada pelo descheduler (https://github.com/kubernetes-incubator/descheduler) ou algo parecido, que poderia consumir o status do contêiner, métricas principais e até métricas personalizadas:

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/rescheduler.md
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/rescheduling.md

Além disso, a documentação oficial sobre como lidar com segredos e configmap: https://kubectl.docs.kubernetes.io/pages/app_management/secrets_and_configmaps.html

A reinicialização contínua é muito necessária. Um exemplo é que obtemos todos os segredos do SSM da AWS. Se alterarmos algum segredo do SSM, gostaríamos de fazer uma reinicialização contínua para que os pods agora selecionem o mais recente quando inicializarem. Além disso, algumas vezes há problemas de aplicativo que precisam ser reiniciados continuamente até que a correção real chegue à produção.

OK, kubectl rollout restart fundiu!

É ótimo ouvir isso depois de quase 4 anos, obrigado!

Acredito que o PR mesclado oferece suporte apenas a implantações, correto?

Algumas pessoas nesta edição expressaram a necessidade de reiniciar daemonsets e statefulsets também.

@apelisse existe também uma maneira de fazer isso via sdk ou apenas kubectl?

@ e-nikolov O que é SDK?

Eu quis dizer o cliente Go que pode ser usado para conversar com kubernetes a partir de programas Go.

Não, você teria que reimplementar a lógica (muito simples) que é implementada em kubectl.

OK, a reinicialização do rollout do kubectl foi mesclada!

Que versão kubectl terá?

Qual versão do kubectl terá?

Kubernetes 1.15

Nosso cluster GKE no canal de lançamento "rápido" foi atualizado para o Kubernetes 1.16 e agora kubectl rollout restart parou de funcionar:

kubectl rollout restart implantação myapp
erro: comando desconhecido "reiniciar implantação myapp"

@nikhiljindal perguntou há algum tempo sobre o caso de uso para atualizar as implantações sem nenhuma alteração nas especificações. Talvez estejamos fazendo isso de uma maneira não ideal, mas aqui está: nossos modelos de ML pré-treinados são carregados na memória a partir do Google Cloud Storage. Quando os arquivos de modelo são atualizados no GCS, queremos reiniciar nossa implantação K8S, que extrai os modelos do GCS.

Agradeço que não possamos reverter a implantação com arquivos de modelo anteriores facilmente, mas essa é a compensação que adotamos para trazer os modelos o mais próximo possível do aplicativo e evitar uma chamada de rede (como alguns podem sugerir).

hey @dimileeh

Você sabe qual versão do kubectl está usando agora? e qual versão você usou antes? Adoraria saber se houve uma regressão, mas ao mesmo tempo ficaria surpreso se a feição tivesse desaparecido totalmente.

Com relação ao GCS, e sabendo muito pouco sobre seu caso de uso, desculpe se não fizer sentido: eu sugeriria que o modelo gcs receba um nome diferente toda vez que for modificado (talvez o sufixo com seu hash), e que o nome seria incluído na implantação. Atualizar a implantação para usar os novos arquivos acionaria automaticamente uma distribuição. Isso dá a você a capacidade de reverter para uma implantação / modelo anterior, ter um melhor entendimento das mudanças que acontecem nos modelos, etc.

oi @apelisse , obrigado pela sua resposta!

Quando executo kubectl version no Terminal do Google Cloud, obtenho o seguinte:

Client Version: version.Info{Major:"1", Minor:"13+", GitVersion:"v1.13.11-dispatcher", GitCommit:"2e298c7e992f83f47af60cf4830b11c7370f6668", GitTreeState:"clean", BuildDate:"2019-09-19T22:20:12Z", GoVersion:"go1.11.13", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.0-gke.20", GitCommit:"d324c1db214acfc1ff3d543767f33feab3f4dcaa", GitTreeState:"clean", BuildDate:"2019-11-26T20:51:21Z", GoVersion:"go1.12.11b4", Compiler:"gc", Platform:"linux/amd64"}

Quando tentei atualizar o kubectl via gcloud components update , ele disse que já estou usando as versões mais recentes de todos os produtos. Portanto, acho que minha versão do kubectl permaneceu a mesma enquanto o cluster K8S foi atualizado de 1.15 para 1.16.

A documentação 1.17, 1.16 e 1.15 do Kubenetes não tem nada sobre o recurso kubectl rollout restart . Então, eu me pergunto se sua valiosa contribuição poderia ter desaparecido de 1.16?


Obrigado por sua sugestão sobre a versão do modelo, faz todo o sentido. Pensamos nisso, mas, como treinamos nossos modelos todos os dias, pensamos que começaríamos a acumular muitos modelos (e eles são bem pesados). Claro, poderíamos usar algum script para limpar versões antigas depois de algum tempo, mas até agora decidimos mantê-lo simples, contando com kubectl rollout restart e não nos importando com o controle de versão do modelo :)

Muito obrigado por esse link, vou garantir que ele seja atualizado!

Na quinta-feira, 19 de dezembro de 2019 às 12h40 Dmitri Lihhatsov [email protected]
escreveu:

Ah, obrigado, eu estava olhando aqui:
https://v1-16.docs.kubernetes.io/docs/reference/kubectl/cheatsheet/

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kubernetes/kubernetes/issues/13488?email_source=notifications&email_token=AAOXDLCDSTPYK6EGBQWSRADQZPL5BA5CNFSM4BOYZ5Z2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHK3ZSA#issuecomment-567655624 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/AAOXDLHWCU4T6NCSHOYZIELQZPL5BANCNFSM4BOYZ5ZQ
.

@dimileeh PTAL https://github.com/kubernetes/website/pull/18224 (selecionarei os branches relevantes assim que for mesclado).

@dimileeh Acho que descobri o que há de errado com sua versão do kubectl, estaremos trabalhando nisso.

Sim, também temos o caso de uso de reiniciar o pod sem alteração do código, após a atualização do configmap. Isso é para atualizar um modelo de ML sem reimplantar o serviço.

@anuragtr com as versões mais recentes que você pode executar

kubectl rollout restart deploy NAME

Eu estava usando um comando personalizado para isso [1], que bom que agora está no kubectl padrão! Obrigado

[1] https://github.com/mauri870/kubectl-renew

@anuragtr com as versões mais recentes que você pode executar

kubectl rollout restart deploy NAME

@countrogue

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