Cấu hình RBAC cho Crossplane và ArgoCD
Bước đầu tiên là cô lập quyền truy cập để ngăn chặn các sự cố bảo mật do quyền quá rộng. Chúng ta sẽ tạo Role và RoleBinding riêng biệt cho Crossplane và ArgoCD.
1. Tạo Role cho Crossplane chỉ cho phép quản lý các tài nguyên Kubernetes liên quan đến hạ tầng (Managed Resources) mà không ảnh hưởng đến namespace khác.
2. Áp dụng Role này vào namespace của Crossplane (thường là crossplane-system).
3. Tạo RoleBinding để liên kết Role với ServiceAccount của Crossplane.
cat > /tmp/crossplane-rbac.yaml
Kết quả mong đợi: Crossplane có thể tạo tài nguyên Managed Resource nhưng bị từ chối khi cố thao tác vào tài nguyên hệ thống nhạy cảm bên ngoài scope đã định.
Tiếp theo, cấu hình RBAC cho ArgoCD để đảm bảo chỉ người dùng đã xác thực mới có quyền deploy và chỉ vào các namespace được phép.
1. Tạo Role cho ArgoCD application controller.
2. Tạo RoleBinding cấp quyền này cho ServiceAccount của ArgoCD.
cat > /tmp/argocd-rbac.yaml
Kết quả mong đợi: ArgoCD controller có thể quản lý các Application nhưng không thể truy cập trực tiếp vào cluster resources của node hoặc các namespace khác.
Cách verify: Thử tạo một Pod từ namespace crossplane-system bằng ServiceAccount của ArgoCD, command này sẽ bị từ chối (Forbidden).
kubectl auth can-i create pods --namespace crossplane-system --as system:serviceaccount:argocd:argocd-application-controller
Kết quả mong đợi: Output trả về "no".
Sử dụng Vault để quản lý Secret và Credentials
Chuyển đổi từ việc lưu secret trong Kubernetes Secret hoặc Terraform State sang HashiCorp Vault để có audit trail và quản lý vòng đời động.
1. Cài đặt Vault Operator trên Kubernetes để quản lý Vault instance.
2. Khởi tạo Vault và lưu unseal key vào Kubernetes Secret (trong môi trường production nên dùng KMS hoặc HSM).
helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault --namespace vault-system --create-namespace --set server.dev.enabled=true --set ui.enabled=true
Kết quả mong đợi: Pod Vault chạy trong namespace vault-system, UI Vault có thể truy cập qua port-forward.
Cấu hình Vault Secrets Engine để lưu trữ credentials AWS và Proxmox.
1. Khởi tạo Vault (nếu chưa làm ở bước trên) và unlock.
2. Tạo KV Secret Engine version 2.
export VAULT_ADDR='http://127.0.0.1:8200'
vault operator init -key-shares=1 -key-threshold=1 > /tmp/vault-init.txt
# Lấy unseal_key và root_token từ file trên để điền vào lệnh dưới
vault operator unseal
vault token create -default-leases-ttl=1h -max-leases-ttl=24h
Kết quả mong đợi: Vault đã sẵn sàng nhận secret, bạn có root_token để cấu hình.
Đưa credentials AWS (Access Key, Secret Key) vào Vault.
1. Tạo secret mới cho AWS.
2. Lưu secret vào Vault.
export VAULT_TOKEN=
vault kv put secret/aws/production access_key="AKIAIOSFODNN7EXAMPLE" secret_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
Kết quả mong đợi: Vault xác nhận đã ghi secret vào path secret/aws/production.
Tương tự, lưu credentials Proxmox (API Token) vào Vault.
vault kv put secret/proxmox/production username="root@pam" token_id="terraform" token_secret="7c6a9e4f-8b2d-4a1e-9c3f-5d6e7f8a9b0c"
Kết quả mong đợi: Secret Proxmox được lưu an toàn.
Cấu hình Crossplane và ArgoCD để đọc secret từ Vault thay vì Kubernetes Secret tĩnh.
1. Cài đặt Vault Plugin cho Crossplane (Vault Provider).
2. Tạo Vault Provider Config trong Crossplane để trỏ đến Vault.
cat > /tmp/vault-provider-config.yaml
Kết quả mong đợi: Crossplane có thể kết nối đến Vault để lấy credentials khi cần deploy tài nguyên AWS/Proxmox.
Cách verify: Kiểm tra trạng thái ProviderConfig của Vault.
kubectl get providerconfig vault-config -n crossplane-system -o yaml
Kết quả mong đợi: Trạng thái "Ready" và có thể thấy thông tin kết nối đã được áp dụng.
Tích hợp OIDC giữa Kubernetes và AWS
Mục tiêu là loại bỏ việc lưu IAM Access Key/Secret Key vĩnh viễn. Thay vào đó, Kubernetes ServiceAccount sẽ trao đổi token OIDC với AWS để lấy quyền truy cập tạm thời (Temporary Credentials).
1. Bật IAM OIDC Provider trên AWS cho Kubernetes cluster.
2. Cấu hình IAM Role trong AWS với trust policy chỉ định Kubernetes OIDC provider.
CLUSTER_OIDC_ISSUER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.oidc-issuer-url}')
aws iam create-open-id-connect-provider \
--url $CLUSTER_OIDC_ISSUER \
--client-id-list sts.amazonaws.com \
--thumbprint-list $(curl -s $CLUSTER_OIDC_ISSUER/.well-known/openid-configuration | jq -r '.jwks_uri' | curl -s | jq -r '.keys[0].thumbprint') \
--output text --query "OpenIdConnectProviderArn"
Kết quả mong đợi: AWS trả về ARN của OIDC Provider mới tạo.
Tạo IAM Role cho AWS với Trust Policy dựa trên OIDC Provider và Kubernetes ServiceAccount.
1. Tạo file trust-policy.json.
2. Tạo IAM Role thông qua AWS CLI.
cat > /tmp/trust-policy.json
Kết quả mong đợi: IAM Role "crossplane-aws-role" được tạo thành công.
Gán IAM Role này cho Kubernetes ServiceAccount của Crossplane.
1. Tạo file IRSA (IAM Role for Service Account) annotation.
2. Apply annotation vào ServiceAccount.
cat > /tmp/irsa-sa.yaml
Kết quả mong đợi: ServiceAccount aws-provider trong namespace crossplane-system đã được gắn IAM Role AWS.
Cấu hình Crossplane AWS Provider để sử dụng IRSA.
1. Update ProviderConfig của AWS để trỏ vào ServiceAccount mới tạo thay vì dùng Secret key.
cat > /tmp/aws-provider-config-irsa.yaml
Kết quả mong đợi: Crossplane AWS Provider chuyển sang chế độ InjectedIdentity, không còn yêu cầu Access Key/Secret Key.
Cách verify: Kiểm tra xem Pod của Crossplane AWS Provider có thể gọi API AWS không.
kubectl logs -n crossplane-system -l app=provider-aws --tail=50
Kết quả mong đợi: Logs hiển thị thông báo kết nối thành công đến AWS API mà không có lỗi "AccessDenied" do key sai.
Audit logging và giám sát hoạt động hạ tầng
Thiết lập cơ chế ghi lại mọi thay đổi trên hạ tầng Hybrid (Proxmox và AWS) để phục vụ truy vết sự cố và kiểm toán bảo mật.
1. Bật CloudTrail trên AWS để ghi lại mọi API call.
2. Cấu hình CloudTrail gửi log vào S3 và CloudWatch Logs.
aws cloudtrail create-trail \
--name hybrid-cloud-trail \
--s3-bucket-name hybrid-audit-logs \
--is-multi-region \
--enableLogFileValidation
Kết quả mong đợi: CloudTrail được tạo, bắt đầu ghi lại hoạt động API của AWS.
Đối với Proxmox, bật audit log và cấu hình gửi log ra tập trung.
1. Chỉnh sửa file /etc/pve/amqp.conf và /etc/pve/qemu.conf để bật audit.
2. Cấu hình rsyslog trên Proxmox để gửi log audit ra Syslog server hoặc Kubernetes (qua Fluentd).
echo "audit = 1" >> /etc/pve/qemu.conf
echo "audit = 1" >> /etc/pve/lxc.conf
systemctl restart pve-cluster
# Cấu hình rsyslog để gửi log audit ra port 514 (giả sử có syslog server)
cat >> /etc/rsyslog.d/40-pve-audit.conf
Kết quả mong đợi: Các hoạt động trên Proxmox (tạo VM, thay đổi cấu hình) được ghi vào file /var/log/pve/audit.log.
Tích hợp Audit Log của Kubernetes (ArgoCD, Crossplane) vào hệ thống giám sát.
1. Bật Audit Log trên API Server của Kubernetes.
2. Cấu hình Audit Policy để ghi lại các hành động CREATE, UPDATE, DELETE.
cat > /tmp/audit-policy.yaml
Kết quả mong đợi: API Server bắt đầu ghi log chi tiết vào /var/log/audit/audit.log (trên control plane).
Cấu hình Fluentd hoặc Filebeat trên cluster để thu thập các log này và đẩy vào Elasticsearch hoặc Loki.
1. Tạo DaemonSet cho Fluentd để đọc file audit log.
cat > /tmp/fluentd-audit-daemonset.yaml
Kết quả mong đợi: Fluentd chạy trên mỗi node, thu thập log audit và đẩy về Elasticsearch.
Cách verify: Thực hiện một thao tác thay đổi (ví dụ: xóa một Pod hoặc tạo một Application trong ArgoCD) và kiểm tra Elasticsearch.
curl -X GET "http://elasticsearch.logging.svc.cluster.local:9200/_search?q=level:RequestResponse" -H "Content-Type: application/json"
Kết quả mong đợi: Elasticsearch trả về các bản ghi log tương ứng với thao tác vừa thực hiện, bao gồm user, timestamp, và action.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Multi-Cloud Hybrid với Terraform, Crossplane và GitOps trên hạ tầng Proxmox và AWS
« Phần 7: Quản lý vòng đời và nâng cấp hạ tầng Hybrid
Phần 9: Giám sát, logging và cảnh báo cho môi trường Hybrid »