¿Cómo fuerzo a Kubernetes a volver a extraer una imagen?

161

Tengo el siguiente controlador de replicación en Kubernetes en 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

Ahora si digo

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

la actualización continua se realiza, pero no se vuelve a tirar. ¿Por qué?

Torsten Bronger
fuente
12
Le di una imagen diferente, solo con la misma etiqueta. Si es necesario dar una etiqueta diferente, bueno, no veo ningún punto en el imagePullPolicycampo.
Torsten Bronger
44
Quiero usar una etiqueta específica, pero su versión más nueva.
Torsten Bronger
3
@TorstenBronger Creo que este es un cambio radical en la teoría de Kubernetes / Docker. La idea de que podría extraer una imagen: etiquetar (que no sea la última) en dos momentos diferentes y obtener dos imágenes diferentes sería problemática. Una etiqueta es similar a un número de versión. Sería una mejor práctica cambiar siempre la etiqueta cuando la imagen cambia.
duct_tape_coder
2
Depende. Hay software con una API muy estable pero actualizaciones de seguridad. Entonces, quiero la última versión sin tener que decirlo explícitamente.
Torsten Bronger
1
@TorstenBronger Respecto al uso latest, no lo hagas. Latest extraerá, bueno, la imagen más reciente con la última etiqueta. Lo que quieres es una gama SemVer. ~ 1.2.3 por ejemplo. esto extraerá imágenes con etiquetas entre el rango de> = 1.2.3 y <1.3.0. Siempre y cuando el proveedor de la imagen siga SemVer, usted sabe (y esta es la parte importante) que no se agregaron cambios atrasados ​​(a propósito) y que no se agregaron nuevas características (posible preocupación de seguridad). Por favor, nunca lo use latesten sistemas de producción.
David J Eddy

Respuestas:

141

Kubernetes utilizará la creación de Pod si cualquiera de los dos (ver el documento de actualización de imágenes ):

  • Usar imágenes etiquetadas :latest
  • imagePullPolicy: Always está especificado

Esto es genial si quieres tirar siempre. Pero, ¿qué sucede si desea hacerlo a pedido ? Por ejemplo, si desea usarlo some-public-image:latestpero solo desea obtener una versión más nueva manualmente cuando lo solicite. Actualmente puedes:

  • Establecido imagePullPolicyen IfNotPresento Nevery extracción previa : extraiga manualmente las imágenes en cada nodo del clúster para que el último se almacene en caché, luego haga una kubectl rolling-updateo similar para reiniciar Pods (¡truco feo que se rompe fácilmente!)
  • Cambia temporalmenteimagePullPolicy , haz un kubectl apply, reinicia el pod (por ejemplo kubectl rolling-update), revierte imagePullPolicy, rehace un kubectl apply(¡feo!)
  • Tire y empuje some-public-image:latest a su repositorio privado y haga un kubectl rolling-update(¡pesado!)

No hay una buena solución para la extracción bajo demanda. Si eso cambia, por favor comente; Actualizaré esta respuesta.

Wernight
fuente
Dices que kubernetes utilizará la creación de Pod al usarlo :latest, ¿qué pasa con patching? ¿también siempre saca la imagen más nueva / más reciente? Parece que no funciona para mí :(
pkyeck
Depende de si tu parche fuerza la recreación de un Pod o no. Probablemente no, entonces no volverá a tirar. Puede matar el Pod manualmente, o etiquetarlo con algo único y aplicar un parche con esa etiqueta actualizada.
Wernight
Esta es una respuesta a una pregunta diferente. Pedí forzar un nuevo tirón.
Torsten Bronger
Esto me permitió forzar un nuevo tirón de GCR. Tenía una :latestetiqueta que apuntaba a una nueva imagen, y kubectl rolling-updatefuncionó para actualizar los pods.
Randy L
Gracias. Fuimos para el enfoque Pull & Push. Automaticé todo lo que
pude
77

Uno tiene que agrupar imagePullPolicydentro de los datos del contenedor en lugar de dentro de los datos de especificaciones. Sin embargo, presenté un problema al respecto porque me parece extraño. Además, no hay mensaje de error.

Entonces, este fragmento de especificaciones funciona:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key
Torsten Bronger
fuente
3
imagePullPolicy(o etiquetado :latest) es bueno si siempre quieres tirar, pero no resuelve la cuestión de tirar de la demanda.
Wernight
1
Sí, siempre quiero tirar, como se indica en la pregunta.
Torsten Bronger
1
El uso imagePullPolicy: Alwaysdentro de la definición del contenedor tendrá kubernetesimágenes de búsqueda etiquetadas :latestcada vez que una versión más nueva de ellas se envíe al registro.
pkaramol
1
@pkaramol No. imagePullPolicy: Alwayssimplemente le dice a Kubernetes que siempre extraiga la imagen del registro. Qué imagen se configurará por imageatributo. Si lo configura image: your-image:latest, siempre extraerá la your-imageimagen con la latestetiqueta.
Gajus
26

Mi truco durante el desarrollo es cambiar mi manifiesto de implementación para agregar la última etiqueta y siempre tirar así

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

Luego elimino el pod manualmente

kubectl delete pod my-app-3498980157-2zxhd

Debido a que es una implementación, Kubernetes recreará automáticamente el pod y extraerá la última imagen.

Everett Toews
fuente
Me gusta aprovechar las premisas del "estado deseado" del objeto "despliegue" ... ¡gracias por la sugerencia!
Marcello de Sales
2
Vale la pena señalar que la estrategia es viable solo si las fallas en el servicio y el tiempo de inactividad son tolerables. Para el desarrollo parece razonable, pero nunca llevaría esta estrategia para un despliegue de producción.
digitaldreamer
Edite la implementación, cambiar la imagePullPolicy a siempre y eliminar el pod fue suficiente para mí, como sugirió Everett. Sin embargo, este es un entorno de desarrollo. kubernetes.io/docs/concepts/containers/images
Jos Roberto Almaraz
17

Una solución popular es parchear la implementación con una anotación ficticia (o etiqueta):

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

Suponiendo que su implementación cumpla con estos requisitos , esto hará que los K8 extraigan cualquier imagen nueva y la vuelvan a implementar.

Tamlyn
fuente
2
Sí, uso una anotación para esto.
Torsten Bronger
que anotación
Jeryl Cook, el
1
Otra solución sofisticada sería una combinación de ambos, es decir. agregando una anotación y configurando ImagePullPolicycomo Siempre . Las anotaciones como deployment.kubernetes.io/revision: "v-someversion"y kubernetes.io/change-cause: the reasonpueden ser bastante útiles y se dirigen hacia implementaciones inmutables.
chandan
7

Aparentemente, ahora, cuando ejecuta una actualización continua con el --imageargumento igual que la imagen del contenedor existente, también debe especificar un --image-pull-policy. El siguiente comando debe forzar una extracción de la imagen cuando es la misma que la imagen del contenedor:

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

sjking
fuente
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
fuente
3

Ahora, el comando kubectl rollout restart deploy YOUR-DEPLOYMENTcombinado con una imagePullPolicy: Alwayspolítica le permitirá reiniciar todos sus pods con una última versión de su imagen.

Orabîg
fuente
3

El comando de actualización continua, cuando se le da un argumento de imagen, supone que la imagen es diferente de la que existe actualmente en el controlador de replicación.

Robert Bailey
fuente
¿Esto significa que la etiqueta de la imagen (también conocido como nombre) debe ser diferente?
Torsten Bronger
Sí, el nombre de la imagen debe ser diferente si pasa la --imagebandera.
Robert Bailey
1
Como dice mi propia respuesta, funciona también si el nombre de la imagen es el mismo. Era simplemente que la imagePullPolicy estaba en el lugar equivocado. En mi defensa, los documentos de k8s 1.0 son erróneos en este aspecto.
Torsten Bronger
Tengo que amar cuando los documentos no están sincronizados con el comportamiento. : /
Robert Bailey
1
Esa url también está desactualizada.
Dan Tenenbaum
2

Puede definir imagePullPolicy: Alwaysen su archivo de implementación.

Sachin Arote
fuente
0

La política de extracción de imágenes siempre ayudará a extraer la imagen cada vez que se cree un nuevo pod (esto puede ser en cualquier caso como escalar las réplicas, o el pod muere y se crea un nuevo pod)

Pero si desea actualizar la imagen del pod en ejecución actual, la implementación es la mejor manera. Te deja una actualización perfecta sin ningún problema (principalmente cuando tienes un volumen persistente conectado al pod) :)

Harish Desetti
fuente