Second Brain

Sebuah catatan perjalanan menekuni bidang IT Infra, Cloud, DevOps, dan Security

Architecting a Self-Hosted GitOps Pipeline: Implementation with K3s, Gitea, & Argo CD

Di era cloud-native saat ini, GitOps telah berevolusi dari sekadar konsep teoretis menjadi standar industri untuk Continuous Delivery. Tutorial ini dirancang untuk membawa Anda melampaui “Hello World” dan masuk ke ranah implementasi infrastruktur nyata.

Kita akan membangun sebuah Self-Hosted GitOps Platform yang sepenuhnya berdaulat (sovereign), ringan, namun production-ready. Dengan meninggalkan pendekatan imperatif (manual kubectl apply) menuju pendekatan deklaratif, kita menjadikan repositori Git sebagai Single Source of Truth (SSoT) bagi seluruh infrastruktur.

Stack Teknologi & Arsitektur

Solusi ini dibangun di atas tumpukan teknologi berikut untuk menyeimbangkan performa dan efisiensi sumber daya:

  1. K3s: Kubernetes distro yang dikurangi overhead-nya, ideal untuk edge computing atau dev environments, namun tetap production-grade.

  2. Gitea: Solusi Version Control System (VCS) yang ditulis dalam Go, sangat ringan dan cepat dibandingkan GitLab/GitHub Enterprise.

  3. Argo CD: Alat CD deklaratif untuk Kubernetes yang menerapkan pola GitOps secara native.

  4. 2 VPS Linux (Ubuntu):
    • vps-master (2 Core, 2 GB RAM): Menjalankan K3s Control Plane.
    • vps-worker (2 Core, 8 GB RAM): Menjalankan semua beban kerja aplikasi kita (Gitea, Argo CD, dan aplikasi demo).

Tujuan & Output

Daalam tutorial ini kita akan memiliki sebuah platform GitOps yang berjalan, tetapi juga akan memahami:
  • Arsitektur Klaster Kubernetes: Memahami perbedaan peran antara Master Node (otak) dan Worker Node (otot) dan cara mengkonfigurasinya dengan benar.
  • Deployment Aplikasi: Belajar cara men-deploy aplikasi stateful (Gitea) dan stateless di atas Kubernetes.
  • Alur Kerja GitOps End-to-End: Mengalami secara langsung bagaimana sebuah git push dapat secara otomatis mengubah keadaan aplikasi yang berjalan di klaster Anda.

Langkah 1: Persiapan Awal & Konfigurasi Firewall (Wajib di Kedua Server)

Update Sistem & Atur Hostname:

# Update sistem
sudo apt update && sudo apt upgrade -y

# Atur hostname (jalankan di server yang sesuai)
# Di vps-master:
sudo hostnamectl set-hostname vps-master
# Di vps-worker:
sudo hostnamectl set-hostname vps-worker

Sinkronisasi Waktu:

Perbedaan waktu antar node dapat menyebabkan masalah autentikasi sertifikat

sudo apt install -y ntpdate
sudo ntpdate pool.ntp.org

Langkah 2: Instalasi Klaster Kubernetes (K3s)

Instal K3s di vps-master:

Ubah A.A.A.A (IP Publik Master) dan 10.X.X.X (IP Privat Master). Jika tidak ada IP privat, hapus baris --tls-san untuk IP privat.

curl -sfL https://get.k3s.io | sh -s - server \
  --tls-san A.A.A.A \
  --tls-san 10.X.X.X \
  --flannel-iface=eth0

Verifikasi Master & Siapkan kubectl:

# Periksa status layanan, pastikan 'active (running )'
sudo systemctl status k3s.service

# Siapkan kubectl untuk pengguna Anda agar tidak perlu sudo
mkdir -p $HOME/.kube
sudo cp -i /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# Verifikasi dengan kubectl tanpa sudo
kubectl get nodes

Dapatkan Token Join:

# Di vps-master
cat /var/lib/rancher/k3s/server/node-token

Instal K3s di vps-worker:

# Di vps-worker
curl -sfL https://get.k3s.io | K3S_URL=https://A.A.A.A:6443 K3S_TOKEN="TOKEN_DARI_MASTER" sh -s - agent \
  --flannel-iface=eth0

Verifikasi Klaster Lengkap:

kubectl get nodes -o wide

Seharusnya sekarang kita melihat kedua node (vps-master dan vps-worker ) dalam status Ready.

 

Langkah 3: Instalasi Gitea (Layanan Git Self-Hosted)

Buat Manifest gitea.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitea-data-pvc
  namespace: gitea
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi # Alokasikan 5GB untuk data Gitea
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: gitea
  namespace: gitea
spec:
  serviceName: "gitea"
  replicas: 1
  selector:
    matchLabels:
      app: gitea
  template:
    metadata:
      labels:
        app: gitea
    spec:
      containers:
      - name: gitea
        image: gitea/gitea:latest
        ports:
        - containerPort: 3000
          name: web
        - containerPort: 2222
          name: ssh
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
  name: gitea-http
  namespace: gitea
spec:
  type: NodePort
  selector:
    app: gitea
  ports:
  - name: http
    port: 3000
    targetPort: 3000
    nodePort: 30080 # Kita akan akses Gitea via port 30080
---
apiVersion: v1
kind: Service
metadata:
  name: gitea-ssh
  namespace: gitea
spec:
  type: NodePort
  selector:
    app: gitea
  ports:
  - name: ssh
    port: 2222
    targetPort: 2222
    nodePort: 30022 # Port untuk Git over SSH

Terapkan Manifest:

# Di vps-master
kubectl create namespace gitea
kubectl apply -f gitea.yaml

Tunggu Pod gitea-0 berjalan dengan command berikut:

kubectl get pods -n gitea -w

Cari tahu di node mana Gitea berjalan dengan command:

kubectl get pods -n gitea -o wide 
# Kemungkinan besar di vps-worker

Buka browser dan akses http://<IP_PUBLIK_WORKER>:30080

Isi Halaman Instalasi:

Pada halaman “Initial Configuration”. Isi dengan cermat:

  • Database Settings: Biarkan default, yaitu SQLite3. Ini adalah pilihan termudah untuk memulai.
  • Gitea Base URL: Ubah menjadi URL yang Anda gunakan untuk mengaksesnya. Contoh: http://<IP_PUBLIK_WORKER>:30080/
  • SSH Server Domain: Isi dengan IP Publik vps-worker juga.
  • SSH Port: Ubah menjadi 30022 (sesuai NodePort yang kita definisikan di gitea.yaml).
  • Administrator Account Settings: Buat akun admin Anda. Isi username, password, dan email. Catat username dan password ini!

Selesaikan Instalasi:

Gulir ke bawah dan klik tombol besar “Install Gitea”. Setelah beberapa detik, Anda akan diarahkan ke halaman login atau langsung ke dashboard Gitea.

Langkah 4: Instalasi Argo CD (Otak GitOps)

Instal Argo CD:

# Di vps-master
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Ekspos UI Argo CD:

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
Login ke Argo CD:
Cari tahu di node mana Pod argocd-server berjalan
ubectl get pods -n argocd -o wide

Dapatkan port NodePort HTTPS

kubectl get svc argocd-server -n argocd

Dapatkan password admin

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

Akses UI di https://<IP_PUBLIK_NODE_ARGO_BERJALAN>:<PORT_HTTPS>. Login dengan user admin dan password yang didapat.

 

Langkah 5: Menghubungkan Semuanya & Deploy Aplikasi Pertama

Inisialisasi Repositori Gitea:

Argo CD tidak bisa memantau repositori yang benar-benar kosong. Kita harus melakukan setidaknya satu commit awal.

  • Login ke Gitea Anda di http://<IP_PUBLIK_WORKER>:30080.
  • Klik ikon + di kanan atas dan pilih “New Repository”.
  • Beri nama repositori, misalnya gitops-app.
  • Biarkan repositori menjadi Public untuk saat ini agar lebih mudah.
  • Jangan centang “Initialize Repository”. Kita akan melakukannya dari baris perintah.
  • Klik “Create Repository”.

Clone dan Inisialisasi dari Terminal:

  • Lakukan langkah-langkah ini di komputer lokal.
# Buat direktori kerja yang bersih
cd ~
mkdir gitops-project && cd gitops-project

# Clone repositori kosong Anda. Ganti URL dengan URL dari halaman Gitea Anda.
git clone http://<IP_PUBLIK_WORKER>:30080/NAMA_USER_GITEA_ANDA/gitops-app.git
cd gitops-app

# Buat file pertama
echo "# Proyek Aplikasi GitOps Saya" > README.md

# Lakukan commit pertama
git add .
git commit -m "Initial commit: Add README file"

# Push ke Gitea untuk membuat branch 'main'
git push -u origin main

Hubungkan Argo CD ke Gitea:

Buka UI Argo CD:
Akses https://<IP_PUBLIK_NODE_ARGO_BERJALAN>:<PORT_HTTPS>.
Hubungkan Repositori:
  • Buka Settings (ikon gerigi ) > Repositories.
  • Klik CONNECT REPO USING HTTPS.
  • Isi formulir:
    • Type: git
    • Repository URL: Gunakan URL lengkap repositori tadi, termasuk nama pengguna dan nama repo. Ini adalah URL yang sama dengan yang digunakan untuk git clonehttp://<IP_PUBLIK_WORKER>:30080/NAMA_USER_GITEA_ANDA/gitops-app.git
    • Username / Password: Masukkan kredensial Gitea.
  • Klik CONNECT.
Sekarang seharusnya melihat status koneksi Successful. Ini adalah bukti bahwa Argo CD sekarang dapat berkomunikasi dengan Gitea melalui internet.

Langkah 6: Membuat Aplikasi GitOps Pertama 

Kita akan melanjutkan pekerjaan kita di dalam direktori repositori yang sudah kita clone tadi.

Buat Manifest Aplikasi di Repositori Lokal

Pastikan Anda berada di dalam direktori repositori gitops-app.

Buat file manifest Kubernetes sederhana untuk aplikasi “Hello World”. Kita akan menggunakan nano untuk membuat file bernama hello-app.yaml.

nano hello-app.yaml
Salin dan tempel konfigurasi berikut ke dalam editor nano.
  • Deployment: Memberitahu Kubernetes untuk menjalankan 2 replika/salinan dari sebuah image kontainer sederhana (nginxdemos/hello).
  • Service: Mengekspos Deployment tersebut ke jaringan menggunakan NodePort di port 30001, sehingga kita bisa mengaksesnya dari browser.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
  labels:
    app: hello
spec:
  replicas: 2 # Kita mulai dengan 2 replika
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: web
        image: nginxdemos/hello # Image sederhana untuk demo
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world-svc
spec:
  type: NodePort
  selector:
    app: hello
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30001 # Kita akan akses aplikasi di port 30001

Commit dan Push file ini ke Gitea:

Perintah ini akan mengirim definisi aplikasi kita ke repositori pusat.

git add hello-app.yaml
git commit -m "feat: Add initial manifest for hello-world app"
git push

 

Buat “Aplikasi” di Argo CD

Sekarang kita perlu memberitahu Argo CD, “Hei, tolong pantau repositori gitops-app dan terapkan apa pun yang ada di dalamnya.”

  • Buka UI Argo CD di browser Anda.
  • Di halaman utama, klik tombol “+ NEW APP”.
  • Isi formulir “Create Application”:
    • Application Name: hello-world (Beri nama yang deskriptif)
    • Project Name: Biarkan default.
    • Sync Policy: Pilih Automatic. Ini adalah kunci dari GitOps.
      • Centang juga kotak PRUNE RESOURCES. Ini berarti jika kita menghapus file dari Git, Argo CD juga akan menghapus resource-nya dari klaster.
      • Centang juga kotak SELF HEAL. Ini berarti jika kita mengubah sesuatu di klaster secara manual (misalnya dengan kubectl), Argo CD akan secara otomatis mengembalikannya ke keadaan yang didefinisikan di Git.
    • Repository URL: Pilih repositori Gitea dari daftar dropdown (seharusnya sudah ada karena kita sudah menghubungkannya).
    • Revision: Biarkan HEAD (ini berarti selalu gunakan versi terbaru dari branch utama).
    • Path: Biarkan . (ini berarti pantau dari direktori root repositori).
    • Cluster URL: Biarkan https://kubernetes.default.svc.
    • Namespace: Biarkan default.
  • Klik tombol “CREATE” di bagian atas.

Verifikasi Aplikasi Anda

Di Terminal (vps-master ):

Anda akan melihat 2 Pod hello-world baru sedang berjalan (Running) dan sebuah Service hello-world-svc dengan port 30001.

sudo kubectl get pods,svc
Di Browser:
Buka tab baru dan navigasikan ke salah satu alamat berikut (keduanya akan berfungsi karena ini NodePort):
  • http://<IP_PUBLIK_MASTER>:30001
  • http://<IP_PUBLIK_WORKER>:30001
Kita akan disambut oleh halaman dari kontainer nginxdemos/hello yang berisi informasi server.
Untuk benar-benar merasakan kekuatan dari apa yang telah kita bangun, mari kita lakukan satu perubahan terakhir. Kita akan mengubah jumlah replika aplikasi kita dari 2 menjadi 3, hanya dengan melakukan git push.
Kembali ke Terminal vps-master:
Pastikan Anda berada di direktori ~/gitops-project/gitops-app.
Edit File hello-app.yaml:
Cari baris replicas: 2 dan ubah menjadi replicas: 3.
# ...
spec:
  replicas: 3 # Mengubah dari 2 menjadi 3
# ...
Commit dan Push Perubahan:
git add hello-app.yaml
git commit -m "ops: Scale hello-world replicas to 3"
git push
Amati Argo CD dan Kubernetes:
    • Buka UI Argo CD di browser. Dalam beberapa detik, kita akan melihat status aplikasi hello-world berubah menjadi Progressing. Argo CD mendeteksi bahwa keadaan di klaster (2 replika) tidak lagi cocok dengan keadaan di Git (3 replika).
    • Karena SELF HEAL aktif, Argo CD akan secara otomatis “menyembuhkan” klaster dengan membuat 1 Pod tambahan.
    • Di terminal vps-master, jalankan:
    • sudo kubectl get pods
    • Kita akan melihat 3 Pod hello-world sedang berjalan.

Kita baru saja melakukan scaling pada aplikasi tanpa menyentuh kubectl sama sekali. Semua perubahan terdokumentasi, dapat diaudit, dan otomatis. Inilah kekuatan dari GitOps.