Jak zmusić Kubernetes do ponownego pobrania obrazu?

161

Mam następujący kontroler replikacji w Kubernetes w 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

Teraz, jeśli powiem

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

przeprowadzana jest aktualizacja krocząca, ale bez ponownego ściągania. Czemu?

Torsten Bronger
źródło
12
Dałem inny obraz, tylko z tym samym tagiem. Jeśli trzeba podać inny tag, cóż, nie widzę sensu w tej imagePullPolicydziedzinie.
Torsten Bronger
4
Chcę użyć konkretnego tagu, ale jego najnowszej wersji.
Torsten Bronger,
3
@TorstenBronger Myślę, że to przełomowa zmiana w teorii Kubernetes / Docker. Pomysł, aby pobrać image: tag (inny niż ostatni) w dwóch różnych momentach i uzyskać dwa różne obrazy, byłby problematyczny. Znacznik jest podobny do numeru wersji. Lepszą praktyką byłoby zawsze zmieniać tag, gdy zmienia się obraz.
channel_tape_coder
2
To zależy. Istnieje oprogramowanie z bardzo stabilnym interfejsem API, ale z aktualizacjami zabezpieczeń. Następnie chcę mieć najnowszą wersję bez konieczności mówienia tego wprost.
Torsten Bronger
1
@TorstenBronger Jeśli chodzi o używanie latest, nie rób tego. Najnowszy pobierze, no cóż, nowszy obraz z najnowszym tagiem. To, czego chcesz, to seria SemVer. ~ 1.2.3 na przykład. spowoduje to pobranie obrazów z tagami z zakresu od> = 1.2.3 do <1.3.0. Tak długo, jak dostawca obrazu podąża za SemVer, wiesz (i jest to ważna część), nie dodano żadnych wstecznych zmian (celowo) i nie dodano żadnych nowych funkcji (możliwe zagrożenie bezpieczeństwa). Proszę nigdy nie używać latestw systemach produkcyjnych.
David J Eddy,

Odpowiedzi:

140

Kubernetes pobierze po utworzeniu Poda, jeśli (zobacz dokument aktualizujący obrazy ):

  • Korzystanie z oznaczonych obrazów :latest
  • imagePullPolicy: Always jest specyficzne

To jest świetne, jeśli chcesz zawsze ciągnąć. Ale co, jeśli chcesz to zrobić na żądanie : na przykład, jeśli chcesz użyć, some-public-image:latestale chcesz ręcznie pobrać nowszą wersję tylko wtedy, gdy o to poprosisz. Obecnie możesz:

  • Zestaw imagePullPolicydo IfNotPresentlub Neveri pre-pull : pull obrazów ręcznie na każdym węźle klastra więc ostatni są buforowane, a następnie zrobić kubectl rolling-updatelub podobny do ponownego uruchomienia Pods (brzydki łamliwe siekać!)
  • Tymczasowo zmień imagePullPolicy, zrób kubectl apply, zrestartuj kapsułę (np. kubectl rolling-update), Przywróć imagePullPolicy, ponów kubectl apply(brzydka!)
  • Przeciągnij i wypchnij some-public-image:latest do swojego prywatnego repozytorium i wykonaj kubectl rolling-update(ciężki!)

Brak dobrego rozwiązania dla ściągania na żądanie. Jeśli to się zmieni, prosimy o komentarz; Zaktualizuję tę odpowiedź.

Wernight
źródło
Mówisz, że kubernetes uruchomi tworzenie Podów podczas używania :latest- a co z patching? czy zawsze pobiera również najnowszy / najnowszy obraz? Wydaje się, że nie działa dla mnie :(
pkyeck
Zależy to od tego, czy twój patch wymusza ponowne utworzenie Poda, czy nie. Najprawdopodobniej nie, wtedy znowu nie pociągnie. Możesz zabić Pod ręcznie lub oznaczyć czymś unikalnym i załatać ten zaktualizowany tag.
Wernight
To jest odpowiedź na inne pytanie. Poprosiłem o wymuszenie ponownego pociągnięcia.
Torsten Bronger
To pozwoliło mi wymusić nowe przyciąganie z GCR. Miałem :latesttag, który wskazywał na nowy obraz i kubectl rolling-updatepracowałem nad aktualizacją strąków.
Randy L
Dzięki. Poszedłem na podejście Pull & Push. Zautomatyzowany jak najwięcej za pomocą skryptów bash, ale zgodził się, jest ciężki :)
arcseldon
76

Należy zgrupować imagePullPolicywewnątrz danych kontenera zamiast wewnątrz danych specyfikacji. Jednak zgłosiłem problem w tej sprawie, ponieważ wydaje mi się to dziwne. Poza tym nie ma komunikatu o błędzie.

Tak więc ten fragment specyfikacji działa:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key
Torsten Bronger
źródło
3
imagePullPolicy(lub tagowanie :latest) jest dobre, jeśli chcesz zawsze ciągnąć, ale nie rozwiązuje problemu ciągnięcia na żądanie.
Wernight
1
Tak, zawsze chcę ciągnąć, jak stwierdzono w pytaniu.
Torsten Bronger
1
Używanie imagePullPolicy: Alwayswewnątrz definicji kontenera spowoduje kubernetespobranie obrazów z tagiem za :latestkażdym razem, gdy ich nowsza wersja zostanie przesłana do rejestru?
pkaramol
1
@pkaramol No. imagePullPolicy: Alwayspo prostu mówi Kubernetesowi, aby zawsze pobierał obraz z rejestru. Jaki obraz będzie konfigurowany przez imageatrybut. Jeśli skonfigurujesz go tak image: your-image:latest, zawsze będzie ściągał your-imageobraz z latesttagiem.
Gajus
25

Mój hack podczas programowania polega na zmianie manifestu wdrożenia, dodaniu najnowszego tagu i zawsze w ten sposób

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

Następnie ręcznie usuwam kapsułę

kubectl delete pod my-app-3498980157-2zxhd

Ponieważ jest to Wdrożenie, Kubernetes automatycznie odtworzy kapsułę i pobierze najnowszy obraz.

Everett Toews
źródło
Lubię korzystać z przesłanek „stanu pożądanego” obiektu „wdrożenie”… dzięki za sugestię!
Marcello de Sales,
2
Warto zauważyć, że strategia jest opłacalna tylko wtedy, gdy awarie usługi i przestoje są tolerowane. W przypadku programowania wydaje się to rozsądne, ale nigdy nie przeniósłbym tej strategii do wdrożenia produkcyjnego.
digitaldreamer
Edytuj wdrożenie, zmieniając imagePullPolicy na zawsze i usuwając kapsułę wystarczyło, jak zasugerował Everett. Jest to jednak środowisko programistyczne. kubernetes.io/docs/concepts/containers/images
Jos Roberto Almaraz
17

Popularne obejście jest plaster rozmieszczenie z adnotacją manekina (lub etykiet):

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

Zakładając, że wdrożenie spełnia te wymagania , spowoduje to, że K8 pobierze nowy obraz i ponownie wdroży.

Tamlyn
źródło
2
Tak, używam do tego adnotacji.
Torsten Bronger,
jaka adnotacja?
Jeryl Cook
1
Innym wyrafinowanym rozwiązaniem byłoby połączenie obu tj. dodanie adnotacji i ustawienie ImagePullPolicyjako Zawsze . adnotacje takie jak deployment.kubernetes.io/revision: "v-someversion"i kubernetes.io/change-cause: the reasonmogą być bardzo pomocne i zmierzają w kierunku niezmiennych wdrożeń.
chandan
7

Najwyraźniej teraz, gdy uruchamiasz aktualizację kroczącą z --imageargumentem takim samym jak istniejący obraz kontenera, musisz również określić plik --image-pull-policy. Poniższe polecenie powinno wymusić wyciągnięcie obrazu, gdy jest taki sam jak obraz kontenera:

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

sjking
źródło
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
źródło
3

Teraz polecenie kubectl rollout restart deploy YOUR-DEPLOYMENTpołączone z imagePullPolicy: Alwayspolityką pozwoli ci ponownie uruchomić wszystkie pody z najnowszą wersją obrazu.

Orabîg
źródło
3

Polecenie rolling update, gdy podano argument image, zakłada, że ​​obraz jest inny niż ten, który obecnie istnieje w kontrolerze replikacji.

Robert Bailey
źródło
Czy to oznacza, że ​​tag obrazu (inaczej nazwa) musi być inny?
Torsten Bronger
Tak, nazwa obrazu musi być inna, jeśli przekażesz --imageflagę.
Robert Bailey
1
Jak mówi moja własna odpowiedź, działa to również, jeśli nazwa obrazu jest taka sama. Po prostu imagePullPolicy był w niewłaściwym miejscu. Na moją obronę dokumenty k8s 1.0 są błędne w tym aspekcie.
Torsten Bronger
Trzeba kochać, gdy dokumenty nie są zsynchronizowane z zachowaniem. : /
Robert Bailey
1
Ten adres URL też jest nieaktualny.
Dan Tenenbaum
2

Możesz zdefiniować imagePullPolicy: Alwaysw pliku wdrożenia.

Sachin Arote
źródło
0

Zasada ściągania obrazu zawsze faktycznie pomaga w ściągnięciu obrazu za każdym razem, gdy tworzony jest nowy pod (w każdym przypadku może to być skalowanie replik lub umieranie zasobnika i tworzenie nowego zasobnika)

Ale jeśli chcesz zaktualizować obraz aktualnie działającego poda, najlepszym sposobem jest wdrożenie. Pozostawia bezbłędną aktualizację bez żadnego problemu (głównie gdy masz stały wolumin dołączony do kapsuły) :)

Harish Desetti
źródło