Argo CD + GitLab CI สร้าง Pipeline ตั้งแต่ Build จนถึง GitOps Deploy

Argo CD + GitLab CI สร้าง Pipeline ตั้งแต่ Build จนถึง GitOps Deploy

Argo CD และ GitLab CI เป็นสองเครื่องมือที่ทรงพลังสำหรับการสร้าง CI/CD Pipeline ที่ยอดเยี่ยม ในบทความนี้เราจะมาศึกษาวิธีการ
ประสานการทำงานระหว่าง GitLab CI กับ Argo CD เพื่อสร้าง Pipeline ที่สมบูรณ์ตั้งแต่ Build, Test, Push Image ไปจนถึง
GitOps-based Deployment บน Kubernetes

ทำความเข้าใจ Argo CD และ GitLab CI

GitLab CI คือ Continuous Integration tool ที่ช่วยให้เราสามารถ automate การ build, test และ push Docker image ไปยัง Registry
ได้อย่างอัตโนมัติ เมื่อมีการ commit ไปยัง repository

Argo CD เป็น Continuous Deployment tool ที่ใช้หลักการ GitOps คือการจัดการ deployment state ผ่าน Git repository
Argo CD จะ monitor changes ในหลังมาจาก repository แล้ว sync ไปยัง Kubernetes cluster โดยอัตโนมัติ

เมื่อนำสองเครื่องมือนี้มารวมกัน จะได้ระบบ CI/CD ที่เสถียร มีความปลอดภัยสูง และ scalable ซึ่งเหมาะสำหรับองค์กรที่ต้องการ
deploy ผลงานบ่อยๆ

สถาปัตยกรรมของระบบ

ขั้นตอนการทำงานของระบบ Argo CD + GitLab CI มีดังนี้:

  1. Developer Push Code: Developer push code ไปยัง GitLab repository
  2. GitLab CI Triggered: GitLab CI pipeline จะ trigger โดยอัตโนมัติ
  3. Build & Test: Pipeline ทำการ build application และ run unit tests
  4. Push Image: Docker image ถูก push ไปยัง Docker Registry พร้อมกับ tag
  5. Update Manifest: Pipeline update image tag ในไฟล์ Kubernetes manifest ใน Deployment repository
  6. Argo CD Sync: Argo CD detect การเปลี่ยนแปลงในไฟล์ manifest และ sync ไปยัง Kubernetes cluster

ตั้งค่า GitLab CI Pipeline

ไฟล์ .gitlab-ci.yml คือ configuration ที่ขับเคลื่อน GitLab CI โดยไฟล์นี้จะต้องอยู่ใน root directory ของ project

ตัวอย่าง .gitlab-ci.yml พื้นฐาน

ด้านล่างนี้คือตัวอย่าง .gitlab-ci.yml ที่มีขั้นตอนการ build, test, push Docker image และ update Kubernetes manifest:

stages:
  - build
  - test
  - push
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  REGISTRY_URL: registry.gitlab.com
  IMAGE_NAME: $REGISTRY_URL/$CI_PROJECT_PATH
  DEPLOYMENT_REPO: https://gitlab.com/myorg/deployment-configs.git
  DEPLOYMENT_BRANCH: main

# Build Docker Image
build_image:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
  script:
    - docker build -t $IMAGE_NAME:$CI_COMMIT_SHA -t $IMAGE_NAME:latest .
  after_script:
    - docker logout

# Run Tests
test_app:
  stage: test
  image: node:18
  script:
    - npm install
    - npm run test

# Push Image to Registry
push_image:
  stage: push
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
  script:
    - docker pull $IMAGE_NAME:$CI_COMMIT_SHA || docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
    - docker push $IMAGE_NAME:$CI_COMMIT_SHA
    - docker tag $IMAGE_NAME:$CI_COMMIT_SHA $IMAGE_NAME:latest
    - docker push $IMAGE_NAME:latest
  only:
    - main

# Update Deployment Manifest
update_manifest:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache git
    - git config --global user.email "[email protected]"
    - git config --global user.name "GitLab CI Bot"
    - git clone --branch $DEPLOYMENT_BRANCH $DEPLOYMENT_REPO deployment-repo
  script:
    - cd deployment-repo
    - sed -i "s|image: .*|image: $IMAGE_NAME:$CI_COMMIT_SHA|g" k8s/deployment.yaml
    - git add k8s/deployment.yaml
    - git commit -m "Update image to $CI_COMMIT_SHA from commit $CI_COMMIT_SHORT_SHA"
    - git push origin $DEPLOYMENT_BRANCH
  only:
    - main

คำอธิบายไฟล์ .gitlab-ci.yml

  • stages: กำหนดขั้นตอนการ execute pipeline ตามลำดับ
  • variables: ตัวแปรทั่วไปที่ใช้ในทั้ง pipeline
  • docker:dind: Docker in Docker service ที่อนุญาตให้ build Docker image ภายใน Docker
  • before_script: commands ที่ execute ก่อน job script
  • only: กำหนดว่า job นี้ execute เฉพาะ branch ที่ระบุ

ตั้งค่า Argo CD Application

Argo CD ใช้ Application resource ในการ define ว่าจะ deploy application นี้อย่างไร โดยจะ specify source repository ที่มี
Kubernetes manifests และ destination cluster ที่ต้องการ deploy ไป

ตัวอย่าง Argo CD Application Manifest

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  project: default

  source:
    repoURL: https://gitlab.com/myorg/deployment-configs.git
    targetRevision: main
    path: k8s

  destination:
    server: https://kubernetes.default.svc
    namespace: default

  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

คำอธิบายตัวเลือก Application

  • repoURL: URL ของ Git repository ที่เก็บ Kubernetes manifests
  • targetRevision: Branch หรือ tag ที่ Argo CD จะ watch
  • path: Path ภายใน repository ที่เก็บ manifests
  • server: Kubernetes cluster API server URL
  • automated: เปิดใช้ automatic sync เมื่อมี changes ใน repository
  • prune: ลบ resources ที่ไม่มีในไฟล์ manifest อีกต่อไป
  • selfHeal: ทำให้ Argo CD ทำการ sync หากพบ drift ระหว่าง Git กับ cluster

ตัวอย่าง Kubernetes Deployment Manifest

ไฟล์ Kubernetes manifest ที่เก็บใน deployment repository ควรมีรูปแบบดังนี้:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: default
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: registry.gitlab.com/myorg/myapp:latest
          ports:
            - containerPort: 8080
          env:
            - name: ENVIRONMENT
              value: "production"
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: default
spec:
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 8080
  type: LoadBalancer

ตั้งค่า GitLab Access Token สำหรับ Argo CD

Argo CD จำเป็นต้องมีสิทธิ์เข้าถึง GitLab repository ดังนั้นเราจึงต้องสร้าง Access Token ใน GitLab

ขั้นตอนการสร้าง GitLab Access Token

  1. เข้า GitLab → Settings → Access Tokens
  2. คลิก “Create personal access token”
  3. ตั้งชื่อ token (เช่น “argocd-access”)
  4. เลือก scopes: read_repository และ read_api
  5. คลิก “Create”
  6. Copy token แล้วเก็บไว้ให้ปลอดภัย

สร้าง Secret ใน Argo CD

kubectl create secret generic gitlab-credentials \
  --from-literal=username=oauth2 \
  --from-literal=password=<YOUR_GITLAB_TOKEN> \
  -n argocd

หลังจากนั้น ให้ configure Argo CD repository credentials ผ่าน argocd-repository-credentials secret

ขั้นตอนการทำงานของ Pipeline

1. Developer Push Code

เมื่อ developer push code ไปยัง main branch ใน application repository:

git add .
git commit -m "Add new feature"
git push origin main

2. GitLab CI Pipeline Execute

GitLab CI จะอัตโนมัติ execute pipeline ที่ได้กำหนดไว้ใน .gitlab-ci.yml:

  • ทำการ build Docker image
  • ทำการ run unit tests
  • Push image ไปยัง Docker registry พร้อมกับ tag ที่เป็น commit SHA

3. Update Deployment Manifest

Pipeline update image tag ในไฟล์ k8s/deployment.yaml ใน deployment-configs repository:

# Before
image: registry.gitlab.com/myorg/myapp:latest

# After
image: registry.gitlab.com/myorg/myapp:abc1234def5678

4. Argo CD Detect Changes

Argo CD monitor deployment-configs repository และ detect การเปลี่ยนแปลงในไฟล์ manifest เมื่อตรวจพบการเปลี่ยนแปลง Argo CD จะทำการ sync
โดยอัตโนมัติ

5. Deploy to Kubernetes

Argo CD apply ไฟล์ manifest ไปยัง Kubernetes cluster และ rollout deployment ใหม่พร้อมกับ image version ที่อัพเดตแล้ว

Best Practices สำหรับ Argo CD + GitLab CI

1. แยก Repository

ให้แยก application repository กับ deployment-configs repository เพื่อให้การจัดการง่ายขึ้น application repository มี source code และ
Dockerfile ส่วน deployment-configs repository มี Kubernetes manifests

2. ใช้ Tag อย่างมีระบบ

ใช้ commit SHA หรือ semantic versioning (เช่น v1.2.3) สำหรับ Docker image tag เพื่อให้ง่ายต่อการ track version ที่ deploy ไปยัง
production

3. ตั้งค่า Notification

ตั้งค่า Argo CD Notifications เพื่อให้ทีมได้รับการแจ้งเตือนเมื่อมี deployment ผ่าน Slack หรือ Email

4. Monitor และ Logging

ตั้งค่า monitoring และ logging สำหรับ Argo CD และ application เพื่อติดตามสถานะของ deployment และตรวจจับปัญหาได้อย่างรวดเร็ว

5. Access Control

ใช้ RBAC (Role-Based Access Control) เพื่อควบคุมสิทธิ์เข้าถึง Argo CD และ GitLab repositories ให้เฉพาะผู้ที่มีสิทธิ์เท่านั้น

6. Health Checks

ตั้งค่า liveness probe และ readiness probe ในไฟล์ Deployment manifest เพื่อให้ Kubernetes สามารถตรวจจับ pod ที่ไม่สามารถทำงานได้

การแก้ไขปัญหาทั่วไป

ปัญหา: Argo CD ไม่ sync application

สาเหตุ: Access token ของ GitLab หมดอายุหรือ permission ไม่เพียงพอ

วิธีแก้: สร้าง token ใหม่และอัพเดต secret ใน Kubernetes

ปัญหา: GitLab CI pipeline fail ตอน push image

สาเหตุ: Docker registry credentials ไม่ถูกต้องหรือ docker:dind service ไม่ทำงาน

วิธีแก้: ตรวจสอบ CI/CD variables ในการตั้งค่า GitLab และตรวจสอบ docker:dind service

ปัญหา: Image ไม่อัพเดตแม้ว่า manifest ได้รับการเปลี่ยนแปลง

สาเหตุ: Argo CD ใช้ image pull policy ที่ไม่ pull image ใหม่

วิธีแก้: เพิ่ม imagePullPolicy: Always ในไฟล์ Deployment manifest

ทำไมควรใช้ Infrastructure บน ผู้ให้บริการโฮสติ้ง Cloud VPS

การทำงานของระบบ Argo CD + GitLab CI ต้องการ infrastructure ที่เสถียร และมีประสิทธิภาพสูง
ผู้ให้บริการโฮสติ้ง Cloud VPS
ให้คุณมีความอิสระในการจัดตั้ง Kubernetes cluster และเครื่องมือ DevOps อื่นๆ

ประโยชน์ของการใช้ ผู้ให้บริการโฮสติ้ง Cloud VPS

  • Performance สูง: SSD storage และ high-speed network สำหรับ build pipeline
  • Flexibility: สามารถเลือก OS และ install software ตามที่ต้องการ
  • Scalability: รองรับการขยายจำนวน nodes ในคลัสเตอร์ได้อย่างง่าย
  • Security: Firewall และ network isolation เพื่อปกป้อง infrastructure
  • Support: ทีมสนับสนุนที่พร้อมช่วยแก้ปัญหา 24/7

สรุป

Argo CD + GitLab CI เป็นการผสมผสาน CI/CD tool ที่ยอดเยี่ยมสำหรับการสร้าง automation pipeline ที่สมบูรณ์ตั้งแต่ build, test,
push image ไปจนถึง deployment บน Kubernetes โดยใช้หลักการ GitOps ที่ทำให้ระบบมีความเสถียร ปลอดภัย และง่ายต่อการบำรุงรักษา

หากคุณต้องการ infrastructure ที่เสถียรเพื่อรองรับระบบนี้ ผู้ให้บริการโฮสติ้ง Cloud VPS คือตัวเลือกที่ดี