สัปดาห์งาน Merge โคตร Branch เข้ามา และมีได้ข่าวอีกว่ามีเอา App Ver pre-alpha ไปส่งลูกค้าด้วย ซึ่งมันพอดีกับ Week นี้ ที่เรียนเรื่อง SemVer พอดีแบบนัดกันมาอีก 555 สำหรับหัวข้อที่เรียนใน Week นี้ตามนี้เลยครับ
Semantic Versioning (Semver)
แนวทางการบอกระดับของการเติบโตของ Software โดยมีรูปแบบ ดังนี้
MAJOR.MINOR.PATCH+LABEL
- MAJOR - Breaking Change มีการแก้ใหญ่ เช่น API เปลี่ยน พฤติกรรมต่างไปจากเดิมเลย
- MINOR - Feature ที่ไม่ Breaking Change และรอบรับกับเวอร์ชันเก่าๆ (Backward Compatibility)
- PATCH - แก้ BUG ที่เกิดขึ้น + Backward Compatibility
- LABEL
➡️ -alpha - พร้อมเล่น แต่ไม่พร้อมใช้จริง อาจจะมี Bug ที่เราไม่รู้
➡️ -beta - ready to production, but have known issue
➡️ -rc (release canidate) - ตัวเต็งที่จะนับเป็นตัวจริง ให้ End-User วงแรกๆทดสอบก่อน Release จริง ถ้าไม่พบ Bug อะไรเพิ่มในการทดสอบขั้นสุดท้าย
Note อื่นๆ
➡️ -pre-alpha - พร้อมจะเป็นเหยื่อได้ทุกเวลา ใน .NET Nuget จะให้กำหนด Ver แบบนี้
➡️ -test / -uat - ตกลงกันภายในองค์กร
➡️ -SNAPSHOT ของ java จะใช้กันเทียบกับ release canidate (rc)
สำหรับใน Blog ผมเรื่อง SemVer จะมีเขียนไว้แล้วในส่วนตอนเตรียมสอบ [AZ-400] Design and implement a dependency management strategy (Implement a versioning strategy) หรือจะไปดูเอกสารของ Semantic Versioning (semver.org)
Git Conventional Commits
- ข้อตกลงบอกการเปลี่ยนแปลงของ Code ที่เกิดขึ้น เพื่อสื่อสาร และส่งต่อความเข้าใจให้ทายาทรุ่นหลัง
- ถ้ากำหนดรูปแบบดี สามารถสรุปอออกมาเป็น Semantic Version Bump (ดูจาก commit type และปรับเวอร์ชันตาม SemVer) / ChangeLog ได้ ตัวอย่างจาก project yq / k8s
- Triggering build + publish
รูปแบบ
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
- <type>
- build : เพิ่ม lib
- ci: แก้ไฟล์ Pipeline หรือ Resource ที่เกี่ยวกับการ Build
- docs: Documentation only changes
- feat: new feature มีผลกับการ bump version
- chore: เปลี่ยนอะไรเล็กๆน้อยๆ มันจะคล้ายๆ feat/fix
- fix: bug fix
- perf: performance improvement
- refactor: for improve code maintainer ability
- test: Adding missing tests or correcting existing tests
- revert: define revert behavior - [optional scope] - แก้ที่ไหน เช่น npm / jenkins / หรือตาม module
- <description> - สั้นๆกระชับว่าแก้อะไร ส่วนใหญ่จะอ้างอิงตามของตัว Angular ไม่นิยมใส่ dot (.) ต่อท้าย
- [optional body] - เนื้อหาแบบยาวๆ แต่ปกติไม่ได้ใช้ไปใส่ใน Ticket
- [optional footer(s)] - บอกอะไรที่สำคัญ เช่น Feature + BREAKING CHANGE!
Sample
feat(compliance): Modified API to Support Limit Check (AMC Base) BREAKING CHANGE: API Change and required field such as condition price (more detail #345269)
ci(jenkins): add filter branchname in main, develop, feature/**, bugfix/**
Ref: Conventional Commits
Tools: commitlint - Lint commit messages / typicode/husky: Git hooks made easy woof! (github.com)
Git Workflow
Workflow = Guideline บอกรูปแบบการทำงาน เพื่อให้การทำงานในทางเดียวกัน และต่อเนื่องได้
- Centralized Workflow
ทำงาน Branch เดียว Trunk Base ไม่มีการแตก Branch เพิ่มใช้ร่วมกัน
PRO & CON
- PRO Simple
- CON
- Single Point of failure เพราะทุกคนทำงานที่เดี๋ยวกัน ถ้าพลาดต้องเสียเวลารอแก้ใน main / trunk ให้เรียบร้อย
- ถ้าทีมงานเยอะ มีปัญหาในการ Scale และถ้าเกิดข้อผิดพลาดได้ตายหมู่
- Feature Branch Flow
เอามาแก้ปัญหาของ Centralized Workflow ที่ Scale ยาก พอแยก Branch ออกไป ต้องมีการนำ Code กลับมารวมกัน ตามแนวทาง ดังนี้
- MERGE
- Rebase
- SQUASH Commit - รวบให้เหลือ Commit เดียว
PRO & CON
- PRO กระจายความเสี่ยง / แยกส่วนการทำงาน (Scale-Up) เช่น ทำ Feature หรือ Bug Fixed
- CON กระจายกัน ตอนรวมเสียเวลาต้องมา Code Review ก่อนเข้าส่วนกลาง
- Git Flow
การเอา Feature Branch Flow มาขยายความต้อง โดยกำหนดลำดับ และหน้าที่ของ Branch ให้ชัดเจน อาทิ เช่น
- master - single source of truth เก็บ code ที่ผ่านการเทสขึ้น Prod แล้ว ส่งลูกค้าแล้ว
- hotfixes - แตกจาก master ใช้แก้ bug ไฟไหม้
- release - แตกจาก develop เป็นการ cut off code มาเพื่อเตรียมตัว Release Canidate merge เข้า master
- develop - ศูนย์รวม Code ล่าสุด จากทุก Feature / Bug Fixed
- feature - แตกจาก develop เอาไว้ทำ feature ใหม่ หรือ จะแก้ bug ก็ได้ บางทีอาจจะแยกชื่อ branch เฉพาะเป็น bugfixed
สำหรับที่อื่น จะมี
- support สำหรับกรณีที่า app นั้นมีส่งหลาย Site จะแยกไว้ แก้บั๊กของแต่ละ site จากนั้นค่อยตบเข้า develop อีกที
ตัว CI/CD Pipeline มันควรจะ Reused ได้ด้วยนะ
PRO & CON คล้ายกับ Feature Branch Flow แต่ความเลือกตามขนาดทีม และอาจจะต้องรอให้ Codebase Stable ก่อน ถึงมาจัด เช่น เข้าช่วง UAT /Go-live
ของผมเองมีเอา Git Flow มาปรับใช้เหมือนกันครับ ตามนี้เลย [GIT] แบ่งปัน Git Flow ที่ได้ใช้งานจริง แต่ตอนนี้จะปรับความถี่ของ branch release จากเดือนละครั้ง มาเป็น 1 week
- Forking Workflow
เหมือนกับ Git Flow / Feature Branch Flow แต่เป็นการแตก Repo ออกมาแก้ไข โดยที่เราสามารถ Sync Code จาก Repo หลัก มองว่าเปลี่ยนจาก Repo เป็น Branch โดยการสงที่แก้ไขกลับไป จะเรียกว่าเป็นการทำ Pull Request (GitHub) / Merge Request (GitLab)
แต่มี Learning Curve สูงเหมือนกัน ใน Open-Source จะทำ Contribution.md ขึ้นมาเป็น Guideline.
GitOps CI/CD
ขยายมาจาก CI/CD โดยให้มันเริ่ม Trigger / ให้พวก Infra (K8S) มาจาก Git
- CI
- Prebuild
- Build - Build Code + Containerized
- GitOpsCI - แก้ไข manifest และ cSommit กลับขึ้นไป
- PostBuild - วัด Metric ที่นิยม DORA Metric + Notify (K8S มี KubeBot)
- CD
- Clone Repo
- Discover manifest
- เขียน bash Kubectl Apply
- หรือใช้พวก CD Tools อย่าง ArgoCD ให้มา pull check state - Tests
- Functional test
- Component test
- Contract test
เป็นต้น - Run-time vulnerability testing
- Publish metrics.
- Notification
Push & Pull Base
เวลา Design Arch ต้องระวังมันมีผลเรื่อง Performance ตอนสรุปอะไรให้ลงเอกสาร ADR ให้ทายาทรุ่นหลังง
GitOps Flow
แตก Branch แล้วให้มันทำ GitOps CI/CD พอผ่านการทดสอบแล้วให้ Approve และ Merge เข้า Branch หลัก
Ref
- Testing Strategies in a Microservice Architecture (martinfowler.com)
- Contraction Test: Introduction | Pact Docs
ARGO CD
argocd เป็น Tools ที่ช่วยให้ตอนทำ CD ง่ายขึ้น เขียน Declarative + กำหนดจาก UI
- Install
มีลงแบบ CORE เบา headless-mode / multi-Tenant มี UI รองรับได้หลาย Cluster โดยเจ้าตัว multi-Tenant จะมีลงแบบ non-ha / ha โดยสามารถลงใน Scope ClusterWide / NameSpace (ให้มันดูเฉพาะ Namspace ที่กำหนด) ลงเสร็จดู Default Password จาก
argocd admin initial-password -n argocd #ใช้เสร็จแล้ว อย่าลืมไป Clear ออกจาก Secret
Ref: Getting Started - Argo CD - Declarative GitOps CD for Kubernetes (argo-cd.readthedocs.io)
- argocd login
argocd login <ARGOCD_SERVER> argocd login https://your-argocd.yoururl.com/ --grpc-web ห้ามใส่ slash ข้างหลังกับ protocal argocd login your-argocd.yoururl.com --grpc-web
- Applications CRD
เป็น GitOps Custom Resource Definition (Kind Applications) ที่มาช่วย Monitor State ของ Deployment
Note ถ้าเป็น CRD อย่างตัว Applications จะสามารถใช้
kubectl get applications
repoURL: git@git ... targetRevision: branch path #Sample ARGO CD Kind Application apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: blog-ping namespace: argocd spec: project: blog-ping-policy #บอก appProject (Policy ที่ใช้) #เอา Deployment จากที่ไหน source: repoURL: <<YOUR-GIT-URL>> targetRevision: develop #Path ใน Git path: Learn/blog #ปลายทาง Deploy destination: #Argo CD UI > Setting > Cluster server: https://kubernetes.default.svc #ลงที่ Namespace อะไร เช่น g1dev / invprod namespace: default #บอกรวมการ pull ตรวจระหว่าง source กับ destination syncPolicy: automated: prune: true selfHeal: true
App of App Patterns เราสามารถสร้าง Resource Kind Applications ที่เข้ามาช่วยตรวจสอบ Applications ที่อยู่ภายใต้ได้
ARGO MAIN | |- ARGO APP-A -[[-Manage Resource-]]-->> deployment/app-a ---| | |--[[-Govern by-]] appProject1 |- ARGO APP B -[[-Manage Resource-]]-->> deployment/app-b ---| | |- ARGO APP C -[[-Manage Resource-]]-->> deployment/app-c ---|--[[-Govern by-]] appProject2
ARGO MAIN - Platform ทำ แลัวเปิดทำ Tools ให้ Dev มาสร้าง ARGO APP-A / ARGO APP-B อยู่ภายใต้ได้ (Self Service)
- Projects
ทำ Policy คุมว่าให้ลง Resource ไหนได้บ้าง ใน Cluster / namespace
//ทำได้ หรือป่าว kubectl get Appprojects
#Sampple ARGOCD AppProject.yaml apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: blog-ping-policy namespace: argocd spec: sourceRepos: - '*' destinations: - namespace: default server: https://kubernetes.default.svc clusterResourceWhitelist: - group: '*' kind: '*' namespaceResourceWhitelist: - group: 'app' kind: 'deployment' - group: 'appdb' kind: 'statefulset'
- App List
argocd app list #บอกว่ามีอะไรบ้างที่ลงใน ARGOCD STATUS HEALTH . NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET ....
- ARGOCD Auth Git
สร้าง Secret ขึ้นมาใน namespace ของ argocd
#Sample Git Secret Kind Secret with argocd apiVersion: v1 kind: Secret metadata: name: blog-secret namespace: argocd labels: argocd.argoproj.io/secret-type: repo-creds stringData: url: <<YOUR GIT URL>> sshPrivateKey: | -----BEGIN OPENSSH PRIVATE KEY----- YOUR PRIVATE KEY EveryThingJigaBell -----END OPENSSH PRIVATE KEY-----
ภาพรวม GitOps
ตรง ArgoCD (รูปปลาหมึก) อาจจะเขียน Bash ตรงๆ หรือใช้ CD ของค่ายอื่นๆ ก็ได้ ส่วนความสัมพันธ์ของ Code > Manifest (deployment / svc/ ingress / configmap บราๆ) ตามรูปด้านล่าง
สรุป Step จะใช้ ARGO CD ต้องมี
- มี manifest ของ app เรา deployment / svc/ ingress / configmap บราๆ
- ทำ yaml CRD kind Application เพื่อบอกให้มันอ่านข้อ 1
- ถ้าเป็นเคส App Of App ให้เอาไฟล์ขึ้นไป Repo ที่ทาง Platform กำหนดไว้
- ถ้าไม่ใช่ kubectl apply โลด - ข้อ 1 ถ้ามี Secret ทำ yaml Secret ของ Repo
- deploy 2 แล้วดูผลหน้าเว็บ
Resource: Getting Started - Argo CD - Declarative GitOps CD for Kubernetes (argo-cd.readthedocs.io)
วันเสาร์ได้มาลองทำ CI/CD เบากว่า Jenkins เยอะ ยิ่งถ้าทำตัว ARGOCD วาง Declarative เอา แล้วให้มันจัดการเอง
Reference
- Assigning permissions to jobs - GitHub Docs -- ใช้ตอน auto tag แก้ k8s manifest แล้ว commit + push
- ArgoCD : How to access private github repository with ssh key new way | by Sanjay Tiwari | Medium
- Docker Tags Action · Actions · GitHub Marketplace ทำการบ้านวันอังคารแล้วงง
- Creating releases with GitHub Actions - Andreas Möller (localheinz.com)
- Automating Tag Creation, Release, and Docker Image Publish with GitHub Actions - DEV Community
- Most effective ways to push within GitHub Actions | Johtizen
- FluxCD vs ArgoCD | Comparing Flux CD and Argo CD for Efficiency | Medium
- Kubernetes recipes: Maintenance and troubleshooting – O’Reilly (oreilly.com) - แปะไว้ ทำให้มัน Hint Command
- kubernetes - How to login to ArgoCD CLI non-interactive in CI like GitHub Actions? - Stack Overflow
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.