Встроить запросы в pipeline Git

Чтобы в pipeline Git встроить запросы к кластеру платформы “Штурвал” для управления объектами, потребуется:

  • создать в кластере платформы “Штурвал” сервисную учетную запись (Service Account) с необходимыми правами для действий в кластере;
  • получить kubeconfig кластера для Service Account;
  • добавить в репозиторий проекта kubeconfig кластера;
  • сконфигурировать в pipeline Git задание (job) на выполнение действий в кластере.

В инструкции приведен пример создания ресурса Namespace в pipeline GitLab.

Создание неймспейса из pipeline GitLab

Создание Service Account в кластере

  1. В неймспейсе default кластера создайте Service Account с именем name-service-account:
Команда
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: name-service-account
  namespace: default
> EOF
  1. Создайте кластерную роль с необходимыми для выполнения действий правами
Команда с примером создания роли
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: special-sa-role
rules:
- apiGroups:
  - ""
  resources:
  - "namespaces"
  verbs:
  - "get"
  - "create"
  - "list"  
> EOF
  1. Свяжите созданную ClusterRole с Service Account, создав ClusterRoleBinding в кластере.
Команда
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: special-sa-rolebinding
subjects:
    kind: ServiceAccount
    name: name-service-account
    namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: special-sa-role
> EOF
  1. Создайте секрет secret-sa в кластере для Service Account. Укажите:
  • название неймспейса default.
  • имя Service Account, созданного на первом шаге - name-service-account;
  • тип секрета kubernetes.io/service-account-token/
Команда
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: secret-sa
  namespace: default
  annotations:
    kubernetes.io/service-account.name: name-service-account
type: kubernetes.io/service-account-token
> EOF
  1. Добавьте созданный секрет secret-sa в Service Account.
Команда
kubectl edit sa name-service-account
Пример Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2024-12-11T05:14:47Z"
  name: name-service-account
  namespace: default
  resourceVersion: "586818"
  uid: cd32a856-76d9-472d-9345-1fe8a755be3f
secrets:
- name: secret-sa
  1. Определите индекс секрета в Service Account, выполнив:
Команда
kubectl get serviceaccount name-service-account --context username@shturval-clustername --namespace default -o json

Где вместо username@shturval-clustername укажите необходимый контекст кластера.

Команда получения списка контекстов доступных кластеров
kubectl config get-contexts
Пример ответа
...
"secrets": [
        {
            "name": "secret-sa"
        }
]

В приведенном примере индекс секрета secret-sa имеет значение 0. Индекс потребуется указать при подготовке kubeconfig кластера.

Подготовка kubeconfig кластера

  1. Сформируйте файл kubeconfig.sh со скриптом создания kubeconfig кластера для системной учетной записи name-service-account.
Пример kubeconfig.sh
# Прописать переменные
SERVICE_ACCOUNT_NAME=name-service-account
NAMESPACE=default
NEW_CONTEXT=namesa
KUBECONFIG_FILE='kubeconfig-sa'
# Получить текущий контекст
CONTEXT=$(kubectl config current-context)
# Получить имя секрета в Service Account
SECRET_NAME=$(kubectl get serviceaccount ${SERVICE_ACCOUNT_NAME} --context ${CONTEXT} --namespace ${NAMESPACE} -o jsonpath='{.secrets[0].name}')
# Получить токен доступа и закодировать его данные в формат base64 
TOKEN_DATA=$(kubectl get secret ${SECRET_NAME} --context ${CONTEXT} --namespace ${NAMESPACE} -o jsonpath='{.data.token}')
TOKEN=$(echo ${TOKEN_DATA} | base64 -d)
# Создать файл для kubeconfig с полной копией текущего kubeconfig кластера
kubectl config view --raw > ${KUBECONFIG_FILE}.full.tmp
# Переключить рабочий контекст на текущий
kubectl --kubeconfig ${KUBECONFIG_FILE}.full.tmp config use-context ${CONTEXT}
kubectl --kubeconfig ${KUBECONFIG_FILE}.full.tmp config view --flatten --minify > ${KUBECONFIG_FILE}.tmp
# Переименовать контекст на новый контекст
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp rename-context ${CONTEXT} ${NEW_CONTEXT}
# Создать токен пользователя
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp set-credentials ${CONTEXT}-token-user --token ${TOKEN}
# Установить контекст для использования токена Service Account
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp set-context ${NEW_CONTEXT} --user ${CONTEXT}-token-user
# Упростить и получить kubeconfig кластера для Service Account
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp view --flatten --minify > ${KUBECONFIG_FILE}
rm ${KUBECONFIG_FILE}.full.tmp
rm ${KUBECONFIG_FILE}.tmp

Где вместо 0 в .secrets[0].name укажите индекс секрета из массива secrets Service Account, полученного на 5 шаге предыдущего раздела.

  1. Выполните команды в файле create-kubeconfig.sh.
Пример
source create-kubeconfig.sh

В результате будет создан kubeconfig кластера c именем kubeconfig-sa для Service Account name-service-account в папке ~/.kube.

  1. Скопируйте данные kubeconfig кластера kubeconfig-sa.
Команда получения данных kubeconfig-sa
cat kubeconfig-sa

Добавить job в pipeline

  1. В Gitlab добавьте переменную CI/CD в репозитории проекта, где в качестве ключа укажите KUBECONFIG_file, а в значении - данные kubeconfig кластера.

  2. В репозитории проекта перейдите к конфигурационному файлу CI/CD (стандартное имя конфигурационного файла в Gitlab - .gitlab-ci.yml).

  3. Добавьте в stages этап pipeline, например, с именем create_ns для создания Namespace в кластере. Укажите этап create_ns в конце pipeline, после

Пример
stages:
  - create_ns
  1. Добавьте job и задайте параметры:
  • stage, в котором укажите имя этапа, добавленного на предыдущем шаге;
  • before_script, где пропишите команду для записи значения переменной KUBECONFIG_file в файл kubeconfig-sa.conf и команду для экспортирования kubeconfig кластера в переменную KUBECONFIG;
  • script, где пропишите команду на создание Namespace.
Пример
create_job:
  stage: create_ns
  before_script:
    echo $KUBECONFIG_file> kubeconfig-sa.conf
    export KUBECONFIG=kubeconfig-sa.conf
  script:
    - kubectl create namespace my-namespace

Где вместо my-namespace пропишите имя создаваемого неймспейса.

  1. Запустите pipeline.

Создание неймспейса с помощью API

Порядок действия:

  • авторизоваться в платформе “Штурвал”. Инструкция по авторизации находится на странице Авторизация в платформе;
  • выполнить запрос на создание неймспейса с помощью утилиты командной строки curl.
Пример создания неймспейса
curl -k --silent --location --request POST $BACKENDPOINT/api/v1/clusters/{cluster_name}/namespaces?is_system=false
--header "Authorization: Bearer $token"
--data @<(cat <<EOF
    {
  "name": "namespacename",
  "labels": [
    {
      "key": "example",
      "value": "1"
    }
  ]
}
EOF
) | jq -r
×