Wie zwinge ich Kubernetes, ein Bild erneut abzurufen?


160

Ich habe den folgenden Replikationscontroller in Kubernetes auf 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

Nun, wenn ich sage

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

Das fortlaufende Update wird durchgeführt, aber kein erneutes Ziehen. Warum?


12
Ich habe ein anderes Bild gegeben, nur mit dem gleichen Tag. Wenn es notwendig ist, ein anderes Tag zu vergeben, sehe ich keinen Sinn auf dem imagePullPolicyFeld.
Torsten Bronger

4
Ich möchte ein bestimmtes Tag verwenden, aber die neueste Version.
Torsten Bronger

3
@TorstenBronger Ich denke, dies ist eine bahnbrechende Änderung in der Kubernetes / Docker-Theorie. Die Idee, dass Sie image: tag (außer dem neuesten) zu zwei verschiedenen Zeiten ziehen und zwei verschiedene Bilder erhalten könnten, wäre problematisch. Ein Tag ähnelt einer Versionsnummer. Es ist besser, das Tag immer zu ändern, wenn sich das Bild ändert.
duct_tape_coder

2
Es hängt davon ab, ob. Es gibt Software mit einer sehr stabilen API, aber Sicherheitsupdates. Dann möchte ich die neueste Version, ohne dies explizit sagen zu müssen.
Torsten Bronger

1
@TorstenBronger In Bezug auf die Verwendung latesttun Sie es nicht. Neueste wird das, nun, neuere Bild mit dem neuesten Tag ziehen. Was Sie wollen, ist eine SemVer-Reihe. ~ 1.2.3 zum Beispiel. Dadurch werden Bilder mit Tags zwischen> = 1.2.3 und <1.3.0 abgerufen. Solange der Image-Anbieter SemVer nach Ihrem Wissen folgt (und dies ist der wichtige Teil), wurden (absichtlich) keine rückwärtsbrechenden Änderungen hinzugefügt und keine neuen Funktionen hinzugefügt (mögliche Sicherheitsbedenken). Bitte, bitte niemals latestin Produktionssystemen verwenden.
David J Eddy

Antworten:


140

Kubernetes zieht bei der Pod-Erstellung Folgendes ein (siehe Dokument zum Aktualisieren von Bildern ):

  • Verwenden von mit Tags versehenen Bildern :latest
  • imagePullPolicy: Always angegeben

Das ist toll, wenn du immer ziehen willst. Was aber, wenn Sie es bei Bedarf tun möchten : Zum Beispiel, wenn Sie some-public-image:latesteine neuere Version verwenden möchten, aber nur manuell abrufen möchten, wenn Sie danach fragen. Sie können derzeit:

  • Set imagePullPolicyzu IfNotPresentoder Neverund Pre-pull : Ziehen Sie Bilder manuell auf jedem Cluster - Knoten , so dass die letzte zwischengespeichert wird, dann tut einem kubectl rolling-updateoder ähnlichen Pods (hässlich leicht gebrochen Hack!) Neu zu starten
  • Vorübergehend ändern imagePullPolicy, a kubectl applyausführen, Pod neu starten (z. B. kubectl rolling-update), zurücksetzen imagePullPolicy, a wiederholen kubectl apply(hässlich!)
  • Ziehen Sie und schieben Sie some-public-image:latest zu Ihrem privaten Repository und machen Sie eine kubectl rolling-update(schwere!)

Keine gute Lösung für On-Demand-Pull. Wenn sich dies ändert, kommentieren Sie bitte; Ich werde diese Antwort aktualisieren.


Sie sagen, Kubernetes ziehen bei der Verwendung die Pod-Erstellung in Anspruch :latest- was ist mit patching? zieht es auch immer das neueste / neueste Bild? Scheint nicht für mich zu arbeiten :(
pkyeck

Es hängt davon ab, ob Ihr Patch die Neuerstellung eines Pods erzwingt oder nicht. Höchstwahrscheinlich nicht, dann wird es nicht wieder ziehen. Sie können den Pod manuell beenden oder mit etwas Einzigartigem markieren und mit diesem aktualisierten Tag patchen.
Wernight

Dies ist eine Antwort auf eine andere Frage. Ich bat um Zwingen eine erneute ziehen.
Torsten Bronger

Dies erlaubte mir, einen neuen Zug von GCR zu erzwingen. Ich hatte ein :latestTag, das auf ein neues Bild zeigte, und das kubectl rolling-updatearbeitete daran, die Pods zu aktualisieren.
Randy L

Vielen Dank. Ging für den Pull & Push-Ansatz. So viel wie möglich mit Bash-Skripten automatisiert, aber einverstanden, es ist schwer :)
arcseldon

75

Man muss imagePullPolicyinnerhalb der Containerdaten gruppieren, anstatt innerhalb der Spezifikationsdaten. Ich habe jedoch ein Problem dazu eingereicht, weil ich es seltsam finde. Außerdem gibt es keine Fehlermeldung.

Dieses Spezifikations-Snippet funktioniert also:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key

3
imagePullPolicy(oder Markieren :latest) ist gut, wenn Sie immer ziehen möchten, aber die Frage des Ziehens auf Nachfrage nicht lösen.
Wernight

1
Ja, ich möchte immer ziehen, wie in der Frage angegeben.
Torsten Bronger

1
Bei Verwendung imagePullPolicy: Alwaysinnerhalb der Containerdefinition werden kubernetesAbrufbilder markiert, mit denen markiert wird, :latestwenn eine neuere Version davon in die Registrierung verschoben wird.
Karamol

1
@pkaramol Nein. imagePullPolicy: AlwaysKubernetes wird lediglich angewiesen, immer ein Bild aus der Registrierung abzurufen . Welches Bild es wird, wird durch imageAttribut konfiguriert . Wenn Sie es so konfigurieren image: your-image:latest, wird das your-imageBild immer mit dem latestTag abgerufen.
Gajus

25

Mein Hack während der Entwicklung besteht darin, mein Bereitstellungsmanifest so zu ändern, dass das neueste Tag hinzugefügt wird, und immer so zu ziehen

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

Dann lösche ich den Pod manuell

kubectl delete pod my-app-3498980157-2zxhd

Da es sich um eine Bereitstellung handelt, erstellt Kubernetes den Pod automatisch neu und ruft das neueste Image ab.


Ich nutze gerne die Prämissen "gewünschter Zustand" des Objekts "Bereitstellung" ... danke für den Vorschlag!
Marcello de Sales

2
Es ist erwähnenswert, dass eine Strategie nur dann realisierbar ist, wenn Fehler im Service und Ausfallzeiten tolerierbar sind. Für die Entwicklung scheint es vernünftig, aber ich würde diese Strategie niemals für eine Produktionsbereitstellung übertragen.
Digitaldreamer

Bearbeiten Sie die Bereitstellung, ändern Sie die imagePullPolicy auf immer und löschen Sie den Pod, wie Everett vorgeschlagen hat. Dies ist jedoch eine Entwicklungsumgebung. kubernetes.io/docs/concepts/containers/images
Jos Roberto Almaraz

17

Eine beliebte Problemumgehung besteht darin, die Bereitstellung mit einer Dummy-Anmerkung (oder Beschriftung) zu patchen:

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

Angenommen, Ihre Bereitstellung erfüllt diese Anforderungen , führt dies dazu, dass K8s ein neues Image abrufen und erneut bereitstellen.


2
Ja, ich verwende dafür eine Anmerkung.
Torsten Bronger

Welche Anmerkung?
Jeryl Cook

1
Eine andere ausgefeilte Lösung wäre eine Kombination von beiden, dh. Hinzufügen einer Anmerkung und Einstellung ImagePullPolicyals Immer . Anmerkungen wie deployment.kubernetes.io/revision: "v-someversion"und kubernetes.io/change-cause: the reasonkönnen sehr hilfreich sein und führen zu unveränderlichen Bereitstellungen.
Chandan


7

Anscheinend müssen Sie jetzt, wenn Sie ein fortlaufendes Update mit dem --imagegleichen Argument wie das vorhandene Container-Image ausführen , auch ein angeben --image-pull-policy. Der folgende Befehl sollte ein Ziehen des Bildes erzwingen, wenn es mit dem Containerbild identisch ist:

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


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('+','_') , "\""}}}}}"))

3

Mit dem Befehl in kubectl rollout restart deploy YOUR-DEPLOYMENTKombination mit einer imagePullPolicy: AlwaysRichtlinie können Sie jetzt alle Pods mit einer neuesten Version Ihres Images neu starten.


3

Der fortlaufende Aktualisierungsbefehl geht bei Angabe eines Image-Arguments davon aus, dass sich das Image von dem unterscheidet, das derzeit im Replikationscontroller vorhanden ist.


Bedeutet dies, dass das Bild-Tag (auch bekannt als Name) unterschiedlich sein muss?
Torsten Bronger

Ja, der Bildname muss unterschiedlich sein, wenn Sie die --imageFlagge übergeben.
Robert Bailey

1
Wie meine eigene Antwort sagt, funktioniert es auch, wenn der Bildname der gleiche ist. Es war einfach so, dass die imagePullPolicy am falschen Ort war. Zu meiner Verteidigung sind die k8s 1.0-Dokumente in dieser Hinsicht fehlerhaft.
Torsten Bronger

Ich muss lieben, wenn die Dokumente nicht mit dem Verhalten synchron sind. : /
Robert Bailey

1
Diese URL ist auch veraltet.
Dan Tenenbaum

2

Sie können imagePullPolicy: Alwaysin Ihrer Bereitstellungsdatei definieren .


0

Die Image-Pull-Richtlinie hilft immer dabei, das Image jedes Mal abzurufen, wenn ein neuer Pod erstellt wird (dies kann in jedem Fall das Skalieren der Replikate oder das Stempeln des Pods und das Erstellen eines neuen Pods sein).

Wenn Sie jedoch das Image des aktuell ausgeführten Pods aktualisieren möchten, ist die Bereitstellung der beste Weg. Sie können problemlos einwandfrei aktualisieren (hauptsächlich, wenn Sie ein dauerhaftes Volume an den Pod angeschlossen haben) :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.