จัดการ Secrets ใน Argo CD ด้วย Sealed Secrets และ External Secrets

จัดการ Secrets ใน Argo CD ด้วย Sealed Secrets และ External Secrets Operator

การจัดการข้อมูลที่เป็นความลับ (Secrets) เป็นหนึ่งในความท้าทายสำคัญเมื่อใช้งาน Argo CD ในสภาพแวดล้อม DevOps แบบที่ใช้ Infrastructure as Code (IaC)। บทความนี้จะอธิบายวิธีการจัดการ Secrets อย่างปลอดภัยโดยใช้ Sealed Secrets และ External Secrets Operator ซึ่งช่วยให้คุณสามารถเก็บข้อมูลลับในที่ที่ปลอดภัยและง่ายต่อการจัดการ

ทำไมการจัดการ Secrets ถึงสำคัญใน Argo CD

เมื่อคุณใช้ Argo CD ในการจัดการ Kubernetes clusters ผ่าน Git repository คุณต้องเก็บข้อมูลที่ไวต่อความปลอดภัยเช่น API keys, database passwords, และ SSH keys ในไฟล์ YAML configuration files ลักษณะปัญหาหลักคือ:

  • ไม่สามารถเก็บ plain text secrets ใน Git repository ได้เนื่องจากความเสี่ยงด้านความปลอดภัย
  • ต้องมีวิธีเข้ารหัส (encryption) ข้อมูลลับเพื่อให้สามารถจัดเก็บใน version control system ได้
  • ผู้มีสิทธิ์ใช้งานต้องสามารถถอดรหัส (decrypt) Secrets ได้เมื่อจำเป็น
  • สำหรับผู้ที่ใช้ Cloud VPS หรือ Cloud Hosting เช่นบริการจาก ผู้ให้บริการโฮสติ้ง ที่ที่อยู่ https://de.co.th/cloud-vps ลักษณะการจัดการ Secrets จึงมีความสำคัญอย่างยิ่งในการรักษาความปลอดภัยของ infrastructure

Sealed Secrets: วิธีการเข้ารหัส Secrets ที่ง่ายและปลอดภัย

Sealed Secrets คืออะไร

Sealed Secrets เป็น Kubernetes controller ที่ถูกพัฒนาโดย Bitnami ซึ่งช่วยในการเข้ารหัส Kubernetes Secrets ด้วยคีย์รหัสที่จัดเก็บบนคลัสเตอร์ ทำให้สามารถจัดเก็บ Secrets ที่เข้ารหัสแล้วใน Git repository ได้อย่างปลอดภัย

ขั้นตอนการติดตั้ง Sealed Secrets

ขั้นแรกให้ติดตั้ง Sealed Secrets controller ลงบน Kubernetes cluster ของคุณ:

kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

จากนั้นติดตั้ง kubeseal command-line tool บนเครื่องของคุณ:

wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-0.24.0-linux-amd64.tar.gz
tar xfz kubeseal-0.24.0-linux-amd64.tar.gz
sudo mv kubeseal /usr/local/bin/

การสร้าง SealedSecret

ขั้นตอนแรกคือสร้าง plain Secret ซึ่งจะถูกเข้ารหัสภายหลัง:

cat <<EOF | kubectl create secret generic mysecret --dry-run=client --from-file=/dev/stdin -o yaml
username: myuser
password: mypassword
EOF

จากนั้นทำการเข้ารหัส Secret ด้วย kubeseal:

kubectl create secret generic mysecret --from-literal=username=myuser --from-literal=password=mypassword --dry-run=client -o yaml | kubeseal -f - > mysealedsecret.yaml

ตอนนี้คุณสามารถจัดเก็บ mysealedsecret.yaml ใน Git repository ได้อย่างปลอดภัย เนื่องจากข้อมูลถูกเข้ารหัสแล้ว

ตัวอย่าง SealedSecret YAML ที่สมบูรณ์

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: database-secret
  namespace: default
spec:
  encryptedData:
    db-username: AgBvX5H8j2K9lM3pQ7sT... (encrypted data)
    db-password: AgCwYzH1k4N6oR2vU5x... (encrypted data)
  template:
    metadata:
      name: database-secret
      namespace: default
    type: Opaque

External Secrets Operator: การจัดการ Secrets จากแหล่งภายนอก

External Secrets Operator คืออะไร

External Secrets Operator (ESO) เป็น Kubernetes operator ที่ช่วยให้คุณสามารถดึง Secrets จากแหล่งภายนอกเช่น AWS Secrets Manager, HashiCorp Vault, Azure Key Vault เข้าไปใน Kubernetes Secrets โดยอัตโนมัติ

การติดตั้ง External Secrets Operator

ติดตั้ง ESO ด้วย Helm:

helm repo add external-secrets https://charts.external-secrets.io
helm repo update
helm install external-secrets external-secrets/external-secrets -n external-secrets-system --create-namespace

ตัวอย่าง: การใช้ HashiCorp Vault กับ External Secrets

ขั้นแรก สร้าง SecretStore ที่จะเชื่อมต่อกับ Vault:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "my-application"

จากนั้นสร้าง ExternalSecret เพื่อดึง Secrets จาก Vault:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: app-secrets
    creationPolicy: Owner
  data:
    - secretKey: database-password
      remoteRef:
        key: app/database
        property: password
    - secretKey: api-token
      remoteRef:
        key: app/api
        property: token

ตัวอย่าง: การใช้ AWS Secrets Manager

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secrets-store
spec:
  provider:
    aws:
      service: SecretsManager
      region: ap-southeast-1
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa

---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: aws-app-secrets
spec:
  refreshInterval: 30m
  secretStoreRef:
    name: aws-secrets-store
    kind: SecretStore
  target:
    name: aws-app-secrets
  data:
    - secretKey: db-password
      remoteRef:
        key: prod/database/password

การเปรียบเทียบ Sealed Secrets และ External Secrets Operator

ลักษณะการ Sealed Secrets External Secrets Operator
แหล่งจัดเก็บ Secrets Kubernetes cluster (built-in) แหล่งภายนอก (Vault, AWS, Azure)
ความซับซ้อน ง่าย เหมาะสำหรับผู้เริ่มต้น ซับซ้อนมากขึ้น แต่ยืดหยุ่นกว่า
ความปลอดภัย เข้ารหัสด้วยคีย์บน cluster มีการจัดการตามมาตรฐานองค์กร
การหมุนเวียนคีย์ (Key Rotation) ต้องทำด้วยตนเอง อัตโนมัติ
กรณีการใช้งาน โปรเจกต์ขนาดเล็ก/กลาง องค์กรขนาดใหญ่ที่มี Secrets Management System

แนวทางปฏิบัติที่ดีที่สุด (Best Practices)

1. ใช้ Namespaces เพื่อแยก Secrets

จัดกลุ่มแอปพลิเคชันตามฟังก์ชัน และใช้ Namespaces แยกกัน เพื่อให้แต่ละ Namespace มี Secrets ของตัวเอง

2. สำหรับผู้ใช้ ผู้ให้บริการโฮสติ้ง Cloud VPS

หากคุณใช้บริการ Cloud VPS จาก ผู้ให้บริการโฮสติ้ง (https://de.co.th/cloud-vps) ให้พิจารณาการใช้ External Secrets Operator เชื่อมต่อกับ Vault หรือ Secret Management Service เพื่อรักษาความปลอดภัยของข้อมูลลับของแอปพลิเคชันของคุณ

3. การตั้งค่า RBAC (Role-Based Access Control)

จำกัดสิทธิ์การเข้าถึง Secrets เฉพาะเจ้าหน้าที่ที่ต้องการเท่านั้น:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
  resourceNames: ["app-secrets"]

4. การติดตามและการตรวจสอบ (Auditing)

เปิดใช้งาน audit logs เพื่อติดตามการเข้าถึง Secrets ทั้งหมด

5. การหมุนเวียนคีย์อย่างสม่ำเสมอ

จัดตั้งนโยบายการหมุนเวียน Secrets โดยอัตโนมัติหรือตามตารางเวลาที่กำหนด

การผสานรวม Secrets Management กับ Argo CD

ตัวอย่างการใช้ SealedSecret ใน Argo CD Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/myrepo
    targetRevision: HEAD
    path: manifests
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

ไฟล์ YAML ที่อยู่ใน Git repository สามารถมี SealedSecret ได้ เมื่อ Argo CD sync ข้อมูล Sealed Secrets controller จะถอดรหัสข้อมูลโดยอัตโนมัติ

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

SealedSecret ไม่สามารถถอดรหัสได้

ตรวจสอบว่า sealed-secrets controller กำลังทำงาน:

kubectl get pods -n kube-system | grep sealed-secrets

ตรวจสอบ logs:

kubectl logs -n kube-system -l app.kubernetes.io/name=sealed-secrets

ExternalSecret ไม่ได้รับข้อมูล

ตรวจสอบการเชื่อมต่อกับ Vault หรือ AWS Secrets Manager:

kubectl describe externalsecret app-secrets
kubectl logs -n external-secrets-system -l app.kubernetes.io/name=external-secrets

สรุป

การจัดการ Secrets อย่างปลอดภัยใน Argo CD เป็นส่วนสำคัญของการปรับใช้งาน Infrastructure as Code การเลือกระหว่าง Sealed Secrets และ External Secrets Operator ขึ้นอยู่กับความต้องการและสภาพแวดล้อมของคุณ สำหรับผู้ที่ใช้บริการ Cloud VPS จาก ผู้ให้บริการโฮสติ้ง ที่ https://de.co.th/cloud-vps ให้พิจารณาใช้ External Secrets Operator เพื่อให้สามารถผสานรวมกับ Secret Management Service ขององค์กรได้อย่างเหมาะสม

ไม่ว่าคุณเลือกวิธีใด การปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุด เช่น การใช้ RBAC, การตรวจสอบ, และการหมุนเวียนคีย์อย่างสม่ำเสมอ จะช่วยให้ Kubernetes cluster ของคุณปลอดภัยและมีประสิทธิภาพยิ่งขึ้น


บทความนี้เป็นส่วนหนึ่งของ ผู้ให้บริการโฮสติ้ง Knowledge Base

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับบริการ Cloud VPS และ Cloud Hosting ของ ผู้ให้บริการโฮสติ้ง โปรดเยี่ยมชม https://de.co.th/cloud-vps และ https://de.co.th/cloud-hosting