Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

227
Visualizações
El contenedor de API de Cloud Run Flask que ejecuta shutit entra en un ciclo de suspensión

El problema apareció recientemente y el contenedor que antes estaba en buen estado ahora entra en un ciclo de suspensión cuando se crea una sesión de cierre. El problema ocurre solo en Cloud Run y no localmente.

Código mínimo reproducible:

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}"

registros de ejecución en la nube que se repiten:

 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

Soluciones alternativas probadas:

  • Diferentes regiones: algunas europeas (nivel 1 y 2), Asia, EE. UU.
  • Construir con ventana acoplable en lugar de kaniko
  • CPU y memoria diferentes asignadas al contenedor
  • Número mínimo de contenedores 1-5 (para garantizar que la CPU siempre se asigne al contenedor)
  • --no-cpu-throttling tampoco hizo ninguna diferencia
  • Número máximo de contenedores 1-30
  • Diferente proyecto GCP
  • Diferentes imágenes base de Docker (3.5-3.9 + varios shas que van desde hace un año hasta los recientes)
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

No es un reemplazo perfecto, pero puede usar uno de los siguientes en su lugar:

No estoy seguro de cuál es el panorama general, así que agregaré varias opciones

Para las tareas de automatización remota desde un servidor web de Flass, estamos usando paramiko por su simplicidad y configuración rápida, aunque es posible que prefiera algo como pyinfra para proyectos grandes o subprocess para tareas locales pequeñas.

  1. Paramiko : un poco más práctico \ manual que shutit , ejecuta comandos sobre el protocolo ssh.

ejemplo:

 import paramiko ip='server ip' port=22 # you can also use ssh keys username='username' password='password' cmd='some useful command' ssh=paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip,port,username,password) stdin,stdout,stderr=ssh.exec_command(cmd) outlines=stdout.readlines() resp=''.join(outlines) print(resp)

más ejemplos

  1. pyinfra - ansible como biblioteca para automatizar tareas en estilo ad-hoc

ejemplo para instalar un paquete usando apt:

 from pyinfra.operations import apt apt.packages( name='Ensure iftop is installed', packages=['iftop'], sudo=True, update=True, )
  1. subproceso - como Paramiko no tan extenso como shutit pero funciona de maravilla
over 4 years ago · Santiago Trujillo Relatório

0

He reproducido su problema y hemos discutido varias posibilidades, creo que el problema es que su Cloud Run no puede procesar solicitudes y, por lo tanto, se prepara para cerrar (sigterm). Estoy enumerando algunas posibilidades para que mires y analices.

  • Una buena razón por la que su servicio Cloud Run no se inicia es que el proceso del servidor dentro del contenedor está configurado para escuchar en la dirección localhost (127.0.0.1). Esto hace referencia a la interfaz de red de bucle invertido, a la que no se puede acceder desde fuera del contenedor y, por lo tanto, no se puede realizar la comprobación de estado de Cloud Run, lo que provoca el error de implementación del servicio. Para resolver esto, configure su aplicación para iniciar el servidor HTTP para escuchar en todas las interfaces de red, comúnmente indicadas como 0.0.0.0.

  • Mientras buscaba el error de registros en la nube que está recibiendo, encontré esta respuesta y un enlace de GitHub del desarrollador de la biblioteca de shutit que apunta a una técnica para rastrear entradas y salidas en compilaciones de contenedores complejos en sesiones de shutit. Un buen hallazgo del enlace de GitHub, creo que tendrá que pasar session_type en shutit.create_session('bash') o shutit.create_session('docker') que no está especificando en el archivo main.py. Esa puede ser la razón por la que su sesión de cierre está fallando.

  • Además, este problema podría deberse a alguna característica del kernel de Linux utilizada por esta biblioteca shutit que actualmente no se admite correctamente en gVisor . No estoy seguro de cómo se ejecutó para ti la primera vez. La mayoría de las aplicaciones funcionarán bien, o al menos tan bien como en Docker normal, pero es posible que no brinden una compatibilidad del 100 %.

    Las aplicaciones de Cloud Run se ejecutan en el entorno de pruebas del contenedor gVisor (que actualmente solo es compatible con Linux), que ejecuta las llamadas al sistema del kernel de Linux realizadas por su aplicación en el espacio de usuario. gVisor no implementa todas las llamadas al sistema (ver aquí ). Desde este enlace de Github , “Si su aplicación tiene una llamada de sistema de este tipo (bastante raro), no funcionará en Cloud Run. Dicho evento se registra y puede usar strace para determinar cuándo se realizó la llamada al sistema en su aplicación”

    Si está ejecutando su código en Linux, instale y habilite strace: sudo apt-get install strace Ejecute su aplicación con strace anteponiendo su invocación habitual con strace -f donde -f significa rastrear todos los subprocesos secundarios. Por ejemplo, si normalmente invoca su aplicación con ./main , puede ejecutarla con strace invocando /usr/bin/strace -f ./main

    De esta documentación , “si cree que su problema se debe a una limitación en el entorno de pruebas de Container. En la sección Cloud Logging de GCP Console (no en la pestaña "Registros" de la sección Cloud Run), puede buscar Container Sandbox con una gravedad DEBUG en los registros varlog/system o usar Log Query:

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

Por ejemplo: Container Sandbox: llamada al sistema no admitida
setockopt(0x3,0x1,0x6,0xc0000753d0,0x4,0x0)”

De forma predeterminada, las instancias de contenedor tienen las instancias mínimas desactivadas, con una configuración de 0. Podemos cambiar este valor predeterminado mediante Cloud Console, la línea de comando de gcloud o un archivo YAML, especificando una cantidad mínima de instancias de contenedor para mantenerlas activas. y listo para atender solicitudes.

También puede echar un vistazo a esta documentación y GitHub Link que habla sobre el comportamiento del tiempo de ejecución del contenedor de Cloud Run y la resolución de problemas como referencia.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda