在多台執行個體內批量執行命令。
背景
阿里雲的客戶遠程在ECS內部執行命令是最常見的營運操作之一了,比如在ECS內安裝卸載軟體,啟動停止某個進程,等等。很多情況下,還需要對一個ECS列表中的多台ECS,統一的執行某個相同的命令並匯聚執行的結果。
具體比如說對於業務應用,我們通過批量下放相關命令,可實現滾動升級更新執行時(Runtime)和執行代碼(Code),這樣能極大提高部署的可靠性。
一個可行的方案是利用SSH遠端連線到ECS上執行命令,但是開放ECS的SSH連接埠給internet訪問是危險的。客戶可以通過自建跳板機來間接訪問ECS以解決安全性的問題,但是這帶來了複雜度和成本的上升。
Ansible是業界比較流行的開源的營運工具,但是其認證是獨立於阿里雲的帳號體系之外的,無法通過阿里雲的官方工具進行許可權控制,其操作記錄也無法在阿里雲上進行審計。
如果使用者使用的是Windows版本的ECS,雖然可以利用PowerShell遠程執行命令,但配置和維護過程或許更加困難。
在此,我們向大家推薦阿里雲官方的批量在多台ECS內執行命令的最佳實務:CloudOps Orchestration Service+雲助手。雲助手提供了在ECS內執行命令的原子能力,CloudOps Orchestration Service (OOS)則附加了更豐富的批量、定時、事件驅動、自訂模板等特性,兩者結合,可以讓ECS營運工作變得既安全又簡單高效。
準備工作
請確保在本地終端,您已安裝並配置了阿里雲命令列工具CLI,且版本號碼大於等於3.0.19。阿里雲命令列工具CLI的GitHub下載連結為GitHub;快速配置指南請參見互動式配置(快速配置)。
開始執行
我們直接先看一個例子,如要針對cn-beijing地區的["i-id45678zxcvb","i-id45679zxcvb"]這兩台遠程Linux ECS,執行“echo 123”這個Shell命令,只需要在本地的Shell終端裡,輸入命令:
aliyun oos StartExecution --region cn-hangzhou --TemplateName ACS-ECS-BulkyRunCommand --Parameters '{"commandType":"RunShellScript", "commandContent":"echo 123", "targets":{"Type":"ResourceIds", "ResourceIds":["i-id45678zxcvb","i-id45679zxcvb"]}, "rateControl":{"maxErrors":0,"mode":"Concurrency"}, "OOSAssumeRole":"" }'
簡單解釋一下上面這個命令,它調用了oos的StartExecution的API,啟動官方提供的公用模板ACS-ECS-BulkyRunCommand,傳入包含了ECS執行個體列表(ResourceIds)和執行內容(commandContent)的參數。該命令會返回一個JSON結構,如果您能找到"ExecutionId":"exec-xxxxx",那麼恭喜您,被指定的命令已經開始在遠程執行了。請記錄下ExecutionId,然後作為參數輸入到下面的ListExecutions命令查詢執行的過程和結果:
aliyun oos ListExecutions --region cn-hangzhou --ExecutionId "exec-id123456zxcvb"
如果命令正在運行中,您會看到類似如下的結果,Status是“Running”。TotalTasks是總的命令數,SuccessTasks是已經執行成功的命令數。兩個數位差,就是還待執行的命令數。
{
"Execution": {
"Outputs": {},
"TemplateName": "ACS-ECS-BulkyRunCommand",
"Parameters": {
"commandType": "RunShellScript",
"OOSAssumeRole": "",
"rateControl": {
"maxErrors": 0,
"mode": "Concurrency"
},
"targets": {
"ResourceIds": [
"i-id45678zxcvb","i-id45679zxcvb"
],
"Type": "ResourceIds"
},
"commandContent": "echo 123"
},
"Counters": {
"Failed": 0,
"Success": 0,
"Total": 0
},
"ExecutedBy": "aliyun-account1",
"LoopMode": "Automatic",
"Mode": "Automatic",
"TemplateId": "t-123456zxcvb",
"Status": "Running",
"TemplateVersion": "v2",
"SafetyCheck": "Skip",
"StartDate": "2019-10-15T07:22:03Z",
"ExecutionId": "exec-id123456zxcvb",
"CurrentTasks": []
},
"RequestId": "1A9B1817-0530-470C-8640-BADADADB220BD"
}
您可以多次執行同樣的ListExecutions命令進行查看,直到看到Outputs表示整個命令的結果,對於本例,為兩台ECS上的標準輸出:
進階-自訂模板
在上面的例子裡,命令的參數有點過於複雜,其實我可以自訂模板把參數固定下來,讓執行的命令變得格外簡單。自訂模板的命令如下,您可以根據自己的需要進行改寫:
aliyun oos CreateTemplate --region cn-hangzhou --TemplateName sample123 --Content '{
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Name": "runCommand",
"Action": "ACS::ECS::RunCommand",
"Properties": {
"commandContent": "echo 1234",
"instanceId": "{{ ACS::TaskLoopItem }}",
"commandType": "RunShellScript"
},
"Loop": {
"Items": ["i-id45678zxcvb","i-id45679zxcvb"],
"Outputs": {
"commandOutputs": {
"AggregateType": "Fn::ListJoin",
"AggregateField": "commandOutput"
}
}
},
"Outputs": {
"commandOutput": {
"Type": "String",
"ValueSelector": "invocationOutput"
}
}
}
],
"Outputs": {
"commandOutputs": {
"Type": "List",
"Value": "{{ runCommand.commandOutputs }}"
}
}
}'
執行建立自訂模版命令後,您只需要執行如下命令就可以完成和前面一樣的效果了。
aliyun oos StartExecution --region cn-hangzhou --TemplateName sample123 --Parameters '{}'
此命令調用oos的StartExecution這個API,執行sample123這個自訂模板,不需要額外傳入參數。當然,前面用CLI所做的一切操作,都可以在OOS控制台執行。
瞭解更多
CloudOps Orchestration Service (OOS)OOS是阿里雲的營運自動化平台,適用於批量、定時、事件驅動、跨地區營運等情境,除了在ECS內執行命令外,還可以完成ECS建立釋放,啟停,變更配置,網路頻寬升級,掛載雲端硬碟等等各種操作。如果想瞭解更多,加入DingTalk群“CloudOps Orchestration Service (OOS)OOS支援群”,群號23330931。我們會有值班人員線上支援。
OOS管理主控台的連結:https://oos.console.aliyun.com