Embedding requests in the Git pipeline

To embed requests to the “Shturval” platform cluster in the Git pipeline to manage objects, you will need:

  • create a service account in the Shturval platform cluster with the necessary rights for actions in the cluster;
  • get cluster kubeconfig for Service Account;
  • add the cluster kubeconfig to the project repository;
  • configure a job in the Git pipeline to perform actions in the cluster.

The instructions provide an example of creating a Namespace resource in the GitLab pipeline.

Creating a namespace from the GitLab pipeline

Creating a Service Account in a cluster

  1. In the namespace default of the cluster, create a Service Account with the name name-service-account:
Command
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: name-service-account
  namespace: default
> EOF
  1. Create a cluster role with the necessary rights to perform actions
Command with an example of creating a role
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. Bind the created ClusterRole to the Service Account by creating a ClusterRoleBinding in the cluster.
Command
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. Create a secret secret-sa in the cluster for the Service Account. Please indicate:
  • namespace name default.
  • the name of the Service Account created in the first step is name-service-account;
  • secret type kubernetes.io/service-account-token/
Command
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. Add the created secret secret-sa to the Service Account.
Command
kubectl edit sa name-service-account
Example 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. Determine the secret index in the Service Account by running:
Command
kubectl get serviceaccount name-service-account --context username@shturval-clustername --namespace default -o json

Where instead of username@shturval-clustername specify the required cluster context.

Command for obtaining a list of available cluster contexts
kubectl config get-contexts
Example response
...
"secrets": [
        {
            "name": "secret-sa"
        }
]

In the example given, the secret index secret-sa has a value of 0. The index will need to be specified when preparing the kubeconfig of the cluster.

Preparing kubeconfig cluster

  1. Create a file kubeconfig.sh with a script for creating a kubeconfig cluster for the system account name-service-account.
Example kubeconfig.sh
# Set variables
SERVICE_ACCOUNT_NAME=name-service-account
NAMESPACE=default
NEW_CONTEXT=namesa
KUBECONFIG_FILE='kubeconfig-sa'
# Get the current context
CONTEXT=$(kubectl config current-context)
# Get the Service Account secret name
SECRET_NAME=$(kubectl get serviceaccount ${SERVICE_ACCOUNT_NAME} --context ${CONTEXT} --namespace ${NAMESPACE} -o jsonpath='{.secrets[0].name}')
# Get the access token and encode its data in base64
TOKEN_DATA=$(kubectl get secret ${SECRET_NAME} --context ${CONTEXT} --namespace ${NAMESPACE} -o jsonpath='{.data.token}')
TOKEN=$(echo ${TOKEN_DATA} | base64 -d)
# Create a kubeconfig file with a full copy of the current cluster kubeconfig
kubectl config view --raw > ${KUBECONFIG_FILE}.full.tmp
# Switch the active context to the current one
kubectl --kubeconfig ${KUBECONFIG_FILE}.full.tmp config use-context ${CONTEXT}
kubectl --kubeconfig ${KUBECONFIG_FILE}.full.tmp config view --flatten --minify > ${KUBECONFIG_FILE}.tmp
# Rename the context to the new context name
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp rename-context ${CONTEXT} ${NEW_CONTEXT}
# Create the user token
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp set-credentials ${CONTEXT}-token-user --token ${TOKEN}
# Set the context to use the Service Account token
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp set-context ${NEW_CONTEXT} --user ${CONTEXT}-token-user
# Simplify and export the cluster kubeconfig for the Service Account
kubectl config --kubeconfig ${KUBECONFIG_FILE}.tmp view --flatten --minify > ${KUBECONFIG_FILE}
rm ${KUBECONFIG_FILE}.full.tmp
rm ${KUBECONFIG_FILE}.tmp

Where instead of 0 in .secrets[0].name, specify the index of the secret from the secrets Service Account array obtained in step 5 of the previous section.

  1. Run the commands in the create-kubeconfig.sh file.
Example
source create-kubeconfig.sh

As a result, a cluster kubeconfig will be created with the name kubeconfig-sa for Service Account name-service-account in the ~/.kube folder.

  1. Copy the kubeconfig data of the kubeconfig-sa cluster.
Kubeconfig-sa data acquisition command
cat kubeconfig-sa

Add job to pipeline

  1. In Gitlab, add a CI/CD variable in the project repository, where you specify KUBECONFIG_file as the key and the cluster kubeconfig data as the value.

  2. In the project repository, navigate to the CI/CD configuration file (the standard Gitlab configuration file name is .gitlab-ci.yml).

  3. Add a pipeline stage to stages, for example, with the name create_ns to create a Namespace in the cluster. Specify the create_ns stage at the end of the pipeline, after

Example
stages:
  - create_ns
  1. Add job and set parameters:
  • stage, in which indicate the name of the stage added in the previous step;
  • before_script, where write the command to write the value of the KUBECONFIG_file variable to the kubeconfig-sa.conf file and the command to export the cluster kubeconfig to the KUBECONFIG variable;
  • script, where write the command to create Namespace.
Example
create_job:
  stage: create_ns
  before_script:
    echo $KUBECONFIG_file> kubeconfig-sa.conf
    export KUBECONFIG=kubeconfig-sa.conf
  script:
    - kubectl create namespace my-namespace

Where instead of my-namespace enter the name of the namespace being created.

  1. Launch the pipeline.

Creating a namespace using the API

Procedure:

  • log in to the Shturval platform. Authorization instructions are located on the Authorization in the platform page;
  • execute a request to create a namespace using the command line utility curl.
Example of creating a namespace
curl -k -s -L --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