我如何透過其 NodeName 追蹤已終止 Amazon EKS 工作節點的執行個體 ID?

3 分的閱讀內容
0

一個事件終止我的 Amazon EKS 叢集中的工作節點,我想要將已終止節點的名稱與其執行個體 ID 相符。

簡短描述

在 Amazon EKS 中,使用其 PrivateDnsName 記錄和顯示節點的名稱。此名稱遵循的格式類似於 ip-172-31-6-187.eu-west-1.compute.internal

您可以使用節點的名稱來尋找其執行個體 ID。但是,預設的 kubectl get nodes 命令不會在其輸出中傳回執行個體 ID。請參閱以下範例輸出:

NAME                                           STATUS   ROLES    AGE   VERSION
ip-192-168-132-83.eu-west-1.compute.internal   Ready    <none>   37m   v1.22.12-eks-ba74326
ip-192-168-96-83.eu-west-1.compute.internal    Ready    <none>   37m   v1.22.12-eks-ba74326

若要擷取作用中工作節點的執行個體 ID,請新增額外的欄,如下列命令所示:

kubectl get nodes -o custom-columns=Name:.metadata.name,Instance:.spec.providerID

您會收到與下列內容類似的輸出:

Name                                            Instance
ip-192-168-104-154.eu-west-1.compute.internal   aws:///eu-west-1a/i-0cb3f1ceeb038fb6c
ip-192-168-157-89.eu-west-1.compute.internal    aws:///eu-west-1b/i-02e80d4889b6ccffa

但是,此命令不適用於已終止的節點。

您也可以使用 TerminateInstancesTerminateInstanceInAutoScalingGroup 作為 AWS CloudTrail 中的 EventName 來傳回執行個體 ID。但是,這些命令本身不會傳回 Amazon EKS 節點的名稱。

因此,您必須先執行個別的命令來擷取節點的 NodeName (PrivateDnsName)。然後,使用該名稱來追蹤節點的執行個體 ID。若要尋找先前已終止工作節點的執行個體 ID,請使用 Amazon CloudWatch Logs Insights 搜尋 Amazon EKS 控制平面日誌。為此,您必須在節點終止之前啟用控制平面日誌記錄。如果您沒有啟用控制平面日誌記錄功能,請使用 CloudTrail。

解決方案

**備註:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤,請確保您使用的是最新的 AWS CLI 版本

擷取節點的 NodeName

對於下列兩種方法,您必須知道已終止節點的 NodeName,才能擷取其執行個體 ID。若要從指定時間範圍擷取已終止 Amazon EKS 節點的清單,請使用 CloudWatch Log Insight 查詢編輯器:

1.    開啟 CloudWatch 主控台

2.    在導覽窗格中,選擇 Logs (日誌),然後選擇 Logs Insights

**備註:**在 Logs Insights 頁面上,查詢編輯器包含預設查詢,其會傳回 20 個最近的日誌事件。

3.    刪除預設查詢。然後,輸入以下命令:

fields @timestamp, objectRef.name as NodeName
| filter @logStream like /^kube-apiserver-audit/
| filter objectRef.resource = "nodes"
| filter responseStatus.code = 200 or responseStatus.code = 201
| sort @timestamp desc
| filter verb like /delete/

4.    在 Select log group(s) (選取日誌群組) 下拉式清單中,選擇要查詢的 Amazon EKS 叢集日誌群組。

**備註:**您的日誌群組看起來類似於 /aws/eks/cluster_name/cluster。在此範例中,請以您自己的 Amazon EKS 叢集名稱取代 cluster_name

5.    使用時間間隔選取器來選取您要查詢的期間。

6.    選擇 Run (執行) 以檢視結果。

您會收到與下列內容類似的輸出:

# @timestamp                    NodeName                                     
1 2023-01-23T08:03:03.062+00:00 ip-192-168-132-83.eu-west-1.compute.internal 
2 2023-01-23T19:03:41.848+00:00 ip-192-168-0-141.eu-west-1.compute.internal

使用 CloudWatch Logs Insights 搜尋 Amazon EKS 控制平面日誌

使用 CloudWatch Logs Insights,在 Amazon EKS 控制平面日誌資料中搜尋記錄節點的 NodeName 的事件。若要在 Amazon CloudWatch Logs 中檢視這些日誌,您必須在節點終止之前啟用 Amazon EKS 控制平面日誌記錄,而且必須保持啟用狀態。

例如,假設您要擷取名稱為 ip-192-168-132-83.eu-west-1.compute.internal 的節點的執行個體 ID。此節點的終止日期是四天前。您可以使用兩個查詢中的任何一個,依據 NodeName 擷取執行個體 ID。

首先,請依照下列步驟執行 CloudWatch Logs Insights 查詢:

1.    開啟 CloudWatch 主控台

2.    在導覽窗格中,選擇 Logs (日誌),然後選擇 Logs Insights

**備註:**在 Logs Insights 頁面上,查詢編輯器包含預設查詢,其會傳回 20 個最近的日誌事件。

3.    刪除預設查詢。然後,輸入下列其中一個查詢,依據 NodeName 擷取執行個體 ID:

查詢 1

fields @timestamp, objectRef.name as NodeName, responseObject.spec.providerID as providerID
| filter @message like 'ip-192-168-132-83.eu-west-1.compute.internal' and @message like 'i-'
| sort responseObject.spec.providerID desc
| limit 10

查詢 2

fields @timestamp, objectRef.name as NodeName, user.extra.sessionName.0 as ID
| filter @message like 'ip-192-168-132-83.eu-west-1.compute.internal' and @message like 'i-'
| sort user.extra.sessionName.0 desc
| limit 5

4.    在 Select log group(s) (選取日誌群組) 下拉式清單中,選擇要查詢的 Amazon EKS 叢集日誌群組。

**備註:**您的日誌群組看起來類似於 /aws/eks/cluster_name/cluster。在此範例中,請以您自己的 Amazon EKS 叢集名稱取代 cluster_name

5.    使用時間間隔選取器來選取您要查詢的期間。

6.    選擇 Run (執行) 以檢視結果。

您會根據執行的查詢收到輸出。

查詢 1 傳回與下列內容類似的輸出:

# @timestamp                    NodeName                                     providerID
1 2023-01-23T08:03:03.062+00:00 ip-192-168-132-83.eu-west-1.compute.internal aws:///eu-west-1a/i-06c893718d4123396

查詢 2 傳回與下列內容類似的輸出:

# @timestamp                    NodeName                                     ID
1 2023-01-22T15:00:32.637+00:00 ip-192-168-11-247.eu-west-1.compute.internal i-06c893718d4123396

使用 API 呼叫作為 CloudTrail 中的事件

您可以透過 CloudTrail 中的 API 呼叫組合,依據 NodeName 擷取節點的執行個體 ID。同時使用 RunInstancesTerminateInstances 作為 EventName。這些 API 呼叫會執行下列動作:

**TerminateInstances:**這會依據終止它們的事件時間檢索所有執行個體 ID。此呼叫只包含執行個體 ID。

**RunInstance:**此呼叫同時包含執行個體 ID 和 NodeName

首先,使用下列命令,查看您要稽核之事件時間範圍內所有終止的工作節點。取代 start-timeend-time 值以設定相關的時間範圍:

% aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=TerminateInstances AttributeKey=ResourceType,AttributeValue=AWS::EC2::Instance \
  --start-time "January 27, 2023, 00:00:00" \
  --end-time "January 27, 2023, 23:59:00" | jq '.Events [] | .CloudTrailEvent | fromjson | .responseElements | .instancesSet | .items | .[]? | {InstanceID: .instanceId, NodeName: .privateDnsName}'

您會收到與下列內容類似的輸出:

{
  "InstanceID": "i-0926c5d4216fd934d",
  "NodeName": null
}
{
  "InstanceID": "i-00da28f580e28ff4f",
  "NodeName": null
}

在您要稽核的事件的時間範圍內,使用下列命令擷取 RunInstances API 呼叫的結果。取代 start-timeend-time 值以設定相關的時間範圍:

% aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances AttributeKey=ResourceType,AttributeValue=AWS::EC2::Instance \
  --start-time "January 27, 2023, 00:00:00" \
  --end-time "January 27, 2023, 23:59:00" | jq '.Events [] | .CloudTrailEvent | fromjson | .responseElements | .instancesSet | .items | .[]? | {InstanceID: .instanceId, NodeName: .privateDnsName}'

**備註:**若要取得最完整的資訊,請將 start-time 設定為工作節點的建立時間。

您會收到與下列內容類似的輸出:

{
  "InstanceID": "i-0926c5d4216fd934d",
  "NodeName": "ip-192-168-96-83.eu-west-1.compute.internal"
}
{
  "InstanceID": "i-00da28f580e28ff4f",
  "NodeName": "ip-192-168-132-83.eu-west-1.compute.internal"
}

AWS 官方
AWS 官方已更新 1 年前