Kubectl применить против kubectl создать?
В документации я понял, что kubectl apply = kubectl create + kubectl replace. Ссылка
Я понимаю, что
если я хочу создать новый ресурс k8s в кластере, я должен использовать операцию kubectl create. Теперь, если я хочу обновить что-либо в живых ресурсах k8s, я должен использовать операцию kubectl replace.
Если я хочу выполнить обе операции (создать новый ресурс k8s, а также обновить живые ресурсы k8s), я должен использовать операцию kubectl apply
Мои вопросы: почему в кластере есть три операции для выполнения одной и той же задачи? Каковы варианты использования для этих операций? Чем они отличаются друг от друга под капотом?
В данный момент я использую kubectl create для создания новых ресурсов в кластере. Спасибо
11 ответов
Это два разных подхода. kubectl create
это то, что мы называем императивным управлением. При таком подходе вы сообщаете Kubernetes API, что вы хотите создать, заменить или удалить, а не то, как вы хотите, чтобы ваш кластерный мир K8s выглядел.
kubectl apply
является частью подхода декларативного управления, где изменения, которые вы, возможно, применили к живому объекту (т.е. через scale
) поддерживаются, даже если вы apply
другие изменения в объекте.
Вы можете прочитать больше об императивном и декларативном управлении в документации по управлению объектами Kubernetes.
При запуске в скрипте CI у вас будут проблемы с императивными командами, так как create вызывает ошибку, если ресурс уже существует.
То, что вы можете сделать, это применить (декларативный шаблон) вывод вашей императивной команды, используя --dry-run=true
а также -o yaml
опции:
kubectl create whatever --dry-run=true -o yaml | kubectl apply -f -
Приведенная выше команда не вызовет ошибку, если ресурс уже существует (и при необходимости обновит ресурс).
Это очень полезно в некоторых случаях, когда вы не можете использовать декларативный шаблон (например, при создании секрета реестра Docker).
Один из лучших способов понять разницу для новичков.
Просто чтобы дать более прямой ответ, насколько я понимаю:
apply
- вносит инкрементальные изменения в существующий объект create
- создает совершенно новый объект (ранее не существовавший / удаленный).
Взяв это из статьи DigitalOcean, на которую была ссылка на веб-сайте Kubernetes:
Здесь мы используем apply вместо create, чтобы в будущем мы могли постепенно применять изменения к объектам Ingress Controller вместо их полной перезаписи.
┌─────────┬───────────────────────┬────────────────────────┐
│ command │ object does not exist │ object already exists │
├─────────┼───────────────────────┼────────────────────────┤
│ create │ create new object │ ERROR │
│ │ │ │
│ apply │ create new object │ configure object │
│ │ (needs complete spec) │ (accepts partial spec) │
│ │ │ │
│ replace │ ERROR │ delete object │
│ │ │ create new object │
└─────────┴───────────────────────┴────────────────────────┘
Это императивные команды:
kubectl run
знак равно kubectl create deployment
Преимущества:
- Просто, легко усвоить и легко запомнить.
- Требуется только один шаг для внесения изменений в кластер.
Недостатки:
- Не интегрируйтесь с процессами проверки изменений.
- Не предоставляйте контрольный журнал, связанный с изменениями.
- Не предоставляйте источник записей, кроме живого.
- Не предоставляйте шаблон для создания новых объектов.
Это императивная конфигурация объекта:
kubectl create -f your-object-config.yaml
kubectl delete -f your-object-config.yaml
kubectl replace -f your-object-config.yaml
Преимущества по сравнению с императивными командами:
- Может храниться в системе контроля версий, такой как Git.
- Может интегрироваться с такими процессами, как проверка изменений перед отправкой и журналы аудита.
- Предоставляет шаблон для создания новых объектов.
Недостатки по сравнению с императивными командами:
- Требуется базовое понимание схемы объекта.
- Требуется дополнительный этап записи файла YAML.
Преимущества по сравнению с декларативным конфигом объекта:
- Проще и понятнее.
- Более зрелый после версии 1.5 Kubernetes.
Недостатки по сравнению с декларативной конфигурацией объекта:
- Лучше всего работает с файлами, а не с каталогами.
- Обновления живых объектов должны быть отражены в файлах конфигурации, иначе они будут потеряны при следующей замене.
Это декларативная конфигурация объекта
kubectl diff -f configs/
kubectl apply -f configs/
Преимущества по сравнению с императивной конфигурацией объекта:
- Изменения, внесенные непосредственно в живые объекты, сохраняются, даже если они не объединяются обратно в файлы конфигурации.
- Улучшена поддержка работы с каталогами и автоматического определения типов операций (создание, исправление, удаление) для каждого объекта.
Недостатки по сравнению с императивной конфигурацией объекта:
- Сложнее отлаживать и понимать результаты, когда они неожиданные.
- Частичные обновления с использованием различий создают сложные операции слияния и исправления.
Это можно сделать на простых примерах:
Давайте создадим простой yaml для развертывания пода с образом nginx.
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
теперь мы создаем pod с помощью команды kubectl —
Теперь создан модуль с именем nginx, вы можете получить информацию о запущенных модулях с помощью -
kubectl get pods -o wide
и подробное представление о модуле от
kubectl describe pod nginx
Теперь, если я хочу внести некоторые изменения в свой файл pod.yaml следующим образом:
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
tier: frontend
title: frontend
spec:
containers:
- name: nginx
image: nginx
теперь попробуйте команду
kubectl create -f pod.yaml
применить изменения в pod.yaml.
у него будет вывод -
Ошибка с сервера (AlreadyExists): ошибка при создании "pod.yaml": модули "nginx" уже существуют
а с командой -
kubectl apply -f pod.yaml
выход -
pod/nginx настроен
Как и в первом комментарии, очень подробно объясняется, чтоcreate
как императивные команды сосредоточены на назначенных им задачах, вы не можете назначить им дополнительные задачи, чтобы настроить мир кластеров, ноapply
Например, декларативные команды предназначены для настройки мира кластеров.
Ниже объяснение из официальной документации помогло мне понять kubectl apply
,
Эта команда сравнивает версию конфигурации, которую вы отправляете, с предыдущей версией и применяет сделанные вами изменения, не перезаписывая автоматические изменения свойств, которые вы не указали.
kubectl create
с другой стороны создаст (должен быть несуществующий) ресурс.
kubectl create может работать с одним файлом конфигурации объекта за раз. Это также известно как императивное управление.
kubectl create -f имя файла | URL
kubectl apply работает с каталогами и их подкаталогами, содержащими yaml-файлы конфигурации объекта. Это также известно как декларативное управление. Можно выбрать несколько файлов конфигурации объекта из каталогов.kubectl apply -f каталог /
Подробности:
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/imperative-config/
Мы любим Kubernetes, потому что, как только мы даем им то, что хотим, он начинает выяснять, как этого добиться без нашего участия.
"создавать" - все равно что играть в БОГА, беря вещи в свои руки. Это хорошо для локальной отладки, когда вы хотите работать только с POD и не заботитесь о контроллере развертывания / репликации.
"применить" - это игра по правилам. "apply" похож на основной инструмент, который помогает вам создавать и изменять и ничего не требует от вас для управления модулями.
Этот вопрос очень глубокий и хороший. Далее я думаю об этой проблеме:
K8s имеет три метода управления ресурсами
Управление объектами на основе команд: напрямую используйте команды для управления ресурсами kubernetes. например:
kubectl run nginx-pod --image=nginx:1.17.1 --port=80
Конфигурация объекта типа команды: управление ресурсами Kubernetes с помощью конфигурации команд и файлов конфигурации. например:
kubectl create/patch -f nginx-pod.yaml
Декларативная конфигурация объекта: управляйте ресурсами kubernetes с помощью команды apply и файла конфигурации. например:
kubectl apply -f nginx-pod.yaml