如何解决AWS Step Functions和Fargate任务:容器运行时错误不会导致管道失败
我有一个在AWS Step Functions中定义的管道。一步定义为Fargate Task,它会提取一个docker映像并运行一些python代码。我惊讶地发现,如果在Fargate任务中运行的容器遇到运行时错误,则Step Functions不会捕获失败的任务,并照常继续运行管道(将Fargate任务设置为成功),但是根据{{3} }一旦发生这种情况,管道就会失败。
这是步进函数定义:
{
"Comment": "My state machine","StartAt": "MyFargateTask","States": {
"MyFargateTask": {
"Type": "Task","Resource": "arn:aws:states:::ecs:runTask.sync","InputPath": "$","Parameters": {
"Cluster": "my-cluster","TaskDefinition": "arn:aws:ecs:us-east-1:617090640476:task-definition/my-task:1","LaunchType": "FARGATE","NetworkConfiguration": {
"AwsvpcConfiguration": {
"Subnets": [
"subnet-xxxxxxxxxxxxxxxxx","subnet-yyyyyyyyyyyyyyyyy"
],"AssignPublicIp": "ENABLED"
}
},},"Next": "Done"
},"Done": {
"Type": "Succeed"
}
}
}
我为Fargate容器尝试了以下简单的python代码:
def main():
raise Exception("foobar")
if __name__ == '__main__':
main()
在CloudWatch的容器日志中,我可以看到程序按预期失败,但是“步进功能”中的管道成功执行(所有绿色)。 我想念什么?这是错误吗?
解决方法
AWS Step Functions不知道ECS作业是成功还是失败。步骤功能将需要查看ECS作业的容器日志,并尝试确定Docker容器内运行的进程是否以失败代码退出。那不是Step Functions要做的。配置完成后,Step Functions仅假定只要容器存在,任务就成功完成。
如果您将arn:aws:states:::ecs:runTask.sync
更改为arn:aws:states:::ecs:runTask.waitForTaskToken
,则Step Fuctions不仅会等待ECS容器退出,还将等待ECS容器将成功或失败代码发送回Step Functions API 。您还需要将任务令牌传递到ECS容器中,这可以通过ContainerOverrides
设置来完成,如下所示:
{
"Comment": "My state machine","StartAt": "MyFargateTask","States": {
"MyFargateTask": {
"Type": "Task","Resource": "arn:aws:states:::ecs:runTask.waitForTaskToken","InputPath": "$","Parameters": {
"Cluster": "my-cluster","TaskDefinition": "arn:aws:ecs:us-east-1:617090640476:task-definition/my-task:1","LaunchType": "FARGATE","NetworkConfiguration": {
"AwsvpcConfiguration": {
"Subnets": [
"subnet-xxxxxxxxxxxxxxxxx","subnet-yyyyyyyyyyyyyyyyy"
],"AssignPublicIp": "ENABLED"
}
},"Overrides": {
"ContainerOverrides": [{
"Environment": [{
"Name": "TASK_TOKEN","Value.$": "$$.Task.Token"
}]
}]
}
},"Next": "Done"
},"Done": {
"Type": "Succeed"
}
}
}
现在,在Python脚本中,您可以获取TASK_TOKEN
环境变量,并向步骤函数发出成功或失败消息,如下所示:
token = os.environ['TASK_TOKEN']
def step_success():
if token is not None:
stfn = boto3.client('stepfunctions')
stfn.send_task_success(taskToken=token,output='{"Status": "Success"}')
def step_fail():
if token is not None:
stfn = boto3.client('stepfunctions')
stfn.send_task_failure(taskToken=token,error="An error occurred")
我还建议您在状态机中配置超时,以防您的Python脚本无法在容器或其他内容中执行。另外,您需要向Fargate任务的IAM角色添加适当的IAM权限,以使其能够将这些状态调用发回到Step Functions API。
,我认为使用 arn:aws:states::ecs:runTask.sync 会使您的 stepfunction 失败,因为 ECS 将显示容器状态已停止并且详细消息为“任务中的基本容器已退出"
如果您使用 arn:aws:states::ecs:runTask(没有 .syn)stepfunction 将不会关心 ECS 并且会导致成功。
根据您的情况,您应该使用 arn:aws:states::ecs:runTask.waitForTaskToken 并使用 StepFunction 提供的令牌发送 sendTaskSuccess 或 sendTaskFailure
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。