Triển khai Vault Operator và Vault Server trên Kubernetes
Bước đầu tiên là cài đặt Vault Operator để quản lý vòng đời của Vault trong Kubernetes và sau đó deploy Vault Server.
Chúng ta sẽ sử dụng Helm để thêm repository chính thức của HashiCorp và cài đặt Operator trước. Điều này giúp Kubernetes tự động quản lý việc khởi động, mở khóa (unseal) và cấp phát chứng chỉ root cho Vault.
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install vault hashicorp/vault --namespace vault --create-namespace
Kết quả mong đợi: Bạn thấy thông báo "NAME: vault" và "STATUS: deployed". Namespace "vault" được tạo tự động nếu chưa tồn tại.
Sau khi Operator đã chạy, chúng ta cần deploy Vault Server với cấu hình mặc định để kiểm tra. File values.yaml sẽ được tạo tại local để cấu hình chi tiết hơn sau, nhưng bước này dùng cấu hình mặc định để đảm bảo tính khả thi.
helm install vault-server hashicorp/vault --namespace vault --version 0.30.0 --set injector.defaultEnabled=true
Kết quả mong đợi: Các Pod trong namespace vault chuyển sang trạng thái "Running". Kiểm tra bằng lệnh kubectl get pods -n vault.
Verify kết quả: Kiểm tra trạng thái của Vault Operator và Vault Server.
kubectl get pods -n vault -l app=vault
Bạn sẽ thấy các pod như vault-operator, vault-server đang chạy. Nếu thấy trạng thái "Error" hoặc "CrashLoopBackOff", hãy xem log bằng kubectl logs -n vault <pod-name>.
Cấu hình lưu trữ backend cho Vault
Vault cần một nơi để lưu trữ dữ liệu secret và trạng thái. Trong Kubernetes, chúng ta sẽ sử dụng Consul hoặc S3. Ở đây, ta chọn S3 (AWS MinIO hoặc AWS S3 thật) vì tính phổ biến và khả năng mở rộng.
Trước tiên, cần tạo secret trong Kubernetes chứa thông tin truy cập S3. Vault sẽ đọc secret này để kết nối.
kubectl create secret generic vault-s3-creds --namespace vault \
--from-literal=aws_access_key_id=YOUR_ACCESS_KEY \
--from-literal=aws_secret_access_key=YOUR_SECRET_KEY \
--from-literal=aws_region=us-east-1 \
--from-literal=s3_bucket=vault-storage
Kết quả mong đợi: Secret "vault-s3-creds" được tạo trong namespace vault. Bạn có thể verify bằng kubectl get secrets -n vault.
File cấu hình values.yaml cho Vault Server cần được chỉnh sửa để trỏ vào backend S3. Lưu file này vào ~/vault-values.yaml.
server:
replicas: 3
extraArgs:
- "storage_type=s3"
- "s3_endpoint=https://s3.us-east-1.amazonaws.com"
- "s3_bucket=vault-storage"
extraEnvFromSecrets:
- name: VAULT_AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: vault-s3-creds
key: aws_access_key_id
- name: VAULT_AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: vault-s3-creds
key: aws_secret_access_key
- name: VAULT_AWS_REGION
valueFrom:
secretKeyRef:
name: vault-s3-creds
key: aws_region
Deploy lại Vault Server với file values.yaml này để áp dụng cấu hình lưu trữ S3.
helm upgrade vault-server hashicorp/vault --namespace vault -f ~/vault-values.yaml
Kết quả mong đợi: Pod Vault Server được restart và kết nối thành công với backend S3. Không có lỗi trong log liên quan đến storage.
Verify kết quả: Kiểm tra log của Vault Server để đảm bảo nó đã mount backend S3 thành công.
kubectl logs -n vault -l app=vault-server | grep "storage backend"
Bạn sẽ thấy dòng log xác nhận "storage backend: s3" và trạng thái "connected".
Khởi tạo Vault (Unseal) và thiết lập xác thực Kubernetes
Vault khi mới deploy sẽ ở trạng thái "sealed". Chúng ta cần khởi tạo (init) và mở khóa (unseal) để có thể sử dụng. Với Vault Operator, bước này có thể tự động hóa, nhưng để minh họa quy trình, ta sẽ làm thủ công qua kubectl exec.
Khởi tạo Vault và lưu các key unseal cũng như token root. Lưu ý: Trong môi trường production, hãy dùng Vault Operator để tự động quản lý unseal key, nhưng ở đây ta thực hiện thủ công để hiểu cơ chế.
kubectl exec -it vault-server-0 -n vault -- vault operator init -key-shares=1 -key-threshold=1 > /tmp/vault-init.txt
Kết quả mong đợi: File /tmp/vault-init.txt chứa "Initial Root Token" và "Unseal Keys".
Đặt biến môi trường để lưu token root và key unseal cho các bước sau.
export VAULT_ROOT_TOKEN=$(grep 'Initial Root Token' /tmp/vault-init.txt | awk '{print $NF}')
export VAULT_UNSEAL_KEY=$(grep 'Unseal Key' /tmp/vault-init.txt | awk '{print $NF}')
Mở khóa Vault bằng key unseal. Lưu ý: Nếu dùng Vault Operator với auto-unseal, bước này có thể bị bỏ qua, nhưng để đảm bảo Vault chạy độc lập, ta thực hiện.
kubectl exec -it vault-server-0 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY
Kết quả mong đợi: Thông báo "Vault unsealed" và trạng thái "sealed: false".
Bây giờ cần thiết lập phương thức xác thực Kubernetes (Kubernetes Auth Method). Điều này cho phép các pod trong cluster xác thực với Vault thông qua ServiceAccount.
Đầu tiên, tạo role Kubernetes trong Vault để ánh xạ ServiceAccount với policy của Vault. Lệnh này chạy trên pod Vault Server.
kubectl exec -it vault-server-0 -n vault -- vault auth enable kubernetes
Kết quả mong đợi: Thông báo "Successfully enabled 'kubernetes' secrets engine".
Cấu hình method Kubernetes để trỏ vào API server của cluster. Cần lấy CA cert của cluster và đặt vào Vault.
kubectl exec -it vault-server-0 -n vault -- vault write auth/kubernetes/config \
token_reviewer_jwt="$(kubectl get secret -o jsonpath="{.data.token}" vault-token) \
kubernetes_host=https://kubernetes.default.svc \
kubernetes_ca_cert="$(kubectl get secret -o jsonpath="{.data.ca\.crt}" vault-ca-cert)"
Kết quả mong đợi: Không có lỗi, thông báo "Successfully wrote to: auth/kubernetes/config".
Tạo role cho Vault để ánh xạ ServiceAccount "vault-auth" trong namespace "vault" với policy "default".
kubectl exec -it vault-server-0 -n vault -- vault write auth/kubernetes/role/vault-auth \
bound_service_account_names=vault-auth \
bound_service_account_namespaces=vault \
policies=default \
ttl=72h
Kết quả mong đợi: Thông báo "Successfully wrote to: auth/kubernetes/role/vault-auth".
Verify kết quả: Kiểm tra xem phương thức xác thực Kubernetes đã được kích hoạt và cấu hình đúng.
kubectl exec -it vault-server-0 -n vault -- vault auth list
Bạn sẽ thấy "kubernetes" trong danh sách các auth method đã kích hoạt.
Kích hoạt và cấu hình Secrets Engine PKI trong Vault
Bước cuối cùng là kích hoạt Secrets Engine PKI (Public Key Infrastructure) để Vault có thể đóng vai trò Certificate Authority (CA).
Kích hoạt PKI secrets engine tại đường dẫn "pki".
kubectl exec -it vault-server-0 -n vault -- vault secrets enable pki
Kết quả mong đợi: Thông báo "Successfully enabled 'pki' secrets engine".
Tạo chứng chỉ Root CA tự động. Vault sẽ tự tạo một cặp khóa và chứng chỉ root. Đây là CA gốc của hệ thống PKI.
kubectl exec -it vault-server-0 -n vault -- vault write -format=json pki/root/generate/internal \
common_name="My Vault CA" \
ttl="87600h" > /tmp/root-ca.json
Kết quả mong đợi: File /tmp/root-ca.json chứa dữ liệu chứng chỉ Root CA (certificate, key, etc.).
Tạo role cho việc cấp phát chứng chỉ Leaf (cho ứng dụng). Role này sẽ giới hạn TTL, tên miền được phép, và loại key.
kubectl exec -it vault-server-0 -n vault -- vault write pki/roles/leaf-role \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="72h" \
key_type="rsa" \
key_bits=2048
Kết quả mong đợi: Thông báo "Successfully wrote to: pki/roles/leaf-role".
Thiết lập policy cho phép người dùng (hoặc service account) đọc chứng chỉ và tạo chứng chỉ mới.
kubectl exec -it vault-server-0 -n vault -- vault policy write pki-policy -
Kết quả mong đợi: Thông báo "Successfully wrote to: pki-policy".
Verify kết quả: Kiểm tra xem PKI engine đã hoạt động và có thể cấp phát chứng chỉ mẫu.
kubectl exec -it vault-server-0 -n vault -- vault read -field=certificate pki/certs/leaf-role common_name="test.example.com"
Bạn sẽ nhận được một chứng chỉ PEM hợp lệ cho tên miền test.example.com, chứng tỏ PKI đã cấu hình thành công.
Điều hướng series:
Mục lục: Series: Series: Xây dựng hệ thống quản lý mật mã và chứng chỉ số tự động (Automated PKI & Certificate Management) với HashiCorp Vault, Caddy và Kubernetes
« Phần 1: Chuẩn bị môi trường và kiến trúc tổng quan cho hệ thống PKI tự động
Phần 3: Cấu hình Caddy như một Certificate Authority (CA) tự động »