Python 在 CircleCI 工作流程中,进程从不在 Docker 容器中退出

Python process never exits in Docker container during CircleCI workflow

我有一个 Dockerfile 看起来像这样:

FROM python:3.6

WORKDIR /app
ADD . /app/

# Install system requirements
RUN apt-get update && \
    xargs -a requirements_apt.txt apt-get install -y

# Install Python requirements
RUN python -m pip install --upgrade pip
RUN python -m pip install -r requirements_pip.txt

# Circle CI ignores entrypoints by default
ENTRYPOINT ["dostuff"]

我有一个 CircleCI 配置:

version: 2.1


orbs:
  aws-ecr: circleci/aws-ecr@6.15.3


jobs:
  benchmark_tests_dev:
    docker:
      - image: blah_blah_image:test_dev
        #auth
    steps:
      - checkout
      - run:
          name: Compile and run benchmarks
          command: make bench

workflows:
  workflow_test_and_deploy_dev:
    jobs:
      - aws-ecr/build-and-push-image:
          name: build_test_dev
          context: my_context
          account-url: AWS_ECR_ACCOUNT_URL
          region: AWS_REGION
          repo: my_repo
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          dockerfile: Dockerfile
          tag: test_dev
          filters:
            branches:
              only: my-test-branch
      - benchmark_tests_dev:
          requires: [build_test_dev]
          context: my_context
          filters:
            branches:
              only: my-test-branch
      - aws-ecr/build-and-push-image:
          name: deploy_dev
          requires: [benchmark_tests_dev]
          context: my_context
          account-url: AWS_ECR_ACCOUNT_URL
          region: AWS_REGION
          repo: my_repo
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          dockerfile: Dockerfile
          tag: test2
          filters:
            branches:
              only: my-test-branch

make bench 看起来像:

bench:
        python tests/benchmarks/bench_1.py
        python tests/benchmarks/bench_2.py

两个基准测试都遵循这种模式:

# imports

# define constants

# Define functions/classes

if __name__ == "__main__":
    # Run those tests

如果我在本地 my-test-branch 上构建我的 Docker 容器,覆盖入口点以进入它的内部,并从容器内部 运行 make bench,两者 Python 脚本完美执行并退出。

如果我提交到同一个分支并触发 CircleCI 工作流,bench_1.py 运行s 然后永远不会退出。我试过在 make 命令中切换 Python 脚本的顺序。在那种情况下,bench_2.py 运行s 然后永远不会退出。我已经尝试在两个脚本的 if __name__ == "__main__": 块的末尾放置一个 sys.exit() 并且不会强制退出 CircleCI。我的第一个脚本 运行 将 运行 完成,因为我在整个脚本中放置了日志以跟踪进度。它永远不会退出。

知道为什么这些脚本会 运行 并在本地容器中退出但不在 CircleCI 上的容器中退出吗?

编辑

我刚刚意识到“永不退出”是我的假设。脚本可能退出但 CircleCI 作业在那之后静静地挂起?重点是脚本 运行s,完成,CircleCI 作业继续 运行,直到我在 10 分钟时收到超时错误 (Too long with no output (exceeded 10m0s): context deadline exceeded)。

原来我们使用的 snowflake.connector Python 库有 this issue where if an error occurs during an open Snowflake connection, the connection is not properly closed and the process hangs. There is also another issue 记录了该库中的某些错误,但没有提出,导致第一个问题悄无声息地发生。

我更新了我们的雪花 IO 处理程序以明确 open/close 每个 read/execute 的连接,这样就不会发生这种情况。现在我的脚本 运行 在 CircleCI 的容器中就好了。我仍然不知道为什么它们 运行 在本地容器中而不是远程容器中,但我将把它留给开发运营之神。