Xin chào mọi người. Đây là dự án về DevOps đầu tiên của mình, dạo gần đây thì mình đọc qua nhiều JD thì thấy rất nhiều công ty đã, đang và chuẩn bị đưa hệ thống chay trên hệ thống Kubernetes, và mình thấy đa số họ sử dụng theo mô hình GitOps, mình thấy khá hay nên đã tìm hiểu và hôm nay mình viết bài này để chia sẻ về cách triển khai mô hình GỉtOps cơ bản. Những bạn mới thì có thể xem tham khảo, còn những anh (chị) lâu năm thì cho em xin những góp ý để em hoàn thiện hơn. Do đây là lần đầu của mình 😁, nên có thiếu hay sai sót ở đâu, mong mọi người bỏ qua và feedback lại để mình cải thiện.
Bài này mình sẽ triển khai 2 mô hình:
Mô hình 1: Sử dụng Terrafom để provision các VM trên MS Azure. Sau đó sử dụng Ansible để tạo hệ thống Cluster Kubernetes
Mô hình 2: Triển khai mô hình CI từ Jenkins và GitOps để deploy vào Cluster K8S
Provision VM trên Azure
Mọi người có thể clone code của mình về để tham khảo: https://github.com/tuananh281/devops-project.git
Sau khi clone project về, chúng ta sẽ tạo cho mình 2 sshkey là publickey và privatekey, sau đó di chuyển 2 key đó vào thư mục chứa souce code, set quyền cho 2 key đó (các bạn có thể tham khảo trong file README).
Thay đổi thông tin trong file terrafom.tfvar:
Mở cmd và truy cập vào folder chưa source code, chạy lệnh:
terraform apply --auto-approve
hoặc
terraform plan -out tfplan
terraform apply tfplan
Sau khi khởi tạo các resource xong, nó sẽ output ra thông tin IP của các VM:
Connect vào control-plane bằng ssh:
ssh -i private_key.pem k8s@public_ip
Thiết lập connect ssh cho ansible: Chạy command:
ssh-agent bash
ssh-add /home/k8s/ansible/private_key.pem
ssh-copy-id <ip_private_control-plane and worker1,2>
Add ip private vào inventory file
sed -i "s+cp ansible_host=control_plane_ip+cp ansible_host=**ip**+g" ./ansible/inventory sed -i "s+worker1 ansible_host=worker_1_ip+worker1 ansible_host=**ip**+g" ./ansible/inventory sed -i "s+worker2 ansible_host=worker_2_ip+worker2 ansible_host=**ip**+g" ./ansible/inventory
Kiểm tra :
- Test connect ansible:
ansible -i ./ansible/inventory -m ping all
Khởi tạo cluster
Cài đặt các dependencies:
ansible-playbook -i inventory install_kube_dependenci.yml
Tạo cluster trên server control:
ansible-playbook -i inventory create_cluster.yml
Join các worker vào cluster:
ansible-playbook -i inventory join_cluster.yml
Kiểm tra xem cluster đã ready chưa:
watch kubectl get node
SETUP CICD
- Cài đặt Jenkins Trong bài này mình sẽ dùng 1 server để chạy Jenkins riêng, mọi người có thể tham khảo 2 link dưới đây để tự setup cho mình:
https://www.jenkins.io/doc/book/installing/
https://www.youtube.com/watch?v=d2-HXYKjfbc&ab_channel=KSPM-KỹSưPhầnMềm
- Cài đặt ArgoCD
-
Tạo namespace cho Argo
kubectl create namespace argocd kubectl create namespace deploy-argocd
-
Cài đặt:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Chỉnh svc để có thể truy cập Argo bằng web:
kubectl edit svc argocd-server -n argocd
type ClusterIP >> NodePort
- Lấy port của Argo để truy cập:
kubectl get svc -n argocd
- Login Argo
User: admin
Lấy password của argo:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
Login bằng web: http://public_ip_control:node_port
ngoài truy cập và làm việc bằng web, mọi người còn có thể làm việc với ArgoCD bằng CLI, tham khảo cài đặt Argo CLI trong file README trên github!
- Tạo Job trên Jenkins
Tạo credentials github và dockerhub
Manage Jenkins -> Manage Credentials -> Global -> Add Credentials
Riêng password của github thì mọi người hãy genarate token của account github và set permision: repo, admin:repo_hook,notifications .
Mọi người hãy fork 2 repo code github này của mình về github của mọi người nhé và nhớ thay đổi github url trong 2 job Jenkins: https://github.com/tuananh281/train-schedule.git https://github.com/tuananh281/deploy-argocd.git
Sau khi fork 2 repo đó về, mọi người hãy chỉnh sửa một vài thông tin trong 2 Jenkinsfile trên cả 2 repo cho khớp vs thông tin mọi người tạo credentials trên Jenkins nhé
Tạo Job 1 build and push image lên dockerhub
Dashboard -> New Item -> Item name ... -> Pipeline -> OK
GitHub project
Project URL: https://github.com/tuananh281/train-schedule.git GitHub hook trigger for GITScm polling
Definition -> Pipeline script from SCM -> Git
URL Project: https://github.com/tuananh281/train-schedule.git branch: main Script Path: Jenkinsfile
-> Save
Tạo Job 2 update manifest vào deployment
Dashboard -> New Item -> Item name: update-manifest-github -> Pipeline -> OK
This project is paramesterized -> Add Paramester -> String Paramester
Name: DOCKERTAG Value: latest
Definition -> Pipeline script from SCM -> Git
URL project: https://github.com/tuananh281/deploy-argocd.git branch: main Script Path Jenkinsfile
Setup webhook để jenkins có thể trigger mỗi khi repo code bị thay đổi
Truy cập vào github repo ở job 1 -> setting -> Webhooks -> Add webhook
Payload URL: http://ip_public_jenkins:port/github-webhook/ Content type: application/json Just the push event.
Đây là quy trính CI ( Continuous Integration)
- Tạo application trên argocd
Truy cập vào ArgoCD bằng browser
NEW APP -> Thiết lập 1 vài thông tin
Application Name: demogitops Project Name: default Sync Policy: Automatic Repository URL: https://github.com/tuananh281/deploy-argocd.git Path: . Cluster URL: ...default.svc Namespace: deploy-argocd ->Create
- Khởi chạy
Sau khi setup khá loằng ngoằng , giờ đến lúc chúng ta nghiệm thu kết quả. Mọi người có thể chọn Build Now trong Job 1 trên Jenkins, hoặc thay đổi một vài thứ gì đó trong code và push lên repo github, khi đó Jenkins sẽ trigger thay đổi của github và sẽ tự động run Job 1. Trong Job1, khi đã build và push image lên dockerhub, bước cuối cùng job1 sẽ build Job 2. Cơ chế mấu chốt ở đây là biến dockertag, nó như là version của image, số version đó sẽ là lần thứ bao nhiêu Job đó chạy, và mỗi lần chạy sẽ là 1 version mới. Job 2 sẽ chạy sau khi nhận được paramester của Job 1 là dockertag, chạy sript để update version mới của image vào trong file deployment.yaml và sẽ push lại lên github repo. Trên ArgoCD, sau một khoảng thời gian, nếu minh nhớ không nhầm khoảng 180s thì Argo sẽ auto sync vs github và deploy file deployment.yaml
- Run Job 1:
Mọi người có thể mở cửa sổ console output để xem quá trình Jenkins chạy nhé
- Run Job 2:
- ArgoCD auto sync với github repo:
- Truy cập vào control-plane, lấy port của service mà ta vừa deploy: kubectl get all -n deploy-argocd
Kết quả:
Mở trình duyệt: http://ip_public_control-plane:port
Thử nghiệm:
Mọi người có thể chỉnh sửa file index.jade trong folder views và commit nó lên github repo:
***Đến đây là hết bài rồi, rất cảm ơn mọi người đã dành thời gian để xem bài viết này của mình, bài này khá cơ bản và mình thấy cũng có rất nhiều hướng dẫn làm dạng lab như này. Chính mình cũng đã tham khảo từ rất nhiều nguồn, để có thể làm được. mỗi người sẽ có cách làm và trình bày khác nhau, mọi người có thể tham khảo rất nhiều bài và tự đưa ra cho mình một con đường đi phù hợp nhé 🤩. Đây là bài viết đầu tiên của mình nên có thể còn nhiều thiếu sót, rất mong có thể nhận được phản hồi của mọi người để mình có thể cải thiện hơn, để trong tương lai mình sẽ có động lưc để chia sẻ nhiều thứ hơn.