¿Cómo fuerzo a Kubernetes a volver a extraer una imagen?
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
se realiza la actualización continua, pero no se vuelve a extraer. ¿Por qué?
Kubernetes realizará la creación del Pod si cualquiera de las dos situaciones (consulte el documento de actualización de imágenes ):
- Usando 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 utilizar some-public-image:latest
pero solo desea obtener una versión más nueva manualmente cuando la solicite. Actualmente puedes:
- Establecer
imagePullPolicy
enIfNotPresent
oNever
y extracción previa : extraiga manualmente imágenes en cada nodo del clúster para que la última se almacene en caché, luego haga algokubectl rolling-update
similar para reiniciar los Pods (¡truco feo que se rompe fácilmente!) - Cambiar temporalmente
imagePullPolicy
, hacer unakubectl apply
, reiniciar el pod (por ejemplokubectl rolling-update
), revertirimagePullPolicy
, rehacer unakubectl apply
(¡feo!) - Tira y empuja
some-public-image:latest
a tu repositorio privado y haz unkubectl rolling-update
(¡pesado!)
No hay una buena solución para la extracción bajo demanda. Si eso cambia, por favor comente; Actualizaré esta respuesta.
Hay que agrupar imagePullPolicy
dentro de los datos del contenedor en lugar de dentro de los datos de especificaciones. Sin embargo, presenté un problema sobre esto porque lo encuentro extraño. Además, no hay ningún mensaje de error.
Entonces, este fragmento de especificación funciona:
spec:
containers:
- name: myapp
image: myregistry.com/myapp:5c3dda6b
ports:
- containerPort: 80
imagePullPolicy: Always
imagePullSecrets:
- name: myregistry.com-registry-key
Hay un comando para hacer eso directamente:
Cree un nuevo kubectl rollout restart
comando que reinicie progresivamente una implementación.
La solicitud de extracción se fusionó. Es parte de la versión 1.15
( changelog ) o superior.
Mi truco durante el desarrollo es cambiar mi manifiesto de implementación para agregar la última etiqueta y siempre hacerlo 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 imagen más reciente.
Una solución alternativa popular es parchear la implementación con una anotación (o etiqueta) ficticia:
kubectl patch deployment <name> -p \
"{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"
Suponiendo que su implementación cumpla con estos requisitos , esto hará que K8 extraiga cualquier imagen nueva y la vuelva a implementar.