Kubernetes як зробити розгортання для оновлення зображення


131

У мене є розгортання з одним стручком із моїм власним зображенням докера на зразок:

containers:
  - name: mycontainer
    image: myimage:latest

Під час розробки я хочу висунути нову останню версію та оновити розгортання. Неможливо знайти, як це зробити, не чітко визначаючи тег / версію та збільшуючи її для кожної збірки та робити

kubectl set image deployment/my-deployment mycontainer=myimage:1.9.1

Відповіді:


151

Ви можете налаштувати свій стручок з пільговим періодом (наприклад, 30 секунд або більше, залежно від часу запуску контейнера та розміру зображення) та встановити "imagePullPolicy: "Always". І використовувати kubectl delete pod pod_name. Буде створений новий контейнер і автоматично завантажується останнє зображення, після чого старий контейнер припиняється.

Приклад:

spec:
  terminationGracePeriodSeconds: 30
  containers:
  - name: my_container
    image: my_image:latest
    imagePullPolicy: "Always"

Наразі я використовую Дженкінса для автоматизованих збірок та тегування зображень, і це виглядає приблизно так:

kubectl --user="kube-user" --server="https://kubemaster.example.com"  --token=$ACCESS_TOKEN set image deployment/my-deployment mycontainer=myimage:"$BUILD_NUMBER-$SHORT_GIT_COMMIT"

Ще одна хитрість полягає в тісному запуску:

kubectl set image deployment/my-deployment mycontainer=myimage:latest

і потім:

kubectl set image deployment/my-deployment mycontainer=myimage

Це насправді буде запускати прокатне оновлення, але переконайтесь, що ви також imagePullPolicy: "Always"встановили.

Оновлення:

Ще один трюк, який я знайшов, коли вам не потрібно змінювати ім'я зображення, - це змінити значення поля, яке спровокує прокатне оновлення, наприклад terminationGracePeriodSeconds. Ви можете зробити це з допомогою kubectl edit deployment your_deploymentабо kubectl apply -f your_deployment.yamlчи використовувати патч , як це:

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'

Просто переконайтеся, що ви завжди змінюєте значення числа.


1
Власне, ваш трюк не поганий, враховуючи мімідж: lastet і myimage в основному одне і те ж, дякую!
абовесун

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

2
Якщо ви хочете, щоб розгортання kubernetes почало новий струк, використовуючи те саме зображення (і цей трюк працює лише з тегом "останній"), вам потрібно вказати його без тегу. Наступного разу додайте тег "останній", і він запустить оновлення. Порядок можна змінити, це не має значення. Ви ніколи не використовуєте "найновіший" тег у виробництві, але для цілей розвитку ви можете отримувати користь від нього іноді.
Каміль

2
Це працює лише за останнім часом. За замовчуванням, принаймні в докер-концентраторі, не позначаючи тегом зображення, він припускає "останній" тег. Але також буде працювати без цього. Цей приклад - це не те, що вам потрібно у виробничих умовах, і не так багато випадків використання, коли ви також можете отримати користь від цього в розвитку. Є кращі методи автоматичного оновлення зображення за допомогою інструмента CI / CD.
Каміль

11
Кожен раз, коли ви міняєте тег і запускаєте kubectl set imageкоманду, kubernetes буде виконувати постійне оновлення. Наприклад, скажімо, ви розгорнули "repo / myimage: latest". Тим часом ваше зображення було змінено та натиснуто на репо з тегом "v0.2". Ви можете виконати оновлення, запустивши kubectl set image deployment/my-deployment mycontainer=myimage:v0.2Це зображення також матиме "останній" тег.
Каміль

73

ОНОВЛЕННЯ 2019-06-24

На основі коментаря @Jodiug, якщо у вас є 1.15версія, ви можете використовувати команду:

kubectl rollout restart deployment/demo

Детальніше про це читайте:

https://github.com/kubernetes/kubernetes/isissue/13488


Ну, є цікава дискусія з цього приводу в кубернетах GitHub проекту. Дивіться випуск: https://github.com/kubernetes/kubernetes/isissue/33664

З описаних там рішень я запропонував би одне з двох.

Перший

1. Підготуйте розгортання

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        image: registry.example.com/apps/demo:master
        imagePullPolicy: Always
        env:
        - name: FOR_GODS_SAKE_PLEASE_REDEPLOY
          value: 'THIS_STRING_IS_REPLACED_DURING_BUILD'

2.Деплой

sed -ie "s/THIS_STRING_IS_REPLACED_DURING_BUILD/$(date)/g" deployment.yml
kubectl apply -f deployment.yml

Другий (один вкладиш):

kubectl patch deployment web -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"

Звичайно, imagePullPolicy: Alwaysце потрібно в обох випадках.


Знайшов ще один пов'язаний трюк. Якщо ви просто зробите "перезапуск кубектл-запуску розгортання", не вказуючи конкретних розгортань, намер він зробить "усі" з них.
Леннарт Ролланд

21
kubectl rollout restart deployment myapp

Це поточний спосіб запустити поновлене оновлення та залишити старі набори реплік для інших операцій, що надаються kubectl rolloutподібними відкатами.


@Prathameshdhanawade операція виправлення не має undoкоманди чи еквівалента.
Мартін Пітер

7

Я використовую Gitlab-CI для створення зображення, а потім розгортаю його безпосередньо в GCK. Якщо використовувати акуратний маленький трюк, щоб домогтися оновлення, не змінюючи реальних налаштувань контейнера, що змінює мітку на поточну команду-шорт-ша.

Моя команда виглядає так:

kubectl patch deployment my-deployment -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$CI_COMMIT_SHORT_SHA\"}}}}}}"

Де ви можете використовувати будь-яке ім’я та будь-яке значення для мітки, якщо воно змінюється з кожною збіркою.

Веселіться!


6

Схоже, k8s очікує, що ми надамо різний тег зображення для кожного розгортання. Моя стратегія по замовчуванням буде зробити систему CI генерувати і розсунути Docker зображення, позначаючи їх з номером збірки: xpmatteo/foobar:456.

Для місцевого розвитку може бути зручно використовувати скрипт або makefile, наприклад:

# create a unique tag    
VERSION:=$(shell date +%Y%m%d%H%M%S)
TAG=xpmatteo/foobar:$(VERSION)

deploy:
    npm run-script build
    docker build -t $(TAG) . 
    docker push $(TAG)
    sed s%IMAGE_TAG_PLACEHOLDER%$(TAG)% foobar-deployment.yaml | kubectl apply -f - --record

sedКоманда замінює заповнювач в документі розгортання з реально генеруються тегом зображення.


kubernetes не вимагає оновлення розгортання новим тегом, щоб витягнути останню версію будь-якого зображення, "найновіший" - найпоширеніший приклад.
Дейв Вайт

1

Я використовую Azure DevOps для розгортання додатків для контейнерів, мені легко вдається подолати цю проблему за допомогою ідентифікатора зборки

Кожен раз, коли він створює та генерує новий ідентифікатор збірки, я використовую цей ідентифікатор збірки як тег для зображення докера

imagename: buildID

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

imagename: env: buildID

тут evn: buildid - це змінна azure devops, яка має значення ідентифікатора build.

тож кожен раз, коли у мене з’являються нові зміни для складання (CI) та розгортання (CD).

будь ласка, прокоментуйте, якщо вам потрібно визначення побудови для CI / CD.


Маніфест є частиною репо. Я не розумію, які найкращі практики для цього. Якщо я будую зображення в конвеєрі, чи потрібно натиснути, щоб освоїти оновлений маніфест? чи я повинен створити оновлений маніфест для артефактів (і, таким чином, маніфест у РЕПО був би просто шаблоном без фактичного позначеного зображення)?
pablete
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.