Як змусити Kubernetes повторно витягнути зображення?


161

У мене є наступний контролер реплікації в Kubernetes на 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

Тепер, якщо я скажу

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

прокатне оновлення виконується, але повторного потягу не відбувається. Чому?


12
Я дав інше зображення, просто з тим же тегом. Якщо потрібно дати інший тег, ну, я не бачу сенсу в imagePullPolicyполі.
Торстен Бронгер

4
Я хочу використовувати конкретний тег, але його новітню версію.
Торстен Бронгер

3
@TorstenBronger Я думаю, що це кардинальна зміна теорії Кубернетеса / Докера. Ідея про те, що ви можете витягнути image: tag (крім останніх) у два різні часи та отримати два різних зображення, була б проблематичною. Тег схожий на номер версії. Було б краще практикувати завжди міняти тег, коли зображення змінюється.
duct_tape_coder

2
Це залежить. Існує програмне забезпечення з дуже стабільним API, але оновлення безпеки. Тоді я хочу останню версію, не кажучи це прямо.
Торстен Бронгер

1
@TorstenBronger Що стосується використання latest, не робіть цього. Останні потягнуть, ну, останнім часом зображення з останнім тегом. Що ви хочете - це асортимент SemVer. ~ 1.2.3, наприклад. це потягне зображення з тегами між діапазоном> = 1.2.3 та <1.3.0. Поки постачальник зображень слідує за SemVer, ви знаєте (і це важлива частина) не було додано (спеціально) жодних змін у зворотному напрямку і не було додано нових функцій (можлива проблема безпеки). Будь ласка, не використовуйте ніколи latestу виробничих системах.
Девід Дж Едді

Відповіді:


140

Kubernetes витягне на створення Pod, якщо будь-який (див. Документ оновлення зображень ):

  • Використання зображень із тегом :latest
  • imagePullPolicy: Always вказано

Це чудово, якщо ти хочеш завжди тягнути. Але що робити, якщо ви хочете робити це на вимогу : Наприклад, якщо ви хочете використовувати, some-public-image:latestале нову версію ви хочете лише витягнути вручну, коли ви попросите її. На даний момент ви можете:

  • Встановіть imagePullPolicyна IfNotPresentабо Neverі попередньо тягнути : Тягнути вручну зображення на кожному вузлі кластера , так що останній кешуються, то зробитиkubectl rolling-update або аналогічним перезапустити Боби (некрасиво легко ламаються хак!)
  • Тимчасово змінити imagePullPolicy, зробити kubectl apply, перезапустити стручок (наприклад kubectl rolling-update), повернути imagePullPolicy, повторитиkubectl apply (негарно!)
  • Потягніть та some-public-image:latest перейдіть у своє приватне сховище та зробіть kubectl rolling-update(важкий!)

Немає хорошого рішення для потягу за запитом. Якщо це зміниться, будь ласка, прокоментуйте; Я оновлю цю відповідь.


Ви кажете, що кубернети підтягуватимуть створення Pod при використанні :latest- а як щодо patch? це також завжди тягне за собою новітнє / останнє зображення? Здається, для мене це не працює :(
pkyeck

Це залежить від того, чи змушує ваш патч відновлювати струмок чи ні. Швидше за все, ні, тоді вона знову не потягнеться. Ви можете вбити Pod вручну або позначити тег чимось унікальним та закріпити цей оновлений тег.
Wernight

Це відповідь на інше питання. Я попросив примусити повторне тягнення.
Торстен Бронгер

Це дозволило мені примусити нову тягу від GCR. У мене був :latestтег, який вказував на нове зображення, і kubectl rolling-updateпрацював над оновленням стручків.
Ренді Л

Дякую. Пішли на підхід Pull & Push. Автоматизовано якомога більше цього за допомогою скриптів bash, але погоджено, це важко :)
arcseldon

76

Треба групуватись imagePullPolicyусередині даних контейнера, а не в специфікаціях. Однак я подав питання з цього приводу, оскільки мені здається дивним. Крім того, немає повідомлення про помилку.

Отже, цей фрагмент специфікації працює:

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

3
imagePullPolicy(або позначення тегів :latest) добре, якщо ви хочете завжди тягнути, але не вирішує питання про те, щоб натягнути на деманду.
Wernight

1
Так, я хочу завжди тягнути, як сказано в питанні.
Торстен Бронгер

1
Використання imagePullPolicy: Alwaysвсередині визначення контейнера буде kubernetesотримувати зображення, позначені тегами :latestкожного разу, коли новіша їх версія буде натиснута до реєстру?
pkaramol

1
@pkaramol No. imagePullPolicy: Alwaysпросто каже Kubernetes завжди витягувати зображення з реєстру. Яке зображення буде налаштовано за imageатрибутом. Якщо ви налаштуєте його image: your-image:latest, то воно завжди буде тягнути your-imageзображення з latestтегом.
Гаджус

25

Мій хак під час розробки полягає в тому, щоб змінити свій маніфест розгортання, щоб додати останній тег і завжди тягнути так

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

Потім я видаляю стручок вручну

kubectl delete pod my-app-3498980157-2zxhd

Оскільки це розгортання, Kubernetes автоматично відтворить стручок і витягне останнє зображення.


Мені подобається скористатися приміщеннями "бажаного стану" об'єкта "розгортання" ... дякую за пропозицію!
Marcello de Sales

2
Варто зазначити, що стратегія є життєздатною лише в тому випадку, якщо збої в сервісі та простої допустимі. Для розвитку це здається розумним, але я ніколи б не переніс цю стратегію для виробництва.
digitaldreamer

Відредагувати розгортання, змінивши imagePullPolicy на завжди та видаливши стручок, мені було достатньо, як запропонував Еверетт. Однак це середовище розвитку. kubernetes.io/docs/concepts/containers/images
Jos Roberto

17

А Популярний обхідний шлях , щоб залатати розгортання з фіктивною анотацією (або міток):

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

Якщо припустити, що ваша розгортання відповідає цим вимогам , це призведе до того, що K8 зможе витягнути будь-яке нове зображення та повторно використовувати.


2
Так, я використовую для цього примітку.
Торстен Бронгер

яка анотація?
Джеріл Кук

1
Іншим складним рішенням було б поєднання обох, тобто. додаючи примітку та налаштування ImagePullPolicyяк завжди . анотації, як deployment.kubernetes.io/revision: "v-someversion"і kubernetes.io/change-cause: the reasonможуть бути дуже корисними, і спрямовуються на незмінні розгортання.
чандан

16

Буде нова команда, щоб безпосередньо це зробити:

Створіть нову kubectl rollout restartкоманду, яка виконує прокатний перезапуск розгортання.

Запит тягнути GOT злиті. Це буде частиною версії 1.15( журнал змін )


Так, частина випуску: github.com/kubernetes/kubernetes/isissue/13488
Tilo

Так, це найкращий спосіб запустити оновлення в новій версії kubernetes 1.15.
Дельфін

7

Мабуть, тепер, коли ви запускаєте прокатне оновлення з --imageаргументом, таким же, як і існуюче зображення контейнера, ви також повинні вказати --image-pull-policy. Наступна команда повинна змусити витягнути зображення, коли воно є таким же, як зображення контейнера:

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

Тепер команда в kubectl rollout restart deploy YOUR-DEPLOYMENTпоєднанні з imagePullPolicy: Alwaysполітикою дозволить вам перезапустити всі ваші стручки з останньою версією зображення.


3

Команда поновлення оновлення при наданні аргументу зображення передбачає, що зображення відрізняється від того, що існує в контролері реплікації.


Чи означає це, що тег зображення (він же ім'я) повинен відрізнятися?
Торстен Бронгер

Так, назва зображення має бути іншим, якщо ви передаєте --imageпрапор.
Роберт Бейлі

1
Як говорить моя власна відповідь, вона працює також, якщо назва зображення однакове. Просто imagePullPolicy опинився в неправильному місці. На мій захист, документи k8s 1.0 в цьому аспекті помилкові.
Торстен Бронгер

Треба любити, коли документи не синхронізовані з поведінкою. : /
Роберт Бейлі

1
Цей URL теж застарів.
Дан Тененбаум


0

Політика витягування зображень завжди допоможе витягувати зображення кожного разу, коли створюється новий струк (це може бути у будь-якому випадку, як масштабування реплік, або струмок відмирає та створюється новий струк)

Але якщо ви хочете оновити зображення поточного запущеного стручка, розгортання - це найкращий спосіб. Це залишає бездоганне оновлення без проблем (головним чином, коли у вас є постійний том, прикріплений до стручка) :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.