Membangun arsitektur Jenkins terdistribusi: mengapa controller tidak boleh menjalankan build produksi, menghubungkan SSH agent permanen, agent Docker dinamis, hingga agent Kubernetes dengan pod sementara.

Di episode 2 kalian menulis Jenkinsfile pertama dengan agent any — dan pada saat itu, build dijalankan di mana saja. Pertanyaannya sekarang: di mana seharusnya build itu berjalan? Jawabannya adalah bahan dari episode ini: distributed architecture. Jenkins yang sesungguhnya tidak menjalankan build di controller, melainkan menyebar pekerjaan ke banyak agent — permanen maupun dinamis.
Episode ini mungkin yang paling berpengaruh terhadap kematangan arsitektur kalian. Kita akan membahas prinsip keamanan paling penting di seluruh Jenkins (controller tidak pernah menjalankan build produksi), lalu mengkonfigurasi tiga jenis agent: SSH agent permanen, Docker agent dinamis, dan Kubernetes agent dinamis, serta menggunakan labels untuk mengarahkan pekerjaan ke agent yang tepat.
Ini aturan nomor satu di dunia Jenkins. Dua alasan utamanya:
npm install, pip install, atau script di dalam repo. Kode yang berjalan di controller berarti kode itu berjalan dengan hak akses konfigurasi Jenkins, kredensial, dan seluruh sistem. Satu repo yang ter-compromise sudah cukup untuk menghancurkan semuanya.Warning
Prinsipnya mutlak: controller adalah konduktor orkestra, bukan pemain musik. Ia mengatur, menjadwalkan, dan memantau — tetapi tidak pernah memainkan build. Selalu arahkan build ke agent, sekecil apapun job-nya. Job "tidak berbahaya" sekalipun bisa menjadi vektor serangan.
Sebelum mengkonfigurasi, pahami tiga istilah yang sering tertukar:
Semua node dikelola dari Manage Jenkins → Nodes (node built-in bernama Built-In Node adalah controller itu sendiri — yang harus kita hindari untuk build produksi). Mari kita bahas tiga cara menghubungkan node pekerja.
Cara paling klasik: menghubungkan sebuah VM Linux terpisah sebagai agent tetap. Kontroler login ke VM tersebut lewat SSH dan menjalankan build di sana. Pertama, siapkan user dan SSH key di VM pekerja:
sudo useradd -m -s /bin/bash jenkins
sudo -u jenkins ssh-keygen -t ed25519 -C "jenkins-agent" -f /home/jenkins/.ssh/id_ed25519 -N ""
sudo -u jenkins ssh-copy-id jenkins@agent-serverSelanjutnya, pasang plugin SSH Build Agents, lalu di UI: Manage Jenkins → Nodes → New Node. Isi nama node, jumlah executor, Remote root directory (misal /home/jenkins/workspace), Labels (misal linux), dan Launch method pilih Launch agents by SSH dengan mengisi host VM serta kredensial SSH key. Setelah terhubung, node muncul dalam daftar Nodes dengan status online.
SSH agent cocok untuk kebutuhan tetap: build machine yang memang harus selalu ada, misalnya runner dengan software khusus yang mahal untuk diputar ulang.
Pendekatan kedua jauh lebih modern: jangan simpan agent, ciptakan per job. Plugin Docker memungkinkan controller men-spin kontainer sementara dari sebuah image, menjalankan job di dalamnya, lalu menghancurkan kontainer itu setelah selesai. Bersih, terisolasi, dan tanpa sisa — kalian bahkan bisa memantaunya dengan docker ps selama job berjalan.
Konfigurasinya: Manage Jenkins → Clouds → New cloud → Docker, isi Docker Host URI (misal unix:///var/run/docker.sock), lalu definisikan Docker Image yang akan dipakai sebagai agent (misal jenkins/inbound-agent:jdk17) dan beri Labels pada template tersebut.
Setelah itu, pipeline bisa menargetkan cloud ini lewat label:
pipeline {
agent { label 'docker-runner' }
stages {
stage('Build') {
steps {
echo 'Job ini berjalan di dalam kontainer Docker sementara'
}
}
}
}Saat job dipicu, Jenkins mengambil image, menjalankan kontainer, dan meletakkan job di dalamnya. Setelah selesai, kontainer dihapus — tidak ada workspace menumpuk, tidak ada mesin yang harus dirawat. Ini cara yang sangat cocok untuk isolasi build pada mesin yang sama.
Pendekatan paling scalable: gunakan cluster Kubernetes sebagai sumber agent. Plugin Kubernetes memungkinkan Jenkins men-spin pod sementara setiap kali ada job — sebuah pod berisi kontainer JNLP (agent inbound) plus kontainer alat bantu build seperti Maven atau Node. Setelah job selesai, pod dihancurkan otomatis.
Setelah plugin terpasang dan cloud Kubernetes dikonfigurasi (URL cluster, kredensial kubeconfig, namespace), Jenkins bisa men-spin pod seperti ini:
apiVersion: v1
kind: Pod
spec:
containers:
- name: jnlp
image: jenkins/inbound-agent:jdk17
- name: maven
image: maven:3.9-eclipse-temurin-17
command: ["cat"]
tty: truePipeline kemudian bisa memilih pod ini lewat label atau direktif agent yang merujuk pod template. Keuntungan besarnya: kapasitas build mengikuti kapasitas cluster. Saat banyak job masuk, Kubernetes men-spin pod sebanyak yang dibutuhkan; saat sepi, pod menghilang — tidak ada biaya idle.
Kita sudah melihat pola agent yang memakai label docker-runner beberapa kali. Label adalah cara Jenkins mengelompokkan node dan menentukan node mana yang boleh menjalankan job tertentu. Satu node bisa punya banyak label, dan satu job bisa mensyaratkan kombinasi label:
| Bentuk | Arti |
|---|---|
label 'linux' | Jalan di node berlabel linux |
label 'linux && docker' | Jalan di node yang punya label linux dan docker |
label 'k8s-build' | Jalan di pod template berlabel k8s-build |
Aturan praktisnya: beri label berdasarkan kemampuan, bukan nama host. Label docker lebih bermakna daripada node-01 — karena kalian bisa menambahkan node baru dengan kemampuan yang sama tanpa mengubah pipeline sama sekali. Ini juga yang membuat arsitektur Jenkins tetap luwes saat mesin diganti atau diperluas.
Tip
Mulai dengan strategi label sederhana: linux untuk VM SSH, docker-runner untuk cloud Docker, dan k8s-* untuk pod Kubernetes. Jangan menciptakan label yang terlalu spesifik per node — tujuannya adalah menyembunyikan detail fisik dari pipeline.
Pada episode 3 ini kalian telah memahami:
agent dengan label docker-runner.Inti yang harus kalian bawa: controller mengatur, pekerjaan dikirim ke agent, dan agent bisa muncul serta menghilang secara dinamis. Di episode 4 kita akan menjawab pertanyaan berikutnya — kapan pipeline dijalankan — dengan membahas event triggers dan otomasi eksekusi: trigger manual, jadwal cron, poll SCM, webhook GitHub dan GitLab, hingga Multibranch Pipeline. Sampai jumpa di episode 4!