Now that I have a number of pipelines running I would like to deploy these to Kubernetes through a service account. that is quite simple. As an admin user provide resources such as:
- the namespaces, optionally with limited resources;
- an isolated service account with restricted access to one namespace;
- an encoded config file to be used by the Gitlab pipeline.
Service Account with permissions
The following file serviceaccount.yaml
creates the service account, a role, and attach that role to that account:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: mynamespace-dev-user
namespace: mynamespace-dev
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: mynamespace-dev-user-full-access
namespace: mynamespace-dev
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: mynamespace-dev-user-view
namespace: mynamespace-dev
subjects:
- kind: ServiceAccount
name: mynamespace-dev-user
namespace: mynamespace-dev
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: mynamespace-dev-user-full-access
The following bash file helps to deploy both the namespace and the access file and it creates the sa.kubeconfig
:
#!/bin/bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
NAMESPACE=mynamespace-dev
kubectl apply -f $SCRIPTPATH/namespace.yaml
kubectl apply -f $SCRIPTPATH/access.yaml
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CLUSTERNAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}')
SECRETNAME=$(kubectl get sa "$NAMESPACE-user" -n $NAMESPACE -o=jsonpath="{.secrets[0].name}")
USERTOKEN=$(kubectl get secret $SECRETNAME -n $NAMESPACE -o "jsonpath={.data.token}" | base64 -D)
CERTIFICATE=$(kubectl get secret $SECRETNAME -n $NAMESPACE -o "jsonpath={.data['ca\.crt']}")
read -r -d '' KCONFIG << EOM
apiVersion: v1
kind: Config
clusters:
- name: ${CLUSTERNAME}
cluster:
certificate-authority-data: ${CERTIFICATE}
server: ${APISERVER}
contexts:
- name: default-kube
context:
cluster: ${CLUSTERNAME}
namespace: ${NAMESPACE}
user: ${NAMESPACE}-user
current-context: default-kube
users:
- name: ${NAMESPACE}-user
user:
token: ${USERTOKEN}
EOM
echo $(echo -ne "$KCONFIG" | base64) > $SCRIPTPATH/sa.kubeconfig
Copy the content of this kubeconfig file.
Setup Gitlab CI
Go to the Gitlab project settings > CI/CD > Variables; name the variable something e.g. KUBECONFIGENCR
and paste the earlier copied content from sa.kubeconfig
as value.
In your projects gitlab-ci.yaml
you can add the following variable and deployment:
variables:
KUBECONFIG: /etc/deploy/config
deploy:
stage: deploy
image: dtzar/helm-kubectl:3.1.2
script:
- mkdir -p /etc/deploy
- echo $KUBECONFIGENCR | base64 -d > ${KUBECONFIG}
- kubectl config use-context default-kube
script:
- kubectl apply --install -f ./path/to/my/service