Trang chủTác giảLiên hệ

[Kubernetes Practice] - Triển khai nodejs microservice trên Kubernetes - phần 3 - Xây dựng CI/CD

By Huỳnh Minh Quân
Published in DevOps
December 03, 2021
8 min read

Giới thiệu

Chào mọi người đến với series practice về kubernetes của mình. Tiếp tục ở bài các phần trước, các bạn nên đọc bài trước để hiểu về hệ thống ta đang triển khai ra sao, phần 1 nói về cách viết config và cách triển khai microservice lên trên Kubernetes, phần 2 nói về ta dùng Argocd để tự động cập nhật application khi template config kubernetes của ta thay đổi. Ở bài này, mình sẽ nói về cách khi developer viết code cho chức năng mới của ứng dụng xong và push nó lên trên git repo, thì ta sẽ xây dựng luồng CI/CD thế nào để cập nhật lại ứng dụng với code mới của developer trên môi trường kubernetes.

Ở bài này mình sẽ sử dụng repository là gitlab và chạy CI/CD với gitlab CI. Để làm được bài này thì các bạn cần tạo một repo trên gitlab và đẩy code lên đó nhé, các bạn đặt tên repo là gì cũng được. Các bạn đẩy code nằm ở trong folder code của repo này https://github.com/hoalongnatsu/microservices.git lên repo gitlab của các bạn nha. Sau khi xong hết ta bắt tay vào làm.

Gitlab Runner

Gitlab cung cấp cho ta khá nhiều cách để chạy CI/CD, mình sẽ nói tới phần đơn giản nhất trước, là ta sử dụng Gitlab Runner. Gitlab Runner là một application mà ta sẽ cài ở trên server ta muốn nó chạy CI/CD. Để install gitlab runner, các bạn ssh tới server mà mình muốn chạy CI/CD trên đó, và cài runner như sau, mình sẽ hướng dẫn cài ở trên server linux.

Install gitlab-runner

Download the binary for your system

Chọn OS phù hợp với server của các bạn nhé.

Give it permissions

Create a GitLab CI user

Install and run as service

Nếu bạn gặp lỗi sudo: gitlab-runner: command not found thì mở /etc/sudoers lên và thêm vào ở Defaults secure_path với dường dẫn /usr/local/bin nữa, còn không thì bạn install gitlab-runner ở dường dẫn /usr/bin cũng được.

Để install trên các môi trường khác thì các bạn xem thêm ở đây https://docs.gitlab.com/runner/install/.

Sau khi install xong thì bạn có thể dùng câu lệnh này để kiểm tra:

Câu lệnh này là để ta list toàn bộ runner hiện tại trên server, bây giờ thì tất niên khi ta list ra thì sẽ không có runner nào 😁. Giờ thì ta sẽ đăng ký một con runner để nó chạy CI/CD cho repo của ta ở trên gitlab. Bạn mở gitlab lên, ở chỗ repo của mình chọn mục Settings -> CI/CD.

image.png

Sau đó bạn mở mục Runners ra.

image.png

Sau khi mở ra, bạn sẽ thấy hai trường mà ta sẽ dùng nó để register runner cho repo của ta là gitlab url và token.

image.png

Register runner

Giờ thì ta sẽ register một con runner cho repo của ta lên trên server, các bạn làm theo các bước như sau, đầu tiên ta chạy câu lệnh register.

Sau khi run thì nó sẽ bắt bạn nhập gitlab url vào, nhập giá trị url ở phía trên vào. Tiếp đó nó sẽ bắt bạn nhập token, bạn nhập token ở trên vào.

image.png

Tiếp theo là nó bắt bạn nhập description, chỗ này thì bạn nhập gì cũng được. Tiếp theo là phần tags, phần này thì quan trọng, lúc chạy CI thì runner sẽ được chạy dựa vào tags, bạn nhập ở đây là microservice nhé.

image.png

Bây giờ thì sẽ tới bước ta chọn runner của ta sẽ được thực thi ra sao. Nó sẽ chạy thẳng trên server, hay là mỗi lần chạy nó sẽ tạo một container ra và chạy job CI/CD trên container đó. Chọn shell nếu các bạn muốn runner chạy thẳng trên môi trường server, chọn docker nếu bạn muốn runner chạy trong môi trường docker. Ở đây thì mình sẽ chọn docker, các bạn nên chọn theo mình để tránh bị lỗi nha.

image.png

Tiếp theo nó sẽ hỏi default Docker image thì bạn nhập vào là docker:stable, tới đây thì ta đã register runner cho repo của ta thành công, để kiểm tra các runner ta đã đăng ký thì ta chạy câu lệnh list ở trên, giờ thì bạn sẽ thấy được runner mà ta vừa đăng ký.

Kiểm tra trên gitlab bạn sẽ thấy nó hiển thị con runner của ta.

image.png

Oke vậy là ta đã xong bước register runner. Và thay vì phải nhập từng bước khá lằng nhằng như trên thì bạn có thể register nhanh một con runner bằng câu lệnh sau:

Giờ thì ta chỉ cần viết file CI/CD ở trong repo của chúng ta, và mỗi lần ta đẩy code lên thì file CI/CD này sẽ được con runner thực thi. Lưu ý là vì ta chọn docker nên bắt buộc trên server chạy CI/CD của ta phải có cài docker rồi thì runner mới thực thi được. Tiếp theo ta sẽ bắt tay vào làm luồng CI.

Continuous Integration

Đầu tiên là ta sẽ làm bước mà integrate code mới của developer với image mà dùng để chạy ứng dụng của ta trước, sau đó ta mới làm bước deploy. Ở bước integrate này thì ta sẽ viết file CI, công việc của nó sẽ là build image tương ứng với code của branch hiện tại, sau đó sẽ push image đó lên docker registery (nơi ta chứa image).

Gitlab có hỗ trợ cho ta image registry, nên ta sẽ sử dụng nó luôn cho tiện. Để viết CI/CD cho gitlab thì ta sẽ viết trong file .gitlab-ci.yml, ở folder mà ta chứa code của repo, tạo một file .gitlab-ci.yml với config như sau:

image.png

Trường stages là ta sẽ định nghĩa những pipe trong một job của ta, hiện tại thì ta chỉ có một pipe là build thôi. Ở trong file config trên ta sẽ có biến là CI_REGISTRY_IMAGE, đây là một trong những biến mặc định của gitlab CI, biến CI_REGISTRY_IMAGE sẽ là tên image của chúng ta. Ở trên gitlab repo, bạn bấm sang phần Package & Registries -> Container Registry, thì bạn sẽ thấy được tên image của chúng ta. Khi ta push image thì ta sẽ push lên chỗ Container Registry này. Trường script là trường ta sẽ chỉ định những công việc ta sẽ làm, ở file trên đơn giản là ta sẽ build image và push image với code mới nhất lên.

image.png

Giờ ta commit và push code lên, ta sẽ thấy CI/CD của ta sẽ được thực thi.

image.png

Bạn nhấn vào chữ running thì nó sẽ dẫn bạn vào trong.

image.png

Sau đó bạn nhấn vào chỗ build thì nó sẽ dẫn ta qua chỗ coi log.

image.png

Runner của ta sẽ chạy và nó tự động pull code của chúng ta xuống container đang chạy job, xong đó ta sẽ thực thi build image.

image.png

Sau khi image build xong thì nó sẽ push lên gitlab registry, và ở đây bạn sẽ thấy nó có lỗi là denied: access forbidden.

image.png

Lý do là do ta chưa để login tới gitlab registry để docker có thể push image lên được. Để login vào gitlab registry, ta làm như sau.

Login gitlab registry

Ta chọn phần Settings -> Repository, chọn mục Deploy tokens

image.png

Ở phần Deploy tokens, bạn nhập trường name và username là microservice (này bạn muốn nhập gì cũng được).

image.png

Chỗ scope thì bạn tạm thời chứ chọn hết. Sau đó ta nhấn tạo.

image.png

Sau khi nhấn tạo xong thì nó sẽ hiện ra cho bạn hai trường là username và password, nhớ lưu lại nha.

image.png

Sau khi có deploy token rồi, bạn chọn mục Settings -> CI/CD, mục Variables. Tạo một env là REGISTRY_PASSWORD để lưu giá trị password của deploy token.

image.png

image.png

Ok, sau khi tạo xong thì bạn update lại file .gitlab-ci.yml như sau:

Ta sẽ thêm trường before_script để chạy câu lệnh login vào gitlab registry. Biến CI_REGISTRY là biến mặc định của gitlab CI, biến REGISTRY_PASSWORD là ta vừa mới tạo. Cập nhật xong thì ta commit code và push nó lên lại. Lúc này bạn sẽ thấy là ta đã build được image và push nó lên thành công.

image.png

Nhưng bạn sẽ để ý là vì ta chạy build image trong một container, nên khi ta build nó không có lưu cache, khiến việc ta build image bị lâu hơn, để khác phục việc này thì trước khi build ta sẽ pull image đã build xuống trước, để nó có layer cache, và khi ta build ta sẽ chỉ định thêm option là --cache-from $CI_REGISTRY_IMAGE:latest. Cập nhật lại file .gitlab-ci.yml.

Commit code và push lên, lúc này thì image của ta sẽ được build với tốc độ nhanh hơn.

Cập nhật lại file config của kubernetes

Tiếp theo ta sẽ cập nhật lại file config Deployment với image mà ta mới build. Để coi tên image, bạn chọn mục copy ở phần Container Registry.

image.png

Các file Deployment ở folder k8s của repo này https://github.com/hoalongnatsu/microservices.git, như api-gateway-deployment.yaml, categories-news-deployment.yaml bạn sửa lại thành tên image của gitlab

Image của mình thì mình sửa lại là registry.kala.ai/microservice/code. Sau đó bạn nếu bạn làm như theo bài trước thì bạn chỉ cần push lên repo chứa template config để Argocd nó tự động cập nhật lại. Còn không thì bạn chạy câu lệnh sau ở folder k8s.

Nhưng khi bạn get pod ra, bạn sẽ thấy mấy Deployment mà ta chỉ định dùng image của gitlab thì nó sẽ bị lỗi là ErrImagePull.

Để kubernetes có thể pull được image từ gitlab, ta cần tạo một Secret với loại là docker-registry rồi chỉ định vào trường imagePullSecrets khi khai báo config cho Pod. Ta tạo Secret bằng câu lệnh sau.

Với —docker-server là tên gitlab server của bạn, —docker-username là username của deploy token ta tạo khi nãy, và —docker-password là password của deploy token. Cập nhật lại file Deployment thêm vào trường imagePullSecrets với Secret ta vừa tạo.

Vậy là ta đã hoàn thành xong bước CI, tiếp theo ta sẽ xem cách làm CD.

Continuous deployment

Bước này thì ta cũng sẽ có nhiều cách, mình sẽ nói về cách dễ nhất trước là ta sẽ ssh lên kubernetes master và thực hiện câu lệnh kubectl, các cách khác mình sẽ nói ở bài sau. Cập nhật lại file .gitlab-ci.yml như sau:

Ta sẽ thêm một stages nữa là deploy. Để ssh được tới server thì tùy cách bạn dùng là password hoặc key pem thì sẽ khác nhau. Của mình sẽ dùng cách key pem. Bạn vào phần Settings -> CI/CD -> Variables khi nãy, khai báo thêm các biến là SERVER_KEY_PEM, SERVER_USER, SERVER_IP tương ứng với server mà đang chạy kubernetes master. Khi ta build image và push lên gitlab xong, job deploy sẽ được chạy, nó sẽ ssh tới kubernetes master và cập nhật lại Deployment với image là image là mới build xong. Vì ở đây mình làm demo nên mình gộp 3 câu cập nhật Deployment lại trong một repo, còn thực tế các bạn nên làm mỗi repo một Deployment khác nhau nhé.

Commit và push code lên, lúc này bạn sẽ thấy pipe của ta sẽ có 2 job là build với deploy.

image.png

image.png

Vào xem log phần deploy.

image.png

Ok, vậy là luồng CD của ta đã chạy thành công 😁.

Kết luận

Vậy là ta đã tìm hiểu xong cách xây dựng luồn CI/CD với kubernetes, khi ta xây dựng CI/CD thì công việc deploy của ta trở nên dễ dàng hơn nhiều. Nếu các bạn có thắc mắc hoặc chưa hiểu rõ chỗ nào, các bạn có thể hỏi ở phần comment. Ở phần tiếp theo mình sẽ nói về cách integrate gitlab CI với thẳng kubernetes, không cần phải chạy gitlab runner, và cách xài RBAC để thiết lập permission cho từng job với namespace cụ thể.


Tags

DevOpsKubernetesCICDGitlab

Huỳnh Minh Quân

DevOps engineer

Related Posts

Hướng dẫn quẩy CICD cho elastic beanstalk với bamboo
December 14, 2021
2 min
© 2021, All Rights Reserved.

Quick Links

Liên hệ quảng cáoThông tinLiên hệ

Social Media