ติดตั้ง KMS สำหรับจัดการ credential ใน Kubernetes ด้วย Hashicorp vault
สร้าง script สำหรับติดตั้ง install-vault.sh
# 1. Add the HashiCorp Helm Repositoryhelm repo add hashicorp https://helm.releases.hashicorp.comhelm repo update# 2. Create a dedicated namespacekubectl create namespace vault# 3. Deploy Vault in High Availability (HA) mode with Raft storage# We use a custom values file for production-like settingscat <<EOF > vault-values.yamlserver: ha: enabled: true raft: enabled: true setNodeId: true config: | ui = true listener "tcp" { tls_disable = 1 address = "[::]:8200" cluster_address = "[::]:8201" } storage "raft" { path = "/vault/data" } service_registration "kubernetes" {}EOFhelm install vault hashicorp/vault \ --namespace vault \ -f vault-values.yaml
ตรวจสอบว่า Vault ได้ install และมี status Running ดังรูป โดย status จะยังเป็น 0/1 Ready เพราะว่าต้องทำการ Initial และ Unseal ก่อน pod ถึงจะทำงาน
nutanix@harbor ~]$ kubectl get pod -n vaultNAME READY STATUS RESTARTS AGEvault-0 0/1 Running 0 19mvault-1 0/1 Running 0 19mvault-2 0/1 Running 0 19mvault-agent-injector-5b7dd85f5c-cht5p 1/1 Running 0 19m
เข้าไปที่ vault-0. เพื่อทำการ initial ด้วยคำสั่ง
kubectl exec -it vault-0 -n vault -- vault operator init
คำสั่ง init จะทำการสร้าง Unseal Keys และ Initial Root Token ซึ่งจะต้องเก็บผลลัพธ์ไว้ เพราะต้องใช้ในการ unseal ในกรณี pod restart ถ้าข้อมูลนี้หายจะไม่สามารถ unseal และดึงข้อมูลที่เก็บใน vault ได้
Unseal Key 1: n80kTk1a0QUsd5XJIVQ+SVF+cmjDj5H0AX8HkDd4xgZgUnseal Key 2: pu2+W0CZWOHcl6xyD77mzip1BeUZOcq9aRW8NwXx5m10Unseal Key 3: 9vGGqh02ZnOvc7T7P45EpPyFeX+KMEYGhv69B/qERaBLUnseal Key 4: 8gbpjijpBLViLDXnfJF7me32ts2pborEyiOH5wHLIHefUnseal Key 5: 0YaO4FKto4I+5ZyV2VGtQrUHJFpLS73bYsQeU153J39IInitial Root Token: hvs.SMpvYTqteXW6Vjup8HWIB972Vault initialized with 5 key shares and a key threshold of 3. Please securelydistribute the key shares printed above. When the Vault is re-sealed,restarted, or stopped, you must supply at least 3 of these keys to unseal itbefore it can start servicing requests.Vault does not store the generated root key. Without at least 3 keys toreconstruct the root key, Vault will remain permanently sealed!It is possible to generate new unseal keys, provided you have a quorum ofexisting unseal keys shares. See "vault operator rekey" for more information.
ทำตามขั้นตอนข้างต้นกับ vault-1 และ vault-2
ขั้นตอนการ Unseal ใช้คำสั่งดังนี้
# Repeat this 3 times with different keys for each podkubectl exec -it vault-0 -n vault -- vault operator unseal <YOUR_UNSEAL_KEY>kubectl exec -it vault-1 -n vault -- vault operator unseal <YOUR_UNSEAL_KEY>kubectl exec -it vault-2 -n vault -- vault operator unseal <YOUR_UNSEAL_KEY>
จำต้องทำคำสั่งข้างบน ด้วยการใช้ Unseal key โดยแต่ละ pod จะต้องทำ 3 ครั้งโดยใช้ Unseal Key ที่แตกต่างกัน และเมื่อทำครบแล้วจะได้ผลลัพธ์ดังตัวอย่าง
[nutanix@harbor ~]$ kubectl exec -it vault-2 -n vault -- vault operator unsealUnseal Key (will be hidden):Key Value--- -----Seal Type shamirInitialized trueSealed falseTotal Shares 5Threshold 3Version 1.21.2Build Date 2026-01-06T08:33:05ZStorage Type raftCluster Name vault-cluster-0f5e0570Cluster ID b4922833-5b45-50ee-3f29-b6639ae0ef16Removed From Cluster falseHA Enabled trueHA Cluster https://vault-2.vault-internal:8201HA Mode activeActive Since 2026-02-05T10:58:54.132265118ZRaft Committed Index 37Raft Applied Index 37
และเมื่อกลับมาดู status ของ pod อีกครั้งจะพบว่า pod ได้ทำงานครบตามจำนวน
[nutanix@harbor ~]$ kubectl get pod -n vaultNAME READY STATUS RESTARTS AGEvault-0 1/1 Running 0 23mvault-1 1/1 Running 0 23mvault-2 1/1 Running 0 23mvault-agent-injector-5b7dd85f5c-cht5p 1/1 Running 0 23m
คำสั่งที่ใช้สำหรับ ตรวจสอบ status, login และ access ui
kubectl exec -it vault-0 -n vault -- vault statuskubectl exec -it vault-0 -n vault -- vault login <ROOT_TOKEN>kubectl port-forward service/vault 8200:8200 -n vault (Visit http://localhost:8200)
ตรวจสอบ status ของ cluster
# Login firstkubectl exec -it vault-0 -n vault -- vault login <YOUR_ROOT_TOKEN># Check Raft memberskubectl exec -it vault-0 -n vault -- vault operator raft list-peers
สิ่งที่ควรต้องพิจารณา
- Storage ที่ใช้ใน Script จะต้องมี StorageClass เพื่อ provision persistent volume
- การ Auto-Unseal สามารถใช้ Cloud KMS (AWS KMS, GCP KMS หรือ Azure Key Vault) ให้ช่วยขั้นตอนการ unseal ได้ ในกรณีที่ pod มีการ restart โดยไม่ต้องทำแบบ manual
- TLS ใน script install ทำการ disable ไว้ (tls_disable =1) เพื่อความง่ายในการติดตั้ง สำหรับ production ต้อง integrate กับ cert-manager เพื่อจัดการ life cycle ของ certificate
ตัวอย่างการสร้าง secret
ssh เข้าไปที่ vault instance
kubectl exec -it vault-0 -n vault -- sh
Login ด้วย root token
# Ensure you are logged in firstvault login hvs.SMpvYTqteXW6Vjup8HWIB972# Enable the KV-v2 engine at the path 'secret'vault secrets enable -path=secret kv-v2
สร้าง secret
# vault kv put <PATH> <KEY>=<VALUE>vault kv put secret/my-app/db-creds password="YourSuperSecurePassword123!"
ตรวจสอบ secret ว่าสามารถเรียกดูได้ถูกต้อง
vault kv get secret/my-app/db-creds======= Secret Path =======secret/data/my-app/db-creds======= Metadata =======Key Value--- -----created_time 2026-02-05T11:13:56.470489651Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 1====== Data ======Key Value--- -----password password123
