Series Jenkins Docker Hub #2: "Độ" vũ khí cho quản gia & Tuyệt kỹ Docker-out-of-Docker (DooD)
1. Tại sao không dùng luôn bản gốc?
Bản chất Image jenkins/jenkins:lts trên Docker Hub được xây dựng dựa trên một hệ điều hành Linux siêu rút gọn (thường là Debian). Bên trong đó, những kỹ sư của CloudBees (tổ chức đứng sau Jenkins) chỉ cài sẵn Java để chạy lõi phần mềm và Git để kéo code. Chấm hết.
Họ cố tình làm vậy để giữ cho Image nhẹ nhất có thể. Không có Node.js, không có Go compiler, và chắc chắn là không có Docker.
Để Jenkins có thể gọi các lệnh như docker build hay docker push, chúng ta phải tự tay "rèn vũ khí" cho nó bằng cách cài thêm Docker CLI (Công cụ dòng lệnh Docker) vào bên trong hệ điều hành của container đó.
2. Sự khác biệt giữa DinD và DooD
Khi muốn dùng Docker bên trong Docker, giới công nghệ có 2 trường phái:
- Docker-in-Docker (DinD): Là bạn chạy một con "Cá mập" (Docker Engine) hoàn chỉnh nằm ngay bên trong bụng một con "Cá mập" khác. Cách này cực kỳ ngốn tài nguyên, chậm chạp và tiềm ẩn nhiều rủi ro bảo mật (đòi hỏi quyền --privileged).
- Docker-out-of-Docker (DooD): Đây là con đường của những người có kinh nghiệm. Thay vì chạy một cái lõi Docker mới bên trong, chúng ta chỉ cài phần "Vỏ" (Docker CLI) vào trong Jenkins. Sau đó, chúng ta "khoét một cái lỗ" để cái Vỏ bên trong gọi ra cái Lõi (Docker Engine) đang chạy trên máy chủ vật lý bên ngoài.
Cái lỗ đó chính là file /var/run/docker.sock. Nó là đường ống giao tiếp (socket) trung tâm của Docker.
3. Thực hành: Viết Dockerfile "Đột biến"
Bây giờ, chúng ta không gọi thẳng lệnh docker run jenkins/jenkins:lts nữa. Chúng ta sẽ tự tay build một cái Image mới dựa trên nền bản gốc.
Tạo một thư mục mới (ví dụ: my-jenkins), tạo một file có tên Dockerfile (không có đuôi) và dán đoạn mã sau vào:
# 1. Kế thừa từ bản gốc LTS trên Docker Hub
FROM jenkins/jenkins:lts
# 2. Chuyển sang quyền root để có thể cài đặt phần mềm
USER root
# 3. Cài đặt các công cụ cần thiết và Docker CLI
RUN apt-get update && \
apt-get install -y apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" && \
apt-get update && \
apt-get install -y docker-ce-cli
# 4. Thêm user jenkins vào nhóm docker để có quyền gõ lệnh
RUN groupadd -f docker && usermod -aG docker jenkins
# 5. Trả lại quyền cho user jenkins để hệ thống chạy an toàn
USER jenkins
Mở Terminal tại thư mục đó, gõ lệnh build Image:
docker build -t my-jenkins-dood:latest .
Quá trình này mất khoảng 1-2 phút. Khi xong, bạn đã sở hữu một Image Jenkins "độc quyền" mang tên my-jenkins-dood.
4. Khởi chạy với quyền năng tối thượng
Giờ là lúc kết hợp kỹ thuật giữ trí nhớ ở Bài 1 và kỹ thuật DooD của Bài 2 vào một câu lệnh chạy duy nhất.
Bạn cần phải map 2 cái ổ cứng (Volume) cùng lúc:
- /var/jenkins_home: Để giữ lại dữ liệu.
- /var/run/docker.sock: Để tạo đường ống DooD.
Chạy câu lệnh sau:
docker run -d \
--name jenkins-master \
-p 8080:8080 \
-p 50000:50000 \
-v /home/user/jenkins_data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
--restart always \
my-jenkins-dood:latest
(Lỗi kinh điển người mới hay gặp: Đôi khi trên Linux, file docker.sock bị phân quyền rất gắt. Nếu Jenkins bên trong vẫn báo lỗi Permission denied khi gõ lệnh docker, bạn hãy ra máy chủ thật gõ thêm lệnh sudo chmod 666 /var/run/docker.sock để cấp quyền đọc ghi cho socket này nhé).
5. Kiểm tra thành quả
Để chắc chắn bác quản gia đã được trang bị tận răng, bạn hãy chui thẳng vào bụng container để kiểm tra:
docker exec -it jenkins-master bash
Khi Terminal đổi sang dấu nhắc lệnh của container, bạn hãy gõ:
docker --version
Nếu hệ thống trả về phiên bản Docker (VD: Docker version 24.0.5...) thì xin chúc mừng!
Tổng kết
Đến đây, bạn đã hoàn thiện một con Jenkins chuẩn mực để đi làm thực tế. Bác quản gia giờ đây không chỉ biết kéo code mà còn có thể gọi trực tiếp lệnh Docker để nhét các service Golang hay Node.js vào các container siêu nhẹ, rồi đẩy chúng lên Docker Registry. Mọi thao tác biên dịch phức tạp giờ đây được phó mặc cho Docker, giúp Jenkins của bạn luôn sạch sẽ, ổn định và không bao giờ bị lỗi xung đột thư viện.
All Rights Reserved