The Cloud Camp Week#11 (ฺGitOps)

สัปดาห์งาน 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
Ref: Git Flow vs GitHub Flow | Alex Hyett

การเอา 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

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 ต้องมี
  1. มี manifest ของ app เรา deployment / svc/ ingress / configmap บราๆ
  2. ทำ yaml CRD kind Application เพื่อบอกให้มันอ่านข้อ 1
    - ถ้าเป็นเคส App Of App ให้เอาไฟล์ขึ้นไป Repo ที่ทาง Platform กำหนดไว้
    - ถ้าไม่ใช่ kubectl apply โลด
  3. ข้อ 1 ถ้ามี Secret ทำ yaml Secret ของ Repo
  4. deploy 2 แล้วดูผลหน้าเว็บ

Resource: Getting Started - Argo CD - Declarative GitOps CD for Kubernetes (argo-cd.readthedocs.io)

วันเสาร์ได้มาลองทำ CI/CD เบากว่า Jenkins เยอะ ยิ่งถ้าทำตัว ARGOCD วาง Declarative เอา แล้วให้มันจัดการเอง

Reference


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.