Actualización II
Ahora es el 16 de julio de 2015 y las cosas han vuelto a cambiar. Descubrí este contenedor automágico de Jason Wilder :
https://github.com/jwilder/nginx-proxy
y resuelve este problema en el tiempo que llevadocker run
el contenedor. Esta es ahora la solución que estoy usando para resolver este problema.
Actualizar
Ahora es julio de 2015 y las cosas han cambiado drásticamente con respecto a la red de contenedores Docker. En la actualidad, hay muchas ofertas diferentes que resuelven este problema (de diversas formas).
Debe usar esta publicación para obtener una comprensión básica del
docker --link
enfoque para el descubrimiento de servicios, que es tan básico como parece, funciona muy bien y, en realidad, requiere menos bailes elegantes que la mayoría de las otras soluciones. Tiene la limitación de que es bastante difícil conectar contenedores en red en hosts separados en un clúster determinado, y los contenedores no se pueden reiniciar una vez conectados en red, pero ofrece una forma rápida y relativamente fácil de conectar contenedores en red en el mismo host. Es una buena manera de tener una idea de lo que está haciendo bajo el capó el software que probablemente usará para resolver este problema.Además, probablemente también querrá ver los
network
nuevos Docker , Hashicorp'sconsul
, Weaveworksweave
, Jeff Lindsay'sprogrium/consul
&gliderlabs/registrator
, y Google'sKubernetes
.Hay también los CoreOS ofertas que utilizan
etcd
,fleet
yflannel
.Y si realmente quieres tener una fiesta, puedes armar un grupo para ejecutar
Mesosphere
, oDeis
, oFlynn
.Si eres nuevo en el mundo de las redes (como yo), entonces deberías sacar tus lentes para leer, poner "Paint The Sky With Stars - The Best of Enya" en el Wi-Hi-Fi y tomar una cerveza. Va a ser un tiempo antes de que realmente comprenda exactamente qué es lo que está tratando de hacer. Sugerencia: está intentando implementar un
Service Discovery Layer
en suCluster Control Plane
. Es una forma muy bonita de pasar la noche del sábado.Es muy divertido, pero desearía haberme tomado el tiempo para educarme mejor sobre las redes en general antes de sumergirme de lleno. Finalmente encontré un par de publicaciones de los benevolentes dioses del Tutorial Digital Ocean:
Introduction to Networking Terminology
yUnderstanding ... Networking
. Sugiero leerlos un par de veces antes de sumergirnos.¡Que te diviertas!
Publicación original
Parece que no puedo comprender la asignación de puertos para Docker
contenedores. Específicamente cómo pasar solicitudes de Nginx a otro contenedor, escuchando en otro puerto, en el mismo servidor.
Tengo un Dockerfile para un contenedor Nginx como este:
FROM ubuntu:14.04
MAINTAINER Me <[email protected]>
RUN apt-get update && apt-get install -y htop git nginx
ADD sites-enabled/api.myapp.com /etc/nginx/sites-enabled/api.myapp.com
ADD sites-enabled/app.myapp.com /etc/nginx/sites-enabled/app.myapp.com
ADD nginx.conf /etc/nginx/nginx.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["service", "nginx", "start"]
Y luego el api.myapp.com
archivo de configuración se ve así:
upstream api_upstream{
server 0.0.0.0:3333;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.mypp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
Y luego otro para app.myapp.com
también.
Y luego corro:
sudo docker run -p 80:80 -p 443:443 -d --name Nginx myusername/nginx
Y todo está bien, pero las solicitudes no se transfieren a los otros contenedores / puertos. Y cuando entro al contenedor de Nginx e inspecciono los registros, no veo errores.
¿Alguna ayuda?
Respuestas:
La respuesta de @ T0xicCode es correcta, pero pensé que ampliaría los detalles, ya que en realidad me tomó alrededor de 20 horas implementar finalmente una solución funcional.
Si está buscando ejecutar Nginx en su propio contenedor y usarlo como un proxy inverso para equilibrar la carga de varias aplicaciones en la misma instancia de servidor, los pasos que debe seguir son los siguientes:
Vincula tus contenedores
Cuando utiliza
docker run
sus contenedores, generalmente ingresando un script de shellUser Data
, puede declarar enlaces a cualquier otro contenedor en ejecución . Esto significa que debe iniciar sus contenedores en orden y solo los últimos contenedores pueden vincularse a los primeros. Al igual que:Entonces, en este ejemplo, el
API
contenedor no está vinculado a ningún otro, pero elApp
contenedor está vinculadoAPI
yNginx
está vinculado a ambosAPI
yApp
.El resultado de esto son cambios en las
env
vars y los/etc/hosts
archivos que residen dentro de los contenedoresAPI
yApp
. Los resultados se ven así:/ etc / hosts
Ejecutar
cat /etc/hosts
dentro de suNginx
contenedor producirá lo siguiente:ENV Vars
Ejecutar
env
dentro de suNginx
contenedor producirá lo siguiente:He truncado muchas de las variables reales, pero los anteriores son los valores clave que necesita para el tráfico proxy a sus contenedores.
Para obtener un shell para ejecutar los comandos anteriores dentro de un contenedor en ejecución, use lo siguiente:
sudo docker exec -i -t Nginx bash
Puede ver que ahora tiene
/etc/hosts
entradas de archivo yenv
variables que contienen la dirección IP local para cualquiera de los contenedores que estaban vinculados. Por lo que puedo decir, esto es todo lo que sucede cuando ejecuta contenedores con opciones de enlace declaradas. Pero ahora puede usar esta información para configurarnginx
dentro de suNginx
contenedor.Configurando Nginx
Aquí es donde se pone un poco complicado y hay un par de opciones. Puede elegir configurar sus sitios para que apunten a una entrada en el
/etc/hosts
archivo quedocker
creó, o puede utilizar lasENV
vars y ejecutar un reemplazo de cadena (yo usésed
) en sunginx.conf
y cualquier otro archivo conf que pueda estar en su/etc/nginx/sites-enabled
carpeta para insertar la IP valores.OPCIÓN A: Configurar Nginx usando ENV Vars
La diferencia clave entre esta opción y el uso de la
/etc/hosts
opción de archivo es cómo escribe suDockerfile
para usar un script de shell comoCMD
argumento, que a su vez maneja el reemplazo de la cadena para copiar los valores de IPENV
a sus archivos conf.Aquí está el conjunto de archivos de configuración con los que terminé:
Dockerfile
nginx.conf
api.myapp.conf
Nginx-Startup.sh
Dejaré que usted haga su tarea sobre la mayoría de los contenidos de
nginx.conf
yapi.myapp.conf
.La magia ocurre
Nginx-Startup.sh
cuando usamossed
para hacer el reemplazo de cadenas en elAPP_IP
marcador de posición que hemos escrito en elupstream
bloque de nuestros archivosapi.myapp.conf
yapp.myapp.conf
.Esta pregunta de ask.ubuntu.com lo explica muy bien: busque y reemplace texto dentro de un archivo usando comandos
Entonces, Docker ha lanzado nuestro contenedor y ha activado la
Nginx-Startup.sh
secuencia de comandos para que se ejecute, que ha utilizadosed
para cambiar el valorAPP_IP
a laENV
variable correspondiente que proporcionamos en elsed
comando. Ahora tenemos archivos conf dentro de nuestro/etc/nginx/sites-enabled
directorio que tienen las direcciones IP de lasENV
vars que Docker configuró al iniciar el contenedor. Dentro de suapi.myapp.conf
archivo, verá que elupstream
bloque ha cambiado a esto:La dirección IP que ve puede ser diferente, pero he notado que normalmente lo es
172.0.0.x
.Ahora debería tener todo enrutado correctamente.
OPCIÓN B: Usar
/etc/hosts
entradas de archivoEsta debería ser la forma más rápida y fácil de hacer esto, pero no pude hacer que funcione. Aparentemente, solo
/etc/hosts
ingresó el valor de la entrada en sus archivosapi.myapp.conf
yapp.myapp.conf
, pero no pude hacer que este método funcione.Aquí está el intento que hice en
api.myapp.conf
:Teniendo en cuenta que hay una entrada en mi
/etc/hosts
archivo como esa:172.0.0.2 API
pensé que solo obtendría el valor, pero no parece serlo.También tuve un par de problemas auxiliares con mi
Elastic Load Balancer
abastecimiento de todas las AZ, por lo que ese pudo haber sido el problema cuando probé esta ruta. En su lugar, tuve que aprender a manejar la sustitución de cadenas en Linux, así que fue divertido. Lo intentaré en un momento y veré cómo funciona.fuente
Intenté usar el popular proxy inverso de Jason Wilder que funciona mágicamente para todos, y aprendí que no funciona para todos (es decir, yo). Y soy nuevo en NGINX, y no me gustó que no entendiera las tecnologías que estaba tratando de usar.
Quería agregar mis 2 centavos, porque la discusión anterior sobre los
linking
contenedores juntos ahora está fechada ya que es una característica obsoleta. Así que aquí hay una explicación sobre cómo hacerlo usandonetworks
. Esta respuesta es un ejemplo completo de cómo configurar nginx como un proxy inverso para un sitio web paginado estáticamente usando unaDocker Compose
configuración de nginx.TL; DR;
Agregue los servicios que necesitan comunicarse entre sí en una red predefinida. Para una discusión paso a paso sobre las redes Docker, aprendí algunas cosas aquí: https://technologyconversations.com/2016/04/25/docker-networking-and-dns-the-good-the-bad-and- el feo/
Definir la red
En primer lugar, necesitamos una red en la que todos sus servicios de backend puedan hablar. Llamé al mío
web
pero puede ser lo que quieras.Crea la aplicación
Simplemente haremos una aplicación de sitio web simple. El sitio web es una página index.html simple servida por un contenedor nginx. El contenido es un volumen montado en el host en una carpeta.
content
DockerFile:
default.conf
docker-compose.yml
Tenga en cuenta que aquí ya no necesitamos mapeo de puertos. Simplemente exponemos el puerto 80. Esto es útil para evitar colisiones de puertos.
Ejecute la aplicación
Encienda este sitio web con
Algunas comprobaciones divertidas con respecto a las asignaciones de dns para su contenedor:
Este ping debería funcionar, dentro de su contenedor.
Construye el Proxy
Proxy inverso de Nginx:
Dockerfile
Reiniciamos toda la configuración del host virtual, ya que la vamos a personalizar.
docker-compose.yml
Ejecutar el proxy
Encienda el proxy usando nuestro confiable
Suponiendo que no haya problemas, entonces tiene dos contenedores en ejecución que pueden comunicarse entre sí usando sus nombres. Probémoslo.
Configurar host virtual
El último detalle es configurar el archivo de alojamiento virtual para que el proxy pueda dirigir el tráfico en función de cómo desee configurar su coincidencia:
sample-site.conf para nuestra configuración de alojamiento virtual:
Según cómo se configuró el proxy, necesitará este archivo almacenado en su
conf.d
carpeta local que montamos a través de lavolumes
declaración en eldocker-compose
archivo.Por último, pero no menos importante, dígale a nginx que vuelva a cargar su configuración.
Esta secuencia de pasos es la culminación de horas de fuertes dolores de cabeza mientras luchaba con el siempre doloroso error 502 Bad Gateway y aprendí nginx por primera vez, ya que la mayor parte de mi experiencia fue con Apache.
Esta respuesta es para demostrar cómo eliminar el error 502 Bad Gateway que resulta de que los contenedores no pueden comunicarse entre sí.
Espero que esta respuesta le ahorre a alguien horas de dolor, ya que lograr que los contenedores se hablen entre sí fue realmente difícil de entender por alguna razón, a pesar de ser lo que esperaba que fuera un caso de uso obvio. Pero, de nuevo, soy tonto. Y hágame saber cómo puedo mejorar este enfoque.
fuente
502 Gateway Error
, un clásico infame en estos días. Gracias @gdbj por perder el tiempo para avanzar en la conversación y brindar una solución tan detallada.Con los enlaces de la ventana acoplable , puede vincular el contenedor ascendente al contenedor nginx. Una característica adicional es que la ventana acoplable administra el archivo de host, lo que significa que podrá hacer referencia al contenedor vinculado usando un nombre en lugar de la IP potencialmente aleatoria.
fuente
Se puede hacer que la "Opción B" de AJB funcione usando la imagen base de Ubuntu y configurando nginx por su cuenta. (No funcionó cuando usé la imagen de Nginx de Docker Hub).
Aquí está el archivo de Docker que utilicé:
Mi configuración de nginx (también conocida como: conf / mysite.com):
Y finalmente, cómo comienzo mis contenedores:
Esto me puso en funcionamiento, por lo que mi nginx apuntó el flujo ascendente al segundo contenedor de la ventana acoplable que expuso el puerto 3000.
fuente
upstream website {
define el valor del sitio web para nginx. Eso es lo que luego usa en suproxy_pass
. La parte de la ventana acoplable de esto solo usa el mismo nombre por coherencia, pero no tiene nada que ver con la configuración de nginx. Para que quede un poco más claro, el pase de proxy debe leer:upstream website { server localhost:3000; }
La respuesta de @ gdbj es una gran explicación y la respuesta más actualizada. Sin embargo, aquí hay un enfoque más simple.
Entonces, si desea redirigir todo el tráfico de nginx que escucha
80
a otro contenedor que expone8080
, la configuración mínima puede ser tan pequeña como:nginx.conf:
docker-compose.yml
Docker docs
fuente
Acabo de encontrar un artículo de Anand Mani Sankar que muestra una forma sencilla de usar el proxy ascendente de nginx con docker composer.
Básicamente, uno debe configurar el enlace de instancias y los puertos en el archivo docker-compose y actualizar en sentido ascendente en nginx.conf.
fuente
links
que están en desuso. Utilice las redes ahora: docs.docker.com/engine/userguide/networking