Sự chuyển dịch sang Pipeline chuẩn Kubernetes-Native
Quản lý CI/CD thường mang lại cảm giác như đang phải trả một khoản “chi phí hạ tầng bóng ma”. Tôi đã dành quá nhiều ngày nghỉ cuối tuần chỉ để vá các node Jenkins độc lập hoặc gỡ lỗi các runner bên ngoài vốn không thể nhìn thấy các dịch vụ nội bộ trong cluster. Sự bất cập này là có thật: ứng dụng của bạn sống trong Kubernetes, nhưng bộ máy xây dựng nó lại là một “người lạ” đứng nhìn từ bên ngoài. Sự sai lệch này tạo ra các rào cản về xác thực, độ trễ mạng và lãng phí tài nguyên khi nhàn rỗi.
Các công cụ CI/CD truyền thống coi Kubernetes như một mục tiêu triển khai thụ động. Chúng không “nói” cùng một ngôn ngữ. Khi lưu lượng truy cập tăng vọt và bạn mở rộng lên 50 node, một runner tĩnh thường trở thành một nút thắt cổ chai lớn. Cuối cùng, bạn phải quản lý hai thế giới khác nhau với hai logic mở rộng khác nhau.
Tekton giải quyết vấn đề này bằng cách biến pipeline thành một phần của chính cluster. Nó không chỉ là một sự tích hợp; nó là một tập hợp các Custom Resource Definitions (CRDs). Theo kinh nghiệm của tôi, việc chuyển sang Tekton đã giúp giảm khoảng 40% chi phí cấu hình vì chúng tôi không còn phải quản lý các máy ảo runner riêng biệt. Mỗi bước build là một container. Mỗi pipeline là một đối tượng native. Đó là một stack sạch sẽ hơn, sử dụng cùng các mẫu YAML mà bạn vốn đã dùng cho ứng dụng của mình.
Triển khai Tekton Engine
Tekton có tính module. Bạn không cần phải cài đặt một bộ công cụ cồng kềnh, nặng nề. Bạn chỉ cần lấy những thành phần mà workflow của bạn thực sự yêu cầu.
1. Cài đặt Tekton Pipelines
Bắt đầu với thành phần pipeline cốt lõi. Lệnh này sẽ thiết lập controller để theo dõi các hướng dẫn build và thực thi chúng dưới dạng các Pod.
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
Kiểm tra trạng thái để đảm bảo controller đã sẵn sàng:
kubectl get pods -n tekton-pipelines
2. Thêm Tekton Triggers
Nếu bạn muốn cluster phản ứng khi có ai đó push code lên GitHub, bạn cần thành phần Triggers.
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
3. Làm chủ CLI (tkn)
Bạn có thể sử dụng kubectl, nhưng nó giống như việc ăn súp bằng nĩa vậy. tkn CLI được xây dựng dành riêng cho workflow này. Nó xử lý việc stream log qua nhiều container tốt hơn nhiều so với các công cụ tiêu chuẩn.
curl -LO https://github.com/tektoncd/cli/releases/download/v0.32.0/tkn_0.32.0_Linux_x86_64.tar.gz
tar xvzf tkn_0.32.0_Linux_x86_64.tar.gz -C /usr/local/bin tkn
Các thành phần cơ bản: Tasks và Pipelines
Tekton hoạt động giống như trò chơi LEGO. Một Task là viên gạch nhỏ nhất của bạn—một chuỗi các bước chạy trong một Pod. Một Pipeline là bản thiết kế kết nối chúng lại với nhau theo thứ tự.
Định nghĩa một Build Task
Hãy xem xét một task thực hiện clone một repo và kiểm tra các file. Mỗi bước ở đây chạy như một container trong cùng một Pod. Điều này rất hiệu quả vì chúng chia sẻ hệ thống file cục bộ theo mặc định.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: source-check
spec:
steps:
- name: list-files
image: alpine
script: |
#!/bin/sh
# Liệt kê đệ quy các tệp tin trong thư mục source
ls -R $(workspaces.source.path)
Trường workspaces đóng vai trò là cầu nối. Nó kết nối các bước của bạn với một Persistent Volume để bước clone có thể bàn giao dữ liệu cho các bước build hoặc test mà không bị mất dữ liệu.
Kết nối Pipeline
Pipeline quyết định luồng công việc. Bạn có thể chạy các task song song hoặc thiết lập các phụ thuộc nghiêm ngặt.
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: simple-deploy-pipeline
spec:
workspaces:
- name: shared-data
tasks:
- name: fetch-source
taskRef:
name: git-clone
params:
- name: url
value: $(params.repo-url)
workspaces:
- name: output
workspace: shared-data
- name: verify-source
runAfter: ["fetch-source"]
taskRef:
name: source-check
workspaces:
- name: source
workspace: shared-data
Tự động hóa với Triggers
Chạy pipeline thủ công là tốt để gỡ lỗi, nhưng tự động hóa mới là mục tiêu cuối cùng. Tekton Triggers sử dụng hệ thống ba phần: TriggerBinding để lấy dữ liệu webhook, TriggerTemplate để định nghĩa lần chạy, và EventListener để đón nhận lưu lượng truy cập.
TriggerTemplate
Hãy coi đây là một bản mẫu có thể tái sử dụng cho một lần build. Khi một webhook gửi đến, Tekton sẽ chèn commit ID và URL của repo vào bản thiết kế này.
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: app-trigger-template
spec:
params:
- name: git-repo-url
- name: git-revision
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: app-run-
spec:
pipelineRef:
name: simple-deploy-pipeline
params:
- name: repo-url
value: $(tt.params.git-repo-url)
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
Mặc dù 1Gi là tiêu chuẩn cho các microservice nhỏ, tôi thường tăng mức này lên 50Gi cho các monorepo khổng lồ để tránh áp lực lên đĩa trong quá trình build nặng.
Khả năng hiển thị và Giám sát
Làm thế nào để bạn biết nó đang hoạt động? Đây là lúc tkn chứng minh giá trị của mình. Bạn không cần phải săn lùng tên các Pod tạm thời chỉ để xem tại sao một lần build lại thất bại.
Theo dõi Logs (Streaming)
Kiểm tra các lần chạy mới nhất của bạn bằng một lệnh duy nhất:
tkn pipelinerun list
Để theo dõi quá trình build trực tiếp, hãy sử dụng lệnh logs. Nó tự động bám sát quá trình thực thi qua mọi container và bước:
tkn pipelinerun logs <name> -f
Giao diện Dashboard
Nếu bạn thích biểu đồ trực quan về các task của mình, Tekton Dashboard là một công cụ tuyệt vời để gỡ lỗi các trigger phức tạp.
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml
kubectl port-forward svc/tekton-dashboard 9097:9097 -n tekton-pipelines
Truy cập trình duyệt tới localhost:9097. Nó cung cấp cho bạn lịch sử sạch sẽ của mọi lần build và log container theo thời gian thực. Đây là cách nhanh nhất để phát hiện tại sao một TriggerBinding có thể thất bại khi truyền một GitHub secret cụ thể.
Xây dựng CI/CD theo cách này mang lại cảm giác native vì bản chất nó là như vậy. Bạn không đang chống lại nền tảng; bạn đang sử dụng nó. Khi quá trình build kết thúc, các Pod sẽ biến mất. Cluster của bạn luôn tinh gọn. Tài nguyên của bạn tập trung vào người dùng, chứ không phải vào các build runner nhàn rỗi.

