Jalur CD · Tekton di minikube · putaran kustom
Cara membaca satu pipeline Tekton tumbuh tiap lab: apa yang ditambahkan, fungsi ↔ command yang menjalankannya, sintaks YAML yang menyusunnya, dan mana nama yang bebas dikustom vs terikat (kata baku). Jalur CI (Lab 1–2 di GitHub Actions) adalah jalur terpisah — tak dibahas di sini.
echo
Yang ditambahkan: Task echo & checkout, satu Pipeline, konsep params dan runAfter. Ini fondasi — rantai clone → lint → tests → build → deploy terbentuk, tapi 4 terakhir masih echo (placeholder).
📦 Yang harus di-install — 5 tool (sekali saja)
# ⚠️ unduh binary di ~ (HOME), BUKAN /mnt/c — Windows Defender hapus binary Linux $ cd ~ $ uname -m # cek dulu: x86_64 = Intel/AMD · aarch64 = ARM (Mac) # 1) Docker — SAMA untuk semua mesin $ sudo apt install -y docker.io $ sudo usermod -aG docker $USER && newgrp docker # 2) kubectl — pilih SATU baris sesuai arsitektur $ curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" # amd64 $ curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl" # ⟵ arm64 (Mac) $ sudo install kubectl /usr/local/bin/ # 3) minikube — pilih SATU, lalu nyalakan $ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 # amd64 $ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-arm64 # ⟵ arm64 (Mac) $ sudo install minikube-linux-* /usr/local/bin/minikube $ minikube start --driver=docker # driver 'docker' untuk KEDUA arsitektur # 4) tkn — $(uname -m) otomatis mengisi x86_64 / aarch64 → 1 baris utk semua $ V=$(curl -s https://api.github.com/repos/tektoncd/cli/releases/latest | grep -oP '"tag_name":\s*"v\K[^"]+') $ curl -sLO "https://github.com/tektoncd/cli/releases/download/v$V/tkn_${V}_Linux_$(uname -m).tar.gz" $ sudo tar xzf tkn_${V}_Linux_$(uname -m).tar.gz -C /usr/local/bin/ tkn # 5) Tekton DI DALAM cluster (Pipelines + Triggers) — "engine"-nya (SAMA semua) $ kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml $ kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml $ kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml $ kubectl get pods -n tekton-pipelines # verifikasi: 6 pod 1/1 Running
amd64 vs arm64 = arsitektur CPU, bukan OS. x86_64/amd64 = Intel/AMD (mayoritas Windows-WSL) · aarch64/arm64 = ARM (Mac Apple Silicon M1/M2/M3). Salah arsitektur → binary Exec format error.
VirtualBox di Mac = pengganti WSL — cara Mac menjalankan Ubuntu (host-nya), bukan driver minikube. Di dalam Ubuntu-nya, minikube tetap --driver=docker. Yang berubah cuma arsitektur binary (arm64), bukan cara install-nya.
✅ Verifikasi tiap tool detail lengkap: §K → “Cara cek tiap tool”
$ docker --version && docker ps # Docker jalan (tanpa 'permission denied') $ kubectl version --client # kubectl OK (--client = tak butuh cluster) $ minikube status # minikube Running $ tkn version # tkn OK $ kubectl get pods -n tekton-pipelines # engine Tekton: 6 pod 1/1 Running
Insight: hasil clone jatuh ke emptyDir pod → hilang saat pod selesai. Makanya lint/tests belum benar-benar memakainya — solusinya Workspace di §L5.
Fungsi ↔ Command
Sintaks YAML — bagian intinya
kind: Task # satuan kerja = 1 pod metadata: name: echo # BEBAS spec: params: # slot input yang bikin task reusable - name: message steps: - name: echo-message image: alpine:3 # TERIKAT: tempat step jalan args: ["$(params.message)"] # sisip nilai param --- kind: Pipeline spec: params: # LAPIS 1: param milik pipeline - name: repo-url tasks: - name: clone # nama task-di-pipeline (BEBAS) taskRef: { name: checkout } params: # LAPIS 2: dioper ke task - name: repo-url value: "$(params.repo-url)" - name: lint runAfter: [ clone ] # INI yang menentukan URUTAN
2 lapis params: param pipeline (spec.params, yang kamu kirim via -p) dioper ke param task (tasks[].params). Nama boleh sama, perannya beda lapis. Dan runAfter = satu-satunya yang menentukan urutan jalan.
BEBAS vs TERIKAT di lab ini
Yang ditambahkan: EventListener + TriggerBinding + TriggerTemplate, plus ServiceAccount pipeline + RBAC (tak ada di dokumen IBM). Pipeline-nya sama — yang berubah: pemicunya jadi event, bukan tkn start manual. Ini cabang, bukan batang.
📦 Yang harus di-install
Tak ada instalasi baru. Tekton Triggers sudah ikut terpasang di §L3 (langkah 5). Di lab ini kamu cuma membuat objek lewat kubectl apply -f rbac.yaml (SA + RBAC) & 3 file trigger — lihat blok Fungsi ↔ Command di bawah.
Fungsi ↔ Command
Sintaks YAML — rantai 3 objek trigger
kind: EventListener metadata: { name: lab4-listener } spec: serviceAccountName: pipeline # ← harus cocok dgn rbac.yaml triggers: - bindings: [{ ref: lab4-binding }] template: { ref: lab4-template } --- kind: TriggerBinding # AMBIL data dari isi event spec: { params: - name: repository value: $(body.repository.url) } --- kind: TriggerTemplate # CETAK PipelineRun baru spec: { resourcetemplates: - kind: PipelineRun metadata: { generateName: lab4-pipeline-run- } spec: { pipelineRef: { name: lab4-pipeline }}} # ← WAJIB = metadata.name pipeline asli
Kendala nyata yang kamu lewati: pipelines.tekton.dev "lab4-pipeline" not found — TriggerTemplate merujuk lab4-pipeline tapi pipeline.yaml masih bernama cd-pipeline. Ganti nama = ganti di SEMUA tempat yang merujuk (impact map).
BEBAS vs TERIKAT di lab ini
Dari mana ClusterRole itu? tekton-triggers-eventlistener-roles/-clusterroles ikut terpasang saat install Tekton Triggers (Lab 3), bukan kamu buat. rbac.yaml cuma menyambungkan SA pipeline ke role itu.
Yang ditambahkan: ganti checkout buatan sendiri dengan git-clone dari catalog, dan sediakan Workspace + PVC supaya hasil clone tersimpan (bukan hilang di emptyDir). Ini tulang punggung — tanpanya lint & test tak bisa lihat kode.
📦 Yang harus di-install
# git-clone dari catalog — ⚠️ JANGAN `tkn hub install` (server mati) $ kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.9/git-clone.yaml # storageClass 'standard' sudah default di minikube — cukup dicek: $ kubectl get storageclass
Fungsi ↔ Command
tkn hub)kubectl apply -f .../git-clone/0.9/git-clone.yamlSintaks YAML — colokan workspace
kind: PersistentVolumeClaim metadata: { name: custom-pvc } spec: storageClassName: standard # minikube; IMMUTABLE (delete dulu utk ubah) accessModes: [ ReadWriteOnce ] --- kind: Pipeline spec: workspaces: - name: ws-source # DEKLARASI colokan (BEBAS) tasks: - name: clone workspaces: - name: output # TERIKAT: git-clone minta "output" workspace: ws-source # sambungkan ke deklarasi di atas taskRef: { name: git-clone } params: - name: url # TERIKAT: bukan repo-url! - name: revision # TERIKAT: bukan branch!
Bedakan: workspaces: (jamak, header deklarasi) vs workspace: (tunggal, penunjuk ke deklarasi). Satu nama workspace harus identik di 3 tempat: deklarasi spec.workspaces, tiap task workspace:, dan flag -w name=.
BEBAS vs TERIKAT di lab ini
Yang ditambahkan: ganti placeholder lint/tests jadi task nyata — flake8 dari catalog + nose tulis sendiri — yang membaca kode lewat workspace. Muncul juga cleanup/init.
📦 Yang harus di-install
# flake8 dari catalog $ kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/flake8/0.1/flake8.yaml # nose = TULIS task sendiri (tak ada yang di-install) # ⚠️ fix DNS node minikube — task ber-`script:` menarik image dari cgr.dev $ minikube ssh "printf 'nameserver 8.8.8.8\noptions ndots:0\n' | sudo tee /etc/resolv.conf" $ minikube ssh "getent hosts cgr.dev" # keluar IP = DNS beres
Fungsi ↔ Command
script: tarik image cgr.dev)minikube ssh "... | sudo tee /etc/resolv.conf"Sintaks YAML — dua bentuk args yang beda
# TASK LINT (flake8 dari catalog) - name: lint workspaces: [{ name: source, workspace: ws-source }] # TERIKAT: "source" taskRef: { name: flake8 } params: - name: image # TERIKAT, huruf kecil value: "python:3.9-slim" - name: args # flake8 = bentuk LIST value: ["--count","--max-line-length=127"] # TASK NOSE (tulis sendiri) - name: nose steps: [{ script: | pip install -r requirements.txt nosetests $(params.args) }] # dipanggil pipeline dgn: args (STRING, bukan list!) value: "-v --with-spec --spec-color"
Jebakan case-sensitive: flake8 minta args berbentuk LIST ["a","b"]; nose (buatanmu) minta STRING "-v ...". Beda bentuk untuk nama param yang sama.
Kendala nyata: satu nama workspace ditulis 3 versi (ws-sources typo · pipeline-workspace lama · ws-source) → expects workspace "ws-source" but none exists. Samakan SEMUA.
BEBAS vs TERIKAT di lab ini
Yang ditambahkan: ganti placeholder build jadi buildah — bangun Docker image lalu push ke DockerHub. Butuh param build-image + secret registry regcred.
📦 Yang harus di-install / disiapkan
# buildah dari catalog — Task biasa, ⚠️ BUKAN ClusterTask (sudah dihapus) $ kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/buildah/0.9/buildah.yaml # akun DockerHub + Access Token (R/W) → login di WSL (password = token): $ docker login -u uyasky # bikin secret registry + sematkan ke ServiceAccount 'default': $ kubectl create secret generic regcred \ --from-file=.dockerconfigjson=$HOME/.docker/config.json \ --type=kubernetes.io/dockerconfigjson $ kubectl patch serviceaccount default -p '{"secrets":[{"name":"regcred"}]}' $ kubectl get secret regcred # verifikasi
Fungsi ↔ Command
Sintaks YAML — task build
spec: params: - name: build-image # param pipeline (BEBAS) — tambahkan di spec.params! tasks: - name: build workspaces: [{ name: source, workspace: ws-source }] taskRef: { name: buildah } # JANGAN tulis kind: ClusterTask params: - name: IMAGE # TERIKAT — HURUF BESAR SEMUA (case-sensitive!) value: "$(params.build-image)" - name: STORAGE_DRIVER value: "vfs" # adaptasi minikube (overlay gagal)
Kendala nyata: 4 task masih workspace: pipeline-workspace (harus ws-source) + param build-image belum di spec.params. Dua-duanya harus beres.
BEBAS vs TERIKAT di lab ini
Catatan: nama/tag image bebas, TAPI bagian uyasky/ wajib username DockerHub-mu — kalau bukan, push denied.
Yang ditambahkan: manifest Deployment + Service. Bukan build ulang — cukup tarik image Lab 7 dari DockerHub → run di minikube → aplikasi Hit Counter (Flask) hidup & bisa di-curl. Pakai Jalur A: kubectl apply langsung (manifest = infrastruktur).
📦 Yang harus di-install
Tak ada instalasi. Image sudah tersedia di DockerHub dari §L7 (docker.io/uyasky/custom-tekton:lab7). Kamu cuma menulis deploy.yaml lalu kubectl apply — lihat blok Fungsi ↔ Command di bawah.
Fungsi ↔ Command
Sintaks YAML — aturan label yang WAJIB cocok
kind: Deployment metadata: { name: surya-counter } spec: selector: { matchLabels: { app: surya-counter }} # (1) template: metadata: { labels: { app: surya-counter }} # (2) WAJIB == (1) spec: { containers: [{ image: docker.io/uyasky/custom-tekton:lab7 # dari DockerHub-mu ports: [{ containerPort: 8000 }] }] } # port gunicorn (TERIKAT) --- kind: Service spec: selector: { app: surya-counter } # (3) WAJIB == (2) ports: [{ port: 8000, targetPort: 8000 }]
Aturan keras yang divalidasi Kubernetes: spec.selector.matchLabels = spec.template.metadata.labels, kalau beda → Deployment ditolak (selector does not match template labels). Lalu Service selector juga harus = label pod, kalau tidak curl gagal diam-diam. 3 label app: harus identik. (Ini persis error yang kamu temui: satu label sempat lab8-app.)
Beda pod ini: pod aplikasi Running terus (dijaga Deployment), bukan Completed seperti pod task. Itu sebabnya curl /health tetap menjawab walau pipeline sudah berakhir.
BEBAS vs TERIKAT di lab ini
Ringkasan lintas-lab: mana nama yang bebas kamu tentukan (asal konsisten) vs mana yang wajib persis karena diminta task catalog.
| BEBAS | Wajib konsisten di |
|---|---|
| nama pipeline | tkn pipeline start · pipelineRef.name |
| nama workspace | tiap task workspace: · -w name= |
| nama PVC | -w claimName= |
| param pipeline | -p …= · $(params.…) |
| nama task di pipeline | runAfter: [nama] |
| nama app (Deploy) | 3 label app: harus sama |
| TERIKAT | Diminta oleh |
|---|---|
output | git-clone (bukan source) |
source | flake8, nose, buildah |
url, revision | git-clone |
image (kecil) | flake8 |
IMAGE (BESAR) | buildah |
args list vs string | flake8 vs nose |
Aturan emas seluruh dokumen: ganti satu nama = ganti di SEMUA tempat yang merujuk. Kalau lupa, ini gejalanya.
| Yang diubah | Wajib ikut diubah | Kalau lupa → gejalanya |
|---|---|---|
| Nama pipeline | tkn pipeline start · pipelineRef | pipelines.tekton.dev "…" not found |
| Nama workspace | semua workspace: · -w name= | workspace … but none exists |
| Nama PVC | -w claimName= | pod Pending |
| Nama param | -p …= dan $(params.…) | param not found |
storageClassName | immutable → delete PVC dulu | PVC Pending selamanya |
serviceAccountName (EL) | rbac.yaml | EventListener gagal buat PipelineRun |
| label app (Deploy) | selector = template = Service | selector does not match template labels |
| Gejala | Artinya | Cari di |
|---|---|---|
Failed 0 detik | gagal validasi (param/YAML) | pesan kubectl apply / tkn logs |
Failed di tengah | gagal eksekusi | tkn pipelinerun logs |
| Log kosong (Pending/ImagePullBackOff) | container belum start | kubectl describe pod → Events |
0/1 Completed | NORMAL — task sekali jalan | — (bukan error) |