Moby: No se puede recuperar la dirección IP del usuario en el modo de enjambre de la ventana acoplable

Creado en 9 ago. 2016  ·  324Comentarios  ·  Fuente: moby/moby

Salida de docker version :

Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 22:00:36 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 22:00:36 2016
 OS/Arch:      linux/amd64

Salida de docker info :

Containers: 155
 Running: 65
 Paused: 0
 Stopped: 90
Images: 57
Server Version: 1.12.0
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 868
 Dirperm1 Supported: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host overlay null bridge
Swarm: active
 NodeID: 0ddz27v59pwh2g5rr1k32d9bv
 Is Manager: true
 ClusterID: 32c5sn0lgxoq9gsl1er0aucsr
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot interval: 10000
  Heartbeat tick: 1
  Election tick: 3
 Dispatcher:
  Heartbeat period: 5 seconds
 CA configuration:
  Expiry duration: 3 months
 Node Address: 172.31.24.209
Runtimes: runc
Default Runtime: runc
Security Options: apparmor
Kernel Version: 3.13.0-92-generic
Operating System: Ubuntu 14.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.42 GiB
Name: ip-172-31-24-209
ID: 4LDN:RTAI:5KG5:KHR2:RD4D:MV5P:DEXQ:G5RE:AZBQ:OPQJ:N4DK:WCQQ
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: panj
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Insecure Registries:
 127.0.0.0/8

Detalles adicionales del entorno (AWS, VirtualBox, físico, etc.):

Pasos para reproducir el problema:

  1. ejecutar el siguiente servicio que publica el puerto 80
docker service create \
--name debugging-simple-server \
--publish 80:3000 \
panj/debugging-simple-server
  1. Intente conectarse con http://<public-ip>/ .

Describe los resultados que recibiste:
Ni ip ni header.x-forwarded-for son la dirección IP correcta del usuario.

Describe los resultados que esperabas:
ip o header.x-forwarded-for debe ser la dirección IP del usuario. El resultado esperado se puede archivar utilizando el contenedor de ventana acoplable independiente docker run -d -p 80:3000 panj/debugging-simple-server . Puede ver ambos resultados a través de los siguientes enlaces,
http://swarm.issue-25526.docker.takemetour.com : 81 /
http://container.issue-25526.docker.takemetour.com : 82 /

Información adicional que considere importante (por ejemplo, el problema ocurre solo ocasionalmente):
Esto sucede tanto en el modo global modo replicated .

No estoy seguro si me perdí algo que debería resolver este problema fácilmente.

Mientras tanto, creo que tengo que hacer una solución que consiste en ejecutar un contenedor proxy fuera del modo enjambre y dejar que se reenvíe al puerto publicado en modo enjambre (la terminación SSL también debe realizarse en este contenedor), lo que rompe el propósito de enjambre modo de autocuración y orquestación.

arenetworking areswarm kinenhancement statuneeds-attention versio1.12

Comentario más útil

También me encontré con el problema al intentar ejecutar logstash en modo enjambre (para recopilar mensajes de syslog de varios hosts). El campo "host" de logstash siempre aparece como 10.255.0.x, en lugar de la IP real del host que se conecta. Esto lo hace totalmente inutilizable, ya que no puede saber de qué host provienen los mensajes de registro. ¿Hay alguna forma de evitar la traducción de la IP de origen?

Todos 324 comentarios

/ cc @aluzzardi @mrjana preguntó

@PanJ , ¿puede compartir algunos detalles sobre cómo debugging-simple-server determina el ip ? Además, ¿cuál es la expectativa si un servicio se escala a más de 1 réplica en varios hosts (o en modo global)?

@mavenugo es el objeto de solicitud de koa que usa el módulo remoteAddress del nodo net . El resultado debería ser el mismo para cualquier otra biblioteca que pueda recuperar direcciones remotas.

La expectativa es que el campo ip siempre sea una dirección remota independientemente de cualquier configuración.

@PanJ, ¿todavía usa su solución alternativa o encontró una solución mejor?

@PanJ Cuando ejecuto tu aplicación como un contenedor independiente ...

docker run -it --rm -p 80:3000 --name test panj/debugging-simple-server

y accedo al puerto publicado desde otro host obtengo esto

vagrant@net-1:~$ curl 192.168.33.12
{"method":"GET","url":"/","header":{"user-agent":"curl/7.38.0","host":"192.168.33.12","accept":"*/*"},"ip":"::ffff:192.168.33.11","ips":[]}
vagrant@net-1:~$

192.168.33.11 es la IP del host en el que estoy ejecutando curl. ¿Es este el comportamiento esperado?

@sanimej Sí, es el comportamiento esperado el que también debería estar en modo enjambre.

@marech Todavía estoy usando el contenedor independiente como solución, que funciona bien.

En mi caso, hay 2 intances nginx, instancias independientes y enjambre. La terminación SSL y el proxy inverso se realizan en nginx independiente. La instancia de Swarm se utiliza para enrutar a otros servicios según el host de la solicitud.

@PanJ La forma en que se accede al puerto publicado de un contenedor es diferente en el modo de enjambre. En el modo de enjambre, se puede acceder a un servicio desde cualquier nodo del clúster. Para facilitar esto, enrutamos a través de una red ingress . 10.255.0.x es la dirección de la interfaz de red ingress en el host del clúster desde el que intenta llegar al puerto publicado.

@sanimej Vi cómo funciona cuando

Tengo un conocimiento limitado sobre cómo se debe implementar la solución. ¿Quizás un tipo especial de red que no altera la dirección IP de origen?

Rancher es similar al modo de enjambre de Docker y parece tener el comportamiento esperado. Quizás sea un buen lugar para comenzar.

@sanimej, una buena idea podría ser agregar todas las direcciones IP al encabezado X-Fordered-For si es posible, entonces podemos ver toda la cadena.

@PanJ hmm, ¿y cómo se comunica su contenedor independiente nignx con la instancia del enjambre, a través del nombre del servicio o la dirección IP? Tal vez pueda compartir la parte de configuración de nginx donde la pasa a la instancia del enjambre.

El contenedor independiente 80 y luego hace proxy a localhost:8181

server {
  listen 80 default_server;
  location / {
    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_pass          http://localhost:8181;
    proxy_read_timeout  90;
  }
}

Si tiene que hacer la terminación SSL, agregue otro bloque de servidor que escuche el puerto 443 , luego haga la terminación SSL y los proxy a localhost:8181 también

El nginx del modo Swarm publica 8181:80 y se enruta a otro servicio según el host de la solicitud.

server {
  listen 80;
  server_name your.domain.com;
  location / {
    proxy_pass          http://your-service:80;
    proxy_set_header Host $host;
    proxy_read_timeout  90;
  }
}

server {
  listen 80;
  server_name another.domain.com;
  location / {
    proxy_pass          http://another-service:80;
    proxy_set_header Host $host;
    proxy_read_timeout  90;
  }
}

En nuestro caso, nuestra API RateLimit y otras funciones dependen de la dirección IP del usuario. ¿Hay alguna forma de evitar el problema en el modo de enjambre?

También me encontré con el problema al intentar ejecutar logstash en modo enjambre (para recopilar mensajes de syslog de varios hosts). El campo "host" de logstash siempre aparece como 10.255.0.x, en lugar de la IP real del host que se conecta. Esto lo hace totalmente inutilizable, ya que no puede saber de qué host provienen los mensajes de registro. ¿Hay alguna forma de evitar la traducción de la IP de origen?

+1 para obtener una solución a este problema.

Sin la capacidad de recuperar la IP del usuario, no podemos usar soluciones de monitoreo como Prometheus.

Quizás las capacidades IPVS del kernel de Linux sean de alguna utilidad aquí. Supongo que el cambio de IP se está produciendo porque las conexiones se están transfiriendo en el espacio de usuario. IPVS, por otro lado, puede redirigir y equilibrar la carga de las solicitudes en el espacio del kernel sin cambiar la dirección IP de origen. IPVS también podría ser bueno en el futuro para incorporar funcionalidades más avanzadas, como diferentes algoritmos de equilibrio de carga, direcciones IP flotantes y enrutamiento directo.

Para mí, sería suficiente si pudiera averiguar de alguna manera la relación entre la IP virtual y la IP del servidor al que pertenece el punto final. De esa forma, cuando Prometheus envía una alerta relacionada con alguna IP virtual, pude averiguar cuál es el servidor afectado. No sería una buena solución pero sería mejor que nada.

@vfarcic No creo que eso sea posible con la forma en que funciona ahora. Todas las conexiones de cliente provienen de la misma IP, por lo que no puede traducirlo. La única forma en que funcionaría es si lo que sea que esté haciendo el proxy / nat de las conexiones guardara un registro de conexión con la marca de tiempo, la dirección IP de origen y el puerto de origen. Incluso entonces, no sería de mucha ayuda en la mayoría de los casos de uso donde se necesita la IP de origen.

Probablemente no expliqué bien el caso de uso.

Utilizo Prometheus que está configurado para descartar exportadores que se ejecutan como servicios globales Swarm. Utiliza tareas.para obtener las direcciones IP de todas las réplicas. Por lo tanto, no está utilizando el servicio, sino los puntos finales de réplica (sin equilibrio de carga). Lo que necesitaría es averiguar de alguna manera la IP del nodo de donde proviene cada una de esas IP de réplica.

Me acabo de dar cuenta de que el "Docker Network Inspect"proporciona información sobre contenedores y direcciones IPv4 de un solo nodo. ¿Puede extenderse para que haya una información de todo el clúster de una red junto con los nodos?

Algo como:

       "Containers": {
            "57bc4f3d826d4955deb32c3b71550473e55139a86bef7d5e584786a3a5fa6f37": {
                "Name": "cadvisor.0.8d1s6qb63xdir22xyhrcjhgsa",
                "EndpointID": "084a032fcd404ae1b51f33f07ffb2df9c1f9ec18276d2f414c2b453fc8e85576",
                "MacAddress": "02:42:0a:00:00:1e",
                "IPv4Address": "10.0.0.30/24",
                "IPv6Address": "",
                "Node": "swarm-4"
            },
...

Tenga en cuenta la adición del "Nodo".

Si dicha información estuviera disponible para todo el clúster, no solo un único nodo con la adición de un argumento --filter , tendría todo lo que necesitaría para averiguar la relación entre una dirección IPv4 de contenedor y la nodo. No sería una gran solución, pero es mejor que nada. En este momento, cuando Prometheus detecta un problema, necesito ejecutar una "inspección de red de la ventana acoplable" en cada nodo hasta que averigüe la ubicación de la dirección.

Estoy de acuerdo con @dack , dado que la red de entrada usa IPVS, deberíamos resolver este problema usando IPVS para que la IP de origen se conserve y se presente al servicio de manera correcta y transparente.

La solución debe funcionar a nivel de IP para que cualquier servicio que no esté basado en HTTP también pueda funcionar correctamente (No se puede confiar en los encabezados http ...).

Y no puedo enfatizar lo importante que es esto, sin él, hay muchos servicios que simplemente no pueden operar en modo enjambre.

@kobolog podría arrojar algo de luz sobre este asunto dada su charla sobre IPVS en DockerCon.

Solo me agrego a la lista. Estoy usando logstash para aceptar mensajes de syslog, y todos se envían a elasticsearch con la IP del host configurada en 10.255.0.4, lo que lo hace inutilizable, y tendré que volver a mi implementación de logstash no en contenedores. si no hay solución para esto.

@mrjana, ¿ puede agregar la sugerencia que tenía para solucionar este problema?

IPVS no es un proxy inverso del espacio de usuario que puede arreglar cosas en la capa HTTP. Esa es la diferencia entre un proxy de espacio de usuario como HAProxy y este. Si desea utilizar HAProxy, puede hacerlo colocando un HAProxy en el clúster y hacer que todas sus instancias de servicio y HAProxy participen en la misma red. De esa manera, HAProxy puede arreglar HTTP header.x-forwarded-for . O si el equilibrador de carga L7 es externo al clúster, puede usar la próxima función (en 1.13) para un nuevo PublishMode llamado Host PublishMode que expondrá cada una de las instancias individuales del servicio en su propio puerto individual y puede apuntar su balanceador de carga externo a eso.

@mrjana La idea de usar IPVS (en lugar de lo que sea que hace actualmente la ventana acoplable en modo enjambre) sería evitar la traducción de la IP de origen para empezar. Agregar un X-Fordered-For podría ayudar para algunas aplicaciones HTTP, pero no sirve de nada para todas las demás aplicaciones que están dañadas por el comportamiento actual.

@dack, según tengo entendido, la red de entrada de Docker ya usa IPVS.

Si desea utilizar HAProxy, puede hacerlo colocando un HAProxy en el clúster y hacer que todas sus instancias de servicio y HAProxy participen en la misma red. De esa manera, HAProxy puede arreglar el encabezado HTTP.x-reenviado-para

Eso tampoco funcionaría @mrjana , la única forma de que HAProxy obtenga la IP del cliente es ejecutarse fuera de la red de entrada usando Docker Run o directamente en el host, pero luego no puede usar ninguno de sus servicios ya que están en una red diferente y no puede acceder a ellos.

En pocas palabras, hasta donde yo sé, no hay absolutamente ninguna manera de lidiar con esto tan pronto como use los servicios de la ventana acoplable y el modo enjambre.

Sería interesante si los autores de la red de entrada de la ventana acoplable pudieran unirse a la discusión, ya que probablemente tendrían una idea de cómo se configura / opera IPVS bajo el capó (hay muchos modos para IPVS) y cómo podemos solucionarlo. la cuestión.

@tlvenn ¿Sabes dónde está esto en el código fuente? Podría estar equivocado, pero no creo que esté usando IPVS en función de algunas cosas que he observado:

  • El puerto de origen está traducido (todo el motivo de este problema). IPVS no hace esto. Incluso en modo NAT, solo traduce la dirección de destino. Debe utilizar la ruta predeterminada o el enrutamiento de políticas para enviar paquetes de retorno al host IPVS.
  • Cuando un puerto se publica en modo enjambre, todas las instancias de dockerd en el enjambre escuchan en el puerto publicado. Si se usara IPVS, sucedería en el espacio del kernel y dockerd no estaría escuchando en el puerto.

Hola @dack ,

De su blog:

Internamente, hacemos que esto funcione utilizando Linux IPVS, un equilibrador de carga multiprotocolo de capa 4 en el kernel que ha estado en el kernel de Linux durante más de 15 años. Con los paquetes de enrutamiento IPVS dentro del kernel, la malla de enrutamiento de swarm ofrece un equilibrio de carga de alto rendimiento consciente del contenedor.

El código fuente debería vivir en el proyecto swarmkit si no me equivoco.

Me pregunto si @stevvooe puede ayudarnos a comprender cuál es el problema subyacente aquí.

Bien, he echado un vistazo breve al código y creo que ahora lo entiendo un poco mejor. De hecho, parece estar utilizando IPVS como se indica en el blog. SNAT se realiza mediante una regla de iptables que se configura en service_linux.go. Si lo entiendo correctamente, la lógica detrás de esto sería algo como esto (asumiendo que el nodo A recibe un paquete de cliente para el servicio que se ejecuta en el nodo B):

  • El nodo A del enjambre recibe el paquete del cliente. Traducciones de IPVS / iptables (src ip) -> (nodo a ip) y (dst ip) -> (nodo B ip)
  • El paquete se reenvía al nodo B
  • El nodo B envía su respuesta al nodo A (ya que eso es lo que ve como la ip src)
  • El nodo A traduce src y dst a los valores originales y reenvía la respuesta al cliente.

Creo que el razonamiento detrás del SNAT es que la respuesta debe pasar por el mismo nodo por el que llegó la solicitud original (ya que ahí es donde se almacena el estado de NAT / IPVS). Como las solicitudes pueden llegar a través de cualquier nodo, el SNAT se utiliza para que el nodo de servicio sepa por qué nodo enrutar la solicitud de regreso. En una configuración de IPVS con un solo nodo de equilibrio de carga, eso no sería un problema.

Entonces, la pregunta es cómo evitar el SNAT y al mismo tiempo permitir que todos los nodos manejen las solicitudes entrantes de los clientes. No estoy totalmente seguro de cuál es el mejor enfoque. Tal vez haya una manera de tener una tabla de estado en el nodo de servicio para que pueda usar el enrutamiento de políticas para dirigir las respuestas en lugar de depender de SNAT. O tal vez algún tipo de encapsulación podría ayudar (¿VXLAN?). O podría utilizarse el método de enrutamiento directo de IPVS. Esto permitiría al nodo de servicio responder directamente al cliente (en lugar de hacerlo a través del nodo que recibió la solicitud original) y permitiría agregar nuevas IP flotantes para los servicios. Sin embargo, también significaría que el servicio solo puede contactarse a través de la IP flotante y no de las IP de los nodos individuales (no estoy seguro si eso es un problema para cualquier caso de uso).

¡Descubrimiento bastante interesante @dack !

Con suerte, se encontrará una solución para omitir ese SNAT por completo.

Mientras tanto, tal vez haya una solución alternativa que se ha comprometido no hace mucho tiempo que introduce una publicación de puertos a nivel de host con PublishMode , evitando efectivamente la red de entrada.

https://github.com/docker/swarmkit/pull/1645

Hola, gracias por la gran cantidad de comentarios. Analizaremos en profundidad este problema después del fin de semana.

Mientras tanto, algo de información:

@tlvenn : @mrjana es el autor principal detrás de la función de red de entrada. La fuente vive principalmente en docker / libnetwork, algunas en SwarmKit

@dack : de hecho, está respaldado por IPVS

@tlvenn , hasta donde yo sé, Docker Swarm usa el enmascaramiento, ya que es la forma más sencilla y está garantizada para funcionar en la mayoría de las configuraciones. Además, este es el único modo que realmente permite enmascarar puertos también [re: @dack], lo cual es útil. En teoría, este problema podría resolverse utilizando el modo de encapsulación IPIP; el flujo de paquetes será así:

  • Un paquete llega al servidor de puerta de enlace, en nuestro caso cualquier nodo del enjambre, y el IPVS en ese nodo determina que, de hecho, es un paquete para un servicio virtual, en función de su dirección IP y puerto de destino.
  • El paquete se encapsula en otro paquete IP y se envía al servidor real que se eligió según el algoritmo de equilibrio de carga.
  • El servidor real recibe el paquete adjunto, lo desencapsula y ve la IP real del cliente como fuente y la IP del servicio virtual como destino. Se supone que todos los servidores reales tienen un alias de interfaz que no es ARPable con la IP del servicio virtual para que asuman que este paquete está realmente destinado a ellos.
  • El servidor real procesa el paquete y envía la respuesta al cliente directamente. La IP de origen en este caso será la IP del servicio virtual , por lo que no hay respuestas marcianas involucradas, lo cual es bueno.

Por supuesto, hay muchas advertencias y cosas que pueden salir mal, pero en general esto es posible y el modo IPIP se usa ampliamente en producción.

Espero que pronto se pueda encontrar una solución para esto, ya que la fijación de IP y otras comprobaciones de seguridad deben poder recibir la IP externa correcta.

Mirando. Nuestro producto aprovecha la información de IP de origen para fines de seguridad y análisis.

@aluzzardi ¿ alguna actualización para nosotros?

bump, necesitamos que esto funcione para un proyecto muy grande que comenzaremos a principios del próximo año.

Al examinar el flujo, parece que actualmente funciona así (en este ejemplo, el nodo A recibe el tráfico entrante y el nodo B está ejecutando el contenedor de servicios):

  • El nodo A realiza DNAT para dirigir el paquete al espacio de nombres de la red ingress_sbox (/ var / run / docker / netns / ingress_sbox)
  • ingress_sbox en el nodo A ejecuta IPVS en modo NAT, que realiza DNAT para dirigir el paquete al contenedor en el nodo B (a través de la red de superposición de entrada) y también SNAT para cambiar la IP de origen a la IP de red de superposición de entrada del nodo A
  • el paquete se enruta a través de la superposición al servidor real
  • los paquetes de retorno siguen la misma ruta a la inversa, reescribiendo las direcciones de origen / destino a los valores originales

Creo que el SNAT podría evitarse con algo como esto:

  • El nodo A pasa el paquete a ingress_sbox sin ningún NAT (¿iptables / enrutamiento de política?)
  • node A ingress_sbox ejecuta IPVS en modo de enrutamiento directo, que envía el paquete al nodo B a través de la red de superposición de entrada
  • el contenedor en el nodo B recibe el paquete inalterado (el contenedor debe aceptar paquetes para todas las IP públicas, pero no enviar ARP para ellos. Hay varias formas de hacer esto, vea los documentos de IPVS).
  • los paquetes de retorno se envían directamente desde el nodo B al cliente (no es necesario volver a través de la red superpuesta o el nodo A)

Como ventaja adicional, no es necesario almacenar ningún estado de NAT y se reduce el tráfico de red superpuesto.

@aluzzardi @mrjana ¿ Alguna actualización sobre esto, por favor? Se agradecería mucho un poco de retroalimentación de Docker.

Mirando. sin información de IP de origen, la mayoría de nuestros servicios no pueden funcionar como se esperaba

Cómo pasó eso ?
unassign_bug

@tlvenn parece un error en Github?

@PanJ @tlvenn @vfarcic @dack y otros, PTAL # 27917. Introdujimos la capacidad de habilitar el modo de publicación del servicio = host que proporcionará una forma para que el servicio omita IPVS y recupere el comportamiento similar a docker run -p y retendrá la ip de origen para los casos que necesito.

Por favor, intente 1.13.0-rc2 y envíe sus comentarios.

eres bastante raro

Con respecto al modo de publicación, ya lo había vinculado desde el kit de enjambre anterior, esto podría ser una solución, pero realmente espero que una solución adecuada venga con Docker 1.13 para abordar este problema para siempre.

Este problema podría clasificarse como un error porque preservar la IP de origen es el comportamiento que esperamos como usuarios y es una limitación muy seria de los servicios de la ventana acoplable en este momento.

Creo que tanto @kobolog como @dack han encontrado algunas pistas potenciales sobre cómo resolver esto y han pasado casi 2 semanas sin seguimiento de las del lado de Docker.

¿Podríamos tener alguna visibilidad sobre quién está investigando este problema en Docker y una actualización de estado? Gracias por adelantado.

Aparte del # 27917, no hay otra solución para 1.13. La funcionalidad de retorno directo debe analizarse para varios casos de uso y no debe tomarse a la ligera como una corrección de errores. Podemos investigar esto para 1.14. Pero, esto también cae en la categoría de comportamiento LB configurable, que incluye el algoritmo (rr frente a otros 10 métodos), Ruta de datos (LVS-DR, LVS-NAT y LVS-TUN). Si alguien está dispuesto a contribuir a esto, por favor presione un PR y podemos ponerlo en marcha.

Es justo, supongo que @mavenugo, dado que ahora tenemos una alternativa.

Como mínimo, ¿podemos modificar el documento para 1.13 para que indique claramente que cuando se usan los servicios de la ventana acoplable con el modo de publicación de entrada predeterminado, la IP de origen no se conserva y se sugiere usar el modo de host si este es un requisito para ejecutar el servicio? ?

Creo que ayudará a las personas que están migrando a servicios a no ser quemadas por este comportamiento inesperado.

Claro y sí, una actualización del documento para indicar este comportamiento y la solución alternativa de usar la publicación mode=host será útil para los casos de uso que fallan en el modo LVS-NAT.

¿Simplemente volviendo a revisar para ver si no hubo nuevos desarrollos para resolver esto? Sin duda, también es una gran limitación para nosotros.

¿Hay una solución en la hoja de ruta para Docker 1.14? Estamos retrasados ​​en la implementación de nuestras soluciones utilizando Docker debido en parte a este problema.

Me encantaría ver un encabezado personalizado agregado a la solicitud http / https que conserva la ip del cliente. Esto debería ser posible, ¿no? No me importa cuando se sobrescribe X_Fordered_for, solo quiero tener un campo personalizado que solo se establece la primera vez que la solicitud ingresa al enjambre.

Me encantaría ver un encabezado personalizado agregado a la solicitud http / https que conserva la ip del cliente. Esto debería ser posible, ¿no? No me importa cuando se sobrescribe X_Fordered_for, solo quiero tener un campo personalizado que solo se establece la primera vez que la solicitud ingresa al enjambre.

El equilibrio de carga se realiza en L3 / 4. No es posible agregar un encabezado http.

Una solución implicará eliminar la reescritura de la dirección de origen.

@mavenugo Actualicé a la ventana acoplable 1.13 hoy y usé mode=host en mi servicio de proxy. Actualmente funciona, la IP del cliente se conserva, pero espero una mejor solución :) ¡Gracias por tu trabajo!

Perdón por doble publicación ...
¿Cómo puedo usar un archivo de pila (yml v3) para obtener el mismo comportamiento que cuando usaría --publish mode=host,target=80,published=80 través del servicio docker create?

Lo intenté

...
services:
  proxy:
    image: vfarcic/docker-flow-proxy:1.166
    ports:
      - "80:80/host"
      - "443:443/host" 
...

pero eso no funciona (se usó el mismo patrón que en https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/#/ports)

¿Cómo puedo usar un archivo de pila (yml v3) para obtener el mismo comportamiento que cuando usaría --publish mode = host, target = 80, Published = 80 a través del servicio docker create?

@hamburml : https://github.com/docker/docker/issues/30447, es un problema / característica abierta.

Desafortunadamente, no puedo usar mode=host como solución porque necesito que mi servicio se comunique con la red del enjambre y también esté escuchando en todos los nodos, no solo en la interfaz del host ...

@ tkeeler33 Creo que debería poder implementar el servicio como un servicio global (que implementa una instancia en cada nodo en el enjambre) y conectarlo a una red de enjambre para comunicarse con otros servicios en el enjambre

@thaJeztah : Sí, pero no puedo conectar un contenedor a una red de superposición / enjambre y al host mode=host al mismo tiempo. Esa es mi mayor limitación en este momento.

@ tkeeler33 parece funcionar para mí;

$ docker network create -d overlay swarm-net

$ docker service create \
  --name web \
  --publish mode=host,published=80,target=80 \
  --network swarm-net \
  --mode=global \
  nginx:alpine

$ docker service create --name something --network swarm-net nginx:alpine

Pruebe si el servicio web puede conectarse con el servicio something en la misma red;

docker exec -it web.xczrerg6yca1f8ruext0br2ow.kv8iqp0wdzj3bw7325j9lw8qe sh -c 'ping -c3 -w1 something'
PING something (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.251 ms

--- something ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.251/0.251/0.251 ms

@thaJeztah - ¡Gracias! Después de profundizar más, me di cuenta de que mi problema era que creé mi red de Docker usando la opción --opt encrypted , lo que provocó que el contenedor fallara en las conexiones del host. Una vez que probé tus pasos, pude identificar rápidamente la causa raíz. Esta opción puede ser una buena solución provisional, solo necesito entender las implicaciones de seguridad.

¡Aprecio mucho la información!

@ tkeeler33 --opt encrypted no debería afectar la asignación de puertos de host. El único propósito de la opción cifrada es cifrar el tráfico del túnel vxlan entre los nodos. De los documentos: "Si planea crear una red superpuesta con cifrado (--opt cifrado), también deberá asegurarse de que se permita el tráfico del protocolo 50 (ESP)". ¿Puedes comprobar tus configuraciones para asegurarte de que se permite ESP?
Además, la opción --opt encrypted es puramente cifrado de plano de datos. Todo el tráfico del plano de control (intercambios de enrutamiento, distribución de descubrimiento de servicios, etc.) está cifrado de forma predeterminada, incluso sin la opción.

@mavenugo Tienes razón. Cuando creé una nueva red con --opt encrypted funcionó bien. Cuando comparé la red recién creada con la existente, noté que se estableció "Internal": true . Ese fue probablemente el problema y fue un error durante la creación inicial de la red ... Gracias por su ayuda y aclaración, ha sido un día largo ...

@dack @kobolog En implementaciones típicas del modo LVS-Tunnel y LVS-DR, la IP de destino en el paquete entrante será el servicio VIP que también está programado como una IP no ARP en los servidores reales. La malla de enrutamiento funciona de una manera fundamentalmente diferente, la solicitud entrante podría ser para cualquiera de los hosts. Para que el servidor real acepte el paquete (en cualquier modo LVS), la IP de destino debe cambiarse a una IP local. No hay forma de que el paquete de respuesta del contenedor backend regrese con la dirección de origen correcta. En lugar de la devolución directa, podemos intentar devolver el paquete de respuesta al host de entrada. Pero no hay una forma limpia de hacerlo, excepto cambiando la IP de origen, lo que nos lleva de vuelta al punto de partida.

@thaJeztah Creo que deberíamos aclarar esto en la documentación, sugerir el uso del mod de host si la IP del cliente debe conservarse y cerrar este problema.

@sanimej Todavía no veo por qué es imposible hacer esto sin NAT. ¿No podríamos tener la opción de usar, por ejemplo, el flujo LVS-DR regular? Docker agrega el vip que no es arp a los nodos apropiados, LVS dirige los paquetes entrantes a los nodos y los paquetes salientes regresan directamente. ¿Por qué importa que el paquete entrante pueda llegar a cualquier host? Eso no es diferente al LVS estándar con múltiples servidores frontend y backend.

@thaJeztah gracias por la solución :)
Si está implementando su proxy con compose versión 3, la nueva sintaxis de publicación no es compatible, por lo que podemos parchear el servicio implementado usando este comando (reemplace nginx_proxy con el nombre del servicio)

docker service update nginx_proxy \
    --publish-rm 80 \
    --publish-add "mode=host,published=80,target=80" \
    --publish-rm 443 \
    --publish-add "mode=host,published=443,target=443"

@dack En el flujo LVS-DR regular, la IP de destino será el servicio VIP. Entonces, el LB puede enviar el paquete al backend sin ningún cambio de IP de destino. Este no es el caso de la malla de enrutamiento porque la IP de destino del paquete entrante será una de las IP del host.

@sanimej ¿Algún comentario sobre la propuesta anterior para usar el modo de encapsulación IPIP para resolver este problema?

El túnel @tlvenn LVS-IP funciona de manera muy similar a LVS-DR, excepto que el backend obtiene el paquete a través de una IP en un túnel IP en lugar de una reescritura de mac. Por lo tanto, tiene el mismo problema para el caso de uso de la malla de enrutamiento.

De la propuesta a la que te refieres ...
The real server receives the enclosing packet, decapsulates it and sees real client IP as source and virtual service IP as destination.

La IP de destino del paquete sería la IP del host al que el cliente envió el paquete y no la VIP. Si no se reescribe, el servidor real lo eliminará después de eliminar el encabezado IP externo. Si se reescribe la IP de destino, la respuesta del servidor real al cliente tendrá una IP de origen incorrecta, lo que provocará una falla en la conexión.

Gracias por la aclaración @sanimej. ¿Quizás podría implementar el protocolo PROXY ? No proporcionaría una solución perfecta, pero al menos ofrecería al servicio una solución para resolver la IP del usuario.

Existe una manera complicada de lograr la preservación de la IP de origen dividiendo el rango del puerto de origen en bloques y asignando un bloque para cada host en el clúster. Entonces es posible hacer un enfoque híbrido de NAT + DR, donde el host de entrada hace el SNAT habitual y envía el paquete a un servidor real. En el host donde se está ejecutando el servidor real, según la IP de origen, haga un SNAT para cambiar el puerto de origen a un puerto en el rango asignado para el host de entrada. Luego, en el paquete de retorno del contenedor, haga coincidir el rango del puerto de origen (y el puerto de destino) y cambie la IP de origen a la del host de entrada.

Técnicamente, esto funcionaría, pero es poco práctico y frágil en implementaciones reales donde los miembros del clúster se agregan y eliminan rápidamente. Esto también reduce significativamente el espacio del puerto.

El enfoque NAT + DR que mencioné no funcionaría porque la IP de origen no se puede cambiar en el host de entrada. Cambiar solo el puerto de origen a uno en el rango para ese host en particular y usar la política de enrutamiento del host backend para devolver el paquete al host de entrada podría ser una opción. Esto todavía tiene otros problemas que mencioné anteriormente.

@thaJeztah
¿Existe alguna solución alternativa en este momento para reenviar la dirección IP real del contenedor Nginx al contenedor web?
Tengo el contenedor Nginx ejecutándose en el modo global y publicado en host , por lo que el contenedor Nginx obtiene una dirección IP correcta. Ambos contenedores se ven bien, sin embargo, el contenedor web obtiene la dirección IP del contenedor Nginx, no la del cliente.
Nginx es un proxy inverso para la web y la web ejecuta uwsgi en el puerto 8000:

server {
    resolver 127.0.0.11;
    set $web_upstream http://web:8000;

    listen 80;
    server_name domain.com;
    location / {
        proxy_pass $web_upstream;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

@lpakula Por favor, verifique mi respuesta anterior + esta configuración de trabajo nginx

@ pi0 Gracias por responder

Estoy usando la configuración de nginx desde el enlace, pero la dirección IP sigue siendo incorrecta, debo tener algo que falta en mi configuración

Tengo un clúster de enjambre de Docker (

    docker service create --name nginx --network overlay_network --mode=global \
        --publish mode=host,published=80,target=80 \
        --publish mode=host,published=443,target=443 \
        nginx:1.11.10

    docker service create --name web --network overlay_network \
        --replicas 1 \
        web:newest

El contenedor Nginx utiliza el contenedor oficial más reciente https://hub.docker.com/_/nginx/
El contenedor web ejecuta el servidor uwsgi en el puerto 8000

Estoy usando global nginx.conf del enlace y conf.d/default.conf ve de la siguiente manera:

   server {
       resolver 127.0.0.11;
       set $web_upstream http://web:8000;

       listen 80;
       server_name domain.com;
       location / {
        proxy_pass $web_upstream;
      }
  }

Y luego los registros del contenedor nginx:

  194.168.X.X - - [17/Mar/2017:12:25:08 +0000] "GET / HTTP/1.1" 200

Registros de contenedor web:

  10.0.0.47 - - [17/Mar/2017 12:25:08] "GET / HTTP/1.1" 200 -

¿Qué falta ahí?

La dirección IP seguirá siendo incorrecta. Pero agregará encabezados HTTP que
contener una dirección IP real. Debe configurar su servidor web de su elección
para confiar en el proxy (use el encabezado en lugar de la IP de origen)
El viernes 17 de marzo de 2560 a las 7:36 p.m. Lukasz Pakula [email protected]
escribió:

@ pi0 https://github.com/pi0 Gracias por responder

Estoy usando la configuración de nginx desde el enlace, pero la dirección IP sigue siendo
mal, debo tener algo que falta en mi configuración

Tengo un clúster de enjambre de Docker (
servicios

docker service create --name nginx --network overlay_network --mode=global \
    --publish mode=host,published=80,target=80 \
    --publish mode=host,published=443,target=443 \
    nginx:1.11.10

docker service create --name web --network overlay_network \
    --replicas 1 \
    web:newest

El contenedor Nginx usa el contenedor oficial más reciente
https://hub.docker.com/_/nginx/ http: // url
El contenedor web ejecuta el servidor uwsgi en el puerto 8000

Estoy usando nginx.conf global desde el enlace y conf.d / default.conf parece
de la siguiente manera:

servidor {
resolver 127.0.0.11;
establecer $ web_upstream http: // web : 8000;

   listen 80;
   server_name domain.com;
   location / {
    proxy_pass $web_upstream;
  }

}

Y luego los registros del contenedor nginx:

194.168.XX - - [17 / Mar / 2017: 12: 25: 08 +0000] "GET / HTTP / 1.1" 200

Registros de contenedor web:

10.0.0.47 - - [17 / Mar / 2017 12:25:08] "GET / HTTP / 1.1" 200 -

¿Qué falta ahí?

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/docker/docker/issues/25526#issuecomment-287342795 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ABtu97EFaCmLwAZiOrYT4nXi4oXPCbLQks5rmn43gaJpZM4Jf2WK
.

>

PanJ,
Panjamapong Sermsawatsri
Tel. (+66) 869761168

@lpakula Ah, hay otra cosa que tu imagen web:newest debería respetar el encabezado X-Real-IP . nginx no cambiará automáticamente la IP del remitente, solo envía un encabezado de sugerencia.

@ pi0 @PanJ
Tiene sentido, gracias chicos!

Vincula el puerto usando el modo de host.

nginx admite la transparencia de IP mediante el módulo del kernel TPROXY .

@stevvooe ¿Puede Docker hacer algo así también?

nginx admite la transparencia de IP mediante el módulo del kernel TPROXY.
@stevvooe ¿Puede Docker hacer algo así también?

Es poco probable, ya que es necesario realizar un seguimiento de la entrada a través de los nodos. Dejaré @sanimej o @mavenugo.

¿Swarm puede proporcionar la API REST para obtener la dirección IP del cliente?

@tonysongtl que no está relacionado con este problema

Otra cosa a considerar es cómo se envía su tráfico a sus nodos en una configuración de alta disponibilidad. Un nodo debería poder desactivarse sin generar errores para los clientes. La recomendación actual es usar un balanceador de carga externo (ELB, F5, etc.) y balancear la carga en la Capa 4 para cada nodo Swarm, con una simple verificación de estado de la Capa 4. Creo que F5 usa SNAT, por lo que el mejor caso en esta configuración es capturar la IP única de su F5, y no la IP real del cliente.

Referencias:
https://docs.docker.com/engine/swarm/ingress/#configure -an-external-load-balancer
https://success.docker.com/Architecture/Docker_Reference_Architecture%3A_Docker_EE_Best_Practices_and_Design_Considerations
https://success.docker.com/Architecture/Docker_Reference_Architecture%3A_Universal_Control_Plane_2.0_Service_Discovery_and_Load_Balancing

Reflejando el comentario anterior : ¿no se puede usar el protocolo proxy? Todos los balanceadores de carga en la nube y haproxy usan esto para la preservación de la IP de origen.

Calico también tiene el modo ipip, https://docs.projectcalico.org/v2.2/usage/configuration/ip-in-ip , que es una de las razones por las que github lo usa. https://githubengineering.com/kubernetes-at-github/

Hola.

En aras de la comprensión y la integridad, permítame resumir y corregirme si me equivoco:

El problema principal es que los contenedores no reciben src-IP original, sino VIP de enjambre. He replicado este problema con el siguiente escenario:

create docker swarm
docker service create --name web --publish 80:80 nginx
access.log source IP is 10.255.0.7 instead of client's browser IP

Parece:

Cuando los servicios dentro del enjambre usan malla (predeterminada), ¿enjambre hace NAT para garantizar que el tráfico del mismo origen siempre se envíe al mismo servicio en ejecución de host?
Por lo tanto, está perdiendo el src-IP original y reemplazándolo por el servicio VIP de swarm.

Parece que @kobolog https://github.com/moby/moby/issues/25526#issuecomment -258660348 y @dack https://github.com/moby/moby/issues/25526#issuecomment -260813865 las propuestas fueron refutadas por @sanimej https://github.com/moby/moby/issues/25526#issuecomment -280722179 https://github.com/moby/moby/issues/25526#issuecomment -281289906 pero, TBH, sus argumentos no son del todo claros para yo todavía, tampoco entiendo por qué no se ha cerrado el hilo si esto es definitivamente imposible.

@sanimej, ¿no funcionaría esto ?:

  1. Swarm recibe un mensaje con src-IP = A y destination = "my-service-virtual-address"
  2. El paquete se envía a un nodo de enjambre que ejecuta ese servicio, encapsulando el mensaje original.
  3. El nodo reenvía a la tarea que cambia el destino a un contenedor que ejecuta ese servicio IP
    Swarm y los nodos podrían mantener tablas para garantizar que el tráfico del mismo origen se reenvíe al mismo nodo siempre que sea posible.

¿Una opción para habilitar "proxy inverso en lugar de NAT" para servicios específicos no resolvería todos estos problemas satisfaciendo a todos?

Por otro lado, IIUC, la única opción que queda es usar https://docs.docker.com/engine/swarm/services/#publish -a-services-ports- lo tanto

Gracias por tu ayuda y tu paciencia.
Saludos

@sanimej
Aún más ... ¿por qué Docker no solo está haciendo un reenvío de puertos NAT (cambiando solo dest IP / puerto)?

  1. Swarm recibe el mensaje "de A a mi servicio"
  2. Swarm reenvía el mensaje al host que ejecuta ese servicio, configurando dest = node1
  3. El nodo1 recibe el mensaje "de A al nodo1" y reenvía la configuración dest = contenedor1
  4. El contenedor1 recibe el mensaje "de A al contenedor1"
  5. Para responder, el contenedor usa la ruta de puerta de enlace predeterminada

Solo me gustaría intervenir; Si bien entiendo que no hay una manera fácil de hacer esto, no tener la dirección IP de origen preservada de alguna manera obstaculiza severamente una serie de casos de uso de aplicaciones. Aquí hay algunos que se me ocurren:

  • Poder tener métricas que detallen de dónde se originan sus usuarios es vital para la ingeniería de redes / servicios.

  • En muchas aplicaciones de seguridad, debe tener acceso a la dirección IP de origen para permitir la creación de listas negras dinámicas basadas en el abuso del servicio.

  • Los servicios de reconocimiento de ubicación a menudo necesitan poder acceder a la dirección IP para ubicar la ubicación general del usuario cuando fallan otros métodos.

De mi lectura de este hilo de problemas, no parece que las soluciones provisionales funcionen muy bien cuando desea tener servicios escalables dentro de un Docker Swarm. Limitarse a una instancia por nodo trabajador reduce en gran medida la flexibilidad de la oferta. Además, mantener un enfoque híbrido de tener un LB / Proxy en el borde ejecutándose como un contenedor no orquestado por Swarm antes de alimentar a los contenedores orquestados por Swarm parece retroceder en el tiempo. ¿Por qué debería el usuario mantener 2 paradigmas diferentes para la orquestación de servicios? ¿Qué hay de poder escalar dinámicamente el LB / Proxy en el borde? Eso tendría que hacerse manualmente, ¿verdad?

¿Podría el equipo de Docker considerar estos comentarios y ver si hay alguna forma de introducir esta funcionalidad, sin dejar de mantener la calidad y flexibilidad presentes en el ecosistema de Docker?

Como otro aparte, actualmente me está golpeando esto. Tengo una aplicación web que reenvía solicitudes autorizadas / autenticadas a un servidor web descendente. Nuestros técnicos de servicio deben poder verificar si las personas han llegado al servidor descendente, para el que les gusta usar los registros de acceso web. En el escenario actual, no tengo forma de proporcionar esa funcionalidad, ya que mi servidor proxy nunca ve la dirección IP de origen. Quiero que mi aplicación sea fácilmente escalable, y no parece que pueda hacer esto con las soluciones alternativas presentadas, al menos no sin lanzar nuevas VM para cada instancia escalada.

@Jitsusama, ¿ podría Kubernetes resolver tu problema?

@thaJeztah, ¿hay alguna manera de

Lo intenté

`services:
  math:
    build: ./math
    restart: always
    ports:
    - target: 12555
      published: 12555
      mode: host

Pero parece tomar 172.xx1 como IP de origen

@trajano , no tengo ni idea. ¿Kubernetes se las arregla de alguna manera para solucionar este problema?

@Jitsusama
Sí, tienen documentación referente a cómo preservan la IP de origen . Es funcional, pero no tan bonito si no usa un Load Balancer, ya que el paquete se coloca en los nodos sin esos puntos finales. Si planea usar Rancher como su Load Balancer autohospedado, desafortunadamente todavía no lo admite .

@trajano

Pero parece tomar 172.xx1 como IP de origen

Si está accediendo a su aplicación localmente, esa IP debe ser correcta (si usa swarm) ya que docker_gwbridge es la interfaz que interactúa con su contenedor de proxy. Puede intentar acceder a la aplicación desde otra máquina dentro de su red IP para ver si detecta la dirección correcta.

En cuanto a la solución de redacción, es posible. Aquí, uso la imagen jwilder/nginx-proxy como mi proxy inverso de frontend (para simplificar conceptos) junto con una imagen de compilación oficial de nginx como servicio de backend. Implemento la pila en el modo Docker Swarm:

version: '3.3'

services:

  nginx-proxy:
    image: 'jwilder/nginx-proxy:alpine'
    deploy:
      mode: global
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  nginx:
    image: 'nginx:1.13.5-alpine'
    deploy:
      replicas: 3
    ports:
      - 80
      - 443
    environment:
      - VIRTUAL_HOST=website.local
$ echo '127.0.0.1 website.local' | sudo tee -a /etc/hosts
$ docker stack deploy --compose-file docker-compose.yml website

Esto creará una red website_default para la pila. Mi punto final se define en la variable de entorno VIRTUAL_HOST y acceder a http://website.local me da:

website_nginx-proxy.0.ny152x5l9sh7<strong i="30">@Sherry</strong>    | nginx.1    | website.local 172.18.0.1 - - [08/Sep/2017:21:33:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
website_nginx.1.vskh5941kgkb<strong i="33">@Sherry</strong>    | 10.0.1.3 - - [08/Sep/2017:21:33:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36" "172.18.0.1"

Tenga en cuenta que el final del encabezado de website_nginx.1.vskh5941kgkb tiene una pista de la IP original ( 172.18.0.1 ). X-Forward-For y X-Real-IP se establecen en el nginx.tmpl de jwilder/nginx-proxy de forma predeterminada.

Para el puerto 443 , no pude agregar ambos puertos en el archivo docker-compose, así que solo uso:

docker service update website_nginx-proxy \
    --publish-rm 80 \
    --publish-add "mode=host,published=80,target=80" \
    --publish-rm 443 \
    --publish-add "mode=host,published=443,target=443" \
    --network-add "<network>"

al mismo tiempo que agrego redes que quiero hacer un proxy inverso con aplicaciones que contienen la variable de entorno VIRTUAL_HOST . Son posibles opciones más detalladas en la documentación por jwilder/nginx-proxy , o puede crear su propia configuración.

Los controladores de ingreso en Kubernetes hacen esencialmente lo mismo, ya que los gráficos de ingreso (generalmente) tienen soporte X-Forwarded-For y X-Real-IP con un poco más de flexibilidad con la elección y el tipo de ingresos y también sus réplicas de implementación.

Entonces, la documentación de Kubernetes no está completa. Otra forma que esta siendo
con bastante frecuencia es en realidad el protocolo de entrada + proxy.

https://www.haproxy.com/blog/haproxy/proxy-protocol/

El protocolo proxy es un protocolo ampliamente aceptado que conserva la fuente
información. Haproxy viene con soporte integrado para el protocolo proxy. Nginx
puede leer pero no inyectar el protocolo proxy.

Una vez que se configura el protocolo proxy, puede acceder a esa información desde cualquier
servicios posteriores como
https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/proxy-protocol/README.md

Incluso openshift aprovecha esto para la información de IP de origen
https://docs.openshift.org/latest/install_config/router/proxy_protocol.html

Esta es la última entrada de haproxy para k8s que inyecta el protocolo proxy.

En mi humilde opinión, la forma de hacer esto en swarm es hacer que la entrada sea capaz de leer proxy
protocolo (en caso de que esté recibiendo tráfico de un LB ascendente que tiene
protocolo proxy ya inyectado) así como también inyectar protocolo proxy
información (en caso de que todo el tráfico llegue primero a la entrada).

No estoy a favor de hacerlo de otra manera, especialmente cuando hay un
estándar generalmente aceptado para hacer esto.

Traefik agregó soporte proxy_protocol hace unas semanas y está disponible a partir de v1.4.0-rc1 en adelante.

Esto debe hacerse en el nivel de ingreso del enjambre de la ventana acoplable. Si la entrada
no inyecta datos de protocolo proxy, ninguno de los servicios posteriores
(incluyendo traefix, nginx, etc.) podrá leerlo.

El 10 de septiembre de 2017 a las 21:42, "monotykamary" [email protected] escribió:

Traefik agregó soporte proxy_protocol
https://github.com/containous/traefik/pull/2004 hace unas semanas y es
disponible a partir de v1.4.0-rc1 en adelante.

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-328352805 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU3jj5dJcpMDysjIyGQK7SGx8GwWbks5shApqgaJpZM4Jf2WK
.

También estoy confundido sobre la relación de este error con infrakit. por ejemplo, https://github.com/docker/infrakit/pull/601 ¿alguien puede comentar sobre la dirección que tomará el enjambre de docker?

¿Se acumulará el enjambre en el infrakit? Estoy especialmente interesado en el lado de la entrada.

También nos encontramos con este problema. Queremos saber la IP del cliente y la IP solicitada para las conexiones entrantes. Por ejemplo, si el usuario realiza una conexión TCP sin procesar a nuestro servidor, queremos saber cuál es su IP y a qué IP de nuestra máquina se conectó.

@blazedd Como se comentó anteriormente y en otros hilos, esto es realmente posible usando publishMode. es decir, los servicios no son manejados por una red de malla.

IIUC, se están realizando algunos avances para mejorar la forma en que el ingreso maneja esto, pero en realidad esa es la única solución.

Hemos implementado y desplegado nuestro servicio nginx usando publishmode y mode: global , para evitar la configuración externa de LB

@mostolog Gracias por tu respuesta. Solo algunas notas:

  1. publishMode no resuelve el problema en absoluto. La conexión de socket de entrada aún se resuelve en la red local que se configura en enjambre. Al menos cuando usa la lista de puertos mode: host
  2. nginx no es realmente una buena solución. Nuestra aplicación está basada en TCP, pero no es un servidor web. No hay ningún encabezado que podamos usar sin codificarlo manualmente.
  3. Si utilizo docker run --net=host ... todo funciona bien.
  4. La única solución que he visto que funciona hasta ahora es usar: https://github.com/moby/moby/issues/25873#issuecomment -319109840

@blazedd En nuestra pila tenemos:

    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host

y apuesto a que obtenemos IP reales en nuestros registros.

@mostolog No funciona en Windows al menos. Todavía obtengo la dirección 172.0.0.x como fuente.

@mostolog mode: host no expone su contenedor a la red de host. Elimina el contenedor de la red de entrada, que es como Docker normalmente opera cuando se ejecuta un contenedor. Replicaría el --publish 8080:8080 usado en un comando de ejecución de la ventana acoplable. Si nginx obtiene ips reales, no es el resultado de que el socket esté conectado a esos ips directamente. Para probar esto, debe considerar seriamente el uso de una implementación TCP sin procesar o un servidor HTTP, sin un marco, y verificar la dirección informada.

¿Por qué no utilizar la red de ruta IPVS al contenedor directamente? enlazar todos los ips de la interfaz de superposición del nodo de enjambre como ips virtuales, usar ip rule from xxx table xxx para hacer una puerta de enlace múltiple, luego los nodos de enjambre pueden enrutar el cliente al contenedor directamente (DNAT), sin ningún demonio de proxy de red de espacio de usuario (dockerd)

@blazedd ¿ Obtengo direcciones IP externas al seguir el ejemplo de

Me estoy enfrentando a este problema de nuevo.

Mi configuración es la siguiente:

  • balanceador de carga ipvs en modo DR (externo al enjambre de Docker)
  • 3 nodos de docker, con IP de destino agregada a todos los nodos y arp configurado apropiadamente para el enrutamiento IPVS DR

Me gustaría implementar una pila en el enjambre y hacer que escuche en el puerto 80 en la IP virtual sin alterar las direcciones.

Casi puedo llegar haciendo esto:
puertos:
- objetivo: 80
publicado: 80
protocolo: tcp
modo: anfitrión

El problema aquí es que no le permite especificar a qué dirección IP vincularse, simplemente se vincula a todas. Esto crea problemas si desea ejecutar más de un servicio utilizando ese puerto. Necesita vincularse solo a una IP. El uso de diferentes puertos no es una opción con el equilibrio de carga de DR. Parece que los desarrolladores asumieron que la misma IP nunca existirá en varios nodos, lo que no es el caso cuando se usa un equilibrador de carga de DR.

Además, si usa la sintaxis corta, ignorará la IP de enlace y seguirá enlazando a todas las direcciones. La única forma que he encontrado para vincularme a una sola IP es ejecutar un contenedor no agrupado (no un servicio o pila).

Así que ahora he vuelto a tener que usar contenedores independientes y tener que administrarlos yo mismo en lugar de depender de las funciones de servicio / pila para hacer eso.

Tenemos el mismo problema.
Votaría por una solución transparente dentro de la entrada de la ventana acoplable que permitiría que todas las aplicaciones (algunas que usan UDP / TCP sin procesar, no especialmente HTTP) funcionen como se espera.

Podría usar la solución alternativa "mode = host port publishing" ya que mi servicio se implementa a nivel mundial.
Sin embargo, parece que esto es incompatible con el uso del controlador de red macvlan, que necesito por otras razones.
Obtenemos registros como "el controlador macvlan no admite asignaciones de puertos".
Intenté usar varias redes, pero no sirvió de nada.

Creé un ticket específico aquí: https://github.com/docker/libnetwork/issues/2050
Eso no me deja solución por ahora: '(

Hola tios
¿Existe alguna solución alternativa por ahora? Sin tenerlo como puerto host publicado
Puerto ?

El 11 de enero de 2018 a las 00:03, "Olivier Voortman" [email protected] escribió:

Tenemos el mismo problema.
Votaría por una solución transparente dentro de la entrada de Docker que permitiría a todos
aplicaciones (algunas usan UDP / TCP sin procesar, no especialmente HTTP) para funcionar como
esperado.

Podría usar la solución alternativa "mode = host port publishing" ya que mi servicio es
desplegado a nivel mundial.
Sin embargo, parece que esto es incompatible con el uso de macvlan
controlador de red, que necesito por otras razones.
Obtenemos registros como "el controlador macvlan no admite asignaciones de puertos".
Intenté usar varias redes, pero no sirvió de nada.

Creé un ticket específico aquí: docker / libnetwork # 2050
https://github.com/docker/libnetwork/issues/2050
Eso no me deja solución por ahora: '(

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-356693751 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUzlM-BMbEsDYAiYH6hKLha-aRqerks5tJQJngaJpZM4Jf2WK
.

Realmente es una pena que no sea posible obtener la IP del cliente. esto hace que la mayoría de las características agradables de la ventana acoplable no se puedan utilizar.

En mi configuración, la única forma de obtener la IP del cliente es usar network_mode:host y no usar swarm en absoluto.

usar mode=host port publishing o un docker run -p "80:80" ... tradicional no funcionó

Se sugirieron algunas soluciones en https://github.com/moby/moby/issues/15086 pero la única solución que funcionó para mí fue la red de "host" ...

Otro problema de no tener la IP correcta es que la limitación de velocidad de nginx no funciona correctamente y, por lo tanto, no se puede usar con el equilibrador de carga de enjambre de docker, porque las solicitudes tienen una velocidad limitada y se niegan, ya que nginx las cuenta todas ya que provienen de un solo usuario / IP. Entonces, la única solución es usar mode = host, pero de esta manera pierdo las capacidades de equilibrio de carga y tengo que apuntar el DNS a instancias específicas.

Quizás Docker no sea la herramienta ideal para este trabajo, estaba buscando vagabundo para configurar los servidores HTTP frontales y poner la IP del cliente como parte de los encabezados de solicitud HTTP.

Hasta que Docker sea capaz de pasar información del cliente a través de redes superpuestas, se podría usar un proxy como Docker Flow Proxy o Traefik, publicar los puertos deseados en modo host en ese servicio y conectarle los servicios de la aplicación. No es una solución completa, pero funciona bastante bien y permite el equilibrio de carga de los servicios de la aplicación / recuperación de la IP del cliente.

@ deeky666 Traefik y trabajos similares solo si no están acoplados

No veo el soporte de udo en traefik

Enviado desde mi iPhone

Finalmente nos dimos por vencidos con el contenedor Docker. ¡No está listo para producción!

El miércoles 24 de enero de 2018 a las 5:43 a. M., Efrain [email protected] escribió:

No veo el soporte de udo en traefik

Enviado desde mi iPhone

>

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-360091189 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AHf7rvMcH2iFBxcExfO_Ol0UttCspuTnks5tNwlkgaJpZM4Jf2WK
.

El problema parece resuelto parcialmente en 17.12.0-ce usando mode=host .

docker service create --publish mode=host,target=80,published=80 --name=nginx nginx

Tiene algunas limitaciones (sin malla de enrutamiento), ¡pero funciona!

@goetas mode=host funcionó durante un tiempo como solución, por lo que no diría que el problema está resuelto de alguna manera. El uso de mode = host tiene muchas limitaciones, el puerto está expuesto, no se puede usar el equilibrio de carga de enjambre, etc.

@darklow Conozco las limitaciones, pero para mi caso de uso está bien (¡si no mejor!). En 17.09.1-ce no funcionaba en absoluto, ¡así que para mí ya es una mejora!

El gran inconveniente de esa solución es que no es posible evitar el tiempo de inactividad durante la actualización.
Actualmente, tenemos que optar por renunciar a la estabilidad o la dirección IP de origen.

Estoy de acuerdo. Swarm necesita una forma de alta disponibilidad para preservar la IP de origen.

Probablemente usando el protocolo proxy. No creo que sea un gran esfuerzo agregar
soporte de protocolo proxy para docker swarm.

¿Alguien está investigando esto?

El 28 de enero de 2018 a las 22:39, "Genki Takiuchi" [email protected] escribió:

El gran inconveniente de esa solución es que no es posible evitar la caída
tiempo durante la actualización.
Actualmente, tenemos que optar por renunciar a la estabilidad o la IP de origen.
Dirección.

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-361078416 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU-or7fnhKTg7fhjtZYjGYHBFRE7Dks5tPKnYgaJpZM4Jf2WK
.

@sandys estoy de acuerdo. El protocolo proxy sería una gran idea.
@thaJeztah @aluzzardi @mrjana ¿ Podría este tema recibir algo de atención, por favor? No ha habido ninguna respuesta del equipo durante un tiempo. Gracias.

El protocolo Proxy me parece la mejor solución. Ojalá el equipo lo considere.

@goetas funcionó en un punto, al menos lo vi funcionando, pero parece haber vuelto al comportamiento 172.xxx nuevamente en la ventana acoplable 1.12.6

¡Esto es MUY malo, mitiga cualquier limitación de velocidad, prevención de fraude, registro, inicios de sesión seguros, monitoreo de sesiones, etc.!
Escuchar con modo: el host funciona, pero no es una solución real, ya que pierde el equilibrio de carga de la malla y solo el equilibrador de carga del software en el host que tiene la IP pública tiene que manejar todo el tráfico solo.

Este es un error muy crítico e importante para nosotros y está bloqueando nuestro lanzamiento con Swarm. También creemos que el protocolo proxy es la solución adecuada para esto. La entrada de Docker debe pasar la IP de origen en el protocolo proxy.

En Twitter, una de las soluciones que se ha propuesto es utilizar Traefik como ingreso administrado fuera de Swarm . Esto es muy subóptimo para nosotros, y no es una sobrecarga que nos gustaría administrar.

Si los desarrolladores de Swarm quieren ver cómo implementar el protocolo proxy en Swarm-ingress, deberían verificar todos los errores que se discuten en Traefik (por ejemplo, https://github.com/containous/traefik/issues/2619)

Conseguí que esto funcionara constantemente usando "componer" en lugar del modo de enjambre. Quizás algo en lo que pensar.

Algunas preocupaciones con el protocolo proxy:

¿Lo decodifica la propia ventana acoplable o la aplicación? Si confiamos en la aplicación para implementar el protocolo proxy, entonces esta no es una solución general para todas las aplicaciones y solo funciona para servidores web u otras aplicaciones que implementan el protocolo proxy. Si la ventana acoplable desenvuelve el protocolo proxy y traduce la dirección, también tendrá que rastrear el estado de la conexión y realizar la traducción inversa en los paquetes salientes. No estoy a favor de una solución web específica (que se base en el protocolo proxy en la aplicación), ya que la ventana acoplable también es útil para muchas aplicaciones que no son web. Este problema debe abordarse para el caso general de cualquier aplicación TCP / UDP; nada más en la ventana acoplable es específico de la web.

Al igual que con cualquier otro método de encapsulación, también existe la preocupación por los problemas de tamaño de paquete / MTU. Sin embargo, creo que esto probablemente será una preocupación con casi cualquier solución a este problema. La respuesta probablemente será asegurarse de que su red de enjambre admita una MTU lo suficientemente grande como para permitir la sobrecarga. Creo que la mayoría de los enjambres se ejecutan en redes locales, por lo que probablemente no sea un problema importante.

@trajano : sabemos que funciona con redes de host (que es probablemente lo que está haciendo su solución de redacción). Sin embargo, eso descarta todas las ventajas de las redes de clústeres del enjambre (como el equilibrio de carga).

@dack Backends debe conocer el protocolo de proxy.
Creo que resuelve la mayoría de los casos y al menos puede colocar un proxy delgado similar a un paso a través que procese el encabezado del protocolo frente a sus backends dentro de los contenedores.
Debido a que la falta de información es un problema mortal, creo que es necesario resolverlo lo más rápido posible antes de otra solución ordenada.

El protocolo proxy tiene una amplia aceptación. consulte la cantidad de herramientas compatibles: https://www.haproxy.com/blog/haproxy/proxy-protocol/
ni siquiera cubre los equilibradores de carga en la nube (ELB, Google LB) y herramientas más nuevas como Traefik.

Además, este es prácticamente el estándar en kubernetes: https://github.com/kubernetes/ingress-nginx#proxy -protocol

En este punto, el protocolo proxy es el estándar más ampliamente aceptado para resolver este problema. No veo un valor enorme en reinventar esto y romper la compatibilidad con los nginxes del mundo.

Estos son protocolos L7. El ingreso del enjambre es L4. Aquí no se está reinventando nada, todo es IPVS usando DNAT.

@ cpuguy83 no querías decir.

El protocolo de proxy es la capa 4.
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

El objetivo del protocolo PROXY es llenar las estructuras internas del servidor con la
información recopilada por el proxy que el servidor habría podido obtener
por sí mismo si el cliente se estaba conectando directamente al servidor en lugar de a través de un
apoderado. La información transportada por el protocolo son las que el servidor
obtener el uso de getsockname () y getpeername ():

  • familia de direcciones (AF_INET para IPv4, AF_INET6 para IPv6, AF_UNIX)
  • protocolo de socket (SOCK_STREAM para TCP, SOCK_DGRAM para UDP)
  • direcciones de origen y destino de capa 3
  • puertos de origen y destino de capa 4, si los hay

http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#5.1 -accept-proxy

aceptar proxy

Hace cumplir el uso del protocolo PROXY sobre cualquier conexión aceptada por cualquiera de
los sockets declarados en la misma línea. Versiones 1 y 2 del protocolo PROXY
son compatibles y detectados correctamente. El protocolo PROXY dicta la capa
3/4 direcciones de la conexión entrante que se utilizarán en todos los lugares donde se encuentre una dirección.
utilizado, con la única excepción de las reglas de "conexión tcp-request" que
solo vea la dirección de conexión real. Los registros reflejarán las direcciones
indicado en el protocolo, salvo que sea violado, en cuyo caso el real
La dirección seguirá siendo utilizada. Esta palabra clave combinada con el apoyo de
Los componentes se pueden utilizar como una alternativa eficiente y confiable a la
Mecanismo X-Fordered-For que no siempre es confiable y ni siquiera siempre
usable. Consulte también "tcp-request connection wait-proxy" para una descripción más detallada
configuración de qué cliente puede utilizar el protocolo.

¿Querías decir que hay una forma mejor que el protocolo proxy? eso es completamente posible y me encantaría saber más en el contexto de la preservación de IP de origen en Docker Swarm. Sin embargo, Proxy Protocol es más ampliamente soportado por otras herramientas (como nginx, etc.) que serán posteriores a la entrada de enjambre ... así como herramientas como AWS ELB, que estarán en sentido ascendente a la entrada de enjambre. Ese fue mi único $ 0.02

@sandys El protocolo proxy parece encapsulado (al menos en el inicio de la conexión), lo que requiere conocimiento de la encapsulación del receptor hasta el final de la pila. Hay muchas compensaciones en este enfoque.

No quisiera admitir esto en el núcleo, pero quizás hacer que la entrada sea enchufable sería un enfoque que valdría la pena.

@sandys https://github.com/sandys El protocolo proxy se parece a
encapsulación (al menos al inicio de la conexión), que requiere conocimientos
de la encapsulación desde el receptor hasta el final de la pila. Allí
Hay muchas compensaciones para este enfoque.

Eso es verdad. Es por eso que es un estándar con un RFC. Hay
Sin embargo, el impulso detrás de esto: prácticamente la importancia de todos los componentes
lo apoya. En mi humilde opinión, no es una mala decisión apoyarlo.

No quisiera apoyar esto en el núcleo, pero tal vez ingresando
conectable sería un enfoque que valdría la pena.

Esta es una discusión más amplia, sin embargo, podría agregar que la mayor
La ventaja de Docker Swarm sobre otros es que tiene todas las baterías
incorporado.

Todavía le pediría que considere el protocolo proxy como una gran solución para
este problema que cuenta con el apoyo de la industria.

¿No es posible simular un enrutador L3 en Linux y LxC (no específicamente docker)?

@trajano No se necesita simulación sino encapsulación para resolver este problema.
Por ejemplo, se puede proporcionar una opción (por ejemplo: --use-proxy-protocol ) para los servicios que necesitan una dirección IP del cliente y saben cómo tratar los paquetes encapsulados como nginx.

Como funciona actualmente, el nodo de la ventana acoplable que recibe el paquete realiza SNAT y reenvía el paquete al nodo con el contenedor de la aplicación. Si se utilizó alguna forma de tunelización / encapsulación en lugar de SNAT, entonces debería ser posible pasar el paquete original sin alterar a la aplicación.

Este es un problema resuelto en otros proyectos. Por ejemplo, con OpenStack puede utilizar túneles como GRE y VXLAN.

¿Alguien en la parte reciente de este hilo está aquí para representar al equipo de Docker y al menos decir que 'te escuchamos'? Parece algo que una característica que esperaría que estuviera 'lista para usar' y de tal interés para la comunidad aún no se ha resuelto después de que se informó por primera vez el 9 de agosto de 2016, hace unos 18 meses.

¿Alguien en la parte reciente de este hilo está aquí para representar al equipo de Docker y al menos decir que 'te escuchamos'?

/ cc @GordonTheTurtle @thaJeztah @riyazdf @aluzzardi

@bluejaguar @ruudboon Soy parte de Docker. Este es un problema bien conocido. En este momento, el equipo de red se centra en errores de larga data con estabilidad de red superpuesta. Es por eso que realmente no ha habido nuevas funciones de red en las últimas versiones.

Mi sugerencia sería presentar una propuesta concreta en la que esté dispuesto a trabajar para resolver el problema o al menos una propuesta lo suficientemente buena como para que cualquiera pueda tomarla y ejecutarla.

@ cpuguy83 He estado siguiendo algunas de las características del protocolo de proxy entrante en k8s. Por ejemplo, https://github.com/kubernetes/kubernetes/issues/42616 (PD curiosamente, el protocolo proxy aquí fluye desde Google Kubernetes Engine, que admite el protocolo proxy de forma nativa en modo HTTPS).

Además, ELB ha agregado soporte para Proxy Protocol v2 en noviembre de 2017 (https://docs.aws.amazon.com/elasticloadbalancing/latest/network/doc-history.html)

Openstack Octavia LB-as-a-service (similar a nuestro ingreso) fusionó el protocolo proxy en abril pasado: http://git.openstack.org/cgit/openstack/octavia/commit/?id=bf7693dfd884329f7d1169eec33eb03d2ae81ace

Aquí está parte de la documentación sobre el protocolo proxy en openstack: https://docs.openshift.com/container-platform/3.5/install_config/router/proxy_protocol.html
Algunos de los matices están relacionados con el protocolo proxy para https (tanto en los casos en los que está terminando los certificados en el momento de la entrada como si no).

¿Alguna actualización o solución alternativa con respecto a este problema? Realmente necesitamos conocer la IP del cliente en el modo de enjambre de la ventana acoplable.
Cualquier ayuda será muy apreciada.

Mi version:

Cliente:
Versión: 18.02.0-ce
Versión de API: 1.36
Go versión: go1.9.3
Confirmación de Git: fc4de44
Construido: mié 7 feb 21:16:33 2018
SO / Arch: linux / amd64
Experimental: falso
Orquestador: enjambre

Servidor:
Motor:
Versión: 18.02.0-ce
Versión API: 1.36 (versión mínima 1.12)
Go versión: go1.9.3
Confirmación de Git: fc4de44
Construido: mié 7 feb 21:15:05 2018
SO / Arch: linux / amd64
Experimental: falso

@adijes y otros usuarios que enfrentan este problema. Puede vincular los contenedores a la red bridge (como lo mencionó alguien en este hilo).

version: "3.4"

services:
  frontend:
    image: nginx
    deploy:
      placement:
        constraints:
          - node.hostname == "prod1"
    networks:
      - default
      - bridge
  # backed services...
  # ...

networks:
  bridge:
    external:
      name: bridge

Nuestro frontend está vinculado a bridge y siempre permanece en un host exacto, cuya IP está vinculada a nuestro dominio público. Esto le permite recibir IP de usuario real. Y debido a que también está vinculado a la red default , podrá conectarse a servicios respaldados.

También puede escalar el frontend , siempre que lo mantenga activo en ese único host. Esto hace que el host sea un punto único de falla, pero (creo) está bien para un sitio pequeño.

Editado para agregar más información:

Mis contenedores nginx están detrás de https://github.com/jwilder/nginx-proxy , también uso https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion para habilitar SSL. El proxy nginx se ejecuta a través del comando docker run , no a través de un servicio de enjambre de docker. Quizás, es por eso que obtuve IP real de los clientes. Se requiere la red bridge para permitir que mis contenedores nginx se comuniquen con nginx-proxy.

FWIW, estoy usando:

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:40 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:25:03 2017
 OS/Arch:      linux/amd64
 Experimental: false

La configuración anterior también funciona en otra configuración, que se está ejecutando:

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:40 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:25:03 2017
 OS/Arch:      linux/amd64
 Experimental: false

@ letientai299 eso no me funciona me sale

El "puente" de la red se declara como externo, pero no está en el ámbito correcto: "local" en lugar de "enjambre"

tengo un maestro y tres nodos de trabajo

@trajano , mira mi actualización.

@ letientai299 en realidad me preguntaba cómo conseguiste que bridge funcionara en modo enjambre . es decir, no recibiste el error que tengo.

@dack cuando dices redes de host, supongo que te refieres a tener

ports:
- target: 12555
  published: 12555
  protocol: tcp
  mode: host

Desafortunadamente, cuando se ejecuta en el modo docker stack deploy , no funciona y aún pierde la IP de origen, mientras que docker-compose up funciona correctamente.

También probé lo siguiente basado en @goetas

docker service create --constraint node.hostname==exposedhost \
  --publish published=12555,target=12555,mode=host \
  trajano.net/myimage

Todavía no hay suerte para obtener la IP de origen, esto está en Server Version: 17.12.0-ce

Parece algo que todos querrían en algún momento, y dado que el uso de redes superpuestas junto con redes puente / host no es realmente posible, esto es un bloqueador en los casos en que realmente necesita la IP del cliente por varias razones.

Cliente:
Versión: 17.12.0-ce
Versión de API: 1.35
Go versión: go1.9.2
Confirmación de Git: c97c6d6
Construido: mié 27 dic 20:03:51 2017
Sistema operativo / Arco: darwin / amd64

Servidor:
Motor:
Versión: 17.12.1-ce
Versión API: 1.35 (versión mínima 1.12)
Go versión: go1.9.4
Confirmación de Git: 7390fc6
Construido: Tue Feb 27 22:17:54 2018
SO / Arch: linux / amd64
Experimental: cierto

Es 2018. ¿Algo más nuevo sobre este tema?
En el modo de enjambre, no puedo usar el límite de requisitos de nginx. $ remote_addr siempre detectaba 10.255.0.2.
Este es un problema realmente serio sobre el enjambre de Docker.
Quizás debería probar kubernetes desde hoy.

@Maslow Publiqué donde estamos solo algunos comentarios arriba.

¿Podemos relajar el cheque para

networks:
  bridge:
    external:
      name: bridge

o extenderlo como

networks:
  bridge:
    external:
      name: bridge
      scope: local

y las redes scope: local solo se permiten si el modo de red es host

El "puente" de la red se declara como externo, pero no está en el ámbito correcto: "local" en lugar de "enjambre"

o permitir

networks:
  bridge:
    driver: bridge

Para no fallar con

no se pudo crear el servicio trajano_serv: Respuesta de error del demonio: La red trajano_bridge no se puede utilizar con los servicios. Solo se pueden utilizar las redes delimitadas por el enjambre, como las creadas con el controlador de superposición.

al tener mode: host en puertos publicados.

ports:
- target: 32555
  published: 32555
  protocol: tcp
  mode: host

@trajano Puede usar redes sin alcance de enjambre con enjambre ya ... por ejemplo, esto funciona:

version: '3.4'

services:
  test:
    image: alpine
    command: top
    ports:
      - target: 32555
        published: 32555
        protocol: tcp
        mode: host
    networks:
      - bridge

networks:
  bridge:
    external:
      name: bridge

¿Probó esto en un enjambre con más de un trabajador con implementación de pila de Docker? Sé que funciona con componer.

El 18 de marzo de 2018, a las 8:55 p.m., Brian Goff [email protected] escribió:

@trajano Puede usar redes sin alcance de enjambre con enjambre ya ... por ejemplo, esto funciona:

versión: '3.4'

servicios:
prueba:
imagen: alpine
comando: top
puertos:
- objetivo: 32555
publicado: 32555
protocolo: tcp
modo: anfitrión
redes:
- puente

redes:
puente:
externo:
nombre: puente
-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.

Sí, estoy haciendo esto a través de un enjambre ...

El lunes 19 de marzo de 2018 a las 9:12 a. M., Archimedes Trajano <
[email protected]> escribió:

¿Probó esto en un enjambre con más de un trabajador con la pila de docker?
desplegar. Sé que funciona con componer.

El 18 de marzo de 2018, a las 8:55 p.m., Brian Goff [email protected]
escribió:

@trajano Puedes usar redes sin alcance de enjambre con enjambre ya ...
por ejemplo, esto funciona:

versión: '3.4'

servicios:
prueba:
imagen: alpine
comando: top
puertos:

  • objetivo: 32555
    publicado: 32555
    protocolo: tcp
    modo: anfitrión
    redes:
  • puente

redes:
puente:
externo:
nombre: puente
-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-374206587 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAwxZsm3OohKL0sqUWhlgUNjCrqR0OaVks5tf67YgaJpZM4Jf2WK
.

-

  • Brian Goff

+1

Tener este problema con el siguiente equilibrio de carga de enjambre de docker con 3 nodos:

red superpuesta <-> nginx proxy jwilder docker <-> nginx web head docker

Seguí las sugerencias y los registros siguen devolviendo la IP de la red Docker 10.255.0.3 en lugar de la IP del Real Client.

+1

@ cpuguy83 esto ha comenzado a convertirse en un bloqueador para nuestras configuraciones de enjambre más grandes. A medida que comenzamos a aprovechar más la nube (donde los equilibradores de carga utilizan el protocolo proxy de facto), perdemos esta información que es muy importante para nosotros.

¿Tiene alguna idea de una ETA? esto nos ayudaría mucho.

@sandys ¿ Una ETA para qué exactamente?

@ cpuguy83 hola, gracias por tu respuesta. Soy consciente de que no hay un acuerdo amplio sobre cómo desea resolverlo. Estoy comentando cómo el equipo ha estado ocupado en cuestiones de estabilidad y no está libre para este problema.
¿Cuándo pensaría que se abordaría este tema (si es que se abordaría)?

Tenga en cuenta que puede resolver este problema ejecutando un servicio global y publicando puertos usando PublishMode = host. Si sabe en qué nodo se conectarán las personas, ni siquiera lo necesita, solo use una restricción para arreglarlo en ese nodo.

@kleptog Parcialmente no puedes. No puede evitar el tiempo de inactividad mientras se actualiza el servicio.

Escenario de prueba: observe más de cerca lvs / ipvs.

  • Ingrese al contenedor de ingreso oculto y elimine la regla snat
  • Ingrese al servicio con puertos publicados, elimine el gw predeterminado y agregue la ruta predeterminada a los contenedores de entrada ip.

Ahora se conservará la ip de origen.

Todavía estoy tratando de comprender las implicaciones de la sobrecarga, manteniendo el enrutamiento basado en políticas dentro de cada contenedor de servicios en lugar de tener solo la regla snat en el contenedor de entrada.
Sin embargo, sería realmente un alivio tener esto funcionando.

Perdón por mi ingenua manipulación, pero ¿alguien ( @dack ?) ¿ ventana acoplable, donde se hace esto?

Ah, ahora lo entendí. En un enjambre multinodo, la IP tiene que ser la de los directores de lvs, para encontrar el camino de regreso al nodo correcto en el que entró la solicitud ...

Sin embargo, sería interesante ver el código de todos modos. Me podría ahorrar algo de tiempo si alguien ya lo supiera. Gracias

Cualquier actualización sobre esto, tener tres clústeres en diferentes países, e incluso Azure Traffic Manager necesita IP de usuario real, si no, no redirigirá al usuario a un buen clúster, etc. ¿Alguien, pronto o nunca, comprobará esto? Gracias

También necesito una actualización sobre esto, esto es un gran problema, la única forma que encontré es agregar otro proxy al frente y enviar x-reenviado a la pila, en cierto modo significa que Swarm no es una opción para el público frente al tráfico en muchos escenarios.

@ cpuguy83 @trajano
Puedo confirmar que lo siguiente no funciona

version: '3.4'
services:
  nginx:
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80
      - mode: host
        protocol: tcp
        published: 443
        target: 81
networks:
  bridge:
    external:
      name: bridge

Falla con network "bridge" is declared as external, but it is not in the right scope: "local" instead of "swarm" .

versión docker

Client:
 Version:       18.03.0-ce-rc4
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    fbedb97
 Built: Thu Mar 15 07:33:59 2018
 OS/Arch:       windows/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:      18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:        Wed Mar 21 23:08:31 2018
  OS/Arch:      linux/amd64
  Experimental: false

@ Mobe91
Intenta recrear el enjambre. También tuve un error. Después del enjambre de reinicio, todo funcionó para mí.
Mi archivo docker-compose.yml :

version: "3.6"

services:
    nginx:
        image: nginx:latest
        depends_on:
            - my-app
            - my-admin
        ports: 
            - target: 80
              published: 80
              protocol: tcp
              mode: host
            - target: 443
              published: 443
              protocol: tcp
              mode: host
            - target: 9080
              published: 9080
              protocol: tcp
              mode: host
        volumes:
            - /etc/letsencrypt:/etc/letsencrypt:ro
            - /home/project/data/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
            - /home/project/data/nginx/conf.d:/etc/nginx/conf.d
            - /home/project/public:/var/public
        networks:
            - my-network
            - bridge
        deploy:
            placement:
                constraints: [node.role == manager]

    my-app:
        image: my-app
        ports:
            - 8080:8080
        volumes:
            - /usr/src/app/node_modules
            - /home/project/public:/usr/src/app/public
        networks:
            - my-network

    my-admin:
        image: my-admin
        ports:
            - 9000:9000
        networks:
            - my-network

networks:
    my-network:
    bridge:
        external: true
        name: bridge

my docker version :

Client:
 Version:   18.03.0-ce
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    0520e24
 Built: Wed Mar 21 23:10:01 2018
 OS/Arch:   linux/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:  18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:    Wed Mar 21 23:08:31 2018
  OS/Arch:  linux/amd64
  Experimental: false

Lo siento por mi ingles.

@ Mobe91 esto es lo que usé pero lo implemento desde "portainer" o en la máquina Linux. No puedo implementarlo correctamente desde Windows.

version: '3.4'
services:
  hath:
    image: trajano.net/hath
    deploy:
      placement:
        constraints:
        - node.hostname==docker-engine
    networks:
    - host
    ports:
    - target: 12555
      published: 12555
      protocol: tcp
      mode: host
    secrets:
    - hath_client_login
    volumes:
    - hath:/var/lib/hath
volumes:
  hath:
    name: 'noriko/s/hath'
    driver: cifs
networks:
  host:
    external:
      name: host
secrets:
  hath_client_login:
    external:
      name: hath_client_login

La diferencia clave es que uso host lugar de bridge En mi caso, también estoy ejecutando mis hosts como VM VirtualBox y uso el enrutador que realiza el enrutamiento NAT y que conserva la IP entrante hasta El contenedor.

Por supuesto, no hay capacidad de equilibrio de carga. Creo que si desea equilibrio de carga, debe tener algo al frente, como un enrutador L3 que haga el equilibrio de carga.

@trajano tiene razón, el cliente de Windows era el problema, la implementación con el cliente de Linux funcionó.

Pero no entiendo por qué necesitas la red host o bridge .
Lo siguiente funciona bien para mí, es decir, obtengo direcciones IP de clientes reales en nginx:

version: '3.4'
services:
  nginx:
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80

@ Mobe91 gracias. Tenía la intención de abrir un problema para eso. Básicamente, empate con https://github.com/moby/moby/issues/32957 ya que todavía ocurrió con el cliente 18.03-ce para Windows.

¿Alguien ha usado Cilium? http://cilium.readthedocs.io/en/latest/gettingstarted/docker/ .

Parece que podría solucionar este problema sin vincular los servicios al host.

@sandys good find: estoy a punto de comenzar a probarlo, ¿te funcionó? Estoy a punto de sacar a nginx de mi enjambre si no puedo arreglar esto ...

Logramos esto al rediseñar nuestra implementación para evitar anclar proxies a hosts individuales (que, en producción, se unen a una interfaz por otras razones y, por lo tanto, "recogen" la IP del cliente como un subproducto).

En nuestro entorno de prueba, solo podemos mejorar implementando a los administradores por restricción y configurando mode = global para garantizar que cada administrador obtenga una instancia en ejecución. Todavía es una sobrecarga adicional que debemos tener en cuenta, especialmente si perdemos un nodo administrador y algo está dirigiendo nuestro tráfico hacia él. Sin embargo, es mejor que estar anclado a un solo host.

@sandys, ¿ https://github.com/kubernetes/kubernetes/issues/51014

No he podido usar Cilium, pero me comuniqué con Cilium
desarrolladores para ayudar en la configuración del enjambre. Pero estoy bastante emocionado con Cilium
porque la entrada es un problema declarado que quiere resolver (a diferencia del tejido)

El jueves 10 de mayo de 2018 a las 17:24, James Green, [email protected] escribió:

Logramos esto al rediseñar nuestra implementación para evitar anclar proxies a
hosts individuales (que, en producción, se unen a una interfaz para otros
razones y por lo tanto "recoger" la IP del cliente como un subproducto).

En nuestro entorno de prueba, solo podemos mejorar implementando a los gerentes mediante
modo de restricción y configuración = global para garantizar que cada gerente obtenga un
instancia en ejecución. Todavía es una sobrecarga adicional que hay que tener en cuenta,
particularmente si perdemos un nodo administrador y algo está dirigiendo nuestro
tráfico hacia él. Sin embargo, es mejor que estar anclado a un solo host.

@sandys https://github.com/sandys ¿ Probaste Cilium? Se parece a
Weave, que parece sufrir el mismo problema al menos con k8s:
kubernetes / kubernetes # 51014
https://github.com/kubernetes/kubernetes/issues/51014

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-388032011 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK
.

El 10 de mayo de 2018 a las 17:24, "James Green" [email protected] escribió:

Logramos esto al rediseñar nuestra implementación para evitar anclar proxies a
hosts individuales (que, en producción, se unen a una interfaz para otros
razones y por lo tanto "recoger" la IP del cliente como un subproducto).

En nuestro entorno de prueba, solo podemos mejorar implementando a los gerentes mediante
modo de restricción y configuración = global para garantizar que cada gerente se ejecute
ejemplo. Todavía hay que tener en cuenta una sobrecarga adicional, especialmente si
perdemos un nodo administrador y algo está dirigiendo nuestro tráfico hacia él.
Sin embargo, es mejor que estar anclado a un solo host.

@sandys https://github.com/sandys ¿ Probaste Cilium? Parece similar a
Weave, que parece sufrir el mismo problema al menos con k8s:
kubernetes / kubernetes # 51014
https://github.com/kubernetes/kubernetes/issues/51014

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-388032011 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK
.

  • 1

Hola tios,
si desea compatibilidad con Docker Swarm en Cilium (especialmente para ingreso y
alrededor de este problema en particular), por favor comente / haga clic en Me gusta sobre este error -
https://github.com/cilium/cilium/issues/4159

El viernes 11 de mayo de 2018 a las 12:59 a.m., McBacker [email protected] escribió:

>

  • 1

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-388159466 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU_18F_cNttRUaAwaRF3gVpMZ-3qSks5txJUfgaJpZM4Jf2WK
.

para mí con la versión actual funciona así:
Luego puedo acceder a los otros nodos en el enjambre, ya que también está en la red 'predeterminada'

  web-server:
    image: blabla:7000/something/nginx:latest
    #ports:
    #  - "80:80"
    #  - "443:443"
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host        
    deploy:
      mode: global
      restart_policy:
        condition: any
      update_config:
        parallelism: 1
        delay: 30s

Puedo confirmar que la clave es usar ports.mode: host . De la documentación (https://docs.docker.com/compose/compose-file/#long-syntax-1):

modo: host para publicar un puerto de host en cada nodo, o entrada para un puerto en modo enjambre para equilibrar la carga.

Luego, usando mode: host deja de ser balanceado de carga por ingreso y aparece la IP real. Como ejemplo, aquí están mis registros de nginx:

  • con mode: host
    metrics-agents_nginx.1.pip12ztq3y1h<strong i="14">@xxxxxxxx</strong> | 62.4.X.X - - [12/Jun/2018:08:46:04 +0000] "GET /metrics HTTP/1.1" 200 173979 "-" "Prometheus/2.2.1" "-" [CUSTOM] "request_time: 0.227" remote_addr: 62.4.X.X proxy_add_x_forwarded_for: 62.4.X.X
  • sin mode: host
    metrics-agents_nginx.1.q1eosiklkgac<strong i="20">@xxxxxxxx</strong> | 10.255.0.2 - - [12/Jun/2018:08:50:04 +0000] "GET /metrics HTTP/1.1" 403 162 "-" "Prometheus/2.2.1" "-" [CUSTOM] "request_time: 0.000" remote_addr: 10.255.0.2 proxy_add_x_forwarded_for: 10.255.0.2

Y si se pregunta por qué el último registro es una respuesta 403 Prohibida, esto se debe al uso de una lista blanca en nginx ( allow 62.4.X.X y deny all ).

Contexto:
Description: Debian GNU/Linux 9.4 (stretch)
Docker version 18.03.0-ce, build 0520e24

Confirmo lo que dijo @nperron .
El uso del modo host permite obtener la IP del cliente.

Docker versión 18.03.1-ce, compilación 9ee9f40
Ubuntu 16.04.4 LTS

Puedo confirmar que está funcionando.

Docker versión 18.03.1-ce, compilación 9ee9f40
Ubuntu 16.04.4 LTS

ATENCIÓN: ESTO NO FUNCIONARÁ SI HA CONFIGURADO IPTABLES = FALSE!
Es posible que haya hecho esto (o al menos yo lo hice) si está utilizando UFW para proteger los puertos y encontró que el enjambre de docker anula la configuración de UFW.

Hay algunos tutoriales que sugieren configurar iptables = false a través de un comando o en /etc/docker/daemon.json

¡Ojalá esto le ahorre a alguien la frustración por la que acabo de pasar!

la gente debería dejar de decir "Mode: host" = funcionando, porque eso no es usar Ingress. Eso hace que sea imposible tener un solo contenedor con un servicio ejecutándose en el enjambre, pero aún poder acceder a él a través de cualquier host. O tiene que hacer que el servicio sea "Global" o solo puede acceder a él en el host que se está ejecutando, lo que frustra un poco el propósito de Swarm.

TLDR: "Mode: Host" es una solución alternativa, no una solución

@ r3pek Si bien estoy de acuerdo contigo en que pierdes Ingress si usas el modo Host para resolver este problema, diría que difícilmente derrota todo el propósito de Swarm, que hace mucho más que una red de ingreso de cara al público. En nuestro escenario de uso, tenemos en el mismo enjambre de superposición:
contenedores replicados de administración a los que solo se debe acceder a través de la intranet -> no necesitan la IP de la persona que llama, por lo tanto, están configurados "normalmente" y aprovechan la entrada.
contenedores no expuestos -> nada que decir sobre estos (creo que está subestimando el poder de poder acceder a ellos a través de su nombre de servicio).
servicio de cara al público -> este es un proxy nginx que realiza enrutamiento basado en https y url. Se definió como global incluso antes de la necesidad de x-forward para la IP real del cliente, por lo que no hay ningún problema real allí.

Tener nginx global y no tener entrada significa que puede acceder a él a través de cualquier ip del clúster, pero no tiene equilibrio de carga ni tolerancia a fallas, por lo que agregamos un equilibrador de carga de Azure L4 muy económico y fácil de configurar frente al nginx Servicio.

Como dices, Host es una solución alternativa, pero decir que habilitarlo anula por completo el propósito de Docker Swarm es un poco exagerado en mi opinión.

Hola roberto
No creo que sea exagerado, porque el modo host expone puntos únicos
de fracaso. Además, espera capas adicionales de gestión para la carga.
equilibrio fuera del ecosistema del enjambre.

Al decir que usó azure lb usted mismo, ha validado que
argumento.

Es equivalente a decir que "para ejecutar swarm con propagación de IP de cliente,
asegúrese de que está utilizando un equilibrador de carga externo que configuró ... O utilice
uno de los servicios en la nube ".

No estamos diciendo que no sea una solución temporal ... Pero sería
ignorando la promesa de Swarm si no todos reconocemos categóricamente la
defecto.

El jueves 5 de julio de 2018 a las 14:16 Roberto Fabrizi, [email protected]
escribió:

@ r3pek https://github.com/r3pek Aunque estoy de acuerdo contigo en que pierdes
Ingress si usa el modo Host para resolver este problema, diría que
difícilmente derrota todo el propósito de Swarm, que hace mucho más que un
red de entrada de cara al público. En nuestro escenario de uso tenemos en el mismo
enjambre de superposición:
contenedores replicados de administración a los que solo se debe acceder a través del
intranet -> no necesitan la ip de la persona que llama, por lo tanto están configurados
"normalmente" y aprovechar la entrada.
contenedores no expuestos -> nada que decir sobre estos (creo que
subestimar el poder de poder acceder a ellos a través de su servicio
aunque nombre).
contenedor público -> este es un proxy nginx que hace https y url
enrutamiento basado. Se definió como global incluso antes de la necesidad de x-forward-for
IP real del cliente, por lo que no hay ningún problema real allí.

Tener nginx global y no tener entrada significa que puede acceder a él a través de
cualquier ip del clúster, pero no tiene balance de carga, por lo que agregamos un muy muy
Barato y fácil de configurar Azure Load Balancer L4 frente al nginx
Servicio.

Como usted dice, Host es una solución alternativa, pero dice que habilitarlo completamente
derrota el propósito de Docker Swarm es un poco exagerado en mi opinión.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-402650066 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU_ogRzwM6X0PMknXxsxmZLLTtfraks5uDdJlgaJpZM4Jf2WK
.

Está claro que se eligió un equilibrador de carga deficiente (IPVS) para el ingreso de Docker Swarm. Si fuera compatible al menos con el protocolo proxy L4, esto no sería un problema. Excepto que aún sería un balanceador de carga L4 (TCP) sin todas las características adicionales que puede brindar L7 lb.

En Kubernetes hay balanceadores de carga L4 (TCP) -L7 (HTTP) como nginx ingress , haproxy ingress que permiten el uso del protocolo de proxy L4 o los encabezados HTTP L7 para garantizar que X-Forwarded-For se aproveche para pasar el valor real del usuario. IP al backend.

Me pregunto qué dirían los desarrolladores de ingreso de Docker Swarm. Probablemente alguien tenga que trasladar este caso a https://github.com/docker/swarmkit/issues ?

En Kubernetes hay balanceadores de carga L4 (TCP) -L7 (HTTP) como nginx ingress, haproxy ingress que permiten el uso del protocolo proxy L4 o los encabezados HTTP L7 para garantizar que X-Fordered-For se aproveche para pasar la IP real del usuario. al backend.

AFAICS, esos servicios LB no están integrados en K8, sino servicios que deben implementarse explícitamente. También puede hacer lo mismo con Docker Swarm. No veo ninguna diferencia aquí. (Aparte de eso, el controlador de entrada nginx parece ser "oficial").

Hasta donde yo sé, la diferencia es que incluso si implementa un servicio de balanceo de carga de este tipo, será 'llamado' desde el balanceador de carga swarmkit y, por lo tanto, perderá la IP de los usuarios. Por lo tanto, no puede deshabilitar el balanceador de carga swarmkit si no usa el modo host.

para ser justos, en k8s, es posible tener una entrada personalizada. en enjambre
no es.

swarm toma la posición de que todo está "integrado". Igual es el caso con
redes: en k8s, debe configurar el tejido, etc ... en swarm está integrado.

entonces el punto que Andrei está haciendo (y estoy de acuerdo) es que -
swarm debe hacer que estas características sean parte de la entrada, ya que el usuario ha
sin control sobre él.

El sábado, 28 de julio de 2018 a las 5:07 p.m., Seti [email protected] escribió:

Hasta donde yo sé, la diferencia es que incluso si implementa un
servicio de balanceo de carga será 'llamado' desde el balanceador de carga swarmkit
y así pierdes la ip de los usuarios. Entonces no puedes deshabilitar el swarmkit
loadbalancer si no usa hostmode.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-408601274 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU1-Ism_S1Awml8lO8N0Aq6rtrLH4ks5uLEzugaJpZM4Jf2WK
.

Pensé que habíamos terminado de arreglar las arrugas de nuestro enjambre, pero luego llegamos al escenario y notamos que todo acceso externo al contenedor del servidor web aparece como la IP de la red de entrada.

Estoy ejecutando mi pila en un enjambre de un solo nodo y lo haré al menos durante los próximos meses. ¿Puede recomendar la solución menos mala para nuestro caso de uso actual (enjambre de un solo nodo)? No puedo prescindir de la IP del cliente, depende demasiado de ella.

Nuestro enfoque temporal ha sido ejecutar un contenedor de proxy simple en modo "global" (que IIRC puede obtener la IP de la NIC real) y luego hacer que reenvíe todas las conexiones al servicio interno que se ejecuta en la red de superposición de enjambre con encabezados de proxy agregados.

Si obtener un encabezado x-reenviado para es suficiente para usted, esa configuración debería funcionar AFAICT.

Gracias, @maximelb. ¿Con qué terminaste yendo (por ejemplo, nginx, haproxy)?

@jamiejackson ahí es donde las cosas serán un poco diferentes. En nuestro caso, estamos ejecutando un servidor que aloja conexiones SSL de larga duración y un protocolo binario personalizado debajo, por lo que los proxies HTTP no eran posibles. Así que creamos un reenviador TCP simple y usamos un encabezado "msgpack" que pudimos descomprimir manualmente en el servidor interno.

No estoy muy familiarizado con los proxies HTTP, pero sospecho que la mayoría de ellos te servirían. : - /

hola maxime
esto es muy interesante para nosotros. ¿Puede compartir su ventana acoplable-componer por cualquier
oportunidad ?

Estoy tratando de entender cómo funciona esto. Hoy tenemos nginx a la inversa
proxy (como servicio) y múltiples servicios de Docker detrás de él.

En su caso, ¿nginx se convierte en el proxy de "modo global"? o es un
reenviador TCP especial. Entonces, a medida que escala el número de nodos, el reenviador de proxy
va en cada nodo. De alguna manera pensé que en esta situación el x-reenviado para
el encabezado se pierde ... porque la red de entrada mata la ip externa
(ya que no hay protocolo proxy).

Estaríamos muy agradecidos si nos pudieras ayudar con algunos detalles más.

Saludos
sandeep

El miércoles 8 de agosto de 2018 a las 7:18 a.m. Maxime Lamothe-Brassard <
[email protected]> escribió:

Nuestro enfoque temporal ha sido ejecutar un contenedor proxy simple en
Modo "global" (que IIRC puede obtener la IP de la NIC real) y luego tenerlo
reenviar todas las conexiones al servicio interno que se ejecuta en el enjambre
superponga la red con encabezados de proxy agregados.

Si obtener un encabezado x-reenviado-for es suficiente para usted, esa configuración debería
trabajar AFAICT.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411257087 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUx3DOjXb79FNjsuZ-RZVqkkhHAbYks5uOkOHgaJpZM4Jf2WK
.

@sandys seguro, aquí hay un extracto de nuestra ventana acoplable-componer con los contenedores relevantes.

Esta es la entrada de composición de ventana acoplable del proxy inverso:

reverseproxy:
    image: yourorg/repo-proxy:latest
    networks:
      - network_with_backend_service
    deploy:
      mode: global
    ports:
      - target: 443
        published: 443
        protocol: tcp
        mode: host

Esta es la entrada del servicio backend:

backendservice:
    image: yourorg/repo-backend:latest
    networks:
      - network_with_backend_service
    deploy:
      replicas: 2

El objetivo del proxy inverso (el lado del backend) sería tasks.backendservice (que tiene registros A para cada réplica). Puede omitir la parte networks si el servicio de backend está en la red de superposición de enjambre predeterminada.

El bit global dice "implementar este contenedor exactamente una vez en cada nodo de enjambre de Docker. Los puertos mode: host son los que dicen" enlazar con la NIC nativa del nodo ".

Espero eso ayude.

Está utilizando el modo de host. Prácticamente tienes un equilibrador de carga externo
delante de todo.
Ya no puedes depender de Swarm porque estás en modo anfitrión.

Ese es en realidad el problema del que hemos estado hablando durante un tiempo :(

El miércoles, 8 de agosto de 2018, 20:47 Maxime Lamothe-Brassard, <
[email protected]> escribió:

@sandys https://github.com/sandys seguro, aquí hay un extracto de nuestro
docker-compose con los contenedores correspondientes.

Esta es la entrada de composición de ventana acoplable del proxy inverso:

proxy inverso:
imagen: yourorg / repo- proxy: latest
redes:
- network_with_backend_service
desplegar:
modo: global
puertos:
- objetivo: 443
publicado: 443
protocolo: tcp
modo: anfitrión

Esta es la entrada del servicio backend:

backendservice:
imagen: yourorg / repo- backend: último
redes:
- network_with_backend_service
desplegar:
réplicas: 2

El objetivo del proxy inverso (el lado del backend) sería
tasks.backendservice (que tiene registros A para cada réplica). Usted puede
omita la parte de redes si el servicio de backend está en el enjambre predeterminado
superposición de red.

El bit global dice "implemente este contenedor exactamente una vez en cada Docker
nodo de enjambre. El modo de puertos: el host es el que dice "enlazar con el nativo
NIC del nodo ".

Espero eso ayude.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411442155 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU8N7KAFtOp_cPO8wpbBQqzDfpBWOks5uOwEkgaJpZM4Jf2WK
.

No estoy 100% seguro de lo que quiere decir, pero externamente usamos un DNS con un registro A por nodo de clúster. Esto proporciona un "equilibrio" económico sin tener una parte móvil externa. Cuando un cliente realiza una solicitud, elige un registro A aleatorio y se conecta a 443 en uno de los nodos del clúster.

Allí, el proxy inverso que se ejecuta en ese nodo específico y escucha en 443 obtiene una conexión nativa, incluida la IP real del cliente. Ese contenedor de proxy inverso luego agrega un encabezado y reenvía la conexión a otro contenedor interno usando la red de superposición de enjambre (tasks.backend). Dado que utiliza el destino tasks.backend, también obtendrá un registro A aleatorio para un servicio interno.

Entonces, en sentido estricto, está evitando la magia de la red superpuesta que redirige la conexión. En su lugar, replica este comportamiento con el proxy inverso y agrega un encabezado. El efecto final es el mismo (en un sentido amplio) que la magia de la red superpuesta. También lo hace en paralelo a ejecutar el enjambre, lo que significa que puedo ejecutar todos mis otros servicios que no requieren la IP del cliente en el mismo clúster sin hacer nada más por ellos.

De ninguna manera es una solución perfecta, pero hasta que se haga una reparación (si es que se hace alguna), se las arregla sin componentes externos o una configuración principal de la ventana acoplable.

@jamiejackson, la solución alternativa "menos mala" que hemos encontrado es usar Traefik como un servicio global en modo host. Tienen un buen ejemplo genérico en sus documentos . Hemos visto algunos errores que pueden o no estar relacionados con esta configuración, pero Traefik es un gran proyecto y parece bastante estable en Swarm. Hay un hilo completo en su página de problemas (que se repite aquí :)), con soluciones similares:
https://github.com/containous/traefik/issues/1880

Espero que esto ayude. Tampoco podemos usar una solución que no nos permita verificar las direcciones IP de los solicitantes reales, por lo que nos quedamos con esta solución de problemas hasta que algo cambie. Parece una necesidad bastante común, al menos por razones de seguridad.

Entendido (y una versión suelta de esto es lo que usamos).

Sin embargo, la agenda de este error en particular era solicitar a los desarrolladores
para construir eso en la red de superposición mágica (tal vez usando proxy
protocolo u otros mecanismos)

El miércoles 8 de agosto de 2018, 21:22 Maxime Lamothe-Brassard, <
[email protected]> escribió:

No estoy 100% seguro de lo que quiere decir, pero externamente usamos un DNS con una A
registro por nodo de clúster. Esto proporciona un "equilibrio" económico sin tener
parte móvil externa. Cuando un cliente hace una solicitud, elige un A aleatorio
grabar y conectarse a 443 en uno de los nodos del clúster.

Allí, el proxy inverso que se ejecuta en ese nodo específico y
escuchar en 443 obtiene una conexión nativa, incluida la IP real del cliente.
Ese contenedor de proxy inverso luego agrega un encabezado y reenvía la conexión
a otro contenedor interno usando la red de superposición de enjambre
(tareas.backend). Dado que utiliza el destino tasks.backend, también obtendrá un
aleatorio Un registro para un servicio interno.

Entonces, en el sentido estricto, está pasando por alto la magia de la red superpuesta que
redirige la conexión. En cambio, replica este comportamiento con
el proxy inverso y agrega un encabezado. El efecto final es el mismo (en un
sentido suelto) como la magia de la red superpuesta. También lo hace en
paralelo a ejecutar el enjambre, lo que significa que puedo ejecutar todos mis otros servicios que
no requiera la IP del cliente en el mismo clúster sin hacer nada
más para esos.

De ninguna manera es una solución perfecta, pero hasta que se haga una solución (si alguna vez) se
usted por sin componentes externos o configuración principal de la ventana acoplable.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411455384 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU5RKjGc3hEk6bk-doicDa1MbYGAyks5uOwlIgaJpZM4Jf2WK
.

TBH no estoy seguro de por qué la red de entrada no está siendo parcheada para agregar ip
datos en protocolo proxy.

Es incremental, no romperá las pilas existentes, es un bien definido
estándar, es ampliamente compatible incluso con los grandes proveedores de nube, es ampliamente
soportado por marcos de aplicaciones.

¿Es un esfuerzo de desarrollo significativo?

El miércoles 8 de agosto de 2018 a las 21:30, Matt Glaser, [email protected] escribió:

@jamiejackson https://github.com/jamiejackson el "menos malo"
La solución alternativa que hemos encontrado es utilizar Traefik como un servicio global en modo host.
Tienen un buen ejemplo genérico en sus documentos.
https://docs.traefik.io/user-guide/cluster-docker-consul/#full-docker-compose-file_1 .
Hemos visto algunos errores que pueden o no estar relacionados con esta configuración, pero
Traefik es un gran proyecto y parece bastante estable en Swarm. Hay una
hilo completo en su página de problemas (que se repite aquí :)), con
soluciones alternativas similares:
containous / traefik # 1880
https://github.com/containous/traefik/issues/1880

Espero que esto ayude. Tampoco podemos usar una solución que no nos permita
Verifique las direcciones IP de los solicitantes reales, por lo que estamos atascados con esta solución de kludge hasta
algo cambia. Parece una necesidad bastante común, por razones de seguridad.
por lo menos.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411458326 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU7NNbsW44L95VYCvlyL_Bje-h6L9ks5uOwsUgaJpZM4Jf2WK
.

Bueno, Docker actualmente no toca el tráfico de entrada, por lo que definitivamente no es insignificante agregarlo.
Tenga en cuenta también que este es un proyecto de código abierto, si realmente desea algo, generalmente dependerá de usted implementarlo.

+1, esto realmente es espectacular.
Creo que la mayoría de las aplicaciones necesitan la IP de los clientes reales. Solo piense en una pila de servidor de correo: no puede permitirse aceptar correos de hosts arbitrarios.

Cambiamos al modo de host de instancia de flujo global proxy_protocol nginx, que se reenvía a la aplicación replicada proxy_nginx. Esto funciona bastante bien por el momento.

servicio global nginx_stream

stream {
    resolver_timeout 5s;
    # 127.0.0.11 is docker swarms dns server
    resolver 127.0.0.11 valid=30s;
    # set does not work in stream module, using map here
    map '' $upstream_endpoint {
        default proxy_nginx:443;
    }

    server {
        listen 443;
        proxy_pass $upstream_endpoint;
        proxy_protocol on;
    }
}

servicio replicado nginx_proxy

server {
    listen 443 ssl http2 proxy_protocol;
    include /ssl.conf.include;

    ssl_certificate /etc/nginx/certs/main.crt;
    ssl_certificate_key /etc/nginx/certs/main.key;

    server_name example.org;

    auth_basic           "closed site";
    auth_basic_user_file /run/secrets/default.htpasswd;

    # resolver info in nginx.conf
    set $upstream_endpoint app;
    location / {
        # relevant proxy_set_header in nginx.conf
        proxy_pass http://$upstream_endpoint;
    }
}

¿Sería posible pasar toda la configuración de nginx para nginx_stream y
nginx_proxy con sus configuraciones Swarm?

¡Esto es increíble si funciona!

El martes, 11 de septiembre de 2018, 17:14 rubot, [email protected] escribió:

Cambiamos a la instancia de flujo global proxy_protocol nginx, que es
reenvío a la aplicación replicada proxy_nginx. Esto funciona bastante bien
por el momento.

servicio global nginx_stream

Arroyo {
resolver_timeout 5s;
# 127.0.0.11 es el servidor dns de docker swarms
resolver 127.0.0.11 válido = 30 s;
# conjunto no funciona en el módulo de flujo, usando el mapa aquí
mapa '' $ upstream_endpoint {
proxy_ nginx predeterminado
}

server {
    listen 443;
    proxy_pass $upstream_endpoint;
    proxy_protocol on;
}

}

servicio replicado nginx_proxy

servidor {
escuchar 443 ssl http2 proxy_protocol;
incluir /ssl.conf.include;

ssl_certificate /etc/nginx/certs/main.crt;
ssl_certificate_key /etc/nginx/certs/main.key;

server_name example.org;

auth_basic           "closed site";
auth_basic_user_file /run/secrets/default.htpasswd;

# resolver info in nginx.conf
set $upstream_endpoint app;
location / {
    # relevant proxy_set_header in nginx.conf
    proxy_pass http://$upstream_endpoint;
}

}

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-420244262 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU5K-gK09XdI9NxLlT36IrJP7U7_cks5uZ6IrgaJpZM4Jf2WK
.

@sandys Tengo una solución basada en haproxy para la parte del protocolo proxy que se configura a través de variables de entorno.

¿Sería posible pasar toda la configuración de nginx para nginx_stream y nginx_proxy con sus configuraciones de Swarm? ¡Esto es increíble si funciona!

@sandys Algo como esto:
https://gist.github.com/rubot/10c79ee0086a8a246eb43ab631f3581f

encontrándose con el mismo problema, ¿se va a solucionar este problema? parece una funcionalidad básica que debería estar programada para su lanzamiento.

desplegar:
modo: global
puertos:

  • target: 443 publicado: 443 protocolo: tcp mode: host

Seguir este consejo soluciona el problema, ya que el equilibrador de enjambre de la ventana acoplable ahora está fuera de la ecuación.
Para mí, es una solución válida, ya que todavía es HA y ya tenía haproxy (dentro del contenedor de proxy de flujo de docker).
El único problema es que las estadísticas de haproxy se distribuyen entre todas las réplicas, por lo que de alguna manera necesito agregar esa información al monitorear el tráfico de todo el clúster. En el pasado, solo tenía una instancia de haproxy que estaba detrás del balanceador de enjambre de docker.
Salud,
Jacq

Al leer la solicitud del OP ( @PanJ ), parece que las características actuales ahora resuelven este problema, como se ha sugerido durante meses. El OP no solicitó enrutamiento de entrada + IP de cliente AFAIK, pidieron una forma de tener un servicio de enjambre en réplica / obtención global de IP de cliente, que ahora es factible. Dos áreas principales de mejora permiten que esto suceda:

  1. Ahora podemos crear un servicio Swarm que "publica" un puerto a la IP del host, omitiendo la capa de enrutamiento de entrada.
  2. Ese mismo servicio puede conectarse a otras redes como superposición al mismo tiempo, por lo que puede acceder a otros servicios con beneficios de superposición.

Para mí, con el motor 18.09, obtengo lo mejor de ambos mundos en las pruebas. Un solo servicio puede conectarse a redes superpuestas de backend y también publicar puertos en la NIC del host y ver la IP real del cliente entrante en la IP del host. Lo estoy usando con el proxy inverso traefik para registrar el tráfico IP del cliente en traefik que está destinado a los servicios de backend . Siento que esto podría resolver la mayoría de las solicitudes que he visto para "registrar la IP real".

@PanJ, ¿esto lo resuelve por ti?

La clave es publicar puertos en mode: host lugar de mode: ingress (el valor predeterminado).

La ventaja de este modo es que obtiene IP de cliente real y rendimiento de NIC de host nativo (ya que está fuera de la encapulación de IPVS AFAIK). La desventaja es que solo escuchará en los nodos que ejecutan las réplicas.

Para mí, la solicitud de "Quiero usar el enrutamiento IPVS de entrada y también ver la IP del cliente" es una solicitud de función diferente de libnetwork.

¿Qué ha cambiado aquí? Porque hemos estado usando el modo host para hacer esto durante
mucho tiempo ahora. De hecho, esa es la solución alternativa sugerida en este hilo como
bien.

El problema es que, por supuesto, debe bloquear este servicio a un
host, por lo que Swarm no puede programarlo en otro lugar. Cual es el problema
por completo: ese protocolo proxy / IPVS, etc. resuelve este problema.

El viernes 4 de enero de 2019 a las 09:34, Bret Fisher < [email protected] escribió:

Al leer la solicitud del OP ( @PanJ https://github.com/PanJ ),
Parece que las características actuales ahora resuelven este problema, como se ha sugerido para
meses. El OP no solicitó enrutamiento de entrada + IP de cliente AFAIK, preguntaron
para una forma de tener un servicio de enjambre en réplica / global obtener IP de cliente,
que ahora es factible. Dos áreas principales de mejora permiten que esto suceda:

  1. Ahora podemos crear un servicio Swarm que "publica" un puerto al
    IP de host, omitiendo la capa de enrutamiento de entrada
  2. Ese mismo servicio se puede conectar a otras redes como superposición en el
    al mismo tiempo, para que pueda acceder a otros servicios con beneficios superpuestos

Para mí, con el motor 18.09, obtengo lo mejor de ambos mundos en las pruebas. A
un solo servicio puede conectarse a redes superpuestas de backend y también publicar
puertos en la NIC del host y ver la IP del cliente real entrante en la IP del host. soy
usando eso con el proxy inverso traefik para registrar el tráfico IP del cliente en traefik
que está destinado a servicios backend
https://github.com/BretFisher/dogvscat/blob/7e9fe5b998f2cf86951df3f443714beb413d63fb/stack-proxy-global.yml#L75-L83 .
Siento que esto podría resolver la mayoría de las solicitudes que he visto para "registrar lo real
IP ".

@PanJ https://github.com/PanJ ¿Esto lo resuelve por ti?

La clave es publicar puertos en modo: host en lugar de modo: entrada (el
defecto).

La ventaja de este modo es que obtiene IP de cliente real y NIC de host nativo
rendimiento (ya que está fuera de la encapulación IPVS AFAIK). La estafa es
solo escuchará en los nodos que ejecutan las réplicas.

Para mí, la solicitud de "Quiero usar el enrutamiento IPVS de entrada y también ver
IP del cliente "es una solicitud de función diferente de libnetwork.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451348906 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUzs15UVWOVl54FLwBJSZJKX-9D0jks5u_tLPgaJpZM4Jf2WK
.

@BretFisher el mode: host es solo una solución, pero no la solución. Como @sandys dijo que la solución tiene algunas advertencias, no deberíamos considerar este problema como solucionado.

No estoy seguro de si hay alguna mejora desde que se descubrió la solución. Me he mudado a Kubernetes durante bastante tiempo y todavía me sorprende que el problema siga abierto durante más de dos años.

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De mi
perspectiva, incluso la declaración de mudarse a kubernetes no es una adecuada
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento. Tu tampoco
tener un LB externo, o usar algo como el proxy de entrada nginx que debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos el mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre debe ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019, 09:28:

@BretFisher https://github.com/BretFisher el modo: el host es solo un
alternativa pero no la solución. Como @sandys https://github.com/sandys
dijo que la solución tiene algunas salvedades, no deberíamos considerar este problema
como fijo.

No estoy seguro de si hay alguna mejora ya que la solución ha sido
descubierto. Me he mudado a Kubernetes durante bastante tiempo y todavía estoy
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
.

Incluso puede extender el proyecto dockerflow y agregar una variante nginx para comenzar
kubernetes-ingressproxy para swarn. Definitivamente todo esto lleno de enjambre
generaría un contenedor de sistema adicional, ya que sabes que hay un montón de
ellos con kubernetes. ¿No es la fuerza del enjambre por un recurso escaso?
proyectos para ser lean?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Ene.2019, 09:48:

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De mi
perspectiva, incluso la declaración de mudarse a kubernetes no es una adecuada
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento. Tu tampoco
tener un LB externo, o usar algo como el proxy de entrada nginx que debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos el mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre debe ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019, 09:28:

@BretFisher https://github.com/BretFisher el modo: el host es solo un
alternativa pero no la solución. Como @sandys https://github.com/sandys
dijo que la solución tiene algunas salvedades, no deberíamos considerar este problema
como fijo.

No estoy seguro de si hay alguna mejora ya que la solución ha sido
descubierto. Me he mudado a Kubernetes durante bastante tiempo y todavía estoy
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
.

Esas son soluciones complejas: el protocolo proxy solo agrega un encabezado adicional
información y es un estándar muy conocido: haproxy, nginx, AWS elb,
etc todos lo siguen. https://www.haproxy.com/blog/haproxy/proxy-protocol/

La superficie del cambio se limitaría al Swarm incorporado
ingreso (donde se agregaría este soporte). Y todos los servicios lo tendrán
disponible.

El viernes 4 de enero de 2019 a las 14:36 ​​rubot < [email protected] escribió:

Incluso puede extender el proyecto dockerflow y agregar una variante nginx para comenzar
kubernetes-ingressproxy para swarn. Definitivamente todo esto lleno de enjambre
generaría un contenedor de sistema adicional, ya que sabes que hay un montón de
ellos con kubernetes. ¿No es la fuerza del enjambre por un recurso escaso?
proyectos para ser lean?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Ene.2019, 09:48:

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De mi
perspectiva, incluso la declaración de mudarse a kubernetes no es una adecuada
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento. usted
cualquiera
tener un LB externo, o usar algo como el proxy de entrada nginx que debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos el mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre debe ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019, 09:28:

@BretFisher https://github.com/BretFisher el modo: el host es solo un
alternativa pero no la solución. Como @sandys https://github.com/sandys
dijo que la solución tiene algunas salvedades, no deberíamos considerar esto
asunto
como fijo.

No estoy seguro de si hay alguna mejora ya que la solución ha sido
descubierto. Me mudé a Kubernetes durante bastante tiempo y todavía
ser
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 , o
silencio
la amenaza
<
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK
.

Como dije, verifique la solución de transmisión tcp anterior, que ya utiliza proxy
protocolo.
Agregar protocolo proxy requeriría también configuración dentro del contenedor si
añadido para pulular río arriba. No veo ningún valor, además de un limpiador y quizás mejor
objetivo documentado en su solicitud

Sandeep Srinivasa [email protected] schrieb am Fr., 4 de enero de 2019,
11:37:

Esas son soluciones complejas: el protocolo proxy solo agrega un encabezado adicional
información y es un estándar muy conocido: haproxy, nginx, AWS elb,
etc todos lo siguen. https://www.haproxy.com/blog/haproxy/proxy-protocol/

La superficie del cambio se limitaría al Swarm incorporado
ingreso (donde se agregaría este soporte). Y todos los servicios lo tendrán
disponible.

El viernes 4 de enero de 2019 a las 14:36 ​​rubot < [email protected] escribió:

Incluso podría extender el proyecto dockerflow y agregar una variante nginx a
comienzo
kubernetes-ingressproxy para swarn. Definitivamente todo esto lleno de enjambre
generaría un contenedor de sistema adicional, ya que sabes que hay un montón de
ellos con kubernetes. ¿No es la fuerza del enjambre por un recurso escaso?
proyectos para ser lean?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Ene.2019, 09:48:

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De mi
perspectiva, incluso la declaración de mudarse a kubernetes no es una adecuada
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento. usted
cualquiera
tener un LB externo, o usar algo como el proxy de entrada nginx que
debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos el mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre necesita
ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019, 09:28:

@BretFisher https://github.com/BretFisher el modo: el host es solo un
alternativa pero no la solución. Como @sandys <
https://github.com/sandys>
dijo que la solución tiene algunas salvedades, no deberíamos considerar esto
asunto
como fijo.

No estoy seguro de si hay alguna mejora ya que la solución ha sido
descubierto. Me mudé a Kubernetes durante bastante tiempo y todavía
ser
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
>

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 , o
silencio
la amenaza
<
https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
.

La solución anterior requiere un enlace en modo host. Ese es el gran problema. Eso
elimina la posibilidad de utilizar el programador de la ventana acoplable para asignar contenedores
a diferentes hosts: ya no formo parte de la red de malla.

El viernes 4 de enero de 2019 a las 17:28, rubot < [email protected] escribió:

Como dije, verifique la solución de transmisión tcp anterior, que ya utiliza proxy
protocolo.
Agregar protocolo proxy requeriría también configuración dentro del contenedor si
añadido para pulular río arriba. No veo ningún valor, además de un limpiador y quizás mejor
objetivo documentado en su solicitud

Sandeep Srinivasa [email protected] schrieb am Fr., 4 de enero de 2019,
11:37:

Esas son soluciones complejas: el protocolo proxy solo agrega un encabezado adicional
información y es un estándar muy conocido: haproxy, nginx, AWS elb,
etc todos lo siguen. https://www.haproxy.com/blog/haproxy/proxy-protocol/

La superficie del cambio se limitaría al Swarm incorporado
ingreso (donde se agregaría este soporte). Y todos los servicios tendrán
eso
disponible.

El viernes 4 de enero de 2019 a las 14:36 ​​rubot < [email protected] escribió:

Incluso podría extender el proyecto dockerflow y agregar una variante nginx a
comienzo
kubernetes-ingressproxy para swarn. Definitivamente todo esto lleno de
enjambre
generaría un contenedor de sistema adicional, ya que sabes que hay un montón
de
ellos con kubernetes. ¿No es la fuerza del enjambre por un recurso escaso?
proyectos para ser lean?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Ene.2019, 09:48:

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De mi
perspectiva, incluso la declaración que se traslada a Kubernetes no es una
adecuado
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento. usted
cualquiera
tener un LB externo, o usar algo como el proxy de entrada nginx que
debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos la
mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien
podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre necesita
ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019, 09:28:

@BretFisher https://github.com/BretFisher el modo: el host es solo
a
alternativa pero no la solución. Como @sandys <
https://github.com/sandys>
dijo que la solución tiene algunas salvedades, no deberíamos considerar
esta
asunto
como fijo.

No estoy seguro de si hay alguna mejora, ya que la solución
estado
descubierto. Me mudé a Kubernetes durante bastante tiempo y
todavía
ser
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 , o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK
>

.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 , o
silencio
la amenaza
<
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451424992 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK
.

Como dije, la entrada de kubernetes nginx también necesita un enlace en modo host, llamado
daemonset. LB externo se conecta a los puertos de nodo, que también requieren el modo de host
en servicio, o configurar manualmente el protocolo proxy en servicio. Kubernetes
se ocupa de los mismos problemas, todavía.
Una posible solicitud de característica desde mi punto de vista para swarm sería
hacer que el proveedor de red sea enchufable. Esto haría posible utilizar
otras técnicas además de lvs / iptables

Sandeep Srinivasa [email protected] schrieb am Fr., 4 de enero de 2019,
13:05:

La solución anterior requiere un enlace en modo host. Ese es el gran problema. Eso
elimina la posibilidad de utilizar el programador de la ventana acoplable para asignar contenedores
a diferentes hosts: ya no formo parte de la red de malla.

El viernes 4 de enero de 2019 a las 17:28, rubot < [email protected] escribió:

Como dije, verifique la solución de transmisión tcp anterior, que ya utiliza proxy
protocolo.
Agregar protocolo proxy requeriría también configuración dentro del contenedor
si
añadido para pulular río arriba. No veo ningún valor, además de un limpiador y tal vez
mejor
objetivo documentado en su solicitud

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Ene.
2019,
11:37:

Esas son soluciones complejas: el protocolo proxy solo agrega más
encabezamiento
información y es un estándar muy conocido: haproxy, nginx, AWS
elba
etc todos lo siguen.
https://www.haproxy.com/blog/haproxy/proxy-protocol/

La superficie del cambio se limitaría al Swarm incorporado
ingreso (donde se agregaría este soporte). Y todos los servicios tendrán
eso
disponible.

El viernes 4 de enero de 2019 a las 14:36 ​​rubot < [email protected] escribió:

Incluso podría extender el proyecto dockerflow y agregar una variante nginx a
comienzo
kubernetes-ingressproxy para swarn. Definitivamente todo esto lleno de
enjambre
generaría un contenedor de sistema adicional, ya que sabes que hay un montón
de
ellos con kubernetes. ¿No es la fuerza del enjambre para adelgazar?
recurso
proyectos para ser lean?

Ruben Nicolaides [email protected] schrieb am Fr., 4 de enero de 2019,
09:48:

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De
mi
perspectiva, incluso la declaración que se traslada a Kubernetes no es una
adecuado
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento.
usted
cualquiera
tener un LB externo, o usar algo como el proxy de entrada nginx
cuales
debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos la
mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien
podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para
obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre necesita
para
ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019,
09:28:

@BretFisher https://github.com/BretFisher el modo: el host es
solamente
a
alternativa pero no la solución. Como @sandys <
https://github.com/sandys>
dijo que la solución tiene algunas salvedades, no deberíamos considerar
esta
asunto
como fijo.

No estoy seguro de si hay alguna mejora, ya que la solución
estado
descubierto. Me mudé a Kubernetes durante bastante tiempo y
todavía
ser
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
< https://github.com/moby/moby/issues/25526#issuecomment -451382365
,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

>

.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 , o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
>

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451424992 , o
silencio
la amenaza
<
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451426276 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK
.

Y solo para aclarar, la solución anterior tiene tcp stream frente al servicio
apoderado. Entonces, su solicitud definitivamente no es un error, sino una solicitud de función. Y
esta característica solo podría implementarse en enjambre, si el modo de red
cambiar, ya que el problema principal sigue siendo la pérdida de ip en el nivel Nat / host

Ruben Nicolaides [email protected] schrieb am Fr., 4. Ene.2019, 13:11:

Como dije, la entrada de kubernetes nginx también necesita un enlace en modo host, llamado
daemonset. LB externo se conecta a los puertos de nodo, que también requieren el modo de host
en servicio, o configurar manualmente el protocolo proxy en servicio. Kubernetes
se ocupa de los mismos problemas, todavía.
Una posible solicitud de característica desde mi punto de vista para swarm sería
hacer que el proveedor de red sea enchufable. Esto haría posible utilizar
otras técnicas además de lvs / iptables

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Ene.
2019, 13:05:

La solución anterior requiere un enlace en modo host. Ese es el gran problema. Eso
elimina la posibilidad de utilizar el programador de la ventana acoplable para asignar
contenedores
a diferentes hosts: ya no formo parte de la red de malla.

El viernes 4 de enero de 2019 a las 17:28, rubot < [email protected] escribió:

Como dije, verifique la solución de transmisión tcp anterior, que ya utiliza proxy
protocolo.
Agregar protocolo proxy requeriría también configuración dentro del contenedor
si
añadido para pulular río arriba. No veo ningún valor, además de un limpiador y tal vez
mejor
objetivo documentado en su solicitud

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Ene.
2019,
11:37:

Esas son soluciones complejas: el protocolo proxy solo agrega más
encabezamiento
información y es un estándar muy conocido: haproxy, nginx, AWS
elba
etc todos lo siguen.
https://www.haproxy.com/blog/haproxy/proxy-protocol/

La superficie del cambio se limitaría al Swarm incorporado
ingreso (donde se agregaría este soporte). Y todos los servicios
tengo
eso
disponible.

El viernes 4 de enero de 2019 a las 14:36 ​​rubot < [email protected] escribió:

Incluso podría extender el proyecto dockerflow y agregar una variante nginx a
comienzo
kubernetes-ingressproxy para swarn. Definitivamente todo esto lleno de
enjambre
generaría un contenedor de sistema adicional, ya que sabes que hay un
racimo
de
ellos con kubernetes. ¿No es la fuerza del enjambre para adelgazar?
recurso
proyectos para ser lean?

Ruben Nicolaides [email protected] schrieb am Fr., 4 de enero de 2019,
09:48:

Todavía estoy un poco sorprendido de por qué la gente piensa que esto es un error. De
mi
perspectiva, incluso la declaración que se traslada a Kubernetes no es una
adecuado
respuesta. Como veo, kubernetes tiene exactamente el mismo problema / comportamiento.
usted
cualquiera
tener un LB externo, o usar algo como el proxy de entrada nginx
cuales
debe
ejecutar como daemonset. Por favor corríjame si me equivoco, pero tenemos la
mismo
situación exacta aquí, pero aquí no hay autosolución preparada. Alguien
podría
verifique y empaque mi solución de flujo tcp propuesta descrita anteriormente para
obtener
algo como el comportamiento del proxy nginx. Solo acepta, ese enjambre
necesita
ser
personalizado por ti mismo

PanJ [email protected] schrieb am Fr., 4 de enero de 2019,
09:28:

@BretFisher https://github.com/BretFisher el modo: el host es
solamente
a
alternativa pero no la solución. Como @sandys <
https://github.com/sandys>
dijo que la solución tiene algunas salvedades, no deberíamos considerar
esta
asunto
como fijo.

No estoy seguro de si hay alguna mejora, ya que la solución
estado
descubierto. Me mudé a Kubernetes durante bastante tiempo y
todavía
ser
Me sorprende que el tema siga abierto desde hace más de dos años.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
<
https://github.com/moby/moby/issues/25526#issuecomment-451382365>,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

>

.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 ,
o
silencio
la amenaza
<

https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
>

.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451424992 , o
silencio
la amenaza
<
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

.

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451426276 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK
.

  1. después de un hilo tan largo, estaba tratando de documentar el conjunto de características actual con un ejemplo completo.
  2. No veo su necesidad específica en la solicitud del OP. @PanJ pidió ver la IP del cliente usar , lo que a partir de mediados de 2018 puede hacer. No veo que requieran que también use una malla de enrutamiento de entrada.

Ya sea que lo llame un error o una solicitud de función, la malla de entrada sin fuente nat es (en mi opinión) esencial. Hay muchas aplicaciones que se rompen cuando no pueden ver la verdadera IP de origen. Claro, en el caso de los servidores web, puede invertir el proxy utilizando un nodo host y agregar encabezados IP de cliente. Sin embargo, esto agrega gastos generales y probablemente no sea una opción para aplicaciones no basadas en web. Con una aplicación que realmente necesita que la IP de origen real en el paquete sea correcta, la única opción es no usar la malla de entrada. Eso elimina una gran parte del beneficio de usar swarm en primer lugar.

Háganos saber cuándo se ha solucionado este problema o no.
¿Deberíamos usar kuberneties en su lugar?

Corrí en el mismo problema ... no he encontrado una solución en este momento.

Cuando alguien encuentre una solución para este comportamiento, infórmelo aquí.

¡Gracias!

Tengo el mismo problema. Tengo un servidor httpd apache y quiero registrar todos los accesos para extraer estadísticas más adelante sobre los países de los que estamos recibiendo solicitudes.

Me encontré con este problema mientras intentaba averiguar por qué php: apache no registraba correctamente el campo del encabezado del host. Estoy sorprendido y decepcionado de que esto aún no esté funcionando después de todos estos años. ¿Cómo se supone que usemos el modo Swarm para el alojamiento web cuando el campo del host sigue registrando la IP del proxy del usuario? No he podido encontrar una forma de evitar esto con el modo Swarm. Supongo que podría usar Classic Swarm (basado en contenedores) y algo como Consul, pero siento que eso va al revés.

Encontré una solución aceptable para mi escenario:

services:
  server:
    image: httpd:2
    deploy:
      mode: global
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    networks:
      - my_second_service
      - another_great_software

Esto hará que apache escuche en la computadora host en lugar de detrás de la red superpuesta (leyendo la dirección IP remota adecuada), mientras sigue enviando solicitudes a otros servicios a través de las opciones networks y logrando "alta disponibilidad" al tenerlo corriendo por todas partes

@rafaelsierra : este es el problema que tengo con esto (y

@SysEngDan sí, es cierto que solo puede tener un único contenedor que se vincule a los puertos 80/443, pero en mi caso eso no es un problema porque el contenedor que se une a este puerto solo es responsable de enviar todas las solicitudes a otros contenedores. que se ejecutan detrás de la red superpuesta.

Probablemente pueda usar la misma solución al tener un solo contenedor nginx / apache que reciba todas las solicitudes y haga un proxy al contenedor adecuado según el vhost, y esos contenedores no tienen que vincularse al host

@rafaelsierra - Respetuosamente, no estoy seguro de que entienda el problema documentado en este ticket. Si configuro servicios como mencionaste en tu último párrafo, el problema es que la IP del cliente no se pasa a los contenedores que solo escuchan en la red superpuesta. Si me vinculo directamente al host, no hay problema. Si confiamos en el proxy de la red de la ventana acoplable de externo (host) a interno (superposición), el contenedor Apache de destino no recibirá la dirección IP del cliente original, sino la IP del proxy (de la red de la ventana acoplable).

@SysEngDan Entiendo el problema, y ​​dado que no hay solución durante los últimos 2 años (y honestamente no estoy seguro de si esto es "reparable"), tuve que encontrar una solución alternativa que se adapte a mis necesidades (restringir el acceso basado en la dirección IP remota).

Tener un solo contenedor escuchando en el puerto 80/443 en el host y luego haciendo proxy a otros contenedores (con encabezados HTTP apropiados que no mencioné porque está fuera del alcance de este problema) resolvió mi problema y quería compartir esta solución para las personas que enfrentan un problema similar debido a que las redes superpuestas no pueden pasar la dirección IP remota

Oh, veo lo que hiciste allí ... lo siento, me perdí eso. Corta la red superpuesta y en su lugar adjunta su contenedor externo directamente a la red de servicio (la que se crea automáticamente cuando inicia un nuevo servicio sin especificar una red). Ok, creo que funciona. La sobrecarga agregada es la tarea de agregar la red de servicio al archivo docker-compose. Me pregunto qué sucede cuando se inicia el contenedor de host y uno de esos servicios no está disponible.

En ese caso, obtendrá un 502.

No tengo un solo docker-compose.yml, tengo múltiples pilas con múltiples servicios que se comunican entre sí a través de una red superpuesta, y luego tengo el servicio público que se vincula al servidor host pero aún tengo acceso al todas las demás redes superpuestas para que pueda enviar todas las solicitudes.

La solución alternativa del modo de host ya se ha discutido varias veces sobre este tema. Si bien puede estar bien para algunos escenarios limitados (como ciertas configuraciones de tráfico web de proxy inverso), no es una solución general para este problema. Lea las publicaciones anteriores en lugar de volver a aplicar el hash a las mismas "soluciones" una vez más.

@darrellenns, hay más de 200 comentarios aquí, creo que sería mejor bloquear y limpiar este problema proporcionando la solución básica "solo use el enlace de host si se aplica a usted", mientras que no hay una solución oficial si se proporciona, de lo contrario, más personas como yo se perderán eso y seguir comentando las mismas cosas una y otra vez

Entonces, creo que este error afecta la capacidad de traefik para incluir ips en la lista blanca. ¿Es eso correcto?

De todos modos, para cualquiera que busque ejecutar el modo enjambre, este es un ejemplo del uso del modo host para publicar puertos.

docker service create \
--name traefik \
--constraint=node.role==manager \
--publish mode=host,target=80,published=80 \
--publish mode=host,target=443,published=443 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/home/$USER/dev-ops/logs,target=/dev-ops/logs \
--mount type=bind,source=/opt/data/traefik/traefik.toml,target=/traefik.toml \
--mount type=bind,source=/opt/data/traefik/acme.json,target=/acme.json \
--network traefik \
--label traefik.frontend.rule=Host:traefik.example.com \
--label traefik.port=8080 \
traefik \
--docker \
--docker.swarmMode \
--docker.watch \
--docker.exposedByDefault

@coltenkrauter No sé exactamente a qué afecta, pero en modo host solo puedo ejecutar una réplica del servicio traefik, y no creo que sea solo yo. De esta manera, tengo que confiar plenamente en la estabilidad de traefik sin depender de la función de modo de enjambre para los servicios.

Además, como se informó por primera vez, no tiene mucho que ver con las necesidades especiales traefik, se probó con un servicio http genérico que no recibe la ip original, eso significa que el modo de enjambre de la ventana acoplable está roto (falta esta característica importante), y parece que a nadie le importa.

Y quiero seguir comentando sobre esto, porque espero que nois esté molestando a alguien que preferiría arreglarlo :) (lo siento, me aplica lo mismo de mis usuarios)

en modo host solo puedo ejecutar una réplica del servicio traefik, y no creo que sea solo yo. De esta manera, tengo que confiar plenamente en la estabilidad de traefik sin depender de la función de modo de enjambre para los servicios.

Puede ejecutar una instancia por host

en modo host solo puedo ejecutar una réplica del servicio traefik, y no creo que sea solo yo. De esta manera, tengo que confiar plenamente en la estabilidad de traefik sin depender de la función de modo de enjambre para los servicios.

Puede ejecutar una instancia por host

sí, pero traefik se ve obligado a trabajar en el nodo administrador, porque necesita que esto funcione correctamente. Entonces, un nodo administrador, un host, una instancia

traefik puede trabajar fuera de los nodos del administrador de múltiples maneras, incluido el uso de un
Proxy de socket de Docker, socket remoto o empresa traefik. aquí hay un
ejemplo de archivo de pila para saber cómo hacer eso:
https://github.com/BretFisher/dogvscat/blob/master/stack-proxy-global.yml

El sábado 16 de marzo de 2019 a las 5:25 p.m. Daniele Cruciani [email protected]
escribió:

en modo host solo puedo ejecutar una réplica del servicio traefik, y no
creo que soy solo yo. De esta manera tengo que confiar plenamente en la estabilidad traefik.
sin depender de la función de modo enjambre para los servicios.

Puede ejecutar una instancia por host

ya, pero traefik se ve obligado a trabajar en el nodo administrador, porque necesita esto
para que funcione correctamente. Entonces, un nodo administrador, un host, una instancia

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-473593956 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAwW31DHIwEJE1EqN3-8qj44WopocuQTks5vXWE_gaJpZM4Jf2WK
.

Es interesante saberlo, pero vea, esta función está disponible en kubernetes pero no en el modo de enjambre de la ventana acoplable, e insiste en que hay opciones para ejecutar múltiples instancias de traefik, pero en múltiples nodos, si quiero ejecutar múltiples instancias en un solo nodo, no es posible, porque esto no es compatible.
Además, cualquier otro servicio, que no solo envía solicitudes de proxy, no puede mapear ningún puerto, porque necesita un tipo especial de configuración que necesita mapear cada host a él, y de todos modos necesita múltiples nodos, al menos uno por instancia. .

Y así sucesivamente y así sucesivamente. Puede desplazarse hacia arriba en esta discusión y encontrar otras preocupaciones al respecto. No creo que pueda reducirse a una demostración de lo bueno que eres para producir una solución alternativa, porque sigue siendo una solución difícil de mantener y difícil de seguir. Y todo el tiempo dedicado a mantener la solución de casos especiales se invierte mejor en solucionar el problema.

Por otro lado, si este tipo de característica es un problema de seguridad para el modelo de docker swarm, simplemente márquelo como wontfix y planearía cambiar a kubernetes, si es el caso, no creo que haya conflicto entre proyectos, solo dice explícitamente que nunca sucederá, por lo que todos pueden tomar medidas, si es posible, antes de la elección del modo de enjambre de la ventana acoplable para cualquier tipo de enjambre de nodos

Hay muchas funciones en kubernetes que no están en enjambre y viceversa. Todos tomamos decisiones sobre qué orquestador utilizar para una solución específica en función de muchos factores, incluidas las funciones. Ninguna herramienta resuelve todos los problemas / necesidades.

Solo soy un miembro de la comunidad que intenta ayudar. Si no le gustan las soluciones actuales para este problema, parece que debería buscar otras formas de resolverlo, posiblemente con algo como kubernetes. Esa es una razón razonable para elegir un orquestador sobre otro si cree que la forma de resolverlo de Kubernetes es más de su agrado.

Históricamente, los mantenedores de moby y swarm no cierran problemas como este como solían arreglar porque mañana alguien de la comunidad podría dejar un PR con una solución a este problema. Además, creo que discutir las formas de solucionarlo hasta entonces es un uso válido de este hilo temático. :)

Si bien no soy un mantenedor de enjambres, puedo decir que históricamente el equipo no revela planes de funciones futuras más allá de los PR que puede ver actualmente obteniendo confirmaciones en los repositorios.

Olvidé decir que, por supuesto, su comentario es bienvenido (o lo dije de una manera oscura, lo siento). Pero me gusta reforzar el informe original de @PanJ :

Mientras tanto, creo que tengo que hacer una solución que consiste en ejecutar un contenedor proxy fuera del modo enjambre y dejar que se reenvíe al puerto publicado en modo enjambre (la terminación SSL también debe realizarse en este contenedor), lo que rompe el propósito de enjambre modo de autocuración y orquestación.

Quiero decir que esto "rompe el propósito del modo de enjambre", por supuesto, solo en este tema específico, es suficiente para merecer más atención.

Estoy tratando de que mi equipo cree un PR que agregue el protocolo proxy a
la red de ingreso. No somos programadores de Golang, así que lo encontramos un poco
difícil.

Pero espero fervientemente que el equipo de Docker esté de acuerdo en que lo mejor y más
La solución compatible (en todo el ecosistema) es superponer el protocolo proxy
apoyo a la red de ingreso.

La complejidad viene del hecho de que la red de entrada no solo tiene que
inyectar sus propios encabezados, pero tiene que admitir el hecho de que puede haber
encabezados de protocolo proxy ascendentes ya insertados (por ejemplo, Google LB o
AWS ELB).

El domingo, 17 de marzo de 2019, 12:17 Daniele Cruciani, [email protected]
escribió:

Olvidé decir que, por supuesto, su comentario es bienvenido (o lo dije en un
manera oscura, lo siento). Pero me gusta reforzar el @PanJ original
https://github.com/PanJ informe:

Mientras tanto, creo que tengo que hacer una solución que está ejecutando un
contenedor proxy fuera del modo enjambre y dejar que se reenvíe al puerto publicado
en modo enjambre (la terminación SSL también debe realizarse en este contenedor), que
rompe el propósito del modo enjambre para la autocuración y la orquestación.

Quiero decir que esto "rompe el propósito del modo enjambre", por supuesto, solo en este
tema específico, es suficiente para merecer más atención.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-473621667 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUwNWJsGKlLejcNzS2pR0awBB4OVlks5vXeTugaJpZM4Jf2WK
.

https://stackoverflow.com/questions/50585616/kubernetes-metallb-traefik-how-to-get-real-client-ip
Como se solicitó para k8s donde está en capas, completamente y configurable

Para cualquiera que ejecute nginx en digitalocean con docker swarm e intente obtener el $remote_addr real en lugar de solo 10.255.0.2 dentro de sus registros de nginx; puedes usar la solución de @coltenkrauter. El problema es que sólo se puede ejecutar un contenedor nginx en el host con esta solución, que debe ser aceptable para la mayoría de la gente.

Simplemente cambie su archivo docker-compose.yml :

INCORRECTO

services:
  nginx:
    ports:
      - "80:80"
      - "443:443"

CORRECTO

services:
  nginx:
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

_editar: ahora todos tenemos la garantía de obtener la respuesta correcta_

No usar la entrada ( mode: host ) no es una solución alternativa, cuando el problema indica que el problema ocurre con las redes de entrada.
Nadie usaría un solo host como proxy inverso. Desea varios hosts con una ip flotante, y la malla de enjambre es obligatoria para lograr esta configuración.

Tal vez no sea posible, pero pensé que modificar las reglas de iptables para hacer MASQUERADE en algún momento de las cadenas INGRESS sería una solución alternativa para preservar la IP de origen real. ¿No hay algunos expertos en iptables / netfilter?

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-INGRESS  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (2 references)
target     prot opt source               destination         

Chain DOCKER-INGRESS (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

Como alternativa, ¿no puede swarm simplemente tomar la ip de origen original y crear un encabezado X-Forwarded-For ?

Nadie usaría un solo host como proxy inverso. Desea varios hosts con una ip flotante, y la malla de enjambre es obligatoria para lograr esta configuración.

Cada nodo del enjambre puede ejecutar una instancia del proxy inverso y enrutar el tráfico a los servicios subyacentes a través de una red superpuesta (pero solo el proxy conocería la dirección IP original).

Asegúrate de leer todo el hilo (veo que GitHub esconde algunos comentarios muy útiles, así que tendrás que expandirlos: decepcionado :);

Como alternativa, ¿no puede swarm simplemente tomar la ip de origen original y crear un encabezado X-Forwarded-For ?

Ver https://github.com/moby/moby/issues/25526#issuecomment -367642600; X-Forwarded-For es el protocolo L7; El ingreso del enjambre es L4, usando IPVS con DNAT

@ port22 generalmente estamos de acuerdo en que una solución alternativa no es una solución, una solución es hacerlo en capas, vea la propuesta de @sandys en el comentario # 25526

Como alternativa, no se puede enjambre simplemente tomar la IP de origen original y crear

un encabezado X-Forward-For?
Ver # 25526 (comentario)
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Fordered-For es el protocolo L7; El ingreso del enjambre es L4, usando IPVS con DNAT

la solución correcta aquí es el protocolo proxy inyectado en L4. hay algunos
discusiones relevantes a favor y en contra en Envoy para el mismo caso de uso
https://github.com/envoyproxy/envoy/issues/4128 y
https://github.com/envoyproxy/envoy/issues/1031

El miércoles, 10 de abril de 2019 a las 1:40 a. M. Sebastiaan van Stijn <
[email protected]> escribió:

Nadie usaría un solo host como proxy inverso. Quieres múltiples
hosts con una ip flotante, y la malla de enjambre es obligatoria para lograr esto
configuración.

Cada nodo del enjambre puede ejecutar una instancia del proxy inverso y enrutar
tráfico a los servicios subyacentes a través de una red superpuesta (pero solo el
proxy sabría acerca de la dirección IP original).

Asegúrese de leer todo el hilo (veo que GitHub esconde algunos
comentarios, así que tendrás que expandirlos 😞);

Como alternativa, no se puede enjambre simplemente tomar la IP de origen original y crear
un encabezado X-Forward-For?

Ver # 25526 (comentario)
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Fordered-For es el protocolo L7; El ingreso del enjambre es L4, usando IPVS con DNAT

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-481415217 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsU5KdnWQ21hJx_xzc-QROJiWbAlulks5vfPOigaJpZM4Jf2WK
.

Cada nodo del enjambre puede ejecutar una instancia del proxy inverso

Esto elimina la función del equilibrador de carga de enjambre, de lo que se trata realmente ese problema.
Y mi problema para ser específico es que traefik no es ágil para clústeres. Debe ejecutarse de forma independiente a menos que esté utilizando consul como un backend de configuración, que luego limita el número máximo de certificados a ~ 100, lo cual no es aplicable para mí. Claro, puede afirmar que este no es un problema de enjambre, sino un problema de traefik. Dato curioso: traefik afirma que este es un problema de cónsul. el cónsul dice: traefik lo hace mal.

@ port22 generalmente estamos de acuerdo en que una solución alternativa no es una solución

Mi punto es que NO usar la entrada no es una solución cuando NECESITA la entrada. Una solución alternativa sería algo que hiciera posible seguir usando el balanceador de carga de enjambre mientras se conserva la IP de origen, incluso si requiere alguna piratería.

usando IPVS con DNAT

por lo tanto, estaba pensando que se podría hacer con MASQUERADE dentro de la regla / cadena DNAT. ?

@ port22 Entendí su punto, pero la
Tal vez debería haber opciones como las que existen para la red de puente https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
así que para simplificar la configuración de esto, pero aún así el problema principal es la falta de soporte en la red de superposición. Entonces, las opciones no están allí, porque se ignorarían, y dockerd reescribirá las reglas si se modifica desde afuera.

He presentado una solicitud de función de compatibilidad con el protocolo proxy para resolver el
problema en este error.

En caso de que alguien quiera agregar sus comentarios.

https://github.com/moby/moby/issues/39465

El miércoles 10 de abril de 2019 a las 21:37 Daniele Cruciani, [email protected]
escribió:

@ port22 https://github.com/port22 Tengo tu punto, pero la ventana acoplable administra
sus redes por sí mismo, traté de hacerlo funcionar con shorewall, pero el
La única forma es crear excepciones para las reglas / cadenas de la ventana acoplable, y no tenía
éxito con el modo de enjambre de la ventana acoplable (pero está bien para la ventana acoplable en el modo de enjambre, ya que
lejos, desactivo todos los servicios menos los que se encuentran en el enjambre)
Tal vez debería haber opciones como las que existen para la red de puentes
https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
así que para simplificar la configuración de esto, pero aún así el problema principal es el
Falta soporte en la red superpuesta. Entonces las opciones no están ahí, porque
esos serían ignorados, y dockerd reescribirá las reglas si se modifican desde
fuera de.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526#issuecomment-481754635 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAEsUxsVQ7m9uiYbHhNKMMtkhTZV6iTNks5vfgwygaJpZM4Jf2WK
.

Después de 3 años, ¿no hay solución?

También tengo el mismo problema pero con haproxy. Aunque está bien tener servidores proxy en modo host y HA usando keepalived, la única parte que falta sería el equilibrio de carga que creo que no es un gran problema para un proxy web simple. A menos que se incluyan scripts complicados o que el proxy y el backend no estén en la misma máquina física y el tráfico de red sea demasiado alto para una NIC y ...

Entonces, ¿realmente no es posible ver la dirección IP de origen de una solicitud desde fuera de un Docker Swarm en lugar de la dirección privada de la red superpuesta interna? ¿Todavía?

@thaJeztah ¿Alguien del equipo de Docker Inc puede actualizarnos sobre el estado de este problema? ¿Todavía se está considerando y / o se está trabajando? ¿Alguna ETA? ¿O esto se ignora por completo desde la integración de Docker con Kubernetes? Se informó hace casi 3 años: /

@thaJeztah https://github.com/thaJeztah ¿Puede alguien en Docker Inc
El equipo nos actualiza sobre el estado de este problema. ¿Todavía se está considerando?
y / o trabajado? ¿Alguna ETA? ¿O esto se ignora por completo ya que Docker
integración con Kubernetes? Se informó hace casi 3 años: /

Realmente sería bueno obtener esta declaración ("no se solucionará") para que pueda
justificar una migración a kubernetes. Es una pena.

Gracias.

>

hay una solicitud de mejora propuesta que debería solucionar esto: https://github.com/moby/moby/issues/39465

por favor agregue sus pensamientos y comentarios allí

Ya he estado comentando sobre ese tema :-)

Este ha sido un bloqueador para mí durante algún tiempo. Necesito pasar a través de las direcciones IP y después de mucha búsqueda (wow, casi 3 años de búsqueda junto con los demás en este hilo ...) aún no he encontrado ninguna solución que funcione con swarm.

No he podido usar swarm en producción debido a este problema y estoy esperando una respuesta oficial si se puede agregar o no. Si esto no se agrega, las soluciones alternativas propuestas son bienvenidas.

Nos encontramos con el mismo problema al usar traefik detrás de haproxy. Me sorprendió ver que esto tiene 254 comentarios desde 2016.

@Betriebsrat ¿

Creo que esta "solución" se mencionó varias veces, pero la gente sigue perdiéndola.

También sé que a veces no es una opción, pero creo que la mayoría de las veces debería ser posible.

@ajardan esa solución que he probado y no es viable para mí ya que tengo más de un host para responder en la interfaz. Idealmente, quiero que todo el enjambre pueda enrutar las solicitudes. Estoy de acuerdo en que para operaciones a pequeña escala, simplemente cambiar un servicio al modo host y usarlo como servidor de ingesta puede funcionar bien.

Colocar algo como traefik en modo host niega los beneficios que estamos tratando de aprovechar al usar swarm, aunque en la mayoría de los casos :(

@pattonwebz El modo de host se puede habilitar para un servicio que ejecuta varios contenedores en varios hosts, incluso puede hacerlo con mode = global. Luego traefik se ejecutará en todos sus nodos de enjambre y aceptará conexiones a puertos específicos, luego enrutará las solicitudes internamente a los servicios que necesitan ver estas conexiones.

Usé esta configuración con un servicio en modo global pero limitado a los nodos de administrador, y estaba funcionando perfectamente bien para decenas de miles de solicitudes / s

Estaría feliz de explicarlo si se requieren más detalles.

@pattonwebz @ajardan Estoy usando un servicio haproxy configurable para todos estos casos. haproxy usa solo 2 MB de RAM en mi caso. Creo que eso es insignificante.

@pattonwebz Además de la solución de @ajardan anterior, puede ejecutar https://hub.docker.com/r/decentralize/swarm-tcp-proxy en modo global con redes de host para agregar compatibilidad con el protocolo PROXY al tráfico entrante, y luego reenviarlo a Traefik configurado para decodificar los encabezados del protocolo proxy.

Debería ser solo una bandera como parte de Docker Swarm propiamente dicho, no todos estos
soluciones complicadas en mi humilde opinión.

Solo usamos haproxy para administrar certificados y descargar ssl.
La gente sigue perdiendo que la solución "en ejecución en modo host" no es una solución.
Quieren que funcione con la red de entrada para aprovechar el equilibrio de carga de la ventana acoplable.
Todo el hilo es básicamente un 'use hostmode' -> 'no es posible debido a que el círculo de "razones"' está funcionando desde hace 3 años.

Miraré swarm-tcp-proxy como una alternativa viable aquí nuevamente, sin embargo, al mirar cosas similares en el pasado, algo siempre terminó siendo un vaso de precipitados para mí con tales ideas.

En un mundo perfecto, mi enjambre existente (y funcionando bien con la excepción de que no hay capacidad para recuperar la IP real del cliente) simplemente estaría funcionando y pasando a través de los datos de IP sin necesidad de capas de servicio adicionales o más proxies sobre proxies.

La gente sigue perdiendo que la solución "en ejecución en modo host" no es una solución.

No es una solución en sí misma , pero se puede utilizar (y se está utilizando) con mucho éxito como solución alternativa. Aún puede usar el equilibrador de carga nativo de Docker ; todo lo que está haciendo es agregar una capa a la pila de la red del host antes de llegar a la malla de servicios de Docker.

@Betriebsrat traefik puede hacer certificados y SSL muy bien, así que todavía no estoy seguro de por qué es necesario.

Además, como lo mencionó @matthanley antes, el equilibrio de carga de la

Esto se puede configurar incluso por servicio, por lo que es bastante flexible.

Puede intentar configurar otro servidor Nginx fuera del clúster de enjambre de docker y reenviar la solicitud al servicio de enjambre. en esta configuración de Niginx solo agregue los encabezados de avance. p.ej.
localización / {
proxy_pass http: // phpestate;

    #Proxy Settings
    proxy_redirect     off;
    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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

Parece que no hay solución para obtener una IP de cliente real en el modo de enjambre de la ventana acoplable.

Vimos el mismo problema y lo solucionamos implementando:
https://github.com/moby/moby/issues/25526#issuecomment -475083415

No es una solución ideal ya que no podemos ejecutar varios contenedores de entrada en un solo nodo (supongo que ahora son globales)

La dificultad es que Docker se ocupa de TCP / UDP, mientras que este es un problema de protocolo HTTP. Como mínimo, desearía que Docker "falsificara" la IP de origen como el host remoto en lugar de dar su propia IP interna desde Swarm Mesh ... pero eso probablemente rompería las cosas ya que el tráfico de retorno iría al lugar equivocado.

La forma más sencilla sería agregar el encabezado de la IP original para cada solicitud http.

Correcto. Solo para ser específico, como un encabezado de protocolo proxy que funciona en l4
y l7 y es aceptado por la mayoría de software de aplicación conocido (así como
grandes proveedores de nube).

He presentado un error por separado para eso, que está vinculado a algunos comentarios
encima. Agregue a ese error si está interesado

El jueves 5 de septiembre de 2019 a las 18:56 Vladimir, [email protected] escribió:

La forma más sencilla sería agregar el encabezado de la IP original para cada
solicitud http.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/25526?email_source=notifications&email_token=AAASYU7APUNJPLZ6AJ6XXMDQIECIJA5CNFSM4CL7MWFKYY3PNVWWK3TUL52HS4DFVREXG43VMDVBW63 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAASYU4VZGKUFLL5STZ44GDQIECIJANCNFSM4CL7MWFA
.

¿Es 2019 y esto sigue siendo un problema? Hace que la lista blanca de ip en traefik sea una molestia. No debería necesitar puertos de host en cada nodo.

@kaysond, nuestra posición ha sido renunciar a Swarm. Nos hemos trasladado a AWS y ECS. Lamento no poder publicar algo más constructivo pero, en última instancia, necesitamos algo que funcione; Este no es el único error importante de Swarm (o la falta de funciones) que nos afecta a nosotros y a otros que no han recibido ninguna corrección / retroalimentación aparente en los últimos años. Muy decepcionante, pero ahí.

@jmkgreen estamos en la misma posición y hemos pasado los últimos 6 meses o más alejándonos del enjambre de ventanas acoplables a otras cosas debido a que este problema sigue en curso. Ya he invertido decenas de horas y cientos de horas de tiempo de los miembros del equipo en esto sin encontrar nunca una solución aceptable. La vinculación a todos los puertos host anula totalmente el propósito de nuestros LB flotantes :(

¿Cuál es su problema con la solución? Declara su servicio en modo host + global y configura su LB para acceder a todos los nodos, funciona. Debido a que el proxy es liviano (uso nginx porque hago descargas de https y otras cosas), el hecho de que esté implementado en todos los servidores no es un problema, usa menos del 1% de un recurso del servidor. Puedo ayudarte si encuentras algún error durante el proceso ([email protected]).

¿Cuál es su problema con la solución? Declara su servicio en modo host + global y configura su LB para acceder a todos los nodos, funciona.

@RemiBou Cuando el propio proxy necesita ser actualizado / reiniciado, el balanceador de carga externo no detecta inmediatamente la interrupción y sigue enviando solicitudes a los nodos donde el proxy aún se está reiniciando. Por lo tanto, hay una interrupción de ~ 30 segundos dependiendo de la configuración de LB externa.

Tampoco hay forma en Swarm de poner un enlace en el proceso de actualización del servicio para llamar al equilibrador de carga externo y sacar un nodo de servicio durante la actualización. Tampoco puede activar una secuencia de comandos para que se ejecute dentro del contenedor antes de que se actualice (por ejemplo, para eliminar una marca " i_am_healthy " y dejar que el LB externo descubra que está fuera de servicio mediante sondeo).

¿Cuál es su problema con la solución?

Mi problema es que con esa solución es imposible para mí ejecutar varios del mismo servicio (o varios servicios que quieren los mismos puertos) en el host. Esa es una necesidad para los proyectos en los que trabajo.

De hecho, pero ¿no puede implementar un servicio proxy que solo haga esto y luego, cuando la ip esté dentro del enjambre, puede reenviarlo como encabezado http a sus otros servicios?

De hecho, pero ¿no puede implementar un servicio proxy que solo haga esto y luego, cuando la ip esté dentro del enjambre, puede reenviarlo como encabezado http a sus otros servicios?

Sí ... y siempre que ese servicio de proxy delgado nunca necesite ser reconfigurado o actualizado, es posible actualizar los componentes detrás de él usando Swarm LB para evitar el tiempo de inactividad.

Alguien señaló https://hub.docker.com/r/decentralize/swarm-tcp-proxy que usa haproxy para hacerlo.

Sin embargo, es un poco doloroso. Y si tiene que actualizar el proxy, todavía tiene tiempo de inactividad.

@ ms1111 Inicio de la imagen de la

¿Cuál es su problema con la solución?

En nuestro caso, es la combinación de esta solución con la incapacidad de vincular un puerto expuesto al host a una dirección IP específica. En cambio, todos los servicios internos que necesitan la IP del visitante real y admiten el protocolo PROXY, tienen su puerto expuesto en 0.0.0.0 en el host, que es menos que óptimo.

Otro es el impacto de rendimiento no despreciable cuando tiene cientos de nuevas conexiones por segundo: todos los puertos expuestos son en realidad reglas DNAT en iptables que requieren conntrack y tienen otros problemas (también golpea k8s, pero Swarm tiene esto nivel adicional de NAT que lo empeoran).

Para Docker,

¡Despierta! Existe un problema obvio dada la cantidad de personas involucradas en este tema (hay otras con la misma causa). Todo lo que recibimos son personas que repiten una y otra vez que hay una solución alternativa, a pesar de que se ha explicado varias veces por qué esa solución no es una solución. La misma palabra "solución alternativa" indica que es algo temporal que se resolverá más adelante. Han pasado más de 3 años desde que se creó el problema y durante todo ese tiempo la respuesta es "hay una solución".

A todos los usuarios de Swarm,

Seamos realistas. La triste verdad es que nadie, incluido Docker, se preocupa realmente por Swarm. Todos pasaron a k8s y no hay inversiones "reales" en Swarm. El proyecto está en soporte vital esperando morir, así que no espere que se solucione este problema. Sea inteligente y pase a k8s.

Este problema parece ignorarse durante demasiado tiempo. Parece que nunca se va a implementar. Simplemente vaya al grano y use k8s.

@leojonathanoh, ¿podrías explicar cómo resuelve exactamente k8s este problema en particular :)?

Simple: protocolo proxy

@ajatkj Como se dijo. O, si eso no es posible, entonces un balanceador de carga externo y externalTrafficPolicy: Local en el recurso Service . Eso es todo lo que diré aquí. Y me daré de baja del hilo.

¿Por qué la gente espera que otras personas hagan el trabajo por ellos?

Me encantaría ser el héroe y ocuparme de esto, pero la realidad es que estoy trabajando en muchas otras cosas y esto no tiene ningún efecto en mi día a día. ¿Esto afecta tu día a día? ¡Nos encantaría recibir ayuda para resolver esto!

También he visto esto varias veces y realmente no parece que haya una manera de hacer que esto funcione con IPVS NAT, que es lo que está usando el enrutamiento de enjambre mágico.

Estoy de acuerdo en que k8s es mucho más flexible aquí. Si se adapta mejor a sus necesidades, utilícelo.
Quejarse de que no está arreglado y luego amenazar con cambiar a k8s realmente no tiene lugar en nuestro rastreador de problemas y, en general, no es útil.

La gente ayuda con el conocimiento que tiene. No todos tienen el conjunto de habilidades para cambiar el código por sí mismos, por lo que crean problemas como este para ayudar a lograr un consenso sobre el cambio necesario.

Nadie aquí está argumentando que usted tiene que hacer los cambios específicamente, pero incluso en los problemas abiertos por @sandys sobre el protocolo de proxy, el equipo central acordó los cambios. Entonces, ¿cómo puede alguien trabajar en esto si no sabe si se aceptará el cambio?

La mejor manera es hacer una propuesta, es decir. cómo espera que se vea la arquitectura después de que el trabajo esté terminado. ¿Qué trae? ¿Qué perdemos?

prueba la red en modo host

La mejor manera es hacer una propuesta, es decir. cómo espera que se vea la arquitectura después de que el trabajo esté terminado. ¿Qué trae? ¿Qué perdemos?

Ya hecho aquí: # 39465

prueba la red en modo host

Lea todo el hilo antes de comentar.

"Utilice el protocolo proxy", aunque de hecho es interesante no establece lo que
es necesario realizar cambios en la base del código.

Tal vez esta sea una pregunta ingenua, pero ¿por qué es necesario volver a escribir la IP de origen para empezar? ¿No se devolvería el tráfico a través de la puerta de enlace predeterminada de la interfaz de todos modos? Incluso si vino a través del balanceador de carga de enjambre, la puerta de enlace podría simplemente devolverlo a través del balanceador de carga que ya sabe de dónde proviene el tráfico ...

Tal vez esta sea una pregunta ingenua, pero ¿por qué es necesario volver a escribir la IP de origen para empezar? ¿No se devolvería el tráfico a través de la puerta de enlace predeterminada de la interfaz de todos modos? Incluso si vino a través del balanceador de carga de enjambre, la puerta de enlace podría simplemente devolverlo a través del balanceador de carga que ya sabe de dónde proviene el tráfico ...

Es necesario saber de qué IP proviene la solicitud. Tal vez un usuario específico quiera limitar la ip, y no puedas hacerlo fuera del servicio en ejecución, es decir, traefik no conoce el contenido de la solicitud que puede especificar qué usuario la está haciendo, por lo que no puede excluir a algún usuario y acepta otro basado solo en ip (porque la política en este ejemplo es ip + request-content => allow / disallow).

O, más a menudo, solo para iniciar la conexión. Necesito facturar al cliente por el uso de mi servicio, y debo proporcionar en forma tabular: hora de la solicitud, cantidad de recurso, IP de origen de la solicitud. Casi todos los servicios facturados proporcionan este tipo de informe.

Creo que entendiste mal mi pregunta. Entiendo por qué los servicios querrían ver la verdadera IP de origen. Quiero saber por qué Docker lo cambia antes de que llegue a un contenedor.

El 1 de noviembre de 2019, 1:47 a. M., A las 1:47 a. M., Daniele Cruciani [email protected] escribió:

Quizás esta sea una pregunta ingenua, pero ¿por qué es necesario reescribir
la ip de origen para empezar? ¿No se devolvería el tráfico a través del
la puerta de enlace predeterminada de la interfaz de todos modos? Incluso si vino a través de la carga del enjambre
balanceador, la puerta de enlace podría simplemente devolverlo a través del balanceador de carga que
ya sabe de dónde vino el tráfico ...

Es necesario saber de qué IP proviene la solicitud. Tal vez un
un usuario específico desea limitar la ip, y no puede hacerlo fuera del
servicio en ejecución, es decir, traefik no conoce el contenido de la solicitud
que puede especificar qué usuario lo está haciendo, por lo que no puede excluir algunos
usuario y acepta otro basado solo en ip (porque la política en este
ejemplo es ip + request-content => allow / disallow).

O, más a menudo, solo para iniciar la conexión. Necesito facturar al cliente
para el uso de mi servicio, y necesito proporcionar en forma tabular: hora de
solicitud, cantidad de recurso, IP de origen de la solicitud. Casi todos los servicios
facturado proporcionar este tipo de informe.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/moby/moby/issues/25526#issuecomment -548711563

@kaysond No es un buen lugar para preguntar.

Básicamente estás haciendo dos preguntas,

  1. Cómo funciona IPVS técnicamente y
  2. Por qué libnetwork elige IPVS para empezar

Ambos son difíciles de responder de diferentes maneras.

Me pregunto cuál es el mejor lugar para hacer estas preguntas porque ahora estoy muy intrigado por leer la historia de esas opciones y cómo funciona todo para poder obtener más contexto aquí.

@kaysond No es un buen lugar para preguntar.

Básicamente estás haciendo dos preguntas,

  1. Cómo funciona IPVS técnicamente y
  2. Por qué libnetwork elige IPVS para empezar

Ambos son difíciles de responder de diferentes maneras.

¿cualquier actualización?

He estado siguiendo este hilo por un tiempo porque me encontré con el mismo problema, pero después de girar algunos contenedores whoami en un enjambre detrás de traefik , vi que estaba funcionando. Lo que pasaba era que estábamos detrás de Cloudflare y teníamos que conseguir que los CF reenviaran los encabezados. (sí, usamos ipvs y nuestros servicios se replican en enjambre).

Intenté esto de nuevo con:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:28:22 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

y la siguiente ventana acoplable componen:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=HostRegexp(`{any:.*}`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

La salida de whoami fue:

Hostname: 085c373eb06d
IP: 127.0.0.1
IP: 10.0.1.10
IP: 172.19.0.4
RemoteAddr: 10.0.1.11:51888
GET / HTTP/1.1
Host: testserver.nub.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: testserver.nub.local
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ad14e372f6e9
X-Real-Ip: 10.0.0.2

Entonces no. todavía no funciona

Por curiosidad ... ¿algún desarrollador puede señalarme el código que gestiona las redes de enjambres?

Intenté esto de nuevo con:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:28:22 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

y la siguiente ventana acoplable componen:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=HostRegexp(`{any:.*}`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

La salida de whoami fue:

Hostname: 085c373eb06d
IP: 127.0.0.1
IP: 10.0.1.10
IP: 172.19.0.4
RemoteAddr: 10.0.1.11:51888
GET / HTTP/1.1
Host: testserver.nub.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: testserver.nub.local
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ad14e372f6e9
X-Real-Ip: 10.0.0.2

Entonces no. todavía no funciona

puedes usar traefik por modo host para obtener ip real

ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

todavía abierto?
2020-05-08

todavía abierto?
2020-05-08

Sí, todavía está abierto. Hay problemas arquitectónicos señalados en el hilo que resaltan por qué esto no se puede resolver tan fácilmente como parece que debería ser en la superficie. En este punto, es probable que esos problemas no se puedan superar.

Si necesita obtener una IP de usuario real, se publican algunas alternativas en el hilo aquí que pueden ser adecuadas. El modo HOST para servicios parece el enfoque más simple, pero no es adecuado para algunos que necesitan escalabilidad en nodos individuales.

Hemos tenido éxito usando el protocolo PROXY con DigitalOcean LB -> Traefik -> Apache container. El contenedor Apache pudo registrar las direcciones IP reales de los usuarios que accedían al servicio. Teóricamente debería funcionar siempre que todas las capas de proxy admitan el protocolo PROXY.

https://docs.traefik.io/v1.7/configuration/entrypoints/#proxyprotocol

El servicio Traefik está en una red Docker llamada 'entrada', el servicio Apache tiene su propia red de pila pero también es parte de la red 'entrada' como externa.

https://autoize.com/logging-client-ip-addresses-behind-a-proxy-with-docker/

2020 y todavía no arreglado, qué lastre. parece una característica muy importante

Esto es muy necesario. Poner algún modo de host es solo un parche, a veces es necesario ejecutar NGINX detrás de la red (dependiendo del uso y la configuración). Por favor arregle esto.

Creo que una solución para esto y hacer que se ejecute un enjambre de Docker sin configurar el host es obtener la IP en el lado del cliente. ex. usando js para clientes web y móviles y solo acepte de fuentes confiables. ex. js -> get ip, el backend solo acepta ips que incluyen token de usuario o etc. ip se puede configurar en el encabezado y cifrar a través de https. sin embargo, no sé sobre rendimiento

@ Damidara16 eso es exactamente lo que no queremos hacer. Es realmente inseguro hacer eso. Puede omitirlo como desee.

Lamentablemente, esto sigue siendo un problema abierto, lamentablemente ... no parece que se vaya a solucionar pronto

Lamentablemente, esto sigue siendo un problema abierto, lamentablemente ... no parece que se vaya a solucionar pronto

Creo que el bot lo cerrará pronto. Desde que github lanzó esta función, se pueden ignorar muchos errores.

Lamentablemente, esto sigue siendo un problema abierto, lamentablemente ... no parece que se vaya a solucionar pronto

Creo que el bot lo cerrará pronto. Desde que github lanzó esta función, se pueden ignorar muchos errores.

Esta es la mejor característica para que los equipos hinchados de las empresas obtengan el control de la comunidad.

Hay muy pocas posibilidades de que esto se solucione alguna vez. AFAIK, todo el mundo considera que los k8 ganaron la "carrera" y que el enjambre no es necesario, pero yo diría que ambos pueden coexistir y utilizarse correctamente según las necesidades y habilidades del equipo que los utilice. RIP enjambre :)

Utilizo un HAIP administrado, pero podrías usar algo más frente al enjambre, un equilibrador de carga nginx independiente que apunta a las direcciones IP de tu enjambre.
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

En su enjambre, el proxy inverso necesita esto:

server {
        listen 443 ssl proxy_protocol;
        location / {
        proxy_set_header   X-Real-IP $proxy_protocol_addr;  # this is the real IP address 

Si está ejecutando un enjambre, necesitará un equilibrador de carga para realizar un round robin de las solicitudes a su enjambre (o pegajoso, etc.).

Hasta ahora, esta decisión arquitectónica puede parecer una "pieza faltante", sin embargo, esto agrega flexibilidad al proporcionar opciones y eliminar la necesidad de deshabilitar la funcionalidad incorporada para reemplazarla por algo más adecuado a las necesidades de la aplicación.

Creo que he encontrado una solución para este problema, con la limitación _current_ de que las réplicas del contenedor de servicio deben implementarse en un solo nodo, por ejemplo, con --constraint-add = 'node.hostname == mynode', o con un conjunto de enjambres, cada uno de los cuales consta de un solo nodo.

El problema

El problema subyacente es causado por la regla SNAT en la tabla nat de iptables en el espacio de nombres ingress_sbox, que hace que todas las solicitudes entrantes sean vistas por los contenedores para tener la dirección IP del nodo en la red de entrada (por ejemplo, 10.0.0.2, 10.0.0.3,. .., en la configuración de red de entrada predeterminada), por ejemplo:

iptables -t nat -A POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j SNAT --to-source 10.0.0.2

Sin embargo, eliminar esta regla SNAT significa que mientras los contenedores aún reciben paquetes entrantes, que ahora se originan en la IP de origen original, los paquetes salientes enviados de vuelta a la IP de origen original se envían a través de la puerta de enlace predeterminada del contenedor, que no está en la misma red de entrada sino en la red docker_gwbridge (por ejemplo, 172.31.0.1), y esos paquetes se pierden.

La solución

Entonces, la solución incluye: 1. eliminar (de hecho, inhibir) esta regla SNAT en el espacio de nombres ingress_sbox; y 2. crear una regla de enrutamiento de políticas para contenedores de servicios de enjambre, que obligue a esos paquetes salientes a regresar a la dirección IP de la red de entrada del nodo a la que habría regresado (por ejemplo, 10.0.0.2); 3. Automatizar la adición de reglas de enrutamiento de políticas, de modo que cada nuevo contenedor de servicios las instale de inmediato al momento de su creación.

  1. Para inhibir la regla SNAT, creamos una regla anteriormente en la tabla que evita que se alcance la SNAT habitual:
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

(Lo hacemos de esta manera, en lugar de simplemente eliminar la regla SNAT existente, ya que la ventana acoplable parece recrear la regla SNAT varias veces durante el curso de la creación de un servicio. Este enfoque simplemente reemplaza esa regla, lo que la hace más resistente).

  1. Para crear la regla de enrutamiento de la política de contenedores:
docker inspect -f '{{.State.Pid}}' <container-id>
nsenter -n -t $NID bash -c "ip route add table 1 default via 10.0.0.2 && ip rule add from 10.0.0.0/24 lookup 1 priority 32761"
  1. Finalmente, juntando lo anterior con docker event automatizamos el proceso de modificación de las reglas SNAT, y observando los contenedores recién iniciados, y agregando las reglas de enrutamiento de políticas, a través de este script ingress-routing-daemon :
#!/bin/bash

# Ingress Routing Daemon
# Copyright © 2020 Struan Bartlett
# --------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation files 
# (the "Software"), to deal in the Software without restriction, 
# including without limitation the rights to use, copy, modify, merge, 
# publish, distribute, sublicense, and/or sell copies of the Software, 
# and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.
# --------------------------------------------------------------------
# Workaround for https://github.com/moby/moby/issues/25526

echo "Ingress Routing Daemon starting ..."

read INGRESS_SUBNET INGRESS_DEFAULT_GATEWAY \
  < <(docker inspect ingress --format '{{(index .IPAM.Config 0).Subnet}} {{index (split (index .Containers "ingress-sbox").IPv4Address "/") 0}}')

echo INGRESS_SUBNET=$INGRESS_SUBNET
echo INGRESS_DEFAULT_GATEWAY=$INGRESS_DEFAULT_GATEWAY

# Add a rule ahead of the ingress network SNAT rule, that will cause the SNAT rule to be skipped.
echo "Adding ingress_sbox iptables nat rule: iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -D POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j ACCEPT; do true; done 2>/dev/null
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

# Watch for container start events, and configure policy routing rules on each container
# to ensure return path traffic from incoming connections is routed back via the correct interface.
docker events \
  --format '{{.ID}} {{index .Actor.Attributes "com.docker.swarm.service.name"}}' \
  --filter 'event=start' \
  --filter 'type=container' | \
  while read ID SERVICE
  do
    if [ -n "$SERVICE" ]; then

      NID=$(docker inspect -f '{{.State.Pid}}' $ID)
      echo "Container ID=$ID, NID=$NID, SERVICE=$SERVICE started: applying policy route."
      nsenter -n -t $NID bash -c "ip route add table 1 default via $INGRESS_DEFAULT_GATEWAY && ip rule add from $INGRESS_SUBNET lookup 1 priority 32761"
    fi
  done

Ahora, cuando las solicitudes lleguen a los puertos publicados para el nodo único, sus contenedores verán la dirección IP original de la máquina que realiza la solicitud.

Uso

Ejecute el ingress-routing-daemon como raíz en _cada uno_ de sus nodos de enjambre _antes_ de crear su servicio. (Si su servicio ya está creado, asegúrese de escalarlo a 0 antes de volver a escalarlo a un número positivo de réplicas). El demonio inicializará iptables, detectará cuándo la ventana acoplable crea nuevos contenedores y aplicará nuevas reglas de enrutamiento a cada nuevo contenedor.

Pruebas, casos de uso y limitaciones

Lo anterior se ha probado utilizando múltiples réplicas restringidas a un solo nodo en un servicio que se ejecuta en un enjambre de múltiples nodos.

También se ha probado utilizando múltiples nodos, cada uno con un servicio por nodo separado restringido a ese nodo, pero esto viene con la limitación de que se deben usar diferentes puertos publicados para cada servicio por nodo. Aún así, eso podría funcionar para algunos casos de uso.

El método también debería funcionar utilizando múltiples nodos, si cada uno se configura como un solo nodo en su propio enjambre. Esto conlleva la limitación de que los enjambres de la ventana acoplable ya no se pueden usar para distribuir contenedores entre los nodos; sin embargo, aún podría haber otros beneficios de administración al usar los servicios de la ventana acoplable, como la réplica de contenedores y la administración del ciclo de vida.

Mejorar la solución alternativa para abordar más casos de uso

Con un mayor desarrollo, este método debería poder escalar a múltiples nodos sin la necesidad de servicios separados por nodo o dividir el enjambre. Puedo pensar en dos enfoques posibles: 1. Hacer arreglos para que Docker, o un demonio a medida, elimine todas las direcciones IP no locales de la tabla ipvsadm de cada nodo. 2. Extender las reglas de enrutamiento de la política para acomodar los paquetes de salida de enrutamiento al nodo correcto.

Para 1, podríamos sondear ipvsadm -S -n para buscar nuevas IP agregadas a cualquier servicio, verificar si cada una es local y eliminar las que no lo son. Esto permitiría que cada nodo funcione como un equilibrador de carga para sus propios contenedores dentro del servicio general, pero sin que las solicitudes que lleguen a un nodo puedan ser reenviadas a otro. Esto ciertamente satisfaría mi propio caso de uso, donde tenemos nuestro propio balanceador de carga IPVS frente a un conjunto de servidores, cada uno ejecutando una aplicación web, que nos gustaría reemplazar con varias instancias en contenedores con balanceo de carga de la misma aplicación. , para permitirnos implementar actualizaciones sin perder un servidor completo.

Para 2, podríamos usar iptables para asignar un TOS por nodo en la iptable ingress_sbox de cada nodo (por ejemplo, al byte final de la IP de la red de entrada del nodo); luego en el contenedor, arregle para mapear el valor TOS a una marca de conexión, y luego desde una marca de conexión a una marca de firewall para paquetes salientes, y para cada marca de firewall seleccione una tabla de enrutamiento diferente que enrute los paquetes de regreso al nodo de origen. Las reglas para esto serán un poco torpes, pero imagino que deberían escalar bien a 2-16 nodos.

Espero que lo anterior sea de utilidad. También intentaré en (2), y si avanzo, publicaré una nueva actualización.

A continuación se muestra una versión mejorada del demonio de enrutamiento de entrada, ingress-routing-daemon-v2 , que amplía el modelo de reglas de enrutamiento de políticas para permitir que cada contenedor enrute sus paquetes de salida de regreso al nodo correcto, sin la necesidad de SNAT.

El modelo mejorado

Además de inhibir la regla SNAT según el modelo anterior, el nuevo modelo requiere una regla iptables en el espacio de nombres ingress_sbox en cada nodo que pretenda usar como un punto final del equilibrador de carga IPVS (por lo que normalmente los nodos de su administrador, o un subconjunto de esos nodos de administrador), que asigna un valor TOS por nodo a todos los paquetes destinados a cualquier nodo en la red de entrada. (Usamos el byte final de la IP de red de entrada del nodo).

Como el valor de TOS se almacena dentro del paquete, puede ser leído por el nodo de destino al que se ha dirigido la solicitud entrante y se ha enviado el paquete.

Luego, en el contenedor en el nodo de destino, arreglamos para mapear el valor de TOS en cualquier paquete entrante a una marca de conexión, usando el mismo valor.

Ahora, dado que los paquetes salientes en la misma conexión tendrán la misma marca de conexión, asignamos la marca de conexión en cualquier paquete saliente a una marca de firewall, nuevamente usando el mismo valor.

Finalmente, un conjunto de reglas de enrutamiento de políticas selecciona una tabla de enrutamiento diferente, diseñada para enrutar los paquetes salientes de regreso al nodo de punto final del equilibrador de carga requerido, de acuerdo con el valor de la marca del firewall.

Ahora, cuando las solicitudes del cliente llegan a los puertos publicados para cualquier nodo en el enjambre, el contenedor (ya sea en el mismo y / o en otros nodos) al que se dirige la solicitud verá la dirección IP original del cliente que realiza la solicitud, y poder enrutar la respuesta de regreso al nodo del equilibrador de carga de origen; que, a su vez, podrá enrutar la respuesta de regreso al cliente.

Uso

Configurar

Genere un valor para INGRESS_NODE_GATEWAY_IPS específico para su enjambre, ejecutando ingress-routing-daemon-v2 como raíz en cada uno de los nodos de su enjambre _que le gustaría usar como un punto final de equilibrador de carga_ (normalmente solo su gerente nodos, o un subconjunto de los nodos de su administrador), teniendo en cuenta los valores que se muestran para INGRESS_DEFAULT_GATEWAY . Solo tiene que hacer esto una vez, o cada vez que agregue o elimine nodos. Su INGRESS_NODE_GATEWAY_IPS debería verse como 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 (según la subred definida para la red de entrada y el número de nodos).

Ejecutando el demonio

Ejecute INGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 --install como raíz en _cada uno_ de los nodos de su enjambre (administradores y trabajadores) _antes_ de crear su servicio. (Si su servicio ya está creado, asegúrese de escalarlo a 0 antes de volver a escalarlo a un número positivo de réplicas). El demonio inicializará iptables, detectará cuándo la ventana acoplable crea nuevos contenedores y aplicará nuevas reglas de enrutamiento a cada nuevo contenedor.

Si necesita restringir las actividades del demonio a un servicio en particular, modifique [ -n "$SERVICE" ] a [ "$SERVICE" = "myservice" ] .

Desinstalar reglas de iptables

Ejecute ingress-routing-daemon-v2 --uninstall en cada nodo.

Pruebas

El script ingress-routing-daemon-v2 se ha probado con 8 réplicas de un servicio web implementado en un enjambre de cuatro nodos.

Las solicitudes de Curl para el servicio, dirigidas a cualquiera de las IP de nodo de punto final con equilibrio de carga especificadas, arrojaron respuestas exitosas y el examen de los registros del contenedor mostró que la aplicación vio que las solicitudes entrantes se originaron en la IP del cliente Curl.

Limitaciones

Como el valor de TOS puede almacenar un número de 8 bits, este modelo puede admitir en principio hasta 256 nodos de punto final del equilibrador de carga.

Sin embargo, como el modelo requiere que cada contenedor se instale con una regla de manipulación de iptables + una regla de enrutamiento de políticas + una tabla de enrutamiento de políticas por nodo de punto final de administrador, es posible que haya una degradación del rendimiento a medida que aumenta el número de dichos nodos de punto final (aunque la experiencia sugiere que esto es así). es poco probable que se note con <= 16 nodos de punto final de equilibrador de carga en hardware moderno).

Si agrega nodos de puntos finales de equilibrador de carga a su enjambre, o si desea comenzar a usar nodos de administrador existentes como puntos finales de equilibrador de carga, deberá actuar con cuidado, ya que los contenedores existentes no podrán enrutar el tráfico de regreso a los nuevos nodos de punto final. Intente reiniciar INGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 con el valor actualizado para INGRESS_NODE_GATEWAY_IPS , luego realice una actualización progresiva de todos los contenedores, antes de usar el nuevo punto final del equilibrador de carga.

Alcance de la integración nativa de Docker

No estoy familiarizado con el código base de Docker, pero no puedo ver nada que haga ingress-routing-daemon-v2 que, en principio, no pueda ser implementado por Docker de forma nativa, pero lo dejo para que el equipo de Docker considerar, o como un ejercicio para alguien familiarizado con el código de Docker.

El script del demonio de enrutamiento de entrada v2

Aquí está el nuevo script ingress-routing-daemon-v2 .

#!/bin/bash

# Ingress Routing Daemon v2
# Copyright © 2020 Struan Bartlett
# ----------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation files 
# (the "Software"), to deal in the Software without restriction, 
# including without limitation the rights to use, copy, modify, merge, 
# publish, distribute, sublicense, and/or sell copies of the Software, 
# and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.
# ----------------------------------------------------------------------
# Workaround for https://github.com/moby/moby/issues/25526

if [ "$1" = "--install" ]; then
  INSTALL=1
elif [ "$1" = "--uninstall" ]; then
  INSTALL=0
else
  echo "Usage: $0 [--install|--uninstall]"
fi

echo
echo "  Dumping key variables..."

if [ "$INSTALL" = "1" ] && [ -z "$INGRESS_NODE_GATEWAY_IPS" ]; then
  echo "!!! ----------------------------------------------------------------------"
  echo "!!! WARNING: Using default INGRESS_NODE_GATEWAY_IPS"
  echo "!!! Please generate a list by noting the values shown"
  echo "!!! for INGRESS_DEFAULT_GATEWAY on each of your swarm nodes."
  echo "!!!"
  echo "!!! You only have to do this once, or whenever you add or remove nodes."
  echo "!!!"
  echo "!!! Then relaunch using:"
  echo "!!! INGRESS_NODE_GATEWAY_IPS=\"<Node Ingress IP List>\" $0 -x"
  echo "!!! ----------------------------------------------------------------------"
fi

read INGRESS_SUBNET INGRESS_DEFAULT_GATEWAY \
  < <(docker inspect ingress --format '{{(index .IPAM.Config 0).Subnet}} {{index (split (index .Containers "ingress-sbox").IPv4Address "/") 0}}')

echo "  - INGRESS_SUBNET=$INGRESS_SUBNET"
echo "  - INGRESS_DEFAULT_GATEWAY=$INGRESS_DEFAULT_GATEWAY"

# We need the final bytes of the IP addresses on the ingress network of every node
# i.e. We need the final byte of $INGRESS_DEFAULT_GATEWAY for every node in the swarm
# This shouldn't change except when nodes are added or removed from the swarm, so should be reasonably stable.
# You should configure this yourself, but for now let's assume we have 8 nodes with IPs in the INGRESS_SUBNET numbered x.x.x.2 ... x.x.x.9
if [ -z "$INGRESS_NODE_GATEWAY_IPS" ]; then
  INGRESS_NET=$(echo $INGRESS_DEFAULT_GATEWAY | cut -d'.' -f1,2,3)
  INGRESS_NODE_GATEWAY_IPS="$INGRESS_NET.2 $INGRESS_NET.3 $INGRESS_NET.4 $INGRESS_NET.5 $INGRESS_NET.6 $INGRESS_NET.7 $INGRESS_NET.8 $INGRESS_NET.9"
fi

echo "  - INGRESS_NODE_GATEWAY_IPS=\"$INGRESS_NODE_GATEWAY_IPS\""

# Create node ID from INGRESS_DEFAULT_GATEWAY final byte
NODE_ID=$(echo $INGRESS_DEFAULT_GATEWAY | cut -d'.' -f4)
echo "  - NODE_ID=$NODE_ID"

if [ -z "$INSTALL" ]; then
  echo
  echo "Ingress Routing Daemon v2 exiting."
  exit 0
fi

# Add a rule ahead of the ingress network SNAT rule, that will cause the SNAT rule to be skipped.
[ "$INSTALL" = "1" ] && echo "Adding ingress_sbox iptables nat rule: iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -D POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j ACCEPT; do true; done 2>/dev/null
[ "$INSTALL" = "1" ] && nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

# 1. Set TOS to NODE_ID in all outgoing packets to INGRESS_SUBNET
[ "$INSTALL" = "1" ] && echo "Adding ingress_sbox iptables mangle rule: iptables -t mangle -A POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t mangle -D POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff; do true; done 2>/dev/null
[ "$INSTALL" = "1" ] && nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t mangle -A POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff

if [ "$INSTALL" = "0" ]; then
  echo
  echo "Ingress Routing Daemon v2 iptables rules uninstalled, exiting."
  exit 0
fi

echo "Ingress Routing Daemon v2 starting ..."

# Watch for container start events, and configure policy routing rules on each container
# to ensure return path traffic for incoming connections is routed back via the correct interface
# and to the correct node from which the incoming connection was received.
docker events \
  --format '{{.ID}} {{index .Actor.Attributes "com.docker.swarm.service.name"}}' \
  --filter 'event=start' \
  --filter 'type=container' | \
  while read ID SERVICE
  do
    if [ -n "$SERVICE" ]; then

      NID=$(docker inspect -f '{{.State.Pid}}' $ID)
      echo "Container ID=$ID, NID=$NID, SERVICE=$SERVICE started: applying policy routes."

      # 3. Map any connection mark on outgoing traffic to a firewall mark on the individual packets.
      nsenter -n -t $NID iptables -t mangle -A OUTPUT -p tcp -j CONNMARK --restore-mark

      for NODE_IP in $INGRESS_NODE_GATEWAY_IPS
      do
        NODE_ID=$(echo $NODE_IP | cut -d'.' -f4)

    # 2. Map the TOS value on any incoming packets to a connection mark, using the same value.
        nsenter -n -t $NID iptables -t mangle -A PREROUTING -m tos --tos $NODE_ID/0xff -j CONNMARK --set-xmark $NODE_ID/0xffffffff

    # 4. Select the correct routing table to use, according to the firewall mark on the outgoing packet.
        nsenter -n -t $NID ip rule add from $INGRESS_SUBNET fwmark $NODE_ID lookup $NODE_ID prio 32700

    # 5. Route outgoing traffic to the correct node's ingress network IP, according to its firewall mark
    #    (which in turn came from its connection mark, its TOS value, and ultimately its IP).
        nsenter -n -t $NID ip route add table $NODE_ID default via $NODE_IP dev eth0

      done

    fi
  done

Hola @struanb , no entiendo cómo funciona la sección de desinstalación en su script v2, ¿falta algo?

Hola @jrbecart. Espero que no. Antes de instalar las reglas de iptables, verá que hay dos bucles while que eliminan cualquier regla preexistente, usando iptables -D . Esta es una medida de seguridad, en caso de que el script se ejecute con --install varias veces sucesivamente, sin que intervenga ninguna llamada con --uninstall .

Como tal, cuando se llama al script con --uninstall, para cuando el script salga, esas reglas se habrán eliminado y aún no se agregarán nuevas reglas.

Espero que esto responda a su pregunta.

Hola a todos, quiero decirles que descubrí una solución a este problema, sin instalar y configurar nada más que definir bien la configuración de NGINX. Sé que todos hemos probado diferentes enfoques. Este fue descubierto por error. Para ser honesto, dejé esto hace mucho tiempo. Bueno, hasta hoy. Mientras implementaba un sistema de monitoreo, pude obtener la IP de origen, la IP de origen real, usando el registro de NGINX, así que comencé a depurar cómo era posible.

Aquí hay un ejemplo de ese tipo de registro.

10.0.0.2 - - [19/Nov/2020:04:56:31 +0000] "GET / HTTP/1.1" 200 58 "-" req_t=0.003 upstream_t=0.004 "<browser-info>" "<source-ip-1,source-ip2,....>"

Nota: Hay varias direcciones IP de origen si está utilizando un proxy (es decir, Cloudfare y otros).

La información estaba allí, mi IP real estaba allí. Luego, revisé el formato de registro NGINX para saber cómo era posible la magia, y encontré esto:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      'req_t=$request_time upstream_t=$upstream_response_time '
                      '"$http_user_agent" "$http_x_forwarded_for"';

Eso es, la magia está aquí -> $http_x_forwarded_for

Después de esto, cambié los encabezados del proxy como proxy_set_header X-Real-IP $http_x_forwarded_for; .

Y finalmente, la última prueba, usando esa información en un proyecto NodeJS, dentro del sistema de producción, usando Docker Swarm con una red superpuesta, con aproximadamente 4 VM, y adivinen qué, ¡funcionó! Finalmente pude obtener la dirección IP real.

Estoy muy feliz porque este número se ha abierto durante mucho tiempo, pero creo que esta es la respuesta. Las versiones que utilicé son:

Docker version: 19.03.8
NGINX version: nginx/1.14.2

Esperaré tus comentarios. Espero que puedas tener los mismos resultados que yo.

¡Salud!
Sebastián.

PD: Intente esto usando otra interfaz de red, es decir, fuera de localhost, porque encontrará un "-" en el registro, en lugar de su dirección IP real. Intente probarlo a través de Internet, completamente fuera de su red doméstica.

Bonificación: también podría asignar la dirección IP a una geolocalización, usando una tabla de búsqueda, contarlas y ponerlas en un mapa, así que la respuesta es sí, esto es lo que estábamos buscando, chicos :)

@sebastianfelipe ese es un gran reclamo después de todos estos años. ¿Estás seguro de que no estás usando el modo de host u otras soluciones en este hilo?

@sebastianfelipe ese es un gran reclamo después de todos estos años. ¿Estás seguro de que no estás usando el modo de host u otras soluciones en este hilo?

Estoy seguro. No estoy usando un host de red en todos esos servicios conectados. Acabo de implementar una pila, con una red superpuesta en un entorno similar a la producción, incluido un equilibrador de carga Digital Ocean y funcionó. Quiero decir, no puedo probarlo mejor que esto. Es 100% real.

@sebastianfelipe Supongo que el balanceador de carga de Digital Ocean está agregando la dirección IP del usuario al encabezado X-Fordered-For. Esta es una solución alternativa conocida que no resuelve el problema de recuperar la IP del usuario en el modo Docker Swarm independiente.

@beornf Estaba tratando de dormir y luego leí su notificación, así que tuve que despertarme y probar un enfoque sin un balanceador de carga Digital Ocean y falló. Tienes razón, Digital Ocean agrega una magia allí cuando se agrega un equilibrador de carga. Esto le sucede a la variable $http_x_forwarded_for . El balanceador de carga digital Ocean agrega información a otra variable NGINX, información que Docker Swarm no agrega directamente. Probablemente esto podría llevar a un enfoque "ficticio" para tener una solución real para cada caso. Al menos los clientes de Digital Ocean pueden estar felices de saber cómo lidiar con esto en este momento.

@beornf @sebastianfelipe Adición al contexto, CloudFlare también añade X-Forwarded-For y es en gran parte libre.

@beornf @sebastianfelipe Adición al contexto, CloudFlare también añade X-Forwarded-For y es en gran parte libre.

Creo que esto podría funcionar para muchos de nosotros que necesitamos una salida para obtener la propiedad intelectual real. Cloudfare se puede ajustar como proxy o solo como DNS. Se adapta perfectamente a los clientes que no tienen Digital Ocean. Es la solución más limpia hasta ahora. Pero estoy de acuerdo con @beornf , necesitamos una solución real, sin depender de Digital Ocean o Cloudfare para hacer esto.

¡Gracias!

¿Fue útil esta página
0 / 5 - 0 calificaciones