Estoy tratando de implementar una aplicación de matraz de Python con gunicorn y nginx. Estoy tratando de ejecutar tanto gunicorn (wsgi) como nginx en el mismo contenedor. Pero mi nginx no se inicia. Al iniciar sesión en el contenedor, puedo iniciar nginx. A continuación se muestra mi dockerfile
RUN apt-get clean && apt-get -y update RUN apt-get -y install \ nginx \ python3-dev \ curl \ vim \ build-essential \ procps WORKDIR /app COPY requirements.txt /app/requirements.txt COPY nginx-conf /etc/nginx/sites-available/default RUN pip install -r requirements.txt --src /usr/local/src COPY . . EXPOSE 8000 EXPOSE 80 CMD ["bash" , "server.sh"]
El archivo server.sh parece
# turn on bash's job control set -m gunicorn --bind :8000 --workers 3 wsgi:app service nginx start or /etc/init.d/nginx
gunicorn se inicia con server.sh pero nginx no se inicia.
Mi objetivo es luego ejecutar estos contenedores en kubernetes. ¿Debería i) ejecutar nginx y gunicorn en un pod separado o ii) ejecutarlo en el mismo pod con un contenedor separado o iii) ejecutarlo en el mismo contenedor en el mismo pod?
Acerca de elegir cómo dividir contenedores entre pods, eso realmente depende del caso de uso. Si hablan entre ellos pero realizan tareas separadas, iría con dos contenedores y una cápsula.
Además, sobre su archivo server.sh, la razón por la que gunicorn se inicia pero nginx no es que gunicorn no se ejecuta en modo daemon de forma predeterminada. Si ejecuta gunicorn --help
a ver esto:
-D, --daemon Daemonize the Gunicorn process. [False]
Sigo pensando que es mejor separar los contenedores, pero si quieres que funcione, cámbialo a esto:
# turn on bash's job control set -m gunicorn --bind :8000 --workers 3 wsgi:app -D service nginx start or /etc/init.d/nginx
Para responder a su pregunta sobre Kubernetes:
Depende de lo que quieras hacer.
Los contenedores dentro del mismo Pod comparten el mismo espacio de nombres de red , lo que significa que 2 contenedores en el mismo Pod pueden comunicarse entre sí contactando a localhost
. Esto significa que sus paquetes nunca se envían y la comunicación siempre será posible.
Si los divide en pods separados, querrá crear un objeto de servicio y dejar que se comuniquen a través de ese objeto de servicio. Tenerlos en dos Pods le permite escalarlos hacia arriba y hacia abajo individualmente y, en general, le brinda más opciones para configurarlos individualmente, por ejemplo, configurando diferentes tipos de mecanismos de seguridad.
La opción que elija depende de su arquitectura y de lo que desee lograr. Tener dos contenedores en el mismo Pod generalmente solo se logra cuando sigue un patrón "Sidecar", lo que básicamente significa que hay un contenedor "principal" que hace el trabajo y los demás en el Pod simplemente ayudan al contenedor "principal" y no tienen razón alguna para existir por sí mismos.
Mi objetivo es luego ejecutar estos contenedores en kubernetes. ¿Debería i) ejecutar tanto nginx como gunicorn en un módulo separado?
Si esto. Esto es muy sencillo de configurar (considerando los archivos YAML con docenas de líneas "sencillas"): escriba un servicio de implementación y coincidencia (tipo ClusterIP) para el backend de GUnicorn, y luego escriba una implementación y coincidencia separadas (NodePort- o LoadBalancer). -type) Servicio para el proxy Nginx. En la configuración de Nginx, use una directiva proxy_pass
que apunte al nombre del servicio GUnicorn como el nombre de host del backend.
Hay un par de ventajas al hacer esto. Si el servicio de Python falla por cualquier motivo, tampoco es necesario que reinicie el proxy Nginx. Si está manejando suficiente carga que necesita escalar la aplicación, puede ejecutar una cantidad mínima de proxies Nginx livianos (quizás 3 para redundancia) con una mayor cantidad de backends según la carga. Si actualiza la aplicación, Kubernetes eliminará y volverá a crear los pods gestionados por implementación por usted y, nuevamente, usar una implementación separada para los proxies y backends significa que no tendrá que reiniciar los proxies si solo cambia el código de la aplicación.
Entonces, para abordar la primera parte de la pregunta:
Estoy tratando de implementar una aplicación de matraz de Python con gunicorn y nginx.
En Docker simple, por razones similares, puede ejecutar dos contenedores separados. Puede administrar esto en Docker Compose, que tiene un diseño de archivo YAML mucho más simple; se vería algo como
version: '3.8' services: backend: build: . # Dockerfile just installs GUnicorn, CMD starts it proxy: image: nginx volumes: - ./nginx-conf:/etc/nginx/conf.d # could build a custom image too # configuration specifies `proxy_pass http://backend:8000` ports: - '8888:80'
Esto evita todos los problemas de tratar de ejecutar varios procesos en el mismo contenedor. Puede simplificar el Dockerfile que muestra:
# Dockerfile FROM python:3.9 RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --assume-yes \ python3-dev \ build-essential # (don't install irrelevant packages like vim or procps) WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 8000 # (don't need a shell script wrapper) CMD gunicorn --bind :8000 --workers 3 wsgi:app