[K8S] SERVICE ACCOUNT RBAC FOR CICD DEPLOYMENT - fourslickz/notes GitHub Wiki

Tutorial Membuat ServiceAccount + RBAC + Kubeconfig untuk CI/CD (Jenkins)

Tujuan

Membuat akun khusus (ServiceAccount) yang hanya memiliki hak akses untuk melakukan deployment aplikasi ke namespace tertentu, kemudian membuat kubeconfig yang aman untuk digunakan oleh Jenkins.

Arsitektur:

Jenkins
    │
    │ kubeconfig
    ▼
ServiceAccount (cicd-deployer)
    │
    ▼
Role
    │
    ▼
RoleBinding
    │
    ▼
Kubernetes API

Step 1 - Buat Namespace

Jika namespace belum ada:

kubectl create namespace ayo-pramuka

Cek:

kubectl get ns

Step 2 - Buat ServiceAccount

serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount

metadata:
  name: cicd-deployer
  namespace: ayo-pramuka

Apply:

kubectl apply -f serviceaccount.yaml

Verifikasi:

kubectl get sa -n ayo-pramuka

Contoh output:

NAME            AGE
cicd-deployer   35s
default         81d

Pada Kubernetes 1.24+, token tidak lagi dibuat otomatis sehingga ini adalah kondisi normal.


Step 3 - Buat Role

role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role

metadata:
  name: cicd-deployer
  namespace: ayo-pramuka

rules:

- apiGroups: [""]
  resources:
    - pods
    - pods/log
    - services
    - endpoints
    - configmaps
    - secrets
  verbs:
    - get
    - list
    - watch
    - create
    - update
    - patch
    - delete

- apiGroups: ["apps"]
  resources:
    - deployments
    - replicasets
    - statefulsets
    - daemonsets
  verbs:
    - get
    - list
    - watch
    - create
    - update
    - patch
    - delete

- apiGroups: ["autoscaling"]
  resources:
    - horizontalpodautoscalers
  verbs:
    - get
    - list
    - watch
    - create
    - update
    - patch
    - delete

- apiGroups: ["batch"]
  resources:
    - jobs
    - cronjobs
  verbs:
    - get
    - list
    - watch
    - create
    - update
    - patch
    - delete

Apply:

kubectl apply -f role.yaml

Step 4 - Buat RoleBinding

rolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding

metadata:
  name: cicd-deployer
  namespace: ayo-pramuka

subjects:
- kind: ServiceAccount
  name: cicd-deployer
  namespace: ayo-pramuka

roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: cicd-deployer

Apply:

kubectl apply -f rolebinding.yaml

Step 5 - Verifikasi RBAC

Harus diizinkan:

kubectl auth can-i create deployment \
  --as=system:serviceaccount:ayo-pramuka:cicd-deployer \
  -n ayo-pramuka

Output:

yes

Harus ditolak:

kubectl auth can-i get nodes \
  --as=system:serviceaccount:ayo-pramuka:cicd-deployer

Output:

no

Step 6 - Generate Token

kubectl create token cicd-deployer -n ayo-pramuka

Opsional meminta durasi lebih panjang:

kubectl create token cicd-deployer \
  -n ayo-pramuka \
  --duration=8760h

Catatan: Pada managed Kubernetes seperti DigitalOcean Kubernetes, durasi maksimum tetap mengikuti kebijakan control plane.


Step 7 - Ambil Informasi Cluster

Server API:

kubectl config view --minify \
-o jsonpath='{.clusters[0].cluster.server}'

CA Certificate:

kubectl config view --raw --minify \
-o jsonpath='{.clusters[0].cluster.certificate-authority-data}'

Step 8 - Buat kubeconfig

apiVersion: v1
kind: Config

clusters:
- name: production
  cluster:
    server: https://YOUR_CLUSTER_ENDPOINT
    certificate-authority-data: YOUR_CA_DATA

users:
- name: cicd
  user:
    token: YOUR_SERVICEACCOUNT_TOKEN

contexts:
- name: production
  context:
    cluster: production
    namespace: ayo-pramuka
    user: cicd

current-context: production

Step 9 - Uji kubeconfig

export KUBECONFIG=./kubeconfig.yaml

kubectl get pods

Coba akses yang tidak diizinkan:

kubectl get nodes

Hasil yang diharapkan:

Error from server (Forbidden)

Step 10 - Upload ke Jenkins

  1. Manage Jenkins
  2. Credentials
  3. Add Credentials
  4. Kind: Secret file
  5. Upload kubeconfig.yaml

Contoh penggunaan di Jenkinsfile:

withCredentials([
    file(credentialsId: 'kubeconfig-production', variable: 'KUBECONFIG')
]) {
    sh '''
        kubectl apply -f k8s/
        kubectl rollout status deployment/api -n ayo-pramuka
    '''
}

Best Practice

  • Gunakan satu ServiceAccount untuk setiap environment (dev, staging, production).
  • Jangan gunakan kubeconfig administrator untuk CI/CD.
  • Simpan kubeconfig sebagai Jenkins Secret File.
  • Terapkan prinsip least privilege pada RBAC.
  • Backup Jenkins secara terenkripsi karena credential disimpan di $JENKINS_HOME.