如何稽核 Azure Cosmos DB 控制平面作業

適用於:NoSQL MongoDB Cassandra Gremlin Table

Azure Cosmos DB 中的控制平面是一種 REST (具象狀態傳輸) 服務,可讓您在 Azure Cosmos DB 帳戶上執行一系列不同的作業。 它會公開公用資源模型 (例如:資料庫、帳戶等) 和各種作業,以供終端使用者在資源模型上執行動作。 控制平面作業包括對 Azure Cosmos DB 帳戶或容器所做的變更。 例如建立 Azure Cosmos DB 帳戶、新增區域、更新輸送量、區域容錯移轉、新增 VNet 等作業,都屬於控制平面作業。 本文說明如何在 Azure Cosmos DB 中稽核控制平面作業。 您可以使用 Azure CLI、PowerShell 或 Azure 入口網站在 Azure Cosmos DB 帳戶上執行控制平面作業,而針對容器,請使用 Azure CLI 或 PowerShell。

以下是一些審核控制平面作業的實用案例:

  • 您想要在 Azure Cosmos DB 帳戶的防火牆規則遭到修改時收到警示。 需要有警示才能找出未經授權修改的規則,藉此管理 Azure Cosmos DB 帳戶的網路安全性,並採取快速動作。

  • 您想要在 Azure Cosmos DB 帳戶中新增或移除新區域時收到警示。 新增或移除區域對於計費和資料主權需求都會有所影響。 此警示可協助您偵測到帳戶上意外新增或移除區域的狀況。

  • 您想要從診斷記錄中取得遭變更項目的詳細資料。 例如,VNet 遭到變更。

停用金鑰型中繼資料寫入存取

在 Azure Cosmos DB 中稽核控制平面作業之前,請先停用帳戶上的金鑰型中繼資料寫入存取。 停用金鑰型中繼資料寫入存取後,透過帳戶金鑰連接至 Azure Cosmos DB 帳戶的用戶端,將無法存取該帳戶。 您可以藉由將 disableKeyBasedMetadataWriteAccess 屬性設定為 true 來停用寫入存取。 設定此屬性之後,任何對資源的變更都僅會由具有適當 Azure 角色和認證的使用者進行。 若要深入瞭解如何設定此屬性,請參閱防止從 SDK 進行變更一文。

在將 disableKeyBasedMetadataWriteAccess 開啟之後,如果以 SDK 為基礎的用戶端執行建立或更新作業,則會傳回「'POST' 作業不允許經由 Azure Cosmos DB 端點在 'ContainerNameorDatabaseName' 資源上運行」錯誤。 您必須為您的帳戶開啟這類作業的存取權限,或透過 Azure Resource Manager、Azure CLI 或 Azure PowerShell 來執行建立/更新作業。 若要切換回原本狀態,請如避免來自 Azure Cosmos DB 的更動一文中描述的那樣,將 disableKeyBasedMetadataWriteAccess 設定為 false。 請務必將 disableKeyBasedMetadataWriteAccess 的值變更為 false,而不是 true。

關閉中繼資料寫入存取時,請考慮下列幾點:

  • 透過使用 SDK 或帳戶金鑰,評估並確定您的應用程式,不進行會變更到上述資源的中繼資料呼叫 (例如,建立集合、更新輸送量等等)。

  • disableKeyBasedMetadataWriteAccess 設為 true 時,會封鎖 SDK 所發出的中繼資料作業。 或者,您可以使用 Azure 入口網站、Azure CLI、Azure PowerShell 或 Azure Resource Manager 範本部署來執行這些作業。

啟用控制平面作業的診斷記錄

您可以使用 Azure 入口網站來啟用控制平面作業的診斷記錄。 啟用之後,診斷記錄會將作業記錄為一對具有相關詳細資料的開始和完成事件。 例如,RegionFailoverStart 和 RegionFailoverComplete 將會完成區域容錯移轉事件。

使用下列步驟來啟用登入控制平面作業的記錄:

  1. 登入 Azure 入口網站並瀏覽至 Azure Cosmos DB 帳戶。

  2. 開啟 [診斷設定] 窗格,提供要建立記錄的名稱

  3. 選取 [ControlPlaneRequests] 作為記錄類型,然後選取 [傳送至 log Analytics] 選項。

  4. 選擇性地將診斷記錄傳送至 Azure 儲存體、Azure 事件中樞、Azure 監視器或協力廠商。

您也可以將記錄儲存在儲存體帳戶內,或串流至事件中樞。 本文說明如何將記錄傳送至 Log Analytics,然後進行查詢。 啟用之後,需要經過幾分鐘的時間診斷記錄才會生效。 您可以追蹤在該時間點之後執行的所有控制平面作業。 下列螢幕擷取畫面顯示如何啟用控制平面記錄:

Enable control plane requests logging

檢視控制平面作業

開啟記錄之後,請使用下列步驟來追蹤特定帳戶的作業:

  1. 登入 Azure 入口網站

  2. 開啟左側導覽中的 [監視] 索引標籤,然後選取 [記錄] 窗格。 這會開啟一個能讓您在範圍內的特定帳戶中,輕鬆執行查詢的 UI。 執行下列查詢以檢視控制平面記錄:

    AzureDiagnostics
    | where ResourceProvider=="MICROSOFT.DOCUMENTDB" and Category=="ControlPlaneRequests"
    | where TimeGenerated >= ago(1h)
    

    下列螢幕擷取畫面顯示了在 Azure Cosmos DB 帳戶的一致性層級變更時出現的記錄。 結果中的 activityId_g 值與作業的活動識別碼不同:

    Control plane logs when a VNet is added

    下列螢幕擷取畫面顯示了在建立 Cassandra 帳戶的 Keyspace 或是資料表時,以及輸送量更新時出現的記錄。 在資料庫和容器上建立和更新作業的控制平面記錄會分開記錄,如下列螢幕擷取畫面所示:

    Control plane logs when throughput is updated

識別與特定作業相關聯的身分識別

如果您想要進一步進行偵錯,您可以在活動記錄中使用 activityId_g 或該作業的時間戳記,來識別出特定的作業。 某些不會明確傳遞活動識別碼的 Resource Manager 客戶端會使用時間戳記。 活動記錄會提供與啟動作業有關的身分識別。 下列螢幕擷取畫面顯示如何使用 activityId_g 以在活動記錄中尋找與其相關聯的作業:

Use the activity ID and find the operations

Azure Cosmos DB 帳戶的控制平面作業

以下是帳戶層級可使用的控制平面作業。 大部分的作業會在帳戶層級上進行追蹤。 這些作業可作為 Azure 監視器中的計量:

  • 區域已新增
  • 區域已移除
  • 帳戶已刪除
  • 區域已容錯移轉
  • 已建立帳戶
  • 虛擬網路已刪除
  • 帳戶網路設定已更新
  • 帳戶複寫設定已更新
  • 帳戶金鑰已更新
  • 帳戶備份設定已更新
  • 帳戶診斷設定已更新

資料庫或容器的控制平面作業

以下是資料庫和容器層級可用的控制平面作業。 這些作業可作為 Azure 監視器中的計量:

  • SQL Database 已建立
  • SQL Database 已更新
  • SQL Database 輸送量已更新
  • SQL Database 已刪除
  • SQL 容器已建立
  • SQL 容器已更新
  • SQL 容器輸送量已更新
  • SQL 容器已刪除
  • Cassandra Keyspace 已建立
  • Cassandra Keyspace 已更新
  • Cassandra Keyspace 輸送量已更新
  • Cassandra Keyspace 已刪除
  • Cassandra 資料表已建立
  • Cassandra 資料表已更新
  • Cassandra 資料表輸送量已更新
  • Cassandra 資料表已刪除
  • Gremlin 資料庫已建立
  • Gremlin 資料庫已更新
  • Gremlin 資料庫輸送量已更新
  • Gremlin 資料庫已刪除
  • Gremlin 圖表已建立
  • Gremlin 圖表已更新
  • Gremlin 圖表輸送量已更新
  • Gremlin 圖表已刪除
  • Mongo 資料庫已建立
  • Mongo 資料庫已更新
  • Mongo 資料庫輸送量已更新
  • Mongo 資料庫已刪除
  • Mongo 集合已建立
  • Mongo 集合已更新
  • Mongo 集合輸送量已更新
  • Mongo 集合已刪除
  • AzureTable 資料表已建立
  • AzureTable 資料表已更新
  • AzureTable 資料表輸送量已更新
  • AzureTable 資料表已刪除

診斷記錄作業

下列是在診斷記錄中,針對不同作業的作業名稱:

  • RegionAddStart, RegionAddComplete
  • RegionRemoveStart, RegionRemoveComplete
  • AccountDeleteStart, AccountDeleteComplete
  • RegionFailoverStart, RegionFailoverComplete
  • AccountCreateStart, AccountCreateComplete
  • AccountUpdateStart, AccountUpdateComplete
  • VirtualNetworkDeleteStart, VirtualNetworkDeleteComplete
  • DiagnosticLogUpdateStart, DiagnosticLogUpdateComplete

針對 API 特定的作業,作業會以下列格式命名:

  • Api種類 + Api種類資源類型 + 作業類型
  • pi種類 + Api種類資源類型 + 「輸送量」 + 作業類型

範例

  • CassandraKeyspacesCreate
  • CassandraKeyspacesUpdate
  • CassandraKeyspacesThroughputUpdate
  • SqlContainersUpdate

ResourceDetails 屬性包含了整個資源本文作為要求承載,而且包含了所有要求更新的屬性

控制平面作業的診斷記錄查詢

以下是取得控制平面作業診斷記錄的一些範例:

AzureDiagnostics 
| where Category startswith "ControlPlane"
| where OperationName contains "Update"
| project httpstatusCode_s, statusCode_s, OperationName, resourceDetails_s, activityId_g
AzureDiagnostics 
| where Category =="ControlPlaneRequests"
| where TimeGenerated >= todatetime('2020-05-14T17:37:09.563Z')
| project TimeGenerated, OperationName, apiKind_s, apiKindResourceType_s, operationType_s, resourceDetails_s
AzureDiagnostics
| where Category == "ControlPlaneRequests"
| where OperationName startswith "SqlContainersUpdate"
AzureDiagnostics
| where Category == "ControlPlaneRequests"
| where OperationName startswith "SqlContainersThroughputUpdate"

查詢以取得 activityId (活動識別碼) 和起始容器刪除作業的呼叫端:

(AzureDiagnostics
| where Category == "ControlPlaneRequests"
| where OperationName == "SqlContainersDelete"
| where TimeGenerated >= todatetime('9/3/2020, 5:30:29.300 PM')
| summarize by activityId_g )
| join (
AzureActivity
| parse HTTPRequest with * "clientRequestId\": \"" activityId_g "\"" * 
| summarize by Caller, HTTPRequest, activityId_g)
on activityId_g
| project Caller, activityId_g

查詢以取得索引或 ttl 更新。 您接著可以將此查詢的輸出與先前的更新比較,藉此查看索引或 ttl 的變更。

AzureDiagnostics
| where Category =="ControlPlaneRequests"
| where  OperationName == "SqlContainersUpdate"
| project resourceDetails_s

output

{id:skewed,indexingPolicy:{automatic:true,indexingMode:consistent,includedPaths:[{path:/*,indexes:[]}],excludedPaths:[{path:/_etag/?}],compositeIndexes:[],spatialIndexes:[]},partitionKey:{paths:[/pk],kind:Hash},defaultTtl:1000000,uniqueKeyPolicy:{uniqueKeys:[]},conflictResolutionPolicy:{mode:LastWriterWins,conflictResolutionPath:/_ts,conflictResolutionProcedure:}

下一步