Monday, September 21, 2026
DevOps Git GitLab K3s

Belajar GitLab Part 5-Multi Environtment

image 3

Kali ini kita akan coba buat multi environtmet development dan production.

Workflow Akhir

develop branch

development namespace

testing

main branch

production namespace

live app

Struktur Project

Di repo kamu:

belajar-gitlab/
├── .gitlab-ci.yml
├── Dockerfile
├── index.html

├── k8s/
│ ├── dev/
│ │ ├── deployment.yaml
│ │ └── service.yaml
│ │
│ └── prod/
│ ├── deployment.yaml
│ └── service.yaml

STEP 1 — Buat Namespace

kubectl create namespace development
kubectl create namespace production

STEP 2 — Secret Registry Per Namespace

Development

kubectl create secret docker-registry gitlab-registry \
--docker-server=registry.gitlab.com \
--docker-username=USERNAME \
--docker-password=TOKEN \
[email protected] \
-n development

Production

kubectl create secret docker-registry gitlab-registry \
--docker-server=registry.gitlab.com \
--docker-username=USERNAME \
--docker-password=TOKEN \
[email protected] \
-n production

STEP 3 — Buat Folder K8s

Bisa copy code dari -> https://github.com/kyuby13/belajar-gitlab-multi-envi

Di project:

k8s/
├── dev/
│ ├── deployment.yaml
│ └── service.yaml

└── prod/
├── deployment.yaml
└── service.yaml

Development Deployment

k8s/dev/deployment.yaml

apiVersion: apps/v1
kind: Deployment

metadata:
name: nginx-app
namespace: development

spec:
replicas: 1

selector:
matchLabels:
app: nginx-app

template:
metadata:
labels:
app: nginx-app

spec:

imagePullSecrets:
- name: gitlab-registry

containers:
- name: nginx-app

image: registry.gitlab.com/project7112620/belajar-gitlab/nginx-app:IMAGE_TAG

ports:
- containerPort: 80

Development Service

k8s/dev/service.yaml

apiVersion: v1
kind: Service

metadata:
  name: nginx-service
  namespace: development

spec:
  type: NodePort

  selector:
    app: nginx-app

  ports:
    - port: 80
      targetPort: 80
      nodePort: 30082

Production Deployment

k8s/prod/deployment.yaml

apiVersion: apps/v1
kind: Deployment

metadata:
name: nginx-app
namespace: production

spec:
replicas: 2

selector:
matchLabels:
app: nginx-app

template:
metadata:
labels:
app: nginx-app

spec:

imagePullSecrets:
- name: gitlab-registry

containers:
- name: nginx-app

image: registry.gitlab.com/project7112620/belajar-gitlab/nginx-app:IMAGE_TAG

ports:
- containerPort: 80

Production Service

k8s/prod/service.yaml

apiVersion: v1
kind: Service

metadata:
  name: nginx-service
  namespace: production

spec:
  type: NodePort

  selector:
    app: nginx-app

  ports:
    - port: 80
      targetPort: 80
      nodePort: 30081

Hasilnya

Development

http://IP-KUBE1:30082

Production

http://IP-KUBE1:30081

.gitlab-ci.yml

Ini inti multi environment.


Full Example

stages:
- build
- deploy

variables:
IMAGE_NAME: registry.gitlab.com/project7112620/belajar-gitlab/nginx-app

# =========================
# BUILD
# =========================

build:
image: docker:latest

stage: build

tags:
- main-runner

services:
- docker:dind

variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""

script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com

- docker build -t $IMAGE_NAME:$CI_COMMIT_SHORT_SHA .

- docker push $IMAGE_NAME:$CI_COMMIT_SHORT_SHA

# =========================
# DEVELOPMENT
# =========================

deploy-dev:
image: alpine:latest

stage: deploy

only:
- develop

tags:
- main-runner

before_script:
- apk add --no-cache curl sed
- curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
- chmod +x kubectl
- mv kubectl /usr/local/bin/

variables:
KUBECONFIG: /kubeconfig

script:
- sed -i "s|IMAGE_TAG|$CI_COMMIT_SHORT_SHA|g" k8s/dev/deployment.yaml

- kubectl apply -f k8s/dev/

# =========================
# PRODUCTION
# =========================

deploy-prod:
image: alpine:latest

stage: deploy

only:
- main

tags:
- main-runner

before_script:
- apk add --no-cache curl sed
- curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
- chmod +x kubectl
- mv kubectl /usr/local/bin/

variables:
KUBECONFIG: /kubeconfig

script:
- sed -i "s|IMAGE_TAG|$CI_COMMIT_SHORT_SHA|g" k8s/prod/deployment.yaml

- kubectl apply -f k8s/prod/

Cara Kerja

Push develop

git checkout -b develop
git push origin develop

GitLab akan:



✅ build image
✅ deploy ke namespace development
✅ port 30081


Push main

git checkout main
git push origin main

GitLab akan:

✅ build image
✅ deploy production
✅ namespace production
✅ port 30080

Buat Branch Develop dari Main (RECOMMENDED)

Di Mac/local repo:

git checkout main
git pull origin main

Lalu:

git checkout -b develop

Push ke GitLab:

git push -u origin develop

Cara Merge ke Production

Kalau development sudah aman:

git checkout main
git merge develop
git push origin main

Atau via GitLab Merge Request

Lebih production style:

develop

Create Merge Request

Review

Merge ke main

Cek Branch

git branch

Cek Remote Branch

git branch -a

Setelah Ini Pipeline Akan Jalan Terpisah

Push develop

Pipeline:

deploy-dev

Push main

Pipeline:

deploy-prod

Untuk melihat semua pod dari semua namespace:

kubectl get pods -A

Melihat Semua Resource Semua Namespace

kubectl get all -A

Melihat Pod Namespace Tertentu

Development

kubectl get pods -n development

Production

kubectl get pods -n production

Monitoring Real-Time

watch kubectl get pods -A

Refresh otomatis tiap beberapa detik.

Untuk melihat detail pod gunakan:

kubectl describe pod nginx-app-5795db6896-dw5zg -n production

atau pod kedua:

kubectl describe pod nginx-app-5795db6896-vrtd5 -n production

Shortcut

Kalau mau describe semua pod namespace production:

kubectl describe pods -n production

Melihat Log Pod

kubectl logs nginx-app-5795db6896-dw5zg -n production

Realtime:

kubectl logs -f nginx-app-5795db6896-dw5zg -n production

Kalau Pod Lebih Dari 1 Container

Gunakan:

kubectl logs POD_NAME -c CONTAINER_NAME -n production

Melihat Deployment

kubectl describe deployment nginx-app -n production

Melihat Service

kubectl describe svc nginx-service -n production

Hasil UI di gitlab

image 44

Troubleshoot

Jika muncul error :

This job is stuck because of one of the following problems. There are no active runners online, no runners for the protected branch , or no runners that match all of the job’s tags: main-runner Go to project CI settings

Cara Fix Paling Mudah

Masuk ke:

GitLab Project Settings CI/CD Runner Settings

Enable Ini

✅ Run untagged jobs

(optional)

dan paling penting:

disable Protected

atau nonaktifkan protection branch.

Similar Posts