Kubernetes: kubectl create using inline options in bash script instead of yaml file
Ты ~~написал~~ наваял идеальный yaml-манифест для Tiller. Положил его в репу, настроил джобу в Jenkins, которая должна просто выполнить `kubectl create -f`. Но
Ты написал наваял идеальный yaml-манифест для Tiller. Положил его в репу, настроил джобу в Jenkins, которая должна просто выполнить kubectl create -f. Но потом тебя осеняет: а что если сделать всё одной строчкой в скрипте? Без лишних файлов, просто чистый bash, который можно впихнуть в пайплайн и забыть.
Сначала кажется, что это ересь. Всё вокруг твердит о декларативности, о том, что yaml — это свято. Но иногда хочется императивно, быстро и прямо в консоли. Особенно когда нужно протестить что-то или собрать ресурс на лету.
От манифеста к команде
Вот тот самый tiller-sa-crb.yaml. Два ресурса в одном файле: ServiceAccount и ClusterRoleBinding. Классика для Helm 2.
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system
А вот команда, которая его применяет: kubectl create -f tiller-sa-crb.yaml. Скучно. Предсказуемо. Негибко.
Допустим, тебе нужно в Jenkins-джобе динамически подставлять namespace или имя аккаунта. Лезть в шаблонизацию yaml? Можно. Но есть путь короче.
Bash-ализация кубернетеса
kubectl create умеет многое прямо из командной строки. Зачем файл, если можно так:
#!/bin/bash
#create SA account in one line in namespace kube-system
kubectl create serviceaccount tiller -n kube-system
#create cluster role binding in one line using above serviceaccount and in kube-system namespace
kubectl create clusterrolebinding crb-cluster-admin-test2 --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
Вот и весь скрипт. tiller-sa-crb.sh. Кидаешь его в артефакты, и джоба дёргает его без лишних телодвижений.
Первая команда создаёт ServiceAccount. Всё как в yaml, но флагами: имя, namespace.
Вторая — ClusterRoleBinding. Обрати внимание на флаг --serviceaccount. Тут важен синтаксис: <namespace>:<serviceaccount_name>. Если перепутаешь, binding будет ссылаться в пустоту.
Имя binding (crb-cluster-admin-test2) можно сделать любым. В yaml оно было tiller, но это не обязательно. Главное, чтобы roleRef и subjects сошлись.
Почему это работает (и когда не стоит)
Kubernetes API в итоге получает те же самые структуры данных, что и из yaml-файла. kubectl create просто собирает их из аргументов командной строки и шёт на сервер.
Это отлично подходит для простых ресурсов с парой-тройкой полей. Для чего-то сложного, с кучей аннотаций, меток или вложенных структур — лучше остаться при yaml. Иначе скрипт превратится в нечитаемую портянку с --annotation, --label и --from-literal.
Плюс такого подхода — скорость и прозрачность. Видишь всё сразу в одной строке. Минус — потеря декларативности. Этот ресурс теперь живёт только в твоей команде. Чтобы понять, что было развёрнуто, придётся лезть в историю bash или логи Jenkins.
Итог
Если нужно быстро, для одноразового действия или простого CI-шага — инлайн-команды kubectl create это валидный выход. Запустил скрипт — получил ресурс.
Для production-среды, где важны контроль версий, ревью изменений и ясность — оставайся с yaml. Или иди дальше, к Helm или Kustomize.
Но теперь ты знаешь, что если увидишь в логах джобы загадочный kubectl create serviceaccount..., это не обязательно ошибка. Это кто-то, как и ты, решил срезать угол.