在多臺實例內批量執行命令。
背景
阿里云的客戶遠程在ECS內部執行命令是最常見的運維操作之一了,比如在ECS內安裝卸載軟件,啟動停止某個進程,等等。很多情況下,還需要對一個ECS列表中的多臺ECS,統一的執行某個相同的命令并匯聚執行的結果。
具體比如說對于業務應用,我們通過批量下放相關命令,可實現滾動升級更新運行時(Runtime)和執行代碼(Code),這樣能極大提高部署的可靠性。
一個可行的方案是利用SSH遠程連接到ECS上執行命令,但是開放ECS的SSH端口給internet訪問是危險的。客戶可以通過自建跳板機來間接訪問ECS以解決安全性的問題,但是這帶來了復雜度和成本的上升。
Ansible是業界比較流行的開源的運維工具,但是其認證是獨立于阿里云的賬號體系之外的,無法通過阿里云的官方工具進行權限控制,其操作記錄也無法在阿里云上進行審計。
如果用戶使用的是Windows版本的ECS,雖然可以利用PowerShell遠程執行命令,但配置和維護過程或許更加困難。
在此,我們向大家推薦阿里云官方的批量在多臺ECS內執行命令的最佳實踐:系統運維管理+云助手。云助手提供了在ECS內執行命令的原子能力,系統運維管理 OOS(CloudOps Orchestration Service)則附加了更豐富的批量、定時、事件驅動、自定義模板等特性,兩者結合,可以讓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控制臺執行。
了解更多
系統運維管理 OOS(CloudOps Orchestration Service)OOS是阿里云的運維自動化平臺,適用于批量、定時、事件驅動、跨區域運維等場景,除了在ECS內執行命令外,還可以完成ECS創建釋放,啟停,變配,網絡帶寬升級,掛載云盤等等各種操作。如果想了解更多,加入釘釘群“系統運維管理 OOS(CloudOps Orchestration Service)OOS支持群”,群號23330931。我們會有值班人員在線支持。
OOS管理控制臺的鏈接:https://oos.console.aliyun.com