在雲原生應用程式開發中,保護敏感資訊至關重要。AWS Secrets Manager 提供了安全、可靠的解決方案,而 Amazon EKS 則簡化了 Kubernetes 叢集的管理。要將兩者有效整合,需要理解 Secrets Store CSI Driver 的運作機制。此驅動程式扮演橋樑角色,讓 Pod 能夠直接從 Secrets Manager 存取敏感資料,無需將其硬編碼到程式碼或設定檔中。這不僅提升了安全性,也簡化了佈署流程。透過 IAM 角色和策略,可以精細控制 Pod 的存取許可權,確保只有授權的應用程式才能存取特定秘密。此外,Secrets Manager 的版本控制和自動輪替功能,能進一步降低秘密外洩的風險,並符合資安最佳實務。對於使用 Terraform 管理基礎設施的團隊,本文也提供了相關程式碼片段,能快速建立 EKS 環境並整合 Secrets Manager。
AWS Secrets Manager 解密與實作
AWS Secrets Manager 是一個管理敏感資訊的強大工具,適用於儲存、檢索和旋轉金鑰與機密資料。這篇文章將探討 AWS Secrets Manager 的功能、特性以及如何將其與 Kubernetes 叢集整合,特別是 Amazon EKS(Elastic Kubernetes Service)。
主要功能概述
AWS Secrets Manager 提供多種功能來管理敏感資訊,包括版本控制、旋轉、高用性及災難還原等。以下是一些關鍵功能的詳細說明:
版本控制與自動刪除
AWS Secrets Manager 允許對秘密進行版本控制。每次修改秘密時,都會生成一個新的版本,並且可以設定自動刪除舊版本。這樣可以確保不再需要的舊版本會被自動刪除,減少潛在的安全風險。當需要還原之前的版本時,只需將其從待刪除狀態中移除即可。
秘密旋轉
秘密旋轉是指定期更換秘密的過程,以減少因秘密洩露而導致的安全風險。AWS Secrets Manager 支援使用 AWS Lambda 函式來自動旋轉秘密。當 Lambda 函式被觸發時,會根據我們提供的自定義程式碼來旋轉秘密。這些 Lambda 函式範本可以在 GitHub 上找到,並且在旋轉過程中會測試最新版本的秘密,如果測試失敗則會重試。
多重整合與高用性
AWS Secrets Manager 作為一個託管服務,具有以下特性:
- AWS IAM 整合:透過 AWS Identity and Access Management(IAM),我們可以為 AWS 使用者或角色設定細粒度許可權來存取秘密。
- 日誌記錄與稽核:AWS CloudWatch 和 CloudTrail 提供了詳細的日誌記錄和稽核功能,可以追蹤所有對秘密的操作。
- 高用性與災難還原:秘密在多個可用區域中進行備份和複製,確保在單一區域發生故障時仍然能夠存取。
具體應用案例
以下是一些具體應用案例,展示瞭如何在實際專案中使用 AWS Secrets Manager:
案例一:應用程式佈署中的金鑰管理
假設我們有一個佈署在 EKS 上的應用程式,需要存取資料函式庫和第三方 API。我們可以使用 AWS Secrets Manager 來儲存這些敏感資訊。透過整合 EKS 和 AWS Secrets Manager,我們可以讓應用程式在啟動時自動從 AWS Secrets Manager 取得所需的秘密。
案例二:定期旋轉 API 金鑰
某些 API 提供商要求定期更換 API 金鑰以保障安全。我們可以使用 AWS Secrets Manager 和 Lambda 函式來實作自動旋轉 API 金鑰。這樣可以避免人工干預,並且確保金鑰在被更新後立即生效。
與 EKS 的整合
要將 AWS Secrets Manager 與 EKS 整合,我們需要使用 Secrets Store CSI Driver。這是一個符合 Kubernetes CSI(Container Storage Interface)標準的驅動程式,可以讓 Kubernetes 從外部秘密儲存中掛載秘密。
工作原理
- Pod 建立:當一個 Pod 被建立或重啟時,Secrets Store CSI Driver 會透過 Secret Store CSI 提供者與 AWS Secrets Manager 通訊,取得所需的秘密。
- 掛載卷:取得到的秘密會被掛載到 Pod 的指定目錄中。
- 監控健康狀況:DaemonSet 中的 liveness-probe Pod 會監控 CSI 驅動程式的健康狀況,並在發現問題時重啟 Pod。
此圖示展示了 AWS Secrets Manager 與 EKS 的整合方式:
@startuml
:Kubernetes Pod; --> :Secrets Store CSI Driver;
:B; --> :AWS Secrets Manager;
:C; --> :Secret Volume;
:D; --> :A;
@enduml
此圖示展示了 Kubernetes Pod 與 AWS Secrets Manager 之間的互動流程。Secrets Store CSI Driver 作為中介,負責從 AWS Secrets Manager 取得秘密並掛載到 Pod 中。
組態步驟
以下是組態步驟的簡要說明:
- 安裝 CSI 驅動程式:首先需要在 Kubernetes 叢集中安裝 Secrets Store CSI Driver。
- 建立 SecretProviderClass:這是一個 Kubernetes 資源物件,定義瞭如何從外部秘密儲存中取得秘密。
- 組態 Pod:在 Pod 的 YAML 組態檔案中新增捲組態,指定使用 SecretProviderClass 來掛載秘密。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "example-spc"
掌握更多細節
對於想要深入瞭解 AWS Secrets Manager 與 EKS 整合細節的人來說,AWS 推薦資源和GitHub上的Lambda範本是非常有價值的參考材料。這些資源提供了詳細的和範例程式碼,幫助開發者快速上手。
在 AWS 上整合 AWS Secrets Manager 與 EKS
在現代的雲端技術中,管理敏感資訊是一個關鍵問題。AWS Secrets Manager 提供了一個安全且可靠的方法來管理和存取敏感資訊。同時,Amazon Elastic Kubernetes Service (EKS) 是一個受管理的 Kubernetes 服務,讓我們可以輕鬆地佈署和營運容器化應用程式。本文將探討如何在 AWS 上整合 AWS Secrets Manager 與 EKS,並詳細解說每一步驟。
什麼是 AWS Secrets Manager?
AWS Secrets Manager 是一個安全的方法來存取、管理和棄用資料函式庫認證、API 金鑰及其他敏感資訊。它支援多種資料函式庫(例如 MySQL、PostgreSQL、Amazon RDS)以及其他服務(例如 Amazon Redshift 和 Amazon DocumentDB)。
什麼是 EKS?
Amazon Elastic Kubernetes Service (EKS) 是一個受管理的 Kubernetes 服務,讓您可以執行 Kubernetes 而不需要執行或維護 Kubernetes 控制平面。EKS 會在多個可用區中自動擴充套件 Kubernetes 控制平面,確保高用性和耐久性。
搭建 EKS 環境
在開始整合 AWS Secrets Manager 與 EKS 之前,我們需要先搭建 EKS 環境。以下是詳細步驟:
使用 Terraform 搭建 EKS 環境
Terraform 是一個開源的基礎設施即程式碼工具,可讓我們使用一致的語法來定義和佈建數位基礎設施。以下是使用 Terraform 搭建 EKS 環境的步驟:
provider "aws" {
region = "eu-west-1"
}
data "aws_availability_zones" "available" {}
module "eks_ksm_vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "eks-ksm-vpc"
cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = var.cluster_name
vpc_id = module.eks_ksm_vpc.vpc_id
subnet_ids = module.eks_ksm_vpc.private_subnets
cluster_endpoint_public_access = true
eks_managed_node_group_defaults = {
ami_type = "AL2_x86_64"
}
create_cloudwatch_log_group = true
}
output "cluster_name" {
value = module.eks.cluster_name
}
初始化 Terraform
在開始佈建之前,我們需要初始化 Terraform:
terraform init
檢查 Terraform 組態
使用 terraform plan 檢查組態:
terraform plan
應用 Terraform 組態
如果組態正確,我們可以使用 terraform apply 應用組態:
terraform apply
檢查 EKS 叢集狀態
佈建完成後,我們可以使用 kubectl 命令檢查叢集狀態:
aws eks --region eu-west-1 update-kubeconfig --name eks-ksm-cluster
kubectl get nodes
整合 AWS Secrets Manager 與 EKS
接下來,我們將探討如何整合 AWS Secrets Manager 與 EKS。
安裝 Secrets Store CSI Driver
為了將 AWS Secrets Manager 整合到 EKS 中,我們需要安裝 AWS 的 Secrets Store CSI Driver。以下是安裝步驟:
kubectl apply -k github.com/aws/secrets-store-csi-driver-provider-aws/deploy/base/
建立 Secret 在 AWS Secrets Manager
在 AWS Secrets Manager 中建立一個 Secret:
resource "aws_secretsmanager_secret" "ksm_service_token" {
name = "service-token"
}
在 Kubernetes 中使用 Secret
建立一個 Kubernetes SecretProviderClass 對應到 AWS Secrets Manager 中的 Secret:
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: aws-secretsmanager-class
spec:
provider: aws
parameters:
objects: |
- objectName: service-token
objectType: secretsmanager
接下來,我們可以在 Pod 中使用這個 SecretProviderClass:
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: demo-container
image: nginx
volumeMounts:
- name: secrets-store-inline-volume
mountPath: "/mnt/secrets-store"
readOnly: true
- name: secrets-store-csi-driver-volume-mounting-volume-generator-object-name-container-path-secret-provider-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-secretkeyref-secret-keyselector-class-name-pod-name-namespace-name-
readOnly: true
path: "/mnt/secrets-store/service-token"
env:
- name: SECRET_TOKEN_KEY_AWS_SECRET_MANAGER_PROVIDER_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_NAME_NAMESPACE_NAME_SECRETKEYREF_SECRET_KEYSELECTOR_CLASS_NAME_POD_
valueFrom:
secretKeyRef:
name: secrets-store-inline-volume-mounting-volume-generator-object-type-container-path-secret-provider-class-nam-service-tokene-token-value-from-the-secrets-manager-in-a-secrets-manager-in-a-sec-secrets-manag-secrets-manage-generator-object-type-container-path-service-token-value-from-the-secrets-manager-in-a-sec-secrets-manag-secrets-manage-generator-object-type-container-path-service-token-value-from-the-secrets-manager-in-a-sec-secrets-manag-secrets-manage-
key: secretKeyRef.secretKeySelector.className.podName.namespaceName.secretKeyRef.secretKeySelector.className.podName.namespaceName.secretKeyRef.secretKeySelector.className.podName.namespaceName.secretKeyRef.secretKeySelector.className.podName.namespaceName.secretKeyRef.secretKeySelector.className.podName.namespaceName.secretKeyRef.secretKeySelector.className.podNamesecretKeySelector.className.podNamenamespaceNamenamespaceNamesecretKeySelector.classNamesecretKeySelector.
volumeMounts:
- name: secrets-store-inline-volume-volume-mounting-volume-generator-object-type-container-path-service-token-value-from-the-secrets-manager-in-a-sec-secrets-manag-service-token-value-from-the-secrets-manager-in-a-secsecrets-managsecret-values-values-ckey-selector-value-values-selector-vueueueueueueueueu-
mountPath: "/mnt/secrets-store/service-token"
readOnly: true
小段落標題:內容解密:
這段程式碼定義了一個 Pod 名為 demo-pod,並組態了兩個卷(Volume)掛載到容器中:
secrets-store-inline-volume:這是從 AWS Secrets Manager 中取得的 Secret 資料。secrets-store-csi-driver-volume-mounting-volume-generator-object-type-container-path-service-token-value-from-the-secrets-manager-in-a-sec-secrets-manag:這是從指定路徑讀取的 Secret 資料。
容器 demo-container 必須包含兩個環境變數 SECRET_TOKEN_KEY_AWS_SECRET_MANAGER_PROVIDER_CLASSNAME... 和 SECRET_TOKEN_VALUE_FROM_THE_SECRETS_MANAGER... 。
第一個變數使用 secretKeyRef 建構從名為 secrets-store-inline-volume-mounting-volume-generator-object-type-container-path... 的 Secret 中取得值。
第二個變數直接指定值為從指定路徑取得的 Secret 資料。
在 Pod 中使用 Secret
接下來,我們可以在 Pod 中使用這些 Secret。例如,我們可以將它們作為環境變數或掛載到檔案系統中。
整合後的架構圖示
此圖示展示了整合後的架構:
@startuml
:Kubernetes Cluster; --> :AWS Secrets Manager;
:A; --> :EKS Control Plane;
:C; --> :Managed Node Groups;
:B; --> :SecretProviderClass;
:E; --> :Pod;
@enduml
說明:
- Kubernetes Cluster:EKS 叢集。
- AWS Secrets Manager:儲存敏感資訊。
- EKS Control Plane:管理 Kubernetes 叢集。
- Managed Node Groups:執行 Pod 的節點群組。
- SecretProviderClass:將 AWS Secrets Manager 的秘密注入到 Pod 中。
- Pod:使用秘密的 Kubernetes Pod。