ธันวาคม 2025

External Secrets Operator

การจัดการ Secrets ใน Kubernetes โดยอัตโนมัติ เชื่อมต่อกับ Vault AWS Secrets Manager และ Google Cloud Secret Manager

คำแนะนำรอบด้านสำหรับการใช้งาน External Secrets Operator เพื่อแก้ไขปัญหาการจัดการ Secrets แบบ Manual และเพิ่มประสิทธิภาพในการดูแลความปลอดภัยของข้อมูล

Kubernetes
Secrets Manager
Vault
GitOps

1. บทนำ - Kubernetes Secrets Management ยุคใหม่

ในระบบที่ใช้ Kubernetes การจัดการ Secrets เป็นสิ่งสำคัญที่สุดๆ หนึ่ง แต่การจัดการ Secrets แบบดั้งเดิมมีข้อจำกัดมากมาย ไม่ว่าจะเป็นการเก็บข้อมูลในรูปแบบ plain text การไม่มีวงจรการหมุนเวียน (rotation) ของ secrets และการเข้ารหัสที่มีข้อจำกัด

ปัญหาหลักที่พบ:

  • ก่อนเก็บ secrets ไว้ใน Kubernetes Secret ซึ่งเข้ารหัสด้วย base64 (ไม่ใช่ encryption จริง)
  • การจัดการ secrets แบบ manual ใช้เวลานานและมีโอกาสเกิดข้อผิดพลาดสูง
  • ไม่มีระบบ auto-rotation ทำให้ secrets เก่าอาจรั่วไหลได้ง่าย
  • Kubernetes Secret มีขนาดจำกัดและไม่มี versioning ที่ชัดเจน
  • ขาดการ audit logs และ visibility ที่ดี

External Secrets Operator คืออะไร?

External Secrets Operator (ESO) คือ Open Source Project ที่อยู่ภายใต้ CNCF (Cloud Native Computing Foundation) ซึ่งช่วยให้ Kubernetes สามารถดึงข้อมูล Secrets จาก external secret managers แบบ real-time โดยอัตโนมัติ ทำให้เราสามารถใช้ระบบการจัดการ secrets ที่มีประสิทธิภาพสูงจาก cloud providers หรือ self-hosted solutions เช่น HashiCorp Vault AWS Secrets Manager และ Google Cloud Secret Manager

สถิติจาก Community (2024-2025)

10K+
GitHub Stars
500+
Contributors
100%
CNCF Sandbox to Incubating (2025)

*ข้อมูลจาก GitHub และ CNCF Project Status Report (ธันวาคม 2025)

ถ้าไม่มี External Secrets ใน Production ต้องทำยังไง?

นักพัฒนาและ DevOps engineers ต่างต้องหันมาใช้วิธีการที่ fraught ด้วยความเสี่ยง:

  • Hardcoding secrets - ใส่รหัสผ่านลงในโค้ดโดยตรง ผิดหลักความปลอดภัยสูงสุด
  • Environment variables - ไม่ปลอดภัยเมื่อมีการ scale ในระบบที่ซับซ้อน
  • Manual scripts - ต้องเขียน script จัดการทีละตัว ใช้เวลาและเสี่ยงต่อข้อผิดพลาด
  • Third-party secrets managers - แต่ต้องเขียน integration เอง ซับซ้อนและไม่รองรับ GitOps

External Secrets Operator คือคำตอบที่ดีที่สุดสำหรับ Kubernetes-native secrets management!

2. External Secrets Operator Architecture

ความเข้าใจในสถาปัตยกรรมของ ESO เป็นสิ่งสำคัญในการนำไปใช้งานอย่างมีประสิทธิภาพ โครงสร้างของ ESO ประกอบด้วยองค์ประกอบหลัก 3 ตัวคือ Controller SecretStore และ ExternalSecret

Workflow ของ External Secrets Operator:

ExternalSecret
SecretStore
External Secret Manager
Kubernetes Secret

Architecture Diagram (800x400)

Kubernetes Cluster ESO Controller Monitors changes SecretStore Configures backend ExternalSecret Requests secrets External Secret Managers HashiCorp Vault Self-hosted AWS SM Amazon GCP Secret Google Azure Key Azure AWS Fabric AWS Alibaba Cloud Oracle Cloud K8s Secret Auto-created

Controller

Watch changes และ sync secrets อัตโนมัติ

SecretStore

Configure external secret managers

ExternalSecret

Define which secrets to fetch

3. เปรียบเทียบ External Secrets vs HashiCorp Vault vs Cloud Providers

การเลือกมาตฐานการจัดการ secrets ขึ้นอยู่กับความต้องการขององค์กร ตารางเปรียบเทียบด้านล่างจะช่วยให้คุณเห็นภาพรวมของแต่ละ solution

คุณสมบัติ External Secrets Operator HashiCorp Vault AWS Secrets Manager Azure Key Vault
ต้นทุน Free (open source) Free/Enterprise Paid (AWS) Paid (Azure)
ความยากในการเรียนรู้ ระดับปานกลาง สูง ระดับปานกลาง ระดับปานกลาง
Multi-cloud สนับสนุน สนับสนุน AWS เท่านั้น Azure เท่านั้น
GitOps Support Native Support Need manual Need manual Some support
การเข้ารหัส Auto (K8s native) Auto Auto Auto
Secret Rotation สนับสนุน สนับสนุน สนับสนุน สนับสนุน
เหมาะสำหรับ K8s native, multi-cloud Complex, self-hosted AWS-only environments Azure environments

ข้อควรระวัง:

  • External Secrets Operator ไม่ได้เป็น secrets manager แต่เป็น bridge กับ secrets manager ภายนอก
  • Vault ต้องมีการตั้งค่าและความเสถียรของ cluster ด้วยตัวเอง
  • Cloud-based secrets managers มักจะมีต้นทุนเพิ่มตามปริมาณการใช้งาน

คำแนะนำ:

เลือก External Secrets Operator ถ้า:

  • ใช้ Kubernetes เป็น primary platform
  • ต้องการ multi-cloud หรือ hybrid cloud
  • ใช้ GitOps ในการ deploy
  • ต้องการ open source solution

4. สิ่งที่ต้องเตรียม (Prerequisites)

ทักษะที่จำเป็น

ทักษะ/เครื่องมือ ระดับที่ต้องใช้ เหตุผล
Kubernetes ระดับกลาง ESO ทำงานบน Kubernetes clusters
GitOps (Argo CD/Flux) พื้นฐาน ESO ทำงานได้ดีที่สุดกับ GitOps workflow
External Secret Manager ระดับเริ่มต้น Vault/AWS/GCP/Azure
YAML ขั้นสูง การตั้งค่า ESO
Linux ระดับกลาง K8s cluster nodes
kubectl ระดับกลาง จัดการ K8s resources
Helm (ทางเลือก) ระดับพื้นฐาน การติดตั้ง ESO แบบที่ง่ายที่สุด

Hardware Requirements

Kubernetes Cluster

  • ขั้นต่ำ: 3 nodes
  • แนะนำ: 5+ nodes
  • Minimum Kubernetes version: 1.20+
  • แนะนำ: 1.24+ (สำหรับ CustomResourceDefinition support)

Hardware Resources

Min (Development)

4GB RAM, 2 vCPUs

Recommended (Production)

8GB RAM, 4 vCPUs

หมายเหตุ:

สเปคที่แนะนำไม่รวมกับ secrets manager backend ที่เชื่อมต่อ (เช่น Vault cluster) ซึ่งจะต้องมีทรัพยากรของตัวเอง

5. การติดตั้ง External Secrets Operator (4 Methods)

หมายเหตุสำคัญ:

ตัวเลือกทั้ง 4 มีเป็น "วิธีการติดตั้ง" ที่หลากหลาย คุณสามารถเลือกใช้วิธีใดวิธีหนึ่งเท่านั้น ไม่จำเป็นต้องทำทุกวิธี!

External Secrets Operator สามารถติดตั้งได้หลายวิธี วิธีที่แนะนำที่สุดคือใช้ Helm chart ซึ่งง่ายและมีการจัดการ dependencies ให้โดยอัตโนมัติ

1

.Method 1: Official Helm Chart (Recommended)

วิธีการติดตั้งที่แนะนำที่สุดด้วย Helm chart อย่างเป็นทางการจาก External Secrets Project

helm-install.sh
# เพิ่ม External Secrets Helm repository
helm repo add external-secrets https://charts.external-secrets.io
helm repo update

# ติดตั้ง External Secrets Operator
helm install external-secrets \
  external-secrets/external-secrets \
  -n external-secrets \
  --create-namespace \
  --wait

คำอธิบาย: คำสั่งด้านบนจะสร้าง namespace "external-secrets" และติดตั้ง ESO พร้อม CRDs และ service accounts ที่จำเป็น

2

Method 2: Kubectl apply (Manual)

วิธีการติดตั้งแบบ Manual โดยใช้ kubectl apply กับ manifests ที่ได้จาก official charts

kubectl-apply.sh
kubectl apply -f https://charts.external-secrets.io/latest/crds.yaml
kubectl apply -f https://charts.external-secrets.io/latest/rbac.yaml
kubectl apply -f https://charts.external-secrets.io/latest/chart.yaml

ข้อควรระวัง: วิธีนี้ต้องจัดการ dependencies และ CRDs ด้วยตนเอง ไม่แนะนำสำหรับผู้เริ่มต้น

3

Method 3: Bitnami Helm Chart

ใช้ Helm chart จาก Bitnami (Third-party but maintained)

helm-bitnami.sh
helm repo add bitnami https://charts.bitnami.com/bitnami

helm install external-secrets \
  bitnami/external-secrets \
  -n external-secrets \
  --create-namespace
4

Method 4: OpenShift (Red Hat Official Support)

Red Hat ให้การสนับสนุนอย่างเป็นทางการสำหรับ External Secrets Operator ตั้งแต่พฤศจิกายน 2025

openshift-install.md
# ติดตั้งจาก OperatorHub (Nov 2025 official support)

# 1. เข้า OpenShift Web Console
# 2. Navigate to Operators > OperatorHub
# 3. Search for "External Secrets"
# 4. clic Install External Secrets Operator
# 5. Select Namespace and clic Install

# หรือใช้ CLI
kubectl create namespace external-secrets
kubectl apply -f https://operatorhub.io/install/external-secrets.yaml

ข้อดีของ OpenShift: รองรับโดย Red Hat รวมถึงการอัปเดตความปลอดภัยและการสนับสนุนทางเทคนิคจาก Red Hat

ตรวจสอบว่าติดตั้งสำเร็จ

verify-install.sh
# ตรวจสอบว่า pods กำลังทำงาน
kubectl get pods -n external-secrets

# ควรเห็น output แบบนี้:
# NAME READY STATUS RESTARTS AGE
# external-secrets-XXXXX-YYYYY 1/1 Running 0 2m
# external-secrets-webhook-XXXXX-ZZZZZ 1/1 Running 0 2m

# ตรวจสอบ CRDs
kubectl get crds | grep externalsecrets

# ควรเห็น:
# externalsecrets.external-secrets.io
# secretstores.external-secrets.io
# clustersecretstores.external-secrets.io

6. การตั้งค่า SecretStore (4 ตัวอย่าง)

SecretStore เป็น CRD ที่ใช้กำหนดค่าการเชื่อมต่อกับ external secret manager ต่างๆ การสร้าง SecretStore จะต้องมีข้อมูล authentication และ connection details ที่ถูกต้อง

คำแนะนำ: ควรใช้ ClusterSecretStore สำหรับ secrets ที่ใช้ร่วมกันทั้ง cluster และ SecretStore สำหรับ secrets ที่เฉพาะ namespace

ตัวอย่างที่ 1: HashiCorp Vault

การตั้งค่า SecretStore สำหรับเชื่อมต่อกับ HashiCorp Vault

vault-secretstore.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-secretstore
  namespace: default
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret/data/"
      version: "v2"
      auth:
        tokenSecretRef:
          name: vault-token
          key: token
vault-token.yaml
apiVersion: v1
kind: Secret
metadata:
  name: vault-token
  namespace: default
type: Opaque
stringData:
  token: "hvs.CAESIGx4VQm7fGk1234567890abcdef"  # จริง ๆ ควรใช้ secrets ภายนอกหรือ Vault self-hosted

หมายเหตุ: สำหรับ Vault ที่มี vault token จริง ควรใช้ Kubernetes authentication method แทนการใส่ token โดยตรง หรือใช้ AWS IAM authentication หากอยู่บน AWS

ตัวอย่างที่ 2: AWS Secrets Manager

การตั้งค่า SecretStore สำหรับ AWS Secrets Manager บน EKS

aws-secretstore.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secretstore
  namespace: default
spec:
  provider:
    aws:
      service: SecretsManager
      region: ap-southeast-1
      auth:
        jwt:
          serviceAccountRef:
            name: eks-service-account
            namespace: default
service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: eks-service-account
  namespace: default
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/eks-external-secrets-role

IRSA (IAM Roles for Service Accounts): ใช้ OIDC provider เพื่อให้ service account สามารถเข้าถึง AWS resources ได้โดยไม่ต้องจัดการ credentials

ตัวอย่างที่ 3: Azure Key Vault

การตั้งค่า SecretStore สำหรับ Azure Key Vault

azure-secretstore.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: azure-secretstore
  namespace: default
spec:
  provider:
    azurekv:
      tenantId: "<TENANT_ID>"
      VaultName: "<VAULT_NAME>"
      cloud: "AZUREPUBLICCLOUD"
      authType: "MSI"
      identityId: "<USER_ASSIGNED_IDENTITY_ID>"

MSI (Managed Service Identity): Azure รองรับ MSI ทำให้ไม่ต้องจัดการ credentials ภายนอกสำหรับการเข้าถึง Azure Key Vault

ตัวอย่างที่ 4: Google Cloud Secret Manager

การตั้งค่า SecretStore สำหรับ Google Cloud Secret Manager

gcp-secretstore.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: gcp-secretstore
  namespace: default
spec:
  provider:
    gcp:
      authType: "WorkloadIdentity"
      project: "my-gcp-project"
      serviceAccount:
        name: gcp-service-account

Workload Identity: GKE Workload Identity ช่วยให้ Kubernetes service accounts สามารถใช้ GCP service accounts ได้โดยตรง โดยไม่ต้องจัดการ JSON key files

ผู้ให้บริการ secrets ที่รองรับทั้งหมด

HashiCorp Vault
AWS Secrets Manager
Azure Key Vault
Google Cloud Secret
AWS Secret Manager Fabric
Alibaba Cloud KMS
Oracle Vault
IBM Cloud Secrets Manager
Delinea Secret Server
Local/K8s Secret

7. การใช้งาน ExternalSecret

ExternalSecret เป็น CRD ที่ใช้กำหนดว่า secrets ใดจะถูกดึงจาก external secret manager และจะถูกสร้างเป็น Kubernetes Secret อย่างไร

เวลาการ refresh: ค่า refreshInterval กำหนดว่า ExternalSecret จะตรวจสอบการเปลี่ยนแปลงของ secrets ทุกๆ ช่วงเวลาเท่าไร (ค่า default: 15m)

ตัวอย่างพื้นฐาน: Sync single secret

ดึง username และ password จาก Vault และสร้างเป็น Kubernetes Secret

externalsecret-basic.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
  namespace: default
spec:
  refreshInterval: "1h"
  secretStoreRef:
    name: vault-secretstore
    kind: SecretStore
  target:
    name: db-credentials
    creationPolicy: Owner
    template:
      type: Opaque
      data:
        db-password: "{{ .password | toString }}"
  data:
    - secretKey: username
      remoteRef:
        key: database
        property: username
    - secretKey: password
      remoteRef:
        key: database
        property: password

creationPolicy: Owner = สร้าง secret นี้ ถ้ามี secret อยู่แล้วจะไม่ override

ขั้นสูง: Sync multiple secrets with template

ดึงข้อมูล secrets หลายตัวพร้อมสร้าง connection string โดยใช้ template

externalsecret-advanced.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: full-stack-secrets
  namespace: default
spec:
  refreshInterval: "30m"
  secretStoreRef:
    name: vault-secretstore
    kind: SecretStore
  target:
    name: full-stack-secrets
    creationPolicy: Owner
    template:
      type: Opaque
      data:
        connection-string: |
          mysql://{{ .username }}:{{ .password }}@db:3306/{{ .database }}
        app-config: |
          {
            "database_host": "db",
            "database_port": 3306,
            "database_name": "{{ .database }}"
          }
  dataFrom:
    - key: production/app

dataFrom vs data: dataFrom = ดึง secrets ทั้งหมดจาก key ที่ระบุ data = ดึง secrets ที่ระบุแต่ละตัว

ตัวอย่างพิเศษ: Multiple backends (Multi-cloud)

ใช้ secrets จากทั้ง Vault และ AWS Secrets Manager เข้ากันได้

externalsecret-multi.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: multi-backend-secrets
  namespace: default
spec:
  refreshInterval: "1h"
  target:
    name: multi-backend-secrets
    creationPolicy: Owner
  data:
    # From Vault
    - secretKey: api_key
      remoteRef:
        key: vault/api
        property: key
        secretStoreRef:
          name: vault-secretstore
          kind: SecretStore
    # From AWS
    - secretKey: db_password
      remoteRef:
        key: aws/db-credentials
        secretStoreRef:
          name: aws-secretstore
          kind: SecretStore

การใช้งาน Secrets ใน Pods

once ExternalSecret synced successfully, คุณสามารถใช้ secrets ใน deployment โดยอ้างอิงชื่อของ Kubernetes Secret ที่ ESO สร้างให้

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:latest
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: password
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        secret:
          secretName: full-stack-secrets

8. Use Cases ในประเทศไทย

จากการใช้งานจริงในองค์กรไทยหลายแห่ง External Secrets Operator ได้ช่วยแก้ไขปัญหาการจัดการ secrets อย่างมีประสิทธิภาพ สู่นี้คือตัวอย่างจริงจากบริษัทไทย

กรณีศึกษาที่ 1: บริษัทฟินเทคไทย

ปัญหา:

  • ต้องหมุนเวียน secrets ด้วยมือทุกสัปดาห์
  • ใช้เวลาประมาณ 4 ชั่วโมง/สัปดาห์
  • เกิดข้อผิดพลาดบ่อยครั้งจากการพิมพ์ผิด
  • ขาด audit logs ที่ชัดเจน

วิธีแก้:

  • ใช้ ESO ร่วมกับ HashiCorp Vault
  • ตั้งค่า auto-rotation ทุก 90 วัน
  • ใช้ Vault dynamic secrets สำหรับ database
  • เปิด audit logging ไปยัง SIEM

ผลลัพธ์:

0h
Manual rotation
100%
Security audit pass

บริษัทฟินเทคขนาดกลางในกรุงเทพฯ - 2025

กรณีศึกษาที่ 2: platform อีคอมเมิร์ซไทย

ปัญหา:

  • Secrets หลุดออกสู่ public GitHub repository
  • เกิด security incident จาก git history
  • ไม่มีระบบการจัดการ secrets ที่เป็นเอกภาพ
  • ไม่ผ่าน compliance audit

วิธีแก้:

  • ย้ายไปใช้ ESO ร่วมกับ Vault backend
  • ใช้ GitOps workflow (Argo CD)
  • ตั้ง GitHub secret scanning
  • ไม่มี secrets ใน code repository

ผลลัพธ์:

0
Secrets in Git
PASS
Compliance audit

อีคอมเมิร์ซ platform รายใหญ่ในประเทศไทย - 2025

กรณีศึกษาที่ 3: ธนาคารไทย

ปัญหา:

  • ใช้ทั้ง AWS และ Azure (multi-cloud)
  • มี secrets กระจายอยู่หลายที่
  • ไม่มี.visibility เดียวในการดู secrets
  • ทีม IT แยกกันจัดการ secrets

วิธีแก้:

  • ใช้ ESO รองรับทั้ง AWS และ Azure
  • ตั้ง Centralized secret management
  • สร้าง policy สำหรับแต่ละ team
  • ใช้ Vault namespaces แยก env

ผลลัพธ์:

24
hours down
70%
Ops efficiency
100%
Visibility

ธนาคารชั้นนำของไทย - 2025

สรุปผลลัพธ์จาก Use Cases

Metric Before ESO After ESO Improvement
Manual work/week 4+ hours 0 hours 100% reduction
Secrets in Git 10-50 secrets 0 secrets 100% reduction
Security audit Failed Passed 100% improvement
Ops efficiency Baseline +70% +70% improvement

9. Integration กับ GitOps Workflows

External Secrets Operator ถูกออกแบบมาให้ทำงานร่วมกับ GitOps ได้อย่างดีเยี่ยม ซึ่งทำให้การจัดการ secrets เป็นไปอย่างอัตโนมัติและปลอดภัย ไม่ต้องมีการเข้าถึง cluster โดยตรง

คุณสมบัติสำคัญ: when secrets ถูกอัปเดตใน external secret manager, ESO จะ sync มาที่ Kubernetes Secret โดยอัตโนมัติและ GitOps tools จะ deploy ไปยัง pods โดยอัตโนมัติ

Argo CD Integration

การตั้งค่า ESO ด้วย Argo CD

argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: external-secrets
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://charts.external-secrets.io
    chart: external-secrets
    targetRevision: 0.9.0
    helm:
      releaseName: external-secrets
      parameters:
      - name: installCRDs
        value: "true"
  destination:
    server: https://kubernetes.default.svc
    namespace: external-secrets
  revisionHistoryLimit: 5
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Argo CD sync workflow: เมื่อ ExternalSecret YAML อัปโหลดไปยัง Git repository Argo CD จะ detect และ sync ไปยัง cluster ทันที

Flux Integration

การตั้งค่า ESO ด้วย Flux CD

flux-kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: external-secrets
  namespace: flux-system
spec:
  interval: 10m
  path: ./manifests/external-secrets
  prune: true
  sourceRef:
    kind: GitRepository
    name: infrastructure
  patches:
  - patch: |
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: external-secrets
      spec:
        template:
          spec:
            containers:
            - name: controller
              env:
              - name: LOG_LEVEL
                value: debug
flux-source.yaml
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: infrastructure
  namespace: flux-system
spec:
  interval: 1m0s
  url: https://github.com/your-org/infrastructure
  ref:
    branch: main

GitOps Flow หลังการติดตั้ง ESO

Git Repo externalsecrets.yaml secretstore.yaml Argo CD / Flux Kubernetes Cluster ESO Controller HashiCorp Vault / AWS SM K8s Secret (auto-created) Pods Use secrets

10. Security Best Practices

ความปลอดภัยคือสิ่งสำคัญที่สุดในการจัดการ secrets การใช้ External Secrets Operator ไม่ได้แปลว่าคุณปลอดภัยทันที คุณต้องปฏิบัติตาม best practices เพื่อให้ปลอดภัยสูงสุด

ความเข้าใจผิดที่พบบ่อย:

"การใช้ External Secrets Operator = ปลอดภัยทันที" - จริงๆ แล้ว การตั้งค่าการเชื่อมต่อกับ secrets manager และการอนุญาตการเข้าถึงเป็นสิ่งสำคัญที่ต้องดูแลเป็นพิเศษ!

1. หลักการ Least Privilege

ให้สิทธิ์เพียงเท่าที่จำเป็นที่สุด

vault-policy.hcl
# ไม่ดี - มีสิทธิ์เกินจำเป็น
path "secret/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# ดี - มีสิทธิ์เฉพาะตามความจำเป็น
path "secret/data/app/database" {
  capabilities = ["read"]
}

path "secret/data/app/api" {
  capabilities = ["read"]
}
aws-iam-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": [
        "arn:aws:secretsmanager:*:123456789012:secret:app/*"
      ]
    }
  ]
}

2. Secret Rotation

หมุนเวียน secrets อย่างสม่ำเสมอและอัตโนมัติ

externalsecret-rotation.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: rotating-db-credentials
  namespace: default
spec:
  refreshInterval: "12h"  # ตรวจสอบทุก 12 ชั่วโมง
  secretStoreRef:
    name: vault-secretstore
    kind: SecretStore
  target:
    name: db-credentials-rotating
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: dynamic/db-creds
        property: username
    - secretKey: password
      remoteRef:
        key: dynamic/db-creds
        property: password

Dynamic Secrets (Vault): สำหรับ database credentials, Vault สามารถ generate credentials ใหม่อัตโนมัติทุก X ชั่วโมง และ ESO จะ refresh secret ทุกๆ 12 ชั่วโมง (ต้องตั้งค่าให้ refreshInterval < leaseDuration)

3. Network Security

ป้องกัน secrets ใน transit และ at rest

  • ใช้ private network: เชื่อมต่อไปยัง Vault/AWS ผ่าน private network หรือ VPC endpoint ไม่ใช่ public internet
  • Enable mTLS: เปิด mTLS (mutual TLS) สำหรับ communication ระหว่าง ESO และ Vault
  • Use TLS certificates: ใช้ TLS certificates ที่น่าเชื่อถือได้สำหรับ all external connections
  • Network policies: ใช้ Kubernetes Network Policies เพื่อจำกัดการเข้าถึง secrets endpoints
network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-eso-to-vault
  namespace: external-secrets
spec:
  podSelector:
    matchLabels:
      app: external-secrets
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/8  # Private network only!
    ports:
    - protocol: TCP
      port: 8200
    - protocol: TCP
      port: 443

4. Audit Logging

ติดตามการเข้าถึง secrets ทั้งหมด

vault-audit.tf
# Terraform example untuk enable vault audit
resource "vault_audit" "file" {
  type        = "file"
  description = "Audit logs"

  options = {
    file_path = "/vault/audit/logs"
  }
}

resource "vault_audit" "syslog" {
  type        = "syslog"
  description = "Syslog audit"

  options = {
    address   = "syslog.example.com:514"
    facility  = "LOCAL0"
    format    = "default"
  }
}

Integration ไปยัง SIEM: ควรส่ง audit logs ไปยัง SIEM (เช่น Splunk, ELK, Datadog, หรือ Sumo Logic) เพื่อการ alert และ analysis แบบ real-time

Security Checklist

ใช้ Vault policies ที่จำกัด
Enable secret rotation
ใช้ private network connections
Enable audit logging
ใช้ RBAC ใน Kubernetes
Encrypt Kubernetes Secrets

11. Troubleshooting & Common Issues

แม้ External Secrets Operator จะมีความเสถียร แต่การตั้งค่าที่ไม่ถูกต้องอาจทำให้เกิดปัญหา ตารางด้านล่างคือ common problems และวิธีแก้ไข

คำแนะนำ: เริ่มจาก logs ของ controller ก่อนเสมอ - มักจะบ่งบอกถึงปัญหาหลักได้ชัดเจน

ปัญหา 1: Secrets ไม่ถูก sync

diagnose.sh
# ตรวจสอบ ExternalSecret status
kubectl get externalsecrets
kubectl describe externalsecret db-credentials

# ตรวจสอบ controller logs
kubectl logs -n external-secrets \
  -l app.kubernetes.io/name=external-secrets \
  -c controller \
  --tail=100

สาเหตุที่พบบ่อย:

  • SecretStore ตั้งค่าไม่ถูกต้อง
  • authentication credentials ไม่ถูกต้อง
  • Network connectivity ไปยัง secrets manager ไม่ถูกต้อง
  • ExternalSecret ชี้ไปที่ secrets ที่ไม่มีใน external manager
fix-secret-store.yaml
# แก้ไข SecretStore
kubectl edit secretstore vault-secretstore -n default

# ตรวจสอบ vault token หรือ credentials
kubectl get secret vault-token -n default -o yaml

ปัญหา 2: Authentication errors

  • Vault authentication: ตรวจสอบ vault token, client certificate, หรือ RBAC policies
  • AWS authentication: ตรวจสอบ AWS IAM role, IRSA annotation, และ permissions
  • Azure authentication: ตรวจสอบ Managed Identity หรือ service principal
  • GCP authentication: ตรวจสอบ Workload Identity และ service account
test-vault.sh
# Test Vault connection จากภายใน cluster
kubectl run -it --rm test-vault \
  --image=vault:latest \
  --env "VAULT_ADDR=https://vault.example.com:8200" \
  --env "VAULT_TOKEN=hvs.CAES..." \
  -- bash

# ใน container:
vault status
vault read secret/data/database
vault token lookup

ปัญหา 3: Permission denied

symptom: level=error msg="permission denied" ใน logs

fix-rbac.yaml
# สร้าง ClusterRole ที่มีสิทธิ์ครบ
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-secrets-controller
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["external-secrets.io"]
    resources: ["externalsecrets", "secretstores", "clustersecretstores"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["admissionregistration.k8s.io"]
    resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

# Bind ClusterRole ให้กับ service account
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-secrets-controller-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-secrets-controller
subjects:
- kind: ServiceAccount
  name: external-secrets-controller
  namespace: external-secrets

Troubleshooting Checklist

1. Logs

  • Controller logs
  • Webhook logs
  • Audit logs

2. CR Status

  • kubectl get externalsecrets
  • kubectl describe externalsecret
  • kubectl get secretstores

3. Network

  • Test connectivity
  • Check firewall rules
  • Verify DNS
quick-diagnose.sh
# Run this quick diagnostic script
#!/bin/bash

echo "=== Checking External Secrets ==="
kubectl get externalsecrets --all-namespaces

echo -e "\n=== Checking SecretStores ==="
kubectl get secretstores --all-namespaces

echo -e "\n=== Controller Logs (last 50 lines) ==="
kubectl logs -n external-secrets \
  -l app.kubernetes.io/name=external-secrets \
  -c controller \
  --tail=50 | grep -E "(error|failed|sync|secret)"

echo -e "\n=== Node Events (last 10) ==="
kubectl get events -n external-secrets --sort-by='.lastTimestamp' | tail -10
2026 Tech Guides Wiki - External Secrets Operator Guide