Мы используем kubectl set image для развертывания новой версии 2.0.0 существующего приложения. Затем мы используем kubectl rollout status, чтобы дождаться готовности нового модуля, чтобы мы могли запустить некоторые базовые тесты.
Проблема в том, что kubectl rollout status возвращается (подразумевая, что новый модуль v2 готов), но когда мы используем kubectl exec, мы ВСЕГДА попадаем в старый модуль v1.
$ date
Mon 13 Feb 2023 02:33:50 PM CET
$ k set image deploy/myapp myapp=myapp:2.0.0 && k rollout status deploy/myapp
deployment.apps/myapp image updated
Waiting for deployment "myapp" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "myapp" rollout to finish: 1 old replicas are pending termination...
deployment "myapp" successfully rolled out
Здесь мы предполагаем, что работает новая версия. Давай проверим:
$ k exec deploy/myapp -- show_version
1.0.0
Нет, это все еще старая версия. Проверьте развертывание:
$ k get deploy/myapp
NAME READY UP-TO-DATE AVAILABLE AGE
myapp 1/1 1 1 273d
Выглядит готовым (K9S показывает 1 модуль «Завершение» и 1 модуль готов). Проверить снова:
$date
Mon 13 Feb 2023 02:34:00 PM CET
$ k exec deploy/myapp -- show_version
1.0.0
Нет, проверьте стручки:
kubectl get pod | grep myapp-
myapp-79454d746f-zw5kg 1/1 Running 0 31s
myapp-6c484f86d4-2zsk5 1/1 Terminating 0 3m5s
Итак, наш модуль работает, мы просто не можем запустить его — он всегда «выбирает» завершающий модуль:
$date
Mon 13 Feb 2023 02:34:10 PM CET
$ k exec deploy/myapp -- show_version
1.0.0
Подождите 20-30 секунд:
$ date
Mon 13 Feb 2023 02:34:25 PM CET
$ k exec deploy/myapp -- show_version
2.0.0
Наконец-то у нас есть exec на правильном стручке.
Почему/как мы можем ждать завершения работы старого модуля? ИЛИ Как мы можем убедиться, что мы запускаем правильный модуль для тестирования?
Вы можете выполнить внутри модуля с помощью этой команды: -
$ kubectl exec -it {pod-id} -n {namespace} -- bash
В вашем случае используйте идентификатор работающего модуля: -
$kubectl exec -it myapp-79454d746f-zw5kg -- bash
Нет необходимости использовать имя развертывания для выполнения внутри модуля, так как развертывание будет представлять оба модуля.
Ваш ответ может быть улучшен с помощью дополнительной вспомогательной информации. Пожалуйста, отредактируйте , чтобы добавить дополнительные сведения, такие как цитаты или документация, чтобы другие могли подтвердить правильность вашего ответа. Вы можете найти больше информации о том, как писать хорошие ответы в справочном центре.
Kubectl exec -it pod-name -c main /bin/bash
Используйте эту команду, чтобы войти в модуль. Чтобы просмотреть модули, используйте приведенные ниже команды.
kubectl get pods -l app=myapp
Kubectl get pods
Иногда требуется несколько секунд, чтобы стручок поднялся.
Мы не знаем имя/идентификатор модуля, так как мы развертываем новую версию.
Еще лучше было бы получить идентификатор new_pod и exec непосредственно в него.
Тоже возможно, да. Попробуй это:
k rollout status deploy/myapp >/dev/null && \
k get po -l app=myapp | grep Running | awk '{print $1}' | xargs -I{} kubectl exec {} -- show_version
Я хотел бы знать, что управляет этим 30-м временем.
Это можно настроить с помощью поля TerminationGracePeriodSeconds в спецификации модуля. Значение по умолчанию равно, как вы правильно догадались, 30 секунд. Если вы не беспокоитесь о потере данных (из-за немедленного отключения), его можно установить на 0. После этого вы можете напрямую запустить новый модуль:
spec:
terminationGracePeriodSeconds: 0
k rollout status deploy/myapp >/dev/null && k exec deploy/myapp -- show_version
Будучи «завершенным», старый модуль все еще находится в фазе выполнения , а kubectl exec deploy/myapp, похоже, использует первый запущенный модуль развертывания.
Я бы предложил:
app=myapp
).$ old_pod=$(kubectl get pods -l app=myapp -o jsonpath='{.items[0].metadata.name}')
$ k apply -f Deployment.yaml
$ k rollout status deploy/myapp
$ k wait --for=delete pod/$old_pod --timeout -1s
$ k exec deploy/myapp -- show_version
Спасибо, интересный подход. Еще лучше было бы получить идентификатор new_pod и exec непосредственно в него. Я чувствую, что kubernetes хранит старые модули около 30 секунд. Я хотел бы знать, что управляет этим 30-м временем. Создание живого зонда для пода не помогло сократить это время.
@Marc обновил мой ответ относительно ваших замечаний.
Мы не знаем имя/идентификатор модуля, так как мы развертываем новую версию.