1. Giới thiệu
Trong chu trình của một project, ta thường trải qua nhiều bước khác nhau cho tới khi ra được hoàn chỉnh sản phẩm cuối cùng. Những bước này thường là các bước đồng bộ hoặc xen kẽ, và ta có khái niệm “Continous Integration” tức CI để thực hiện các bước này tự động sau khi ta xây dựng kịch bản cho nó.
GitLab CI được triển khai như một tính năng quan trọng và mang tới sự tiện dụng dành cho những ai đang sử dụng GitLab. Bạn không phải trả tiền, nó có sẵn miễn bạn lên kịch bản đúng. Trong bài viết này, mình sẽ đưa ra các khái niệm và cùng giải thích cho các bạn hiểu để có kiến thức về “món hàng” thú vị này.
Mỗi khi một lập trình viên tạo ra các thay đổi trong code, người đó thường lưu lại nó trong một commit. Sau đó, người này đẩy code lên (gọi là push) lên GitLab để những người khác trong đội nhóm của mình có thể thấy nó và đánh giá.
GitLab cũng bắt đầu làm những việc mà nó được giao, khi commit đó lên, nếu mà bạn cấu hình GitLab CI. Những thao tác nó làm, ta gọi là “runner”. Hãy tưởng tượng “runner” thực ra là một máy chủ, tương tự như máy tính của bạn, nhưng thực thi các hướng dẫn có trong file .gitlab-ci.yml nằm ngay trong project của bạn, và nó sẽ bao gồm các báo cáo gửi lại và được GitLab hiển thị trong giao diện của mình.
Khi lập trình viên nào đó hoàn thành việc làm một tính năng mới hay fix bug (những thao tác đòi hỏi nhiều commit), họ có thể tạo yêu cầu nhập vào cây nhánh chính (Merge Request), nơi mà GitLab cung cấp giao diện trực quan để đánh giá và tiếp tục đưa ra các cải thiện cho tới khi hoàn tất và được “merged” vào nhánh chính.
Như các bạn thấy, ngay cả designer và tester cũng có thể tham gia vào bước này, đưa ra các đánh giá và gợi ý cải thiện. Và thật tuyệt rằng nó rất dễ nhìn trong GitLab.
Bạn sẽ có nhiều thứ không cần làm nữa, mà thay vào đó, nó được thực hiện tự động bởi CI.
Chẳng hạn, chu trình thực thi một ứng dụng web ví dụ sẽ là:
- Kiểm tra code CSS/SCSS/LESS/postCSS xem có đúng syntax không.
- Kiểm tra Javascript xem có đáp ứng ESLint hay không.
- Kiểm tra PHP xem có đáp ứng Code Standard hay không.
- Kiểm tra JSON xem đã viết đúng cấu trúc không.
- Kiểm tra file image đã được compress chưa.
Nếu thông thường, bạn phải chờ đợi từ trình soạn thảo code (nhưng đôi khi chính lập trình viên lại cố tình bỏ qua), thì nay, với GitLab CI, mọi thứ có thể dễ dàng được kiểm soát và qua kiểm thử.
Thêm vào nữa, với những phần build và deploy khác nhau, bạn sẽ cần tách ra, chẳng hạn:
- Bước 1: Chạy npm run build
- Bước 2: Commit code đã compile
- Bước 3: Sau đó lại chạy npm run deploy để đẩy code lên trên site
Thì nay, toàn bộ thao tác đó sẽ được auto thực hiện qua GitLab CI, bằng cách bạn cứ đẩy code lên branch develop thì sẽ tự build và đẩy lên. Vậy là bớt được việc làm đi làm lại hàng ngày rồi.
2. Chạy 1 job đầu tiên bằng Gitlab
Như thường lệ, hãy tạo 1 project.
Bạn hãy vào project vừa tạo xong, vào CI/CD -> Jobs, bấm vào Create CI/CD configuaration file, lúc này Gitlab sẽ tạo cho bạn 1 file có trên .gitlab-ci.yml nằm trong project của bạn. File này sẽ chứa toàn bộ các bước để triển khai 1 job. Nếu bạn đã sử dụng Jenkins thì nó khá là giống với Jenkinsfile của Jenkins.
Bấm vào Configure pipeline.
Ở đây nó sẽ gợi ý cho mình 1 job test, mình sẽ sử dụng job này để demo trong bài viết này luôn.
Nội dung của job mẫu trên như sau:
– Job này có 4 bước để hoàn thành
+ Bước 1: Build, sẽ in ra màn hình nội dung Compiling the code và Compile complete
+ Bước 2: Step, sẽ có 2 công việc chạy song song với nhau ở bước này, các bạn biết lập trình cơ bản sẽ biết nên mình không giải thích thêm.
+ Bước 3: Deploy, bước này cũng đơn giản chỉ là in nội dung Deploying application và Application successfully deployed ra màn hình.
# This file is a template, and might need editing before it works on your project.
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
#
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
stages: # List of stages for jobs, and their order of execution
- build
- test
- deploy
build-job: # This job runs in the build stage, which runs first.
stage: build
script:
- echo "Compiling the code..."
- echo "Compile complete."
unit-test-job: # This job runs in the test stage.
stage: test # It only starts when the job in the build stage completes successfully.
script:
- echo "Running unit tests... This will take about 60 seconds."
- sleep 60
- echo "Code coverage is 90%"
lint-test-job: # This job also runs in the test stage.
stage: test # It can run at the same time as unit-test-job (in parallel).
script:
- echo "Linting code... This will take about 10 seconds."
- sleep 10
- echo "No lint issues found."
deploy-job: # This job runs in the deploy stage.
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
environment: production
script:
- echo "Deploying application..."
- echo "Application successfully deployed."
Nếu bạn không thay đổi gì, bạn hãy bấm vào Commit changes để lưu lại file .gitlab-ci.yml.
Sau khi lưu file .gitlab-ci.yml bạn sẽ thấy có 1 job đang chạy như phần 1 ở hình dưới nhưng nó đang ở trạng thái pending, lí do là nó cần 1 nơi để chạy test ứng dụng của bạn và trong gitlab gọi nó là Gitlab Runner. Vậy Gitlab runner là gì?
Đây là một phần mềm / công cụ mã nguồn mở, được viết bằng ngôn ngữ Go và do chính Gitlab tạo ra để phục vụ cho việc CI/CD cho các dự án / repository được tạo trên Gitlab. Người dùng có thể tự cài đặt cho mình một runner trên server của mình hoặc sử dụng những runner do Gitlab cung cấp. Người dùng chỉ cần tạo 1 file.gitlab-ci.ymlở thư mục gốc của dự án / repository, để khởi tạo CI/CD pipeline và chỉ định Gitlab runner nào sẽ được sử dụng.
Gitlab sẽ cung cấp 2 gói hỗ trợ, bao gồm:
- Miễn phí:
- Giới hạn: 400 phút/tháng đối với “private repository” và 5000 phút/tháng đối với “public repository”.
- Không giới hạn: người dùng tự cài đặt và quản lý runner của riêng mình.
- Trả phí: từ $19 – $99/user/tháng tùy theo các gói đăng ký Lưu ý: chỉ áp dụng đối với “shared runner” do Gitlab cung cấp.
Các loại Gitlab runner
Runner sẽ bao gồm 2 loại:
Shared runner – do Gitlab quản lý
Nếu bạn theo xu hướng “serverless”, đây là một giải pháp hợp lý và nhanh chóng. Bạn không phải cấu hình, quản trị, lo lắng về hiệu năng, tính sẵn sàng của runner. Các công việc này sẽ do Gitlab chịu trách nhiệm xử lý. Việc của bạn là sử dụng, trả thêm tiền nếu đã sử dụng hết định mức và muốn tiếp tục sử dụng.
Các runner này được cài đặt trên hệ thống máy chủ thuộc Google Cloud Platform – GCP. Bao gồm 3 loại runner chạy 3 hệ điều hành phổ biến hiện nay:
- Linux: cấu hình thuộc dòng n1-standard-1 (thuộc khu vực South Carolina – us-east1): 1 vCPU, 3.75GB RAM, 25GB HDD, chạy hệ điều hành của Google – Google COS, và được cài đặt Docker Engine phiên bản mới nhất.
- Windows (Beta): cấu hình thuộc dòng n1-standard-2: 2 vCPU, 7.5GB RAM
- macOS (Beta): chỉ áp dụng đối với các dự án mã nguồn mở hoặc người dùng đăng ký gói Premium / Ultimate
Shared runner sẽ xử lý các “job” thông qua một hàng đợi đặc biệt – “fair usage queue”. Hàng đợi này sẽ ngăn chặn việc các dự án / repository chiếm dụng toàn bộ runner bằng cách tạo ra hàng trăm “job” cần được xử lý cùng lúc. Thay vào đó, hàng đợi này sẽ ưu tiên phân phối các “job” cho các dự án / repository có số lượng “job” đã sử dụng shared runner thấp nhất trước.
Specific runner / Own runner – do người dùng tự cài đặt và quản lý
Đây là một giải pháp sử dụng CI/CD của Gitlab hoàn toàn miễn phí. Bạn có server của mình, bạn muốn tự mình cài đặt, quản lý các runner. Người dùng sẽ cấu hình và chỉ định mỗi runner được sử dụng cho một hoặc nhiều dự án / repository. Nếu sử dụng giải pháp này, bạn có thể đảm bảo yếu tố bảo mật, kiểm soát dữ liệu của mình. Bù lại là bạn sẽ trả thêm một khoản về chi phí đường truyền mạng nếu sử dụng cách này.
Khi người dùng tạo 1 runner thuộc loại “Group runner”, toàn bộ các dự án / repository thuộc group sẽ có thể sử dụng các runner này. Các runner này sẽ sử dụng cơ chế hàng đợi (queue – FIFO – First In First Out) để nhận và xử lý các “job”.
Tính năng của Gitlab Runner
- Có thể chạy nhiều “job” CI/CD cùng một lúc miễn là bạn có đủ runner
- Cho phép tùy chọn môi trường chạy các “job” (khi bạn chạy Gitlab runner bằng Docker)
- “Job” có thể chạy ở local / docker container / kết nối đến server thông qua SSH
- Hỗ trợ Bash, PowerShell Core và Windows PowerShell
- Hỗ trợ “caching” Docker container
- Tích hợp Prometheus metrics HTTP server
- Dễ dàng cài đặt như một dịch vụ / service trên GNU/Linux, macOS và Windows
Bây giờ hãy quay lại phần thực hành, bạn hãy bấm vào view pipeline.
Gitlab sẽ đưa bạn về phần Pipeline của CI/CD, hãy bấm vào phần mình đánh dấu ở hình dưới để tiếp tục.
Ở đây bạn sẽ thấy 1 thông báo như dưới, nó đang thông báo cho bạn biết job của bạn không thể tiếp tục vì không có runner nào được active cho job này. Bạn hãy bấm vào CI Settings.
Hoặc có thể bấm theo hình dưới đây nếu không muốn bấm vào CI Settings. Ở phần Shared runners mình sẽ tắt nó đi vì mình muốn tự build runner riêng của mình. Để build runner riêng của mình bạn hãy bấm vào phần 4 như hình dưới.
Ở đây nó sẽ hiện lên 1 bảng hướng dẫn bạn cài đặt 1 runner riêng của bạn. Runner hỗ trợ nhiều hệ điều hành như windows, macos, linux,… Mình sẽ chọn linux để build, các lệnh để build 1 runner trên linux được liệt kê ở phần 2 hình dưới. Ở phần 3 là lệnh để bạn tạo kết nối từ runner để project của bạn.
Hãy thực hiện chạy các câu lệnh dưới trên máy Linux của bạn.
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
Sau khi cài xong hãy chắc chắn rằng gitlab runner đã chạy.
$ sudo gitlab-runner status
Runtime platform arch=amd64 os=linux pid=504 revision=7178588d version=15.5.1
gitlab-runner: Service is running
Sử dụng lệnh sau để kết nối gitlab runner tới project của bạn. Thay thế GR1348941y9gUxu6XfVcRw2gwTzJx bằng token trên project và http://192.168.13.206/ chính là url Gitlab.
sudo gitlab-runner register --url http://192.168.13.206/ --registration-token GR1348941y9gUxu6XfVcRw2gwTzJx
Hai thông tin được lấy ở đây, trong phần cài đặt runner trên project của bạn.
Chạy lệnh trên ở máy linux cần build Gitlab Runner. Ở đây mình chạy runner là Docker, nếu bạn cũng chạy Docker thì hãy cài đặt theo mình ở dưới.
$ sudo gitlab-runner register --url http://192.168.13.206/ --registration-token GR1348941mHvaWkoR7sUswPbRC_BL
Runtime platform arch=amd64 os=linux pid=21145 revision=7178588d version=15.5.1
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
[http://192.168.13.206/]:
Enter the registration token:
[GR1348941mHvaWkoR7sUswPbRC_BL]:
Enter a description for the runner:
[tf-gitlab]:
Enter tags for the runner (comma-separated):
Enter optional maintenance note for the runner:
Registering runner... succeeded runner=GR1348941mHvaWkoR
Enter an executor: docker, parallels, virtualbox, docker+machine, docker-ssh+machine, kubernetes, custom, docker-ssh, shell, ssh, instance:
docker
Enter the default Docker image (for example, ruby:2.7):
docker
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
Sau khi kết nối xong runner và project, bạn hãy vào phần runner trong project của bạn. Tại phần Availble specific runners bạn sẽ thấy runner tf-gitlab đã xuất hiện.
Hãy vào file config.toml và chỉnh sửa 1 số nội dung dưới để tránh gây ra một số lỗi phát sinh nếu bạn sử dụng Gitlab Runner là Docker.
vi /etc/gitlab-runner/config.toml
Thay đổi 2 nội dung như sau.
privileged = false -> privileged = true
volumes = ["/cache"] -> volumes = ["/cache","/var/run/docker.sock:/var/run/docker.sock"]
Ta có nội dung sau khi thay đổi như dưới.
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "tf-gitlab"
url = "http://192.168.13.206/"
id = 1
token = "8WJ_Q-FKUfX-5j79Q_uL"
token_obtained_at = 2022-11-15T14:26:08Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "docker"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache","/var/run/docker.sock:/var/run/docker.sock"]
shm_size = 0
Restart lại gitlab-runner
gitlab-runner restart
Hãy chắc chắn rằng gitlab-runner đã hoạt động.
$ gitlab-runner status
Runtime platform arch=amd64 os=linux pid=17957 revision=7178588d version=15.5.1
gitlab-runner: Service is running
Sau khi runner được kích hoạt, quay lại pipeline bạn thấy job của bạn đã chuyển sang trạng thái running.
Bấm vào job, bạn thấy các bước triển khai của job này vẫn đang chạy. Hiện tại đã chạy xong bước đầu tiên, bước thứ 2 đang running.
Bấm vào Pipeline bạn cũng có thể xem sơ đồ các bước build của job này.
Bạn cũng có thể xem logs quá trình build.
Và đây là kết quả khi quá trình build 1 job đã hoàn thành.