I. Tổng quan
GitLab CI là một phần của GitLab, là một hệ thống quản lý mã nguồn Git dựa trên web và một công cụ liên kết liền mạch để thực hiện các bước xây dựng, kiểm thử, đóng gói và triển khai phần mềm tự động.
Tổng quan về công cụ này:
- Là công cụ được sử dụng để hỗ trợ quá trình phát triển phần mềm.
- Cho phép lưu trữ và quản lý tài nguyên phần mềm.
- Có tính năng tích hợp và tự động hóa.
- Có khả năng tích hợp với các công cụ phát triển khác như Jenkins và Docker.
- GitLab CI là công cụ mã nguồn mở và có sẵn để sử dụng miễn phí.
II. Gitlab CI/CD
1. Khái niệm CI/CD
GitLab CI là một công cụ tích hợp dịch vụ CI/CD được cung cấp bởi GitLab, cho phép tự động hóa quy trình triển khai và kiểm thử phần mềm, giúp đơn giản hóa việc xây dựng, kiểm thử và triển khai phần mềm trong quá trình phát triển.
Có 3 khái niệm chính để phát triển gitlab CI là:
- Continuous Integration
- Continuous Delivery
- Continuous Deployment
a. Continuous Integration (Tích hợp liên tục)
Mỗi thay đổi được gửi tới một ứng dụng có code được lưu trữ trong một Git Repository trên Gitlab, ngay cả với các nhánh phát triển, bạn có thể tạo một bộ tập lệnh để xây dựng và kiểm tra tự động và liên tục. Các thử nghiệm này đảm bảo các thay đổi vượt qua tất cả các thử nghiệm, nguyên tắc và tiêu chuẩn code mà bạn đã thiết lập cho ứng dụng của mình.
Ví dụ:
Khi một lập trình viên hoàn thành một tính năng mới hoặc sửa lỗi trong mã nguồn của mình, họ sẽ đẩy mã nguồn lên kho lưu trữ như Gitlab hoặc Github, … Hệ thống CI sẽ tự động lấy mã nguồn mới nhất từ kho lưu trữ và thực hiện một số bước kiểm tra tự động như kiểm tra lỗi cú pháp, kiểm tra đơn vị, kiểm tra tích hợp và kiểm tra chức năng.
Nếu tất cả các kiểm tra này đều thành công, hệ thống CI sẽ thông báo cho nhóm rằng mã của họ đã sẵn sàng để được tích hợp vào phiên bản chính của sản phẩm. Việc này đảm bảo rằng mã mới được kiểm tra kỹ trước khi được tích hợp vào sản phẩm và giảm thiểu nguy cơ lỗi phát sinh sau này.
b. Continuous Delivery (Chuyển giao liên tục)
Ứng dụng của bạn không chỉ được xây dựng và thử nghiệm mỗi khi thay đổi mã được đẩy vào nhánh chính, ứng dụng còn được triển khai liên tục. Tuy nhiên, với phân phối liên tục, bạn kích hoạt triển khai theo cách thủ công.
Phân phối liên tục tự động kiểm tra code nhưng yêu cầu sự can thiệp của con người để kích hoạt việc triển khai các thay đổi theo cách thủ công và có chiến lược.
Ví dụ:
Một ví dụ về Continuous Delivery (CD) có thể là trong quá trình phát triển phần mềm, sau khi các thay đổi được tích hợp thành công vào sản phẩm, các thay đổi đó sẽ được triển khai đến môi trường thử nghiệm hoặc môi trường sản phẩm khi có sự can thiệp của con người ở bước triển khai.
c. Continuous Deployment (Triển khai liên tục)
Tương tự như Phân phối liên tục. Sự khác biệt là thay vì triển khai ứng dụng của bạn theo cách thủ công, bạn đặt ứng dụng đó được triển khai tự động. Sự can thiệp của con người là không cần thiết.
Ví dụ:
Một ví dụ về Continuous Deployment (CD) là khi một nhóm lập trình viên triển khai tự động mã nguồn mới vào môi trường sản xuất một cách tự động, tương tự như Continuous Delivery mà không cần phải thực hiện bất kỳ thao tác nào từ con người. Tuy nhiên, việc triển khai tự động cũng cần được kiểm soát chặt chẽ để tránh những lỗi không mong muốn xảy ra trên môi trường sản phẩm.
d. GitLab CI/CD workflow
GitLab CI/CD phù hợp với quy trình phát triển chung:
Bạn có thể bắt đầu về việc phát triển code cho một vấn đề và nó hoạt động trên local. Tiếp theo bạn có thể push các commit của mình lên một feature branch trên remote repository. Sau khi push, CI/CD pipeline sẽ được kích hoạt, và Gitlab CI/CD:
- Tự động chạy các dòng lệnh:
- Build và Test ứng dụng của bạn
- Xem trước các thay đổi trong ứng dụng, giống như bạn sẽ thấy trên localhost của bạn.
Sau khi phần triển khai hoạt động như mong đợi:
- Code của bạn sẽ được xem xét và phê duyệt
- Merge code trên feature branch vào branch mặc định
- Gitllab CI/CD tự động triển khai phần code thay đổi của bạn trên môi trường production
Nếu xảy ra lỗi, bạn có thể quay lại phần code thay đổi của bạn.
2. Điều kiện để có thể triển khai GitLab CI
Để dùng được Gitlab CI thì bạn cần có 2 thành phần sau: file ‘.gitlab-ci.yml’ nằm ở thư mục gốc của dự án và một server chạy Gitlab Runner.
a. File gitlab-ci.yml
Mặc định Gitlab không có cơ chế nào về CI cho dự án của bạn, chỉ khi nào dự án của bạn có file .gitlab-ci.yml nằm ở thư mục gốc thì Gitlab mới nhận dạng được dự án của bạn muốn áp dụng Gitlab CI.
File này có định dạng và cần hợp lệ thì mới có thể hoạt động được, không thì khi bạn push code lên thì Gitlab sẽ báo lỗi file định dạng nội dung của file cấu hình không hợp lệ.
File này có một số section để khai báo như trước khi chạy test thì làm gì, khi test thì thực hiện lệnh gì, test xong rồi thì thực hiện deploy đi đâu (beta, production..) với câu lệnh gì (vd: rsync..). Tùy đặc thù ngôn ngữ lập trình, cách đóng gói của dự án mà sẽ có các lệnh tương ứng thực hiện.
Ví dụ về 2 section trong file gitlab-ci.yml:
- Section 1 (maven-build): build java project with maven
- Section 2 (docker-build): đóng gói source code sau khi build thành một image docker sau đó lưu trữ trên nexus repository
b. Gitlab Runner
Là một máy tính vật lý hoặc ảo, có chức năng thực thi các công việc được định nghĩa trong pipeline. Runner có thể được cấu hình để chạy trên nhiều nền tảng khác nhau, bao gồm Linux, Windows và macOS, và có thể hỗ trợ nhiều ngôn ngữ lập trình khác nhau. Khi có một job được kích hoạt, GitLab CI sẽ tìm kiếm runner phù hợp để thực thi job đó.
Gitlab Runner là thành phần cực kỳ quan trọng trong workflow Gitlab CI. Nếu không có Runner thì sẽ không có lệnh test, deploy nào được thực thi. Runner có nhiều loại, phân biệt dựa vào cái gọi là executor. Khi khởi tạo runner, bạn sẽ phải chọn nó là loại executor nào, và nó sẽ quyết định môi trường thực thi các câu lệnh trong file config ở trên.
Trước khi dự định triển khai gitlab-ci cần kiểm tra xem repository đã có Git Runner hoạt động chưa.
3. Các thành phần khác trong Gitlab CI
a. Pipeline
Là một chuỗi các job, được xây dựng để thực hiện một số công việc trong một quá trình CI/CD nhất định. Pipeline được kích hoạt khi có thay đổi được push lên repository, hoặc khi một trigger được kích hoạt. Mỗi pipeline có thể bao gồm nhiều stage, mỗi stage bao gồm nhiều job. Các job trong một stage sẽ được thực thi đồng thời, còn các stage sẽ được thực thi theo thứ tự tuần tự.
Pipelines là thành phần cấp cao nhất của tích hợp, phân phối và triển khai liên tục.
Pipeline bao gồm:
- Jobs: Các công việc được giao thực thi. (Ví dụ: biên dịch mã hoặc chạy test)
- Stage: Xác định các thời điểm và cách thực hiện. (Ví dụ: test chỉ chạy sau khi biên dịch thành công)
Pipeline hoạt động theo nguyên tắc sau :
- Tất cả các công việc trong cùng một stage được Runner thực hiện song song, nếu có đủ số lượng Runner đồng thời.
- Nếu Success, pipeline chuyển sang stage tiếp theo.
- Nếu Failed, pipeline sẽ dừng lại. Có một ngoại lệ là nếu job được đánh dấu làm thủ công, thì dù bị fail thì pipeline vẫn tiếp tục.
b. Trigger
Là một sự kiện, hoặc một hành động bên ngoài pipeline, được sử dụng để kích hoạt một pipeline. Trigger có thể được định nghĩa để kích hoạt pipeline trong trường hợp có sự kiện bên ngoài, chẳng hạn như khi có một đoạn code mới được đẩy lên một repository khác.
c. Variable
Là một biến được sử dụng để truyền thông tin giữa các job và các stage khác nhau trong pipeline. Biến có thể được định nghĩa cục bộ hoặc toàn cục, và có thể được sử dụng để đặt giá trị cho các thông số trong các script. Biến cục bộ chỉ có thể được truy cập trong phạm vi của job đang thực thi, còn biến toàn cục có thể được sử dụng trong toàn bộ pipeline.
Ví dụ:
Kết quả:
- job1 có kết quả: Variables are ‘A global variable’ and ‘A job variable’
- job2 có kết quả: Variables are ‘A global variable’ and ”
Ngoài ra còn có thể khởi tạo biến cho toàn bộ project trong phần Setting > CI/CD > Variables
d. Artifacts
Là các tệp hoặc thư mục được tạo ra trong quá trình thực thi của một job, và có thể được chia sẻ và sử dụng trong các job khác trong pipeline. Các artifacts có thể bao gồm các tệp như mã nguồn biên dịch, các bản cập nhật cơ sở dữ liệu hoặc các tệp đầu ra được tạo ra bởi các công cụ đóng gói.
Ví dụ:
e. Cache
Là một cơ chế để lưu trữ dữ liệu để giảm thiểu thời gian chạy của pipeline. Các cache có thể được sử dụng để lưu trữ các file hoặc thư mục được tạo ra trong quá trình thực thi của một job, và được sử dụng để đưa ra quyết định về việc chạy lại các job đã hoàn thành. Ví dụ, nếu một job đã tạo ra một file cache trong quá trình thực thi, GitLab CI có thể sử dụng cache đó để tránh việc thực hiện lại job đó trong pipeline tiếp theo.
f. Biểu tượng trạng thái
Là một công cụ giúp theo dõi trạng thái của các job và pipeline trong GitLab CI. Biểu tượng trạng thái bao gồm các hình ảnh và màu sắc để biểu thị trạng thái hiện tại của job hoặc pipeline, bao gồm thành công, thất bại, đang chạy, đang bị hủy bỏ hoặc đang bị trì hoãn. Các biểu tượng trạng thái được hiển thị trong giao diện người dùng của GitLab CI, giúp người dùng theo dõi quá trình CI/CD một cách dễ dàng và thuận tiện.
III. Tổng kết
1. Chức năng của GitLab CI:
- Tự động hóa quá trình xây dựng, kiểm thử, đóng gói và triển khai phần mềm.
- Tích hợp dịch vụ CI/CD vào quy trình phát triển phần mềm.
- Quản lý và lưu trữ tài nguyên phần mềm.
- Cung cấp một cấu trúc file cấu hình (.gitlab-ci.yml) để định nghĩa các bước và công việc trong quy trình CI/CD.
- Hỗ trợ tích hợp với các công cụ phát triển khác như Jenkins và Docker.
- Cung cấp môi trường thử nghiệm, môi trường sản phẩm và môi trường khác nhau để triển khai phần mềm.
- Cung cấp báo cáo chi tiết về quá trình xây dựng và kiểm thử phần mềm.
2. Lợi ích của GitLab CI:
- Tăng tính nhất quán và độ tin cậy của quá trình phát triển phần mềm bằng việc tự động hóa các công việc và quy trình.
- Giảm thiểu sai sót con người và tăng hiệu suất làm việc bằng cách thực hiện tự động các bước xây dựng và kiểm thử.
- Tăng khả năng phát hiện lỗi sớm trong quá trình phát triển bằng việc thực hiện các bài kiểm tra tự động.
- Tích hợp dễ dàng với các công cụ khác trong quy trình phát triển phần mềm như SCM (Source Code Management), quản lý phiên bản, cấp quyền truy cập, và cung cấp sự liên kết liền mạch giữa các công cụ.
- Cung cấp khả năng tái tạo và triển khai tự động các phiên bản phần mềm.
- Tăng sự linh hoạt và khả năng mở rộng của quy trình phát triển phần mềm thông qua việc sử dụng các công cụ mã nguồn mở và tích hợp linh hoạt với các công cụ và dịch vụ khác.
- Tiết kiệm thời gian và công sức của nhóm phát triển bằng việc tự động hóa các bước lặp lại và công việc mà không cần phải thực hiện thủ công.
Vũ Duy Đan