0

Hướng dẫn Setup Jenkins cho hệ thống Monolith - Bài 31: Thiết lập kiến trúc Jenkins Master - Agent (Distributed Builds) để giảm tải cho Server chính

Sau khi đã hoàn thiện toàn bộ vòng đời từ CI, Kiểm thử bảo mật, Quản lý Version, cho đến chiến lược Triển khai Zero-Downtime Blue/Green ở Giai đoạn 3, chúng ta chính thức bước sang Giai đoạn 4: Mở rộng quy mô, Tối ưu hóa và Xử lý sự cố (Scaling & Troubleshooting - Bài 31 đến Bài 40).

Trong các bài học trước, chúng ta đã cấu hình Jenkins chạy toàn bộ mọi thứ (từ giao diện quản lý web, điều phối hàng đợi cho đến việc biên dịch code, chạy hàng nghìn Unit Test, quét SonarQube và Build Docker Image) trên cùng một máy chủ duy nhất (Jenkins Master). Khi dự án Monolith ngày càng phình to và số lượng lập trình viên tăng lên, bạn sẽ nhận thấy máy chủ Master bắt đầu xuất hiện các triệu chứng quá tải: Giao diện web bị đơ, các bản build bị kẹt ở trạng thái Pending hàng giờ đồng hồ vì hết tài nguyên CPU/RAM.

Bài học hôm nay sẽ hướng dẫn bạn giải quyết triệt để vấn đề này bằng cách thiết lập kiến trúc phân tán: Jenkins Master - Agent (Distributed Builds).

1. Bản chất kiến trúc Master - Agent trong Jenkins

Trong mô hình phân tán, nhiệm vụ được tách bạch rõ ràng giữa hai thành phần:

  • Jenkins Master (Server chính):

    • Đóng vai trò là "bộ não" điều phối.

    • Chịu trách nhiệm hiển thị giao diện Web UI, quản lý cấu hình Pipeline, phân phối công việc vào hàng đợi (Queue), quản lý lịch sử bản build, phân quyền RBAC (Bài 28) và lưu trữ Credentials.

    • Quy tắc vàng: Tuyệt đối không cho phép Jenkins Master trực tiếp thực thi các tác vụ build nặng nhọc (như composer install, docker build, phpunit) trên chính nó.

  • Jenkins Agent (Worker / Node phụ):

    • Là các máy chủ (hoặc máy ảo, container) độc lập được kết nối với Master.

    • Chịu trách nhiệm nhận việc từ Master và thực thi trực tiếp toàn bộ các Stage trong Jenkinsfile. Một hệ thống Monolith lớn có thể cắm thêm hàng chục Agent chạy song song để xử lý các nhánh khác nhau cùng lúc.

2. Chuẩn bị máy chủ Linux làm Jenkins Agent (Permanent SSH Agent)

Phương pháp kết nối ổn định và an toàn nhất cho các hệ thống Monolith đòi hỏi cấu hình phần cứng mạnh (nhiều CPU, RAM lớn để chạy Docker build) là sử dụng Permanent Agent qua giao thức SSH.

Hãy thực hiện các bước sau trên máy chủ dự định làm Agent Server (ví dụ IP: 10.0.1.30):

Bước 1: Cài đặt môi trường runtime cơ bản trên Agent

Máy chủ Agent bắt buộc phải được cài đặt các công cụ phục vụ cho hệ thống Monolith tương tự như máy chủ Master:

Bash

# 1. Cài đặt Java (Yêu cầu Java 17 hoặc 21 để tương thích với Jenkins bản mới nhất)
sudo apt update && sudo apt install -y fontconfig openjdk-17-jre

# 2. Cài đặt Git, Docker và các công cụ bổ trợ
sudo apt install -y git curl wget unzip make
sudo apt install -y docker.io
sudo usermod -aG docker $USER

Bước 2: Tạo user jenkins chuyên dụng trên Agent

Để bảo mật, không dùng tài khoản root hay user cá nhân để làm agent:

Bash

sudo useradd -m -s /bin/bash jenkins
sudo passwd jenkins
# Thêm user jenkins vào nhóm docker để có quyền build image
sudo usermod -aG docker jenkins

Bước 3: Cấu hình SSH Key Authentication từ Master sang Agent

Quay trở lại máy chủ Jenkins Master, tạo khóa SSH (nếu chưa có) và đẩy Public Key sang máy chủ Agent:

Bash

# Thực hiện trên Jenkins Master:
ssh-keygen -t ed25519 -C "jenkins-master-to-agent" -f ~/.ssh/jenkins_agent_key -N ""

# Copy Public Key sang máy chủ Agent (10.0.1.30)
ssh-copy-id -i ~/.ssh/jenkins_agent_key.pub jenkins@10.0.1.30

Sau đó, kiểm tra thử từ Master SSH sang Agent xem đã đăng nhập được mà không cần nhập mật khẩu hay chưa: ssh -i ~/.ssh/jenkins_agent_key jenkins@10.0.1.30.

3. Khai báo và kết nối Agent trên giao diện Jenkins Master

  1. Đăng nhập vào giao diện Web của Jenkins Master với tài khoản Admin.

  2. Truy cập Manage Jenkins -> Nodes (hoặc Manage Nodes and Clouds) -> Bấm New Node.

  3. Node name: monolith-worker-01

  4. Chọn Permanent Agent và bấm Create.

  5. Điền các thông số cấu hình chi tiết:

    • Number of executors: Đặt là 2 (Cho phép Agent này chạy tối đa 2 Pipeline song song cùng một lúc).

    • Remote root directory: /var/jenkins (Thư mục làm việc chuyên dụng trên Agent).

    • Labels: monolith-worker linux high-cpu (Nhãn cực kỳ quan trọng dùng để định tuyến trong Jenkinsfile).

    • Usage: Chọn Only build jobs with label expressions matching this node (Chỉ nhận các Job được chỉ định đích danh chạy trên Agent này, không nhận việc linh tinh từ Master).

    • Launch method: Chọn Launch agents via SSH.

      • Host: 10.0.1.30 (IP của máy chủ Agent).

      • Credentials: Bấm Add -> Jenkins, chọn loại SSH Username with private key, nhập Username là jenkins, dán nội dung tệp Private Key (jenkins_agent_key) vào mục Private Key, đặt ID là jenkins-ssh-agent-credential và bấm Add. Chọn Credential vừa tạo ở ô dropdown.

      • Host Key Verification Strategy: Chọn Non-verifying Verification Strategy (để đơn giản hóa trong mạng nội bộ).

  6. Bấm Save.

Ngay lập tức, Jenkins Master sẽ tự động kết nối SSH sang máy chủ Agent. Nếu trạng thái hiển thị node monolith-worker-01 sáng đèn xanh, quá trình thiết lập Distributed Builds đã thành công rực rỡ!

4. Cấu hình Jenkinsfile để định tuyến Pipeline chạy trên Agent cụ thể

Mặc định, nếu bạn dùng agent any, Jenkins có thể đưa Pipeline chạy vào bất kỳ Node nào trống. Đối với hệ thống Monolith yêu cầu môi trường chuyên biệt hoặc cần tận dụng ổ cứng SSD tốc độ cao của một Agent cụ thể, bạn cấu hình chỉ định nhãn (label) trong khối agent:

Groovy

pipeline {
    // Ép buộc toàn bộ các Stage trong Pipeline này bắt buộc phải chạy trên máy chủ Agent có nhãn 'monolith-worker'
    agent {
        node {
            label 'monolith-worker'
        }
    }

    options {
        buildDiscarder(logRotator(numToKeepStr: '30'))
        timeout(time: 30, unit: 'MINUTES')
        timestamps()
    }

    environment {
        APP_NAME = "monolith-core-system"
        // Thư mục cache toàn cục giờ đây sẽ nằm trên ổ cứng của Agent Worker thay vì Master!
        CACHE_ROOT = "/var/jenkins/cache"
        COMPOSER_CACHE_DIR = "${CACHE_ROOT}/composer"
    }

    stages {
        stage('1. Run on Monolith Worker Agent') {
            steps {
                echo "=== Lệnh này đang chạy thực tế trên máy chủ Agent (IP: 10.0.1.30) ==="
                sh 'hostname && uptime && docker --version'
            }
        }
        // Các stage tiếp theo (Test, Build Docker, Deploy) chạy tuần tự trên Agent này...
    }
}

5. Kinh nghiệm thực chiến: Quản lý Workspace và không gian đĩa cứng trên Agent

Khi phân rã sang mô hình Master - Agent, bạn cần lưu ý 3 điểm mấu chốt để hệ thống không bị lỗi vặt:

  1. Đồng bộ hóa phiên bản công cụ (Tool Version Sync): Đảm bảo phiên bản PHP, Node.js hoặc Go trên máy chủ Agent phải khớp phiên bản với môi trường sản xuất. Tránh tình trạng Master gọi Agent chạy mà trên Agent chưa cài extension PHP tương ứng.

  2. Chiến lược dọn dẹp Workspace tự động: Do các Agent Worker phải gánh chịu toàn bộ dung lượng nén, giải nén và build Docker image, ổ cứng của Agent rất dễ bị đầy. Hãy luôn duy trì khối post { always { sh 'rm -rf ...' } } hoặc sử dụng các plugin như Workspace Cleanup Plugin ở cuối mỗi Pipeline.

  3. Bảo mật mạng nội bộ (Firewall): Đảm bảo máy chủ Agent mở cổng SSH (22) cho phép Jenkins Master kết nối vào, nhưng đồng thời phải chặn các truy cập ngoài luồng không cần thiết từ internet công cộng.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí