Como forço o Kubernetes a puxar novamente uma imagem?

161

Eu tenho o seguinte controlador de replicação no Kubernetes no GKE:

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    app: myapp
    deployment: initial
  template:
    metadata:
      labels:
        app: myapp
        deployment: initial
    spec:
      containers:
      - name: myapp
        image: myregistry.com/myapp:5c3dda6b
        ports:
        - containerPort: 80
      imagePullPolicy: Always
      imagePullSecrets:
        - name: myregistry.com-registry-key

Agora, se eu disser

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b

a atualização sem interrupção é executada, mas não é necessário repetir. Por quê?

Torsten Bronger
fonte
12
Eu dei uma imagem diferente, apenas com a mesma tag. Se for necessário dar uma tag diferente, bem, não vejo sentido no imagePullPolicycampo.
Torsten Bronger
4
Eu quero usar uma tag específica, mas sua versão mais recente.
Torsten Bronger
3
@ TorstenBronger Acho que essa é uma mudança radical na teoria de Kubernetes / Docker. A idéia de que você poderia puxar a imagem: tag (diferente da mais recente) em dois momentos diferentes e obter duas imagens diferentes seria problemática. Uma tag é semelhante a um número de versão. Seria uma prática recomendada sempre alterar a tag quando a imagem mudar.
duct_tape_coder
2
Depende. Há software com uma API muito estável, mas atualizações de segurança. Então, quero a versão mais recente sem precisar dizer isso explicitamente.
Torsten Bronger 13/03/19
1
@TorstenBronger Em relação ao uso latest, não faça isso. O mais recente puxará a imagem, bem, mais recentemente, com a tag mais recente. O que você quer é uma linha SemVer. ~ 1.2.3 por exemplo. isso puxará imagens com tags entre o intervalo de> = 1.2.3 e <1.3.0. Desde que o fornecedor da imagem siga o SemVer, você sabe (e essa é a parte importante) que nenhuma alteração reversa foi adicionada (de propósito) e que nenhum novo recurso foi adicionado (possível preocupação com a segurança). Por favor, nunca use latestem sistemas de produção.
David J Eddy

Respostas:

141

O Kubernetes utilizará a criação do Pod, se houver (consulte o documento de atualização de imagens ):

  • Usando imagens marcadas :latest
  • imagePullPolicy: Always é especificado

Isso é ótimo se você quiser puxar sempre. Mas e se você quiser fazê-lo sob demanda : por exemplo, se você deseja usar, some-public-image:latestmas deseja extrair manualmente uma versão mais nova quando solicitada. Você pode atualmente:

  • Defina imagePullPolicycomo IfNotPresentou Nevere pré-puxe : puxe manualmente imagens em cada nó do cluster para que o último seja armazenado em cache e faça um kubectl rolling-updateou semelhante para reiniciar os Pods (hack fácil e feio!)
  • Altere temporariamenteimagePullPolicy , faça a kubectl apply, reinicie o pod (por exemplo kubectl rolling-update), reverta imagePullPolicy, refaça a kubectl apply(feio!)
  • Puxe e empurre some-public-image:latest para o seu repositório privado e faça um kubectl rolling-update(pesado!)

Não é uma boa solução para puxar sob demanda. Se isso mudar, comente; Vou atualizar esta resposta.

Wernight
fonte
Você diz que o kubernetes ativará a criação do Pod ao usar :latest- e quanto patch? também puxa sempre a imagem mais recente / mais recente? Parece não funcionar para mim :(
pkyeck 26/10
Depende se o seu patch força a recriação de um Pod ou não. Provavelmente não, então não será puxado novamente. Você pode matar o Pod manualmente ou marcar com algo exclusivo e corrigir com essa tag atualizada.
Wernight 14/11/16
Esta é uma resposta para uma pergunta diferente. Eu pedi forçar uma re-pull.
Torsten Bronger 02/12/19
Isso me permitiu forçar uma nova atração do GCR. Eu tinha uma :latestetiqueta que apontava para uma nova imagem e kubectl rolling-updatetrabalhava para atualizar os pods.
Randy L
Obrigado. Fui para a abordagem Pull & Push. Automatizado o máximo possível com scripts bash, mas concordou, é pesado :)
arcseldon 31/03
77

É necessário agrupar imagePullPolicydentro dos dados do contêiner em vez de dentro dos dados de especificação. No entanto, arquivei um problema sobre isso porque acho estranho. Além disso, não há mensagem de erro.

Portanto, este trecho de especificação funciona:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key
Torsten Bronger
fonte
3
imagePullPolicy(ou marcação :latest) é bom se você deseja sempre puxar, mas não resolve a questão de puxar sob demanda.
Wernight 11/03/16
1
Sim, eu quero sempre puxar, como indicado na pergunta.
Torsten Bronger
1
O uso imagePullPolicy: Alwaysdentro da definição de contêiner terá kubernetesimagens com tags marcadas :latestsempre que uma versão mais recente delas for enviada para o registro?
precisa saber é o seguinte
1
O @pkaramol No. imagePullPolicy: Alwayssimplesmente diz ao Kubernetes para sempre puxar a imagem do registro. Que imagem será configurada por imageatributo. Se você configurá-lo para image: your-image:latest, sempre puxará a your-imageimagem com a latesttag.
Gajus
26

Meu hack durante o desenvolvimento é alterar meu manifesto de implantação para adicionar a tag mais recente e sempre puxar assim

image: etoews/my-image:latest
imagePullPolicy: Always

Então eu apago o pod manualmente

kubectl delete pod my-app-3498980157-2zxhd

Por ser uma implantação, o Kubernetes recriará automaticamente o pod e exibirá a imagem mais recente.

Everett Toews
fonte
Gosto de aproveitar as premissas do "estado desejado" do objeto "deployment" ... obrigado pela sugestão!
Marcello de Sales
2
Vale a pena notar que a estratégia é viável somente se falhas no serviço e tempo de inatividade forem toleráveis. Para o desenvolvimento, parece razoável, mas eu nunca levaria essa estratégia para uma implantação de produção.
digitaldreamer
Edite a implantação, alterando sempre o imagePullPolicy e excluir o pod foi suficiente para mim, como sugeriu Everett. Este é um ambiente de desenvolvimento. kubernetes.io/docs/concepts/containers/images
Jos Roberto Almaraz
17

Uma solução popular é corrigir a implantação com uma anotação fictícia (ou rótulo):

kubectl patch deployment <name> -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

Supondo que sua implantação atenda a esses requisitos , isso fará com que os K8s obtenham qualquer nova imagem e reimplemente.

Tamlyn
fonte
2
Sim, eu uso uma anotação para isso.
Torsten Bronger 21/03/19
que anotação?
precisa
1
Outra solução sofisticada seria uma combinação de ambos, ie. adicionando uma anotação e definindo ImagePullPolicycomo Sempre . anotações gostam deployment.kubernetes.io/revision: "v-someversion"e kubernetes.io/change-cause: the reasonpodem ser bastante úteis e seguem para implantações imutáveis.
22419 chandan
16

Haverá um novo comando para fazer isso diretamente:

Crie um novo kubectl rollout restartcomando que faça uma reinicialização contínua de uma implantação.

A solicitação de recebimento foi mesclada. Será parte da versão 1.15( changelog )

S.Spieker
fonte
Sim, parte do problema: github.com/kubernetes/kubernetes/issues/13488
Tilo
Sim, esta é a melhor maneira de acionar a atualização na nova versão do kubernetes da 1.15.
Dolphin
7

Aparentemente, agora, quando você executa uma atualização sem interrupção com o --imageargumento igual à imagem do contêiner existente, também deve especificar um --image-pull-policy. O comando a seguir deve forçar a atração da imagem quando ela é igual à imagem do contêiner:

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b --image-pull-policy Always

sjking
fonte
6
# Linux

kubectl patch deployment <name> -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

# windows

kubectl patch deployment <name> -p (-join("{\""spec\"":{\""template\"":{\""metadata\"":{\""annotations\"":{\""date\"":\""" , $(Get-Date -Format o).replace(':','-').replace('+','_') , "\""}}}}}"))
Bar Nuri
fonte
3

Agora, o comando kubectl rollout restart deploy YOUR-DEPLOYMENTcombinado com uma imagePullPolicy: Alwayspolítica permitirá que você reinicie todos os seus pods com uma versão mais recente da sua imagem.

Orabîg
fonte
3

O comando rolling update, quando recebe um argumento de imagem, assume que a imagem é diferente da que existe atualmente no controlador de replicação.

Robert Bailey
fonte
Isso significa que a tag da imagem (também conhecida como nome) deve ser diferente?
Torsten Bronger 14/10/2015
Sim, o nome da imagem deve ser diferente se você passar a --imagebandeira.
Robert Bailey
1
Como minha própria resposta diz, funciona também se o nome da imagem for o mesmo. Simplesmente a imagePullPolicy estava no lugar errado. Para minha defesa, os documentos do k8s 1.0 são errôneos nesse aspecto.
Torsten Bronger
É preciso amar quando os documentos estão fora de sincronia com o comportamento. : /
Robert Bailey
1
Esse URL também está desatualizado.
Dan Tenenbaum
2

Você pode definir imagePullPolicy: Alwaysno seu arquivo de implantação.

Sachin Arote
fonte
0

A política de recebimento de imagem sempre ajuda a extrair a imagem toda vez que um novo pod é criado (isso pode ser como escalar as réplicas ou morrer de pods e criar um novo pod)

Mas se você deseja atualizar a imagem do pod atual em execução, a implantação é a melhor maneira. Deixa você atualizar sem falhas sem nenhum problema (principalmente quando você tem um volume persistente anexado ao pod) :)

Harish Desetti
fonte