จัดการ 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

