Azure DevOps流水线执行成功却因容器退出被标记失败的解决咨询
解决Azure DevOps流水线因初始化容器退出标记失败的问题
我的Azure DevOps流水线拉取Docker镜像并创建5个容器,其中一个初始化容器(airflow-airflow-init-1)完成其他4个容器的配置后退出,这是正常的成功状态,但Azure Pipelines却因该容器的Exited状态将流水线标记为失败。
尝试过添加continueOnError: true,但只能将流水线标记为警告;使用condition: succeededOrFailed(),流水线依然会被标记为失败。
日志示例
2024-07-01T14:47:08.8069778Z ##[error] Container airflow-postgres-1 Healthy 2024-07-01T14:47:08.8073598Z ##[error] Container airflow-postgres-1 Healthy 2024-07-01T14:47:08.8075304Z ##[error] Container airflow-redis-1 Healthy 2024-07-01T14:47:18.3181399Z ##[error] Container airflow-airflow-init-1 Exited Container airflow-airflow-init-1 Exited Container airflow-airflow-init-1 Exited
现有流水线片段
- task: SSH@0 inputs: sshEndpoint: $(SSH_SERVICE_CONNECTION) runOptions: 'inline' inline: | az login --identity az acr login --name $(IMAGE_REGISTRY) cd $(PROJECT_DIR) export AIRFLOW_UID=$(AIRFLOW_UID) export PROJECT_DIR=$(PROJECT_DIR) docker pull $(IMAGE_REGISTRY).azurecr.io/$(IMAGE_NAME):latest docker compose -f docker-compose.prod.yaml up -d continueOnError: true
解决方案
方法1:以关键服务健康状态为判断依据
修改流水线脚本,忽略容器退出状态,转而检查需要持续运行的服务是否健康:
- task: SSH@0 inputs: sshEndpoint: $(SSH_SERVICE_CONNECTION) runOptions: 'inline' inline: | az login --identity az acr login --name $(IMAGE_REGISTRY) cd $(PROJECT_DIR) export AIRFLOW_UID=$(AIRFLOW_UID) export PROJECT_DIR=$(PROJECT_DIR) docker pull $(IMAGE_REGISTRY).azurecr.io/$(IMAGE_NAME):latest docker compose -f docker-compose.prod.yaml up -d # 等待Postgres服务健康 until docker inspect --format='{{.State.Health.Status}}' airflow-postgres-1 | grep -q "healthy"; do sleep 5 done # 等待Redis服务健康 until docker inspect --format='{{.State.Health.Status}}' airflow-redis-1 | grep -q "healthy"; do sleep 5 done
方法2:分离初始化容器与常驻服务
- 在
docker-compose.prod.yaml中给初始化容器配置一次性运行策略:
services: airflow-init: image: $(IMAGE_REGISTRY).azurecr.io/$(IMAGE_NAME):latest restart: "no" command: # 你的初始化命令 depends_on: - postgres - redis
- 修改流水线脚本,先单独运行初始化容器,再启动常驻服务:
- task: SSH@0 inputs: sshEndpoint: $(SSH_SERVICE_CONNECTION) runOptions: 'inline' inline: | az login --identity az acr login --name $(IMAGE_REGISTRY) cd $(PROJECT_DIR) export AIRFLOW_UID=$(AIRFLOW_UID) export PROJECT_DIR=$(PROJECT_DIR) docker pull $(IMAGE_REGISTRY).azurecr.io/$(IMAGE_NAME):latest # 运行初始化容器,完成后自动删除 docker compose -f docker-compose.prod.yaml run --rm airflow-init # 启动需要持续运行的服务 docker compose -f docker-compose.prod.yaml up -d postgres redis
方法3:强制返回成功状态码
在脚本末尾添加exit 0,覆盖容器退出带来的错误码(需确保初始化逻辑确实执行成功):
- task: SSH@0 inputs: sshEndpoint: $(SSH_SERVICE_CONNECTION) runOptions: 'inline' inline: | az login --identity az acr login --name $(IMAGE_REGISTRY) cd $(PROJECT_DIR) export AIRFLOW_UID=$(AIRFLOW_UID) export PROJECT_DIR=$(PROJECT_DIR) docker pull $(IMAGE_REGISTRY).azurecr.io/$(IMAGE_NAME):latest docker compose -f docker-compose.prod.yaml up -d # 强制返回成功状态 exit 0
内容的提问来源于stack exchange,提问作者dimButTries
相关产品推荐
相关产品推荐

