对于私有化部署服务,如果部署模板中包含执行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
来实现。