
利用 AWS 自動診斷工具簡化 EBS CSI Driver 故障排除流程
在現代 Kubernetes 環境中,持久性儲存是有狀態 (Stateful) 應用程式的重要元件。Amazon EKS 使用者通常會使用 Amazon EBS Container Storage Interface (CSI) 驅動程式來為應用程式提供持久性儲存空間 (使用 Amazon EBS)。然而,當任何原因導致驅動故障時,排查問題通常複雜且耗時,並且間接可能導致應用程式停機和資料可用性問題。為了協助團隊更有效地管理和維護 EKS 叢集中的 EBS CSI 驅動程式問題,AWS 推出了一個新的自動化診斷工具。這套工具不只能顯著縮短故障排除時間,還能提供更準確的問題分析報告。本文將深入探討如何運用這項工具來優化您的 Kubernetes 營運流程。
AWS Support Automation Workflow (SAW) 簡介
AWS Support Automation Workflow (SAW) 是一個專門設計用來自動化 AWS 服務疑難排解流程的工具集。它能夠大幅簡化複雜的診斷過程,讓系統管理員和開發人員能更有效率地解決各種 AWS 服務相關的技術問題。其中,SAW 新增 AWSSupport-TroubleshootEbsCsiDriversForEks
1 這個自動化診斷工具用於檢查 EBS CSI Driver 相關的錯誤,並且診斷 Amazon EKS 叢集中的 EBS 磁碟區掛載問題,同時簡化處理 EBS CSI 驅動程式的各種設定疑難:
- 儲存相關問題需要跨多個 AWS 服務(EKS、EBS、EC2)和 Kubernetes 資源進行調查
- 診斷 CSI 驅動程式問題需要同時具備 Kubernetes 和 AWS 儲存服務的專業知識
- 手動故障排除需要執行大量指令,並對複雜的輸出結果進行解讀
- 儲存系統故障會直接影響應用程式的可用性和資料持久性
技術概述
核心架構元件
AWSSupport-TroubleshootEbsCsiDriversForEks
整合了數個 AWS 服務:
- AWS System Manager (SSM):運行該診斷工具的執行引擎
- Amazon EKS:EBS CSI 驅動程式運作的受管 Kubernetes 服務
- Amazon EBS:提供儲存服務
- AWS Lambda:用於運行診斷時建立能夠呼叫 Kubernetes API 的簡易程式
- AWS CloudFormation:管理診斷工具資源的建立與清理
- Amazon S3:疑難排解日誌和報告的選用儲存空間
診斷工具運作機制
AWSSupport-TroubleshootEbsCsiDriversForEks
診斷工具會執行下列步驟:
- 驗證群集狀態:確認目標 EKS 群集存在
- 部署臨時性診斷 AWS 資源:設定執行 Kubernetes API 呼叫的必要元件
- 執行 EBS CSI 控制器健康檢查:評估控制器 pod 狀態和組態
- 檢查 IAM 權限:驗證節點角色和服務帳戶角色是否具有適當權限
- 診斷持久卷建立問題:分析指定 pod 的 PVC/PV 問題
- 檢查 pod 排程:檢查節點及 Pod 調度設定,並分析 Pod 事件
- 收集相關日誌:收集 Kubernetes 和應用程式日誌
- 執行節點健康檢查:驗證 EC2 實體的健康狀況以及與所需端點的連線性
- 檢查磁碟區附件:檢查掛載狀態
- 清理資源:移除運行診斷工具期間建立的暫時性 AWS 資源
- 產生報告:產生包含所有診斷結果的全面疑難排解報告
開始使用 SAW 自動診斷 EBS CSI Driver 問題
-
為 SSM 自動化建立 IAM 角色:
建立具有下列 IAM 信任關係 (Trust Relationship) 的角色,命名為
TroubleshootEbsCsiDriversForEks-SSM-Role
:{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ssm.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
-
新增 IAM 權限政策:
診斷工具需要特定的 IAM 權限才能正常運作。請注意,如果您不打算將 SAW 診斷報告儲存到 Amazon S3 儲存桶,可以移除
OptionalRestrictPutObjects
權限。 以下是必要權限的政策範例:{ "Version": "2012-10-17", "Statement": [ { "Sid": "OptionalRestrictPutObjects", "Effect": "Allow", "Action": ["s3:PutObject"], "Resource": ["arn:{partition}:s3:::BUCKET_NAME/*"] }, { "Effect": "Allow", "Action": [ "ec2:DescribeIamInstanceProfileAssociations", "ec2:DescribeInstanceStatus", "ec2:GetEbsEncryptionByDefault", "eks:DescribeAddon", "eks:DescribeAddonVersions", "eks:DescribeCluster", "iam:GetInstanceProfile", "iam:GetOpenIDConnectProvider", "iam:GetRole", "iam:ListOpenIDConnectProviders", "iam:SimulatePrincipalPolicy", "s3:GetBucketLocation", "s3:GetBucketPolicyStatus", "s3:GetBucketPublicAccessBlock", "s3:GetBucketVersioning", "s3:ListBucket", "s3:ListBucketVersions", "ssm:DescribeInstanceInformation", "ssm:GetAutomationExecution", "ssm:GetDocument", "ssm:ListCommandInvocations", "ssm:ListCommands", "ssm:SendCommand", "ssm:StartAutomationExecution" ], "Resource": "*" }, { "Sid": "SetupK8sApiProxyForEKSActions", "Effect": "Allow", "Action": [ "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:UpdateStack", "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", "ec2:DescribeNetworkInterfaces", "ec2:DescribeRouteTables", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "eks:DescribeCluster", "iam:CreateRole", "iam:DeleteRole", "iam:GetRole", "iam:TagRole", "iam:UntagRole", "lambda:CreateFunction", "lambda:DeleteFunction", "lambda:GetFunction", "lambda:InvokeFunction", "lambda:ListTags", "lambda:TagResource", "lambda:UntagResource", "lambda:UpdateFunctionCode", "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:ListTagsForResource", "logs:PutLogEvents", "logs:PutRetentionPolicy", "logs:TagResource", "logs:UntagResource", "ssm:DescribeAutomationExecutions", "tag:GetResources", "tag:TagResources" ], "Resource": "*" }, { "Sid": "PassRoleToAutomation", "Effect": "Allow", "Action": "iam:PassRole", "Resource": [ "arn:*:iam::*:role/TroubleshootEbsCsiDriversForEks-SSM-Role", "arn:*:iam::*:role/Automation-K8sProxy-Role-*" ], "Condition": { "StringLikeIfExists": { "iam:PassedToService": [ "lambda.amazonaws.com", "ssm.amazonaws.com" ] } } }, { "Sid": "AttachRolePolicy", "Effect": "Allow", "Action": [ "iam:AttachRolePolicy", "iam:DetachRolePolicy" ], "Resource": "*", "Condition": { "StringLikeIfExists": { "iam:ResourceTag/AWSSupport-SetupK8sApiProxyForEKS": "true" } } } ] }
-
設定 EKS 存取權限:
為了讓 SAW 診斷工具在運行時有權限可以檢視 EKS 中的資源,需要適當的 Kubernetes 角色存取控制 (RBAC) 權限,才能在診斷過程執行 Kubernetes API 呼叫。建議的方法是在 EKS 群集中直接將前面新增的 IAM Role (
TroubleshootEbsCsiDriversForEks-SSM-Role
) 加入到 EKS Access Entry 的設定中:- 在 Amazon EKS 主控台中點擊要診斷的 EKS 資源
- 確認 Authentication mode 已設定為
API_AND_CONFIG_MAP
或API
才可以使用 Access Entry - 選擇 “Create access entry”
- 針對 IAM principal ARN,選擇您建立的 SSM 自動化角色 (
TroubleshootEbsCsiDriversForEks-SSM-Role
) - 針對 Type,選擇「Standard」
- 新增具有「Cluster」範圍和
AmazonEKSAdminViewPolicy
的存取政策
-
準備一個 S3 儲存桶 (可選):
如果您打算儲存診斷過程的相關日誌,請在 EKS 叢集相同區域中建立一個 Amazon S3 Bucket。
執行 AWSSupport-TroubleshootEbsCsiDriversForEks 診斷工具
- 使用連結快速啟動診斷工具:Run this Automation (console) 2
- 使用下列參數執行自動化診斷:
- AutomationAssumeRole(可選):您建立的 IAM 角色的 ARN,例如:
arn:aws:iam::123456789012:role/TroubleshootEbsCsiDriversForEks-SSM-Role
- EksClusterName:遇到問題的 EKS 集群名稱
- ApplicationPodName:遇到 EBS CSI 驅動程式問題的 Kubernetes pod 的名稱
- ApplicationNamespace:出現問題的應用程式 Pod 的名稱空間
- EbsCsiControllerDeploymentName(可選):EBS CSI 控制器 pod 的部署名稱 (預設:
ebs-csi-controller
) - EbsCsiControllerNamespace (可選):EBS CSI 控制器的命名空間 (預設:
kube-system
) - S3BucketName (可選):上傳故障診斷日誌的 S3 儲存桶名稱
- LambdaRoleArn (可選):運行簿建立的 Lambda 函式的 IAM 角色 ARN
- AutomationAssumeRole(可選):您建立的 IAM 角色的 ARN,例如:
-
如果您習慣使用命令列工具,也可以透過 AWS CLI 執行自動化診斷工具:
aws ssm start-automation-execution \ --document-name "AWSSupport-TroubleshootEbsCsiDriversForEks" \ --parameters "EksClusterName=my-production-cluster,ApplicationPodName=my-stateful-app,ApplicationNamespace=default,AutomationAssumeRole=arn:aws:iam::123456789012:role/TroubleshootEbsCsiDriversForEks-SSM-Role"
-
在 AWS Systems Manager 主控台或透過 CLI 可以監控執行狀態:
aws ssm get-automation-execution \ --automation-execution-id "execution-id-from-previous-step"
使用範例
診斷 Persistent Volume Claim (PVC) 以及 Pod 處在 Pending 狀態
問題情境:一個在 EKS 上運行應用的開發團隊遇到了一個難題,新建立的 Pod 使用到持久性儲存 Persistent Volume Claim(PVC)一直卡在 Pending 狀態。由於無法成功配置所需的儲存空間,導致應用程式無法正常啟動。這類問題通常需要團隊花費數小時的時間,在多個元件之間來回檢查與排除,包括:
- 檢查 PVC 和 StorageClass 配置
- 檢查 EBS CSI Driver 和相關的 Pod 日誌
- 驗證服務帳戶的 IAM 角色權限
為了重現問題情境,我建立一個簡單的 Shell Script (scenario1.sh),模擬一個故障情境,以展示 AWS 支援自動化工作流程如何識別和解決 EBS CSI 驅動程式相關問題:
export AWS_REGION=eu-west-1
./scenario1.sh
測試情境準備就緒後,我執行重現問題的腳本來建立需要持久性磁碟區(PV)的 Pod。不出所料,由於磁碟區掛載的問題,Pod 仍然維持在 Pending 狀態無法正常啟動。
$ kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
app 0/1 Pending 0 48m
使用 AWS 支援自動化工作流程 (SAW)
在這種情況下,我可以為 EKS 集群新增一個 Access Entry,並且賦予 SAW 診斷工具會使用到 IAM 角色訪問 EKS 資源的權限,然後執行AWSSupport-TroubleshootEbsCsiDriversForEks
runbook 來啟動疑難排解工作流程。自動化作業將系統性地檢查常見問題,包括 IAM 權限、pod 調度問題和磁碟區附加狀態。這種全面的診斷方法可以幫助在調查過程快速找出並解決常見的 EBS CSI 驅動程式相關問題。
新增好 EKS Access Entry 後,執行 AWSSupport-TroubleshootEbsCsiDriversForEks
,啟動過程只需提供 EKS Cluster 名稱、受影響的 Pod 名稱和命名空間。自動化診斷工具可以:
- 驗證 EBS CSI 控制器部署的健康狀況和組態
- 確認 EBS CSI 驅動程式服務帳戶的 IAM 角色配置錯誤
- 確認 StorageClass 參數正確
- 確認節點 IAM 角色缺少所需的 EBS 權限
- 產生一份全面的報告,指出確實遺失的權限
自動診短結果:
故障排除時間從數小時大幅縮短至僅需 15 分鐘。診斷工具產生的輸出報告快速指出了根本原因 - 缺少必要的 IAM 權限,並提供了修復 IAM 角色的步驟說明。
範例輸出:
==================================================
1. IAM and Service Account permissions checks
==================================================
Checked service account role AmazonEKSEBSCSIDriverRoleLab1 and there is no trust policy for federated
arn:aws:iam::123456789:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/C746A744DA16B63394A03370F964F05A
with condition
{
'StringEquals': {
'oidc.eks.eu-west-1.amazonaws.com/id/C746A744DA16B63394A03370F964F05A:aud': 'sts.amazonaws.com'
}
}.
Check AWS documentation https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html
報告指出 IAM 權限中的條件設定不正確。在我的範例中,我使用的是 www.sts.amazonaws.com
,而不是 sts.amazonaws.com
。這個細小但關鍵的組態錯誤讓 EBS CSI 驅動程式無法正確使用關聯的 IAM 角色,導致磁碟區配置失敗。更正 IAM 設定後,PVC 成功建立,應用程式 Pod 也正常啟動。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/C746A744DA16B63394A03370F964F05A"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-west-1.amazonaws.com/id/C746A744DA16B63394A03370F964F05A:aud": "www.sts.amazonaws.com", <-- Incorrect setting
"oidc.eks.eu-west-1.amazonaws.com/id/C746A744DA16B63394A03370F964F05A:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa"
}
}
}
]
}
進階技巧:簡化 EBS CSI 疑難排解工作流程
為了讓 AWS 支援自動化工作流程在處理 EBS CSI 驅動程式問題時發揮最大效益,您也可以整合自動化診斷工具,針對常見的錯誤模式設定自動回應機制。例如:整合 EventBridge 規則,在監控系統偵測到應用程式健康檢查失敗等問題時自動觸發對應動作。這種自動化機制可以幫助團隊減少人工介入的需求,並且更快速地解決問題。
下面的流程圖展示了自動化工作流程如何處理 EBS CSI 驅動程式問題 - 從最初觸發開始,經過全面的診斷步驟,最後產生完整的報告並與外部系統整合。
- 確保系統已準備好進行自動化:
雖然自動化診斷可以與標準 EKS 設定一起使用,但某些進階診斷功能需要工作節點是由 AWS Systems Manager 所管理的執行個體。EKS-optimized Amazon Linux AMI 預設已包含 SSM 代理程式,因此通常能夠正常使用。然而,如果您的工作節點並非使用 EKS-optimized AMI,則需要將它們註冊為受管理的執行個體,才能啟用所有診斷功能。
- 建立特定的 CloudWatch 警示以及早發現 EBS CSI 問題:
建立監控機制來追蹤有狀態系統的健康狀況。這可以包括反映有狀態應用程式健康狀況的自訂 CloudWatch 指標。設定具有適當閾值的 CloudWatch 警示,以便及早發現潛在問題。
- 建立 EventBridge 規則,在偵測到問題時觸發自動化:
使用 CloudWatch 告警狀態的變化,您可以建立特定的 EventBridge 規則來監控應用程式事件,並在發生問題時透過 AWS Lambda 觸發自動化工作流程。
aws events put-rule \
--name "EBSCSITroubleshootingTrigger" \
--event-pattern '{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"resources": ["arn:aws:cloudwatch:us-east-1:123456789012:alarm:EBSVolumeProvisioningFailures"],
"detail": {
"state": {
"value": ["ALARM"]
}
}
}'
如果您有自己的警報系統,您也可以直接使用StartAutomationExecution
API 直接呼叫 SSM執行
簿:
aws ssm start-automation-execution \
--document-name "AWSSupport-TroubleshootEbsCsiDriversForEks" \
--parameters \
"EksClusterName=my-production-cluster,\
ApplicationPodName=my-stateful-app,\
ApplicationNamespace=default,\
AutomationAssumeRole=arn:aws:iam::123456789012:role/TroubleshootEbsCsiDriversForEks-SSM-Role"
與監控和通知系統整合
-
將自動化結果饋送至事件管理平台:
您可以設定一個 Lambda 函式來處理自動化輸出,並將發現和建議的動作更新至您的事件管理系統:
import boto3 import json import requests def lambda_handler(event, context): ssm_client = boto3.client('ssm') execution_id = event['detail']['automation-execution-id'] # Get automation execution output response = ssm_client.get_automation_execution( AutomationExecutionId=execution_id ) outputs = response['AutomationExecution']['Outputs'] diagnosis_report = json.loads(outputs['DiagnosisReport'][0]) # Update PagerDuty incident headers = { 'Content-Type': 'application/json', 'Authorization': 'Token token=YOUR_API_KEY' } payload = { 'incident': { 'id': event['incident_id'], 'type': 'incident', 'status': 'acknowledged', 'notes': [{ 'content': f"EBS CSI Diagnosis Results:\\n{json.dumps(diagnosis_report, indent=2)}" }] } } requests.put( f"<https://api.pagerduty.com/incidents/{event['incident_id']}>", headers=headers, data=json.dumps(payload) ) return { 'statusCode': 200, 'body': 'PagerDuty updated with diagnosis results' }
-
為儲存故障排除結果建立集中式儲存庫:
以可搜尋的格式 (例如 Elasticsearch) 儲存每次自動化執行的結果,以便識別模式並隨時間改善儲存配置。
結論
AWSSupport-TroubleshootEbsCsiDriversForEks
執行手冊為診斷和解決 EKS 環境中的 EBS CSI 驅動程式問題提供了一個簡便的解決方案。藉由在 AWS 服務和 Kubernetes 元件之間自動化疑難排解流程,大幅縮短了識別和修復問題所需的時間。
本文展示了自動化如何在提供全面性診斷的同時,顯著減少故障排除時間。透過將這個工作流程與監控系統和事件管理平台整合,團隊可以在 Kubernetes 環境中建立一個更有效的問題排查機制。
參考資料