Kubernetes, как сделать развертывание для обновления образа

У меня есть развертывание с одним контейнером, с моим пользовательским изображением докеров, например:

containers:
  - name: mycontainer
    image: myimage:latest

Во время разработки я хочу выпустить новую последнюю версию и обновить развертывание. Невозможно найти, как это сделать, без явного определения тега/версии и увеличения его для каждой сборки и

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

Ответы

Ответ 1

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

Пример:

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

В настоящее время я использую Jenkins для автоматических сборок и тегов изображений и выглядит примерно так:

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".

Update:

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

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

Просто убедитесь, что вы всегда меняете числовое значение.

Ответ 2

ОБНОВЛЕНИЕ 2019-06-24

Основываясь на комментарии @Jodiug, если у вас есть версия 1.15, вы можете использовать команду kubectl rollout restart deployment/demo.

Подробнее о проблеме:

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


Ну, есть интересная дискуссия на эту тему по проекту GitHub kubernetes. Смотрите проблему: https://github.com/kubernetes/kubernetes/issues/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.Deploy

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 требуется в обоих случаях.

Ответ 3

Кажется, что k8s ожидает, что мы предоставим разные теги изображений для каждого развертывания. Моя стратегия по умолчанию будет заключаться в том, чтобы система CI генерировала и xpmatteo/foobar:456, помечая их номером сборки: xpmatteo/foobar:456.

Для локальной разработки может быть удобно использовать скрипт или make файл, например так:

# 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 заменяет заполнитель в документе развертывания на фактический сгенерированный тег изображения.

Ответ 4

Я использую Gitlab-CI, чтобы создать образ, а затем развернуть его непосредственно в GCK. Если использовать аккуратный трюк, чтобы добиться непрерывного обновления без изменения каких-либо реальных настроек контейнера, то есть изменения метки на текущий commit-short-sha.

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

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

Где вы можете использовать любое имя и любое значение для метки, если она меняется с каждой сборкой.

Повеселись!

Ответ 5

kubectl rollout restart deployment myapp

Это текущий способ инициировать непрерывное обновление и оставить старые наборы реплик на месте для других операций, предоставляемых kubectl rollout, таких как откаты.