天天看點

SLS告警響應更新——通知對接FC進行自動化操作

前言

所謂監控,直白來說就是“監測并進行控制”。通過對資料的監測,我們可以發現其中的異常,例如機器的CPU使用率異常。異常會觸發告警,然後告警會被通知到相應的負責人,以便進行後續的處理。通常我們對告警會有多種方式進行通知,例如通過短信、電話、釘釘等方式。

但是告警并不是目的,異常産生後最終的目的是消除異常,是以除了人為接收通知之外,在某些場景下,我們還需要程式去接收,然後做一些自動化的事情。例如發送通知到一個 Web 服務,然後根據告警詳情進行後續的自動操作(比如根據業務規則做一些自動運維操作)等。但是如果從頭開始編寫一個Web服務然後部署,又是一件比較麻煩的事情,SLS告警加入了對函數計算(FC)的支援,讓告警的自動化響應變得簡單。

SLS告警響應更新——通知對接FC進行自動化操作

告警通知對接FC

1. 授權RAM通路角色

為了告警觸發後,日志服務可以調用你的函數計算裡的函數,需要授權日志服務相應的權限。進入告警中心後,可以“點選授權”進行一鍵授權。

SLS告警響應更新——通知對接FC進行自動化操作

也可以在配置行動政策的時候進行授權:

SLS告警響應更新——通知對接FC進行自動化操作

這裡需要注意,如果登入的是子賬号,需要具備如下RAM權限才可以授權成功,否則會有相應的錯誤提示。

{
  "Statement": [{
    "Action": "ram:CreateServiceLinkedRole",
    "Resource": "*",
    "Effect": "Allow",
    "Condition": {
      "StringEquals": {
        "ram:ServiceName": "alert.log.aliyuncs.com"
      }
    }
  }],
  "Version": "1"
}      

2. 建立FC函數

需要在函數計算控制台建立函數,這裡需要注意的是:

  • SLS告警通知管道中,FC通知僅支援非HTTP函數,如果是HTTP函數,直接使用自定義Webhook通知管道就可以了。
  • 由于安全限制,是以SLS僅能通路名稱以 "sls-ops-" 開頭的函數,例如 "sls-ops-test",而例如 "test-function" 這樣的函數則無權限通路。

這裡我們建立一個非常簡單的函數,示例代碼如下:

'use strict';
exports.handler = (event, context, callback) => {
  console.log(event.toString());
  callback(null, 'hello world');
}      

3. 建立行動政策

我們可以建立一個行動政策,在行動組中配置相應的函數,例如:

SLS告警響應更新——通知對接FC進行自動化操作

4. 建立告警規則

在通知中選擇剛才建立的行動政策。

SLS告警響應更新——通知對接FC進行自動化操作

告警觸發後可以看到函數的調用日志裡已經有相應的記錄:

SLS告警響應更新——通知對接FC進行自動化操作

這裡需要注意的是,告警通知對接到FC函數預設都是異步調用的方式。

案例:限制OSS Bucket必須為私有通路

考慮一個場景,無論是建立 OSS Bucket 還是修改 Bucket 的 ACL權限,都必須限制為私有通路,如果發現有公共讀或者公共讀寫,就需要快速發現并立即自動修複。在這個場景下,如果完全依賴于人工去修複,就會比較麻煩,是以我們的解決思路如下:

  • 開通 OSS 操作審計日志
  • 由于建立 Bucket 或者修改 Bucket 的 ACL 權限,最終都是一條 PutBucket 的審計日志,是以我們可以檢測該日志,然後抽取出地域、Bucket名稱等資訊,觸發一條告警。
  • 告警通知發送到FC函數,FC對該Bucket的ACL權限進行檢測,如果發現是不合規的,則自動修複。

1. 建立FC函數

我們可以建立一個FC函數,用來檢測 Bucket 的 ACL 權限設定是否為私有,如果不是私有,則将其修改為私有。示例代碼如下:

const OSS = require('ali-oss')
const accessKeyId = '**********'
const accessKeySecret = '**********'
async function checkBucketAcl(region, bucket) {
  const client = new OSS({
    region: `oss-${region}`,
    accessKeyId,
    accessKeySecret
  })
  const result = await client.getBucketACL(bucket)
  if (result.acl !== 'private') {
    await client.putBucketACL(bucket, 'private')
  }
}
exports.handler = async (event, context, callback) => {
  const alert = JSON.parse(event.toString())
  for (const result of alert.fire_results) {
    const { region, bucket } = result
    await checkBucketAcl(region, bucket)
  }
  callback(null, '')
}      

2. 開通OSS操作審計日志

打開日志服務控制台,進入日志審計服務,開啟OSS通路日志。

SLS告警響應更新——通知對接FC進行自動化操作
SLS告警響應更新——通知對接FC進行自動化操作

3. 建立告警

在操作審計日志裡,我們可以看到,建立 Bucket 或者修改 Bucket ACL 會記錄如下日志:

SLS告警響應更新——通知對接FC進行自動化操作

是以我們可以通過如下查詢分析語句篩選出 Bucket 的地域和名稱:

event.ServiceName: Oss and  event.eventName: PutBucket | select "event.acsRegion" as region, split("event.eventSource", '.')[1] as bucket      

然後建立告警:

SLS告警響應更新——通知對接FC進行自動化操作

4. 事件觸發

我們将 Bucket 的 ACL 修改為公共讀:

SLS告警響應更新——通知對接FC進行自動化操作

然後會發現有一條告警觸發:

SLS告警響應更新——通知對接FC進行自動化操作

FC的函數調用日志可以看到調用記錄:

SLS告警響應更新——通知對接FC進行自動化操作

再回到 OSS 看,Bucket 的 ACL 已經是私有:

SLS告警響應更新——通知對接FC進行自動化操作

進一步參考

對我們工作感興趣的,可以通過如下方式了解更多,謝謝關注!

SLS告警響應更新——通知對接FC進行自動化操作