對于私有化部署服務,如果部署模板中包含執行Shell腳本的步驟,您需要考慮腳本執行失敗時,如何進行調試。由于腳本是在用戶的ECS實例內執行,服務商難以登錄機器排查。因此,有必要在編寫腳本時就增加調試信息的輸出。只有獲取到問題的根本原因后,服務商才能夠通過發布新服務版本來修復問題。本文介紹在編寫部署模板時如何編寫更易調試的Shell腳本的詳細信息。
提升方法
1. 使用Command
不使用UserData
Command
相比UserData
有以下好處:
使用
Command
時,可以通過API查詢到Command
的Output
信息,更容易定位和排查問題。計算巢的服務部署成功率分析功能,支持展示部署失敗服務實例中命令的輸出。
Command
失敗后,可以通過繼續部署重復執行來修復問題;UserData
是在創建ECS實例時執行,因此無法通過繼續部署來重復執行。
編輯服務部署模板時,若是ROS模板中建議使用ALIYUN::ECS::RunCommand資源類型;若是Terraform模板,則建議使用alicloud_ecs_command和alicloud_ecs_invocation。
2. 在腳本中增加前置檢查
如果腳本有明確的安裝依賴或者環境要求,請在腳本最前部進行檢查,檢查不通過時,將錯誤信息輸出到stdout
。
3. 將調用信息輸出到stdout
腳本中可以增加調用輸出(stdout
、stderr
等),腳本輸出會作為云助手命令的CommandOutput
。
您可以通過以下方法增加調用輸出。
啟用Bash的
-v
選項,在腳本前面增加set -v
。啟用此選項后,會打印出讀取到的每一行命令,從而可以準確定位出錯的位置和出錯的命令行。您也可以通過
set -v
(開啟)和set +v
(關閉)的組合,使其只在部分區域啟用。重要設置輸出信息時,請不要輸出用戶的敏感信息包括用戶的AK、密碼等。
示例腳本
#! /bin/bash read -p "Enter the input: " val zero_val=0 if [ "$val" -gt "$zero_val" ] then echo "Positive number entered." else echo "The input value is not positive." fi
bash -v .
/positive_check.sh
執行輸出#! /bin/bash read -p "Enter the input: " val Enter the input: -10 zero_val=0 if [ "$val" -gt "$zero_val" ] then echo "Positive number entered." else echo "The input value is not positive." fi The input value is not positive.
啟用Bash的
-x
選項。重要bash的
-x
選項請謹慎開啟,尤其是當變量中存在敏感信息的時候,不能打印用戶的AK或者密碼,否則會引起泄密。使用
-x
選項啟動Bash時,會在執行命令之前打印出命令及展開后的參數,此選項對調試腳本很有幫助。您還可以通過set -x
(開啟)和set +x
(關閉)的組合,只在部分區域啟用。$ cat test3.sh !/bin/bash set -x echo "hello World" mkdiir testing $ ./test3.sh + echo 'hello World' hello World + mkdiir testing ./test3.sh: line 4: mkdiir: command not found
通過
echo
和tee
將日志打印到stdout
。通過
echo
打印日志,再通過tee
將重要指令的輸出內容轉發到stdout
。自有二進制文件輸出清晰報錯信息。
如果安裝過程需要執行服務商自有的二進制文件,請確保二進制文件能夠給出清晰的報錯信息,便于定位問題。
屏蔽過多的無效輸出。
云助手的
CommandOutput
有最大限制,超過限制后的輸出內容會被截斷。因此如果部分命令產生大量的輸出,對診斷用處不大,可以將其標準輸出重定向到/dev/null
中。
4. 通過ROS信號通知機制傳遞錯誤原因和錯誤信息
如果部署模板是ROS原生格式,支持通過ROS信號通信機制將腳本中的錯誤原因和錯誤信息發送給ROS,最終服務商和用戶都可以從服務實例的狀態信息中查看到這個信息。
Terraform模板不支持此功能。
${CurlCli} -d "{\"reason\" : \"用戶可見的錯誤原因\",\"data\" : \"其他診斷相關信息\", \"status\" : \"FAILURE\"}"
腳本中能識別用戶側的錯誤時,可用過該方式返回錯誤信息,便于用戶查看和定位,否則用戶將看到沒有任何可讀性的錯誤信息(如Signal 1 received
)不利于定位問題。
5. 提高命令成功率
使用如下方法可以提高命令的成功率。
盡量不依賴公網下載,通過VPC內網下載會提高成功率和安全性。
盡量不依賴可變數據。如從公網下載一個隨時會變化的安裝腳本。更新可能會破壞安裝腳本的穩定性。
盡量采用鏡像方式交付靜態部分。只有動態部分采用
Command
實現。如預先在自定義鏡像中安裝好數據庫,數據庫啟動后的配置由Command
來實現。