← Kubernetes: основы
8 мин · средне · Урок 7 из 11

Императивные kubectl: run, create, expose, scale

Набор команд, которыми ресурсы создают без YAML, и когда каждая из них уместна.

Императив vs декларатив

В Kubernetes два стиля работы с ресурсами.

Императивный: ты говоришь kubectl что сделать прямо сейчас. kubectl create deploy app --image=nginx это команда «создай Deployment с такими параметрами». Если такой Deployment уже есть, упадёт с AlreadyExists. Внутри kubectl сам собирает манифест и шлёт в API.

Декларативный: ты пишешь желаемое состояние в YAML и зовёшь kubectl apply -f. Если ресурс есть, kubectl сравнит с манифестом и обновит. Если нет, создаст.

КомандаРесурса нетРесурс уже есть
kubectl createсоздаётпадает с AlreadyExists
kubectl apply -fсоздаётсравнивает и обновляет

В проде всегда декларатив, потому что YAML лежит в git и виден через PR. Для быстрой проверки гипотезы или разовой отладки императив быстрее.

Карта: что использовать когда

Команд ниже много. Чтобы не теряться, держи в голове, под какую задачу какая команда:

Дальше каждая команда по отдельности.

Команды, которые надо знать

kubectl run

Создаёт один Pod. Самая компактная команда в kubectl.

kubectl run temp --image=busybox:1.36 --restart=Never -- sh -c 'sleep 3600'

Логика разбора: имя Pod, потом флаги, после -- команда для контейнера.

k run temp --image=busybox:1.36 -- sleep 60
  │   │    │                       └ команда
  │   │    └ флаги
  │   └ имя Pod
  └ подкоманда

--restart задаёт restartPolicy. Значение Always (дефолт), OnFailure, Never. Раньше с --restart=Always создавался Deployment, а с Never один Pod, но эту магию убрали в kubectl 1.18+. Сейчас run всегда создаёт Pod, restart-policy просто прокидывается в spec.

Полезные флаги run:

kubectl create

Создаёт ресурсы выше уровня Pod: Deployment, Service, ConfigMap, Secret, Job, CronJob, Namespace, ServiceAccount.

kubectl create deployment myapp --image=nginxinc/nginx-unprivileged:1.25 \
  --replicas=3 --port=8080

kubectl create configmap app-cfg --from-literal=MODE=prod

kubectl create secret generic db --from-literal=PASS=secret

kubectl create job hello --image=busybox:1.36 -- echo done

kubectl create cronjob clean --image=busybox:1.36 \
  --schedule='*/5 * * * *' -- sh -c 'echo tick'

В отличие от kubectl run, kubectl create уже знает, что создавать (deployment, service, configmap), потому что ты сам сказал.

kubectl expose

Создаёт Service над уже существующим Pod, Deployment, ReplicaSet или другим Service. Самый частый случай: поверх Deployment.

kubectl expose deploy myapp --port=80 --target-port=8080 --name=myapp-svc

Selector он возьмёт автоматически из labels Deployment, тип по умолчанию ClusterIP. Можно поменять через --type=NodePort или --type=LoadBalancer.

Проверяют результат по адресам, которые Service набрал:

kubectl get endpointslice -l kubernetes.io/service-name=myapp-svc

Старая команда kubectl get endpoints myapp-svc показывает то же самое, но объект v1 Endpoints deprecated с 1.33 и kubectl печатает про это предупреждение.

kubectl scale

Изменяет spec.replicas у Deployment, ReplicaSet, StatefulSet.

kubectl scale deploy myapp --replicas=5

Под капотом это просто PATCH. Никаких магических действий, можно делать сколько угодно раз.

--dry-run=client -o yaml

Любую императивную команду можно превратить в генератор YAML, добавив два флага:

kubectl create deploy myapp --image=nginxinc/nginx-unprivileged:1.25 \
  --replicas=3 --port=8080 --dry-run=client -o yaml > deploy.yaml

--dry-run=client означает «не отправляй в API, просто собери манифест локально». -o yaml означает «выведи в YAML». В итоге получаешь готовый каркас, который можно править руками: добавить probes, ресурсы, volume, securityContext.

Это базовый приём: не пиши YAML с нуля. Сгенерируй и правь руками.

# Pod
kubectl run pod1 --image=nginx --dry-run=client -o yaml

# Deployment
kubectl create deploy d1 --image=nginx --dry-run=client -o yaml

# Service ClusterIP
kubectl expose deploy d1 --port=80 --dry-run=client -o yaml

# ConfigMap
kubectl create cm c1 --from-literal=k=v --dry-run=client -o yaml

# Job
kubectl create job j1 --image=busybox --dry-run=client -o yaml -- sh -c 'echo hi'

kubectl set

Меняет конкретные поля у уже созданного ресурса. Быстрее чем edit.

# Поменять образ контейнера
kubectl set image deploy/myapp app=nginxinc/nginx-unprivileged:1.26

# Поменять env
kubectl set env deploy/myapp DEBUG=true

# Поменять ресурсы
kubectl set resources deploy/myapp --limits=cpu=200m,memory=256Mi

kubectl edit

Открывает текущий YAML ресурса в $EDITOR (по умолчанию vi). Сохраняешь, kubectl применяет diff. Удобно для разовых правок, в проде так делать нельзя (изменение пропадёт из git).

kubectl edit deploy myapp

Домашка

Теорию закрепляет задание на своём кластере: 4 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-imperative-commands     # развернуть стартовое состояние
./run.sh verify k8s-imperative-commands    # проверить текущий шаг

Коротко

Прошли материал до конца? Отметьте урок пройденным.