gpt4 book ai didi

python - 运行 shutdown 的 Cloud Run Flask API 容器进入休眠循环

转载 作者:行者123 更新时间:2023-12-04 11:56:27 24 4
gpt4 key购买 nike

这个问题最近出现了,以前健康的容器现在在创建关闭 session 时进入休眠循环。该问题仅发生在 Cloud Run 上,而不发生在本地。
最小可重现代码:requirements.txt

Flask==2.0.1
gunicorn==20.1.0
shutit
Dockerfile
FROM python:3.9

# Allow statements and log messages to immediately appear in the Cloud Run logs
ENV PYTHONUNBUFFERED True

COPY requirements.txt ./
RUN pip install -r requirements.txt

# Copy local code to the container image.
ENV APP_HOME /myapp
WORKDIR $APP_HOME
COPY . ./

CMD exec gunicorn \
--bind :$PORT \
--worker-class "sync" \
--workers 1 \
--threads 1 \
--timeout 0 \
main:app
main.py
import os
import shutit
from flask import Flask, request

app = Flask(__name__)

# just to prove api works
@app.route('/ping', methods=['GET'])
def ping():
os.system('echo pong')
return 'OK'

# issue replication
@app.route('/healthcheck', methods=['GET'])
def healthcheck():
os.system("echo 'healthcheck'")
# hangs inside create_session
shell = shutit.create_session(echo=True, loglevel='debug')
# never shell.send reached
shell.send('echo Hello World', echo=True)
# never returned
return 'OK'

if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=True)
cloudbuild.yaml
steps:
- id: "build_container"
name: "gcr.io/kaniko-project/executor:latest"
args:
- --destination=gcr.io/$PROJECT_ID/borked-service-debug:latest
- --cache=true
- --cache-ttl=99h
- id: "configure infrastructure"
name: "gcr.io/cloud-builders/gcloud"
entrypoint: "bash"
args:
- "-c"
- |
set -euxo pipefail

REGION="europe-west1"
CLOUD_RUN_SERVICE="borked-service-debug"

SA_NAME="$${CLOUD_RUN_SERVICE}@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud beta run deploy $${CLOUD_RUN_SERVICE} \
--service-account "$${SA_NAME}" \
--image gcr.io/${PROJECT_ID}/$${CLOUD_RUN_SERVICE}:latest \
--allow-unauthenticated \
--platform managed \
--concurrency 1 \
--max-instances 10 \
--timeout 1000s \
--cpu 1 \
--memory=1Gi \
--region "$${REGION}"

循环运行的云运行日志:
Setting up prompt
In session: host_child, trying to send: export PS1_ORIGIN_ENV=$PS1 && PS1='OR''IGIN_ENV:rkkfQQ2y# ' && PROMPT_COMMAND='sleep .05||sleep 1'
================================================================================
Sending>>> export PS1_ORIGIN_ENV=$PS1 && PS1='OR''IGIN_ENV:rkkfQQ2y# ' && PROMPT_COMMAND='sleep .05||sleep 1'<<<, expecting>>>['\r\nORIGIN_ENV:rkkfQQ2y# ']<<<
Sending in pexpect session (68242035994000): export PS1_ORIGIN_ENV=$PS1 && PS1='OR''IGIN_ENV:rkkfQQ2y# ' && PROMPT_COMMAND='sleep .05||sleep 1'
Expecting: ['\r\nORIGIN_ENV:rkkfQQ2y# ']
export PS1_ORIGIN_ENV=$PS1 && PS1='OR''IGIN_ENV:rkkfQQ2y# ' && PROMPT_COMMAND='sleep .05||sleep 1'
root@localhost:/myapp# export PS1_ORIGIN_ENV=$PS1 && PS1='OR''IGIN_ENV:rkkfQQ2y# ' && PROMPT_COMMAND='sleep .05||sleep 1'
Stopped sleep .05
Stopped sleep 1
pexpect: buffer: b'' before: b'cm9vdEBsb2NhbGhvc3Q6L3B1YnN1YiMgIGV4cx' after: b'DQpPUklHSU5fRU5WOnJra2ZRUTJ5IyA='
Resetting default expect to: ORIGIN_ENV:rkkfQQ2y#
In session: host_child, trying to send: stty cols 65535
================================================================================
Sending>>> stty cols 65535<<<, expecting>>>ORIGIN_ENV:rkkfQQ2y# <<<
Sending in pexpect session (68242035994000): stty cols 65535
Expecting: ORIGIN_ENV:rkkfQQ2y#
ORIGIN_ENV:rkkfQQ2y# stty cols 65535
stty cols 65535
Stopped stty cols 65535
Stopped sleep .05
Stopped sleep 1
尝试的解决方法:
  • 不同地区:一些欧洲(1 级和 2 级)、亚洲、美国。
  • 使用 docker 而不是 kaniko 构建
  • 分配给容器的 CPU 和内存不同
  • Minimum number of containers 1-5 (to ensure CPU is always allocated to the container)
  • --no-cpu-throttling也没什么区别
  • 最大容器数 1-30
  • 不同的 GCP 项目
  • 不同的 Docker 基础镜像(3.5-3.9 + 从一年前到最近的各种 shas)
  • 最佳答案

    我已经重现了您的问题,我们已经讨论了几种可能性,我认为问题是您的 Cloud Run 无法处理请求,因此准备关闭(sigterm)。
    我列出了一些可能性供您查看和分析。

  • 您的 Cloud Run 服务无法启动的一个很好的原因是
    容器内的服务器进程配置为监听
    本地主机 (127.0.0.1) 地址。这是指环回网络
    无法从容器外部访问的接口(interface)和
    因此无法执行 Cloud Run 运行状况检查,导致
    服务部署失败。要解决此问题,请配置您的应用程序
    启动 HTTP 服务器以监听所有网络接口(interface),
    通常表示为 0.0.0.0。
  • 在搜索您遇到的云日志错误时,我来了
    穿过这个answerGitHub link从关闭图书馆
    开发人员指出跟踪输入和输出的技术
    在关闭 session 中构建的复杂容器中。一个很好的发现
    从 GitHub 链接,我认为你必须通过 session_type
    shutit.create_session(‘bash’)shutit.create_session(‘docker’)您没有在 main.py 文件中指定。那可以是
    关闭 session 失败的原因。
  • 此外,此问题可能是由于某些 Linux 内核功能导致的
    这个shutit库目前在
    gVisor .我不确定它是如何为你执行的
    时间。大多数应用程序都可以正常运行,或者至少可以正常运行
    Docker,但可能无法提供 100% 的兼容性。
    Cloud Run 应用程序在 gVisor 容器沙箱(支持
    目前仅适用于 Linux),它执行 Linux 内核系统调用
    通过您在用户空间中的应用程序。 gVisor 没有实现所有
    系统调用(见 here)。从这里 Github link , “如果你的
    应用程序有这样的系统调用(很少见),它在云上不起作用
    跑。这样的事件是logged你可以使用 strace
    确定何时在您的应用程序中进行系统调用”
    如果您在 Linux 上运行代码,请安装并启用 strace:sudo apt-get install strace使用 strace 运行您的应用程序
    用 strace -f 开始你通常的调用,其中 -f 意味着
    跟踪所有子线程。例如,如果您通常调用
    申请与 ./main ,您可以通过调用 /usr/bin/strace -f ./main 使用 strace 运行它
    从这里 documentation , “如果您觉得您的问题是由
    容器沙箱中的限制。在 Cloud Logging 部分
    GCP Console 的(不在 Cloud Run 部分的“日志”选项卡中),
    你可以找Container SandboxDEBUG严重程度在varlog/system日志或使用日志查询:

  • resource.type="cloud_run_revision"
    logName="projects/PROJECT_ID/logs/run.googleapis.com%2Fvarlog%2Fsystem"

    For example: Container Sandbox: Unsupported syscall
    setsockopt(0x3,0x1,0x6,0xc0000753d0,0x4,0x0)”


    默认情况下,容器实例的 min-instances 关闭,设置为 0。我们可以使用 Cloud Console、gcloud 命令行或 YAML 文件更改此默认值,方法是指定要保温的最小容器实例数并准备好处理请求。
    你也可以看看这个 documentationGitHub Link其中讨论了 Cloud Run 容器运行时行为和故障排除以供引用。

    关于python - 运行 shutdown 的 Cloud Run Flask API 容器进入休眠循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69265924/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com