Moby: Não é possível recuperar o endereço IP do usuário no modo docker swarm

Criado em 9 ago. 2016  ·  324Comentários  ·  Fonte: moby/moby

Resultado 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

Resultado 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

Detalhes adicionais do ambiente (AWS, VirtualBox, físico, etc.):

Etapas para reproduzir o problema:

  1. executar o seguinte serviço que publica a porta 80
docker service create \
--name debugging-simple-server \
--publish 80:3000 \
panj/debugging-simple-server
  1. Tente se conectar com http://<public-ip>/ .

Descreva os resultados que você recebeu:
Nem ip nem header.x-forwarded-for são o endereço IP correto do usuário.

Descreva os resultados que você esperava:
ip ou header.x-forwarded-for deve ser o endereço IP do usuário. O resultado esperado pode ser arquivado usando o contêiner docker autônomo docker run -d -p 80:3000 panj/debugging-simple-server . Você pode ver os dois resultados por meio dos links a seguir,
http://swarm.issue-25526.docker.takemetour.com : 81 /
http://container.issue-25526.docker.takemetour.com : 82 /

Informações adicionais que você considera importantes (por exemplo, o problema acontece apenas ocasionalmente):
Isso acontece no modo global e no modo replicated .

Não tenho certeza se perdi algo que deve resolver esse problema facilmente.

Nesse ínterim, acho que tenho que fazer uma solução alternativa que é executar um contêiner de proxy fora do modo de enxame e encaminhá-lo para a porta publicada no modo de enxame (a terminação SSL deve ser feita neste contêiner também), o que quebra o propósito de enxame modo de autocura e orquestração.

arenetworking areswarm kinenhancement statuneeds-attention versio1.12

Comentários muito úteis

Também tive o problema ao tentar executar o logstash no modo swarm (para coletar mensagens de syslog de vários hosts). O campo "host" do logstash sempre aparece como 10.255.0.x, em vez do IP real do host de conexão. Isso o torna totalmente inutilizável, pois você não pode dizer de qual host as mensagens de log estão vindo. Existe alguma maneira de evitar a tradução do IP de origem?

Todos 324 comentários

/ cc @aluzzardi @mrjana perguntou

@PanJ, você pode compartilhar alguns detalhes sobre como o debugging-simple-server determina o ip ? Além disso, qual é a expectativa se um serviço for dimensionado para mais de 1 réplica em vários hosts (ou modo global)?

@mavenugo é o objeto de solicitação de koa que usa o módulo remoteAddress do nó net . O resultado deve ser o mesmo para qualquer outra biblioteca que possa recuperar endereços remotos.

A expectativa é que o campo ip seja sempre um endereço remoto, independentemente de qualquer configuração.

@PanJ você ainda usa sua solução alternativa ou encontrou uma solução melhor?

@PanJ Quando executo seu aplicativo como um contêiner autônomo ..

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

e acessar a porta publicada de outro host eu recebo isso

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 é o IP do host no qual estou executando o curl. Este é o comportamento esperado ?

@sanimej Sim, é o comportamento esperado que deveria estar no modo enxame também.

@marech Ainda estou usando o contêiner autônomo como uma solução alternativa, que funciona bem.

No meu caso, há 2 instâncias nginx, instâncias autônomas e instâncias de enxame. A terminação SSL e o proxy reverso são feitos em nginx autônomo. A instância do Swarm é usada para rotear para outros serviços com base no host de solicitação.

@PanJ A maneira como a porta publicada de um contêiner é acessada é diferente no modo de enxame. No modo enxame, um serviço pode ser alcançado a partir de qualquer nó do cluster. Para facilitar isso, encaminhamos através de uma rede ingress . 10.255.0.x é o endereço da interface de rede ingress no host no cluster a partir do qual você tenta acessar a porta publicada.

@sanimej Eu meio que vi como funciona quando me concentrei no problema. Mas o caso de uso (capacidade de recuperar o IP do usuário) é bastante comum.

Tenho conhecimento limitado sobre como a correção deve ser implementada. Talvez um tipo especial de rede que não altera o endereço IP de origem?

Rancher é semelhante ao modo Swarm do Docker e parece ter o comportamento esperado. Talvez seja um bom lugar para começar.

@sanimej boa ideia poderia ser adicionar todos os IPs ao cabeçalho X-Forwarded-For se possível, então podemos ver toda a cadeia.

@PanJ hmm, e como seu contêiner autônomo nignx se comunica com a instância do swarm, via nome de serviço ou ip? Talvez você possa compartilhar a parte de configuração do nginx onde você a passa para a instância do swarm.

O contêiner autônomo 80 e, em seguida, faz proxy 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;
  }
}

Se você tiver que fazer a terminação SSL, adicione outro bloco de servidor que escuta a porta 443 , então faça a terminação SSL e os proxies para localhost:8181 também

O nginx do modo Swarm publica 8181:80 e roteia para outro serviço com base no host de solicitação.

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

Em nosso caso, nosso API RateLimit e outras funções dependem do endereço IP do usuário. Existe alguma maneira de pular o problema no modo enxame?

Também tive o problema ao tentar executar o logstash no modo swarm (para coletar mensagens de syslog de vários hosts). O campo "host" do logstash sempre aparece como 10.255.0.x, em vez do IP real do host de conexão. Isso o torna totalmente inutilizável, pois você não pode dizer de qual host as mensagens de log estão vindo. Existe alguma maneira de evitar a tradução do IP de origem?

1 para uma solução para este problema.

Sem a capacidade de recuperar o IP do usuário, nos impede de usar soluções de monitoramento como o Prometheus.

Talvez os recursos IPVS do kernel do linux sejam de alguma utilidade aqui. Estou supondo que a mudança de IP está ocorrendo porque as conexões estão sendo proxy no espaço do usuário. O IPVS, por outro lado, pode redirecionar e carregar solicitações de equilíbrio no espaço do kernel sem alterar o endereço IP de origem. O IPVS também pode ser bom no futuro para criar funcionalidades mais avançadas, como diferentes algoritmos de balanceamento de carga, endereços IP flutuantes e roteamento direto.

Para mim, seria suficiente se eu pudesse de alguma forma descobrir a relação entre o IP virtual e o IP do servidor ao qual o endpoint pertence. Dessa forma, quando o Prometheus enviar um alerta relacionado a algum IP virtual, eu poderia descobrir qual é o servidor afetado. Não seria uma boa solução, mas seria melhor do que nada.

@vfarcic Não acho que isso seja possível com a maneira como funciona agora. Todas as conexões de cliente vêm do mesmo IP, então você não pode traduzi-lo de volta. A única maneira de isso funcionar é se o que está fazendo o proxy / nat das conexões salvou um log de conexão com carimbo de data / hora, ip de origem e porta de origem. Mesmo assim, não seria de muita ajuda na maioria dos casos de uso em que o IP de origem é necessário.

Provavelmente não expliquei bem o caso de uso.

Eu uso o Prometheus que está configurado para sucatear exportadores que estão operando como serviços globais Swarm. Ele usa tarefas.para obter os IPs de todas as réplicas. Portanto, não está usando o serviço, mas pontos de extremidade de réplica (sem balanceamento de carga). O que eu preciso é descobrir de alguma forma o IP do nó de onde cada um desses IPs de réplica vem.

Acabei de perceber que a "inspeção de rede do docker"fornece informações sobre contêineres e endereços IPv4 de um único nó. Isso pode ser estendido para que haja uma informação de todo o cluster de uma rede junto com os nós?

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

Observe a adição do "Nó".

Se tais informações estivessem disponíveis para todo o cluster, não apenas um único nó com a adição de um argumento --filter , eu teria tudo de que preciso para descobrir a relação entre um endereço IPv4 de contêiner e o nó. Não seria uma ótima solução, mas ainda melhor do que nada. Agora, quando o Prometheus detecta um problema, preciso executar "inspeção de rede docker" em cada nó até descobrir a localização do endereço.

Concordo com @dack , dado que a rede de ingresso está usando IPVS, devemos resolver esse problema usando IPVS para que o IP de origem seja preservado e apresentado ao serviço de maneira correta e transparente.

A solução precisa funcionar no nível de IP para que qualquer serviço que não seja baseado em HTTP possa funcionar corretamente também (não posso confiar em cabeçalhos http ...).

E eu não posso enfatizar o quão importante isso é, sem ele, existem muitos serviços que simplesmente não podem operar em modo enxame.

@kobolog pode ser capaz de lançar alguma luz sobre este assunto em sua palestra sobre IPVS na DockerCon.

Apenas me adicionando à lista. Estou usando o logstash para aceitar mensagens syslog, e todas elas estão sendo enviadas para elasticsearch com o IP do host definido como 10.255.0.4, o que o torna inutilizável, e terei que reverter para minha implantação de logstash sem contêineres se não houver solução para isso.

@mrjana pode u pls adicionar a sugestão que você teve para contornar este problema?

O IPVS não é um proxy reverso do espaço do usuário que pode consertar as coisas na camada HTTP. Essa é a diferença entre um proxy de espaço de usuário como o HAProxy e este. Se você quiser usar o HAProxy, poderá fazer isso colocando um HAProxy no cluster e fazer com que todas as suas instâncias de serviço e o HAProxy participem da mesma rede. Dessa forma, o HAProxy pode corrigir HTTP header.x-forwarded-for . Ou se o balanceador de carga L7 for externo ao cluster, você pode usar o próximo recurso (em 1.13) para um novo PublishMode chamado Host PublishMode que irá expor cada uma das instâncias individuais do serviço em sua própria porta individual e você pode apontar seu balanceador de carga externo para ela.

@mrjana A idéia de usar IPVS (em vez de qualquer docker que faça atualmente no modo swarm) seria evitar traduzir o IP de origem para começar. Adicionar um X-Forwarded-For pode ajudar para alguns aplicativos HTTP, mas não tem nenhuma utilidade para todos os outros aplicativos que são interrompidos pelo comportamento atual.

@dack meu entendimento é que a rede de entrada Docker já usa IPVS.

Se você quiser usar o HAProxy, poderá fazer isso colocando um HAProxy no cluster e fazer com que todas as suas instâncias de serviço e o HAProxy participem da mesma rede. Dessa forma, o HAProxy pode corrigir o cabeçalho HTTP.x-encaminhado para

Isso também não funcionaria @mrjana , a única maneira de o HAProxy obter o ip do cliente é rodando fora da rede de ingresso usando docker run ou diretamente no host, mas então você não pode usar nenhum dos seus serviços, pois eles estão em uma rede diferente e você não pode acessá-los.

Resumindo, não há absolutamente nenhuma maneira, pelo que eu saiba, de lidar com isso assim que você usar os serviços docker e o modo de enxame.

Seria interessante se o (s) autor (es) da rede de entrada do docker pudessem se juntar à discussão, pois provavelmente teriam alguma ideia de como o IPVS é configurado / operado sob o capô (há muitos modos para IPVS) e como podemos consertar o problema.

@tlvenn Você sabe onde isso está no código-fonte? Posso estar errado, mas não acredito que esteja usando IPVS com base em algumas coisas que observei:

  • A porta de origem é traduzida (toda a razão para este problema). IPVS não faz isso. Mesmo no modo NAT, ele traduz apenas o endereço de destino. Você precisa usar a rota padrão ou o roteamento de política para enviar pacotes de retorno de volta ao host IPVS.
  • Quando uma porta é publicada no modo swarm, todas as instâncias dockerd no swarm escutam na porta publicada. Se o IPVS fosse usado, isso aconteceria no espaço do kernel e o dockerd não estaria escutando na porta.

Olá @dack ,

Do blog deles:

Internamente, fazemos esse trabalho usando Linux IPVS, um balanceador de carga multiprotocolo da Camada 4 no kernel que está no kernel do Linux há mais de 15 anos. Com pacotes de roteamento IPVS dentro do kernel, a malha de roteamento do swarm oferece balanceamento de carga com reconhecimento de contêiner de alto desempenho.

O código-fonte deve residir no projeto swarmkit se eu não estiver errado.

Eu me pergunto se @stevvooe pode nos ajudar a entender qual é o problema subjacente aqui.

OK, dei uma rápida olhada no código e acho que entendi um pouco melhor agora. Ele realmente parece estar usando IPVS, conforme declarado no blog. O SNAT é feito por meio de uma regra iptables que é configurada em service_linux.go. Se bem entendi, a lógica por trás disso seria algo assim (assumindo que o nó A recebe um pacote de cliente para o serviço em execução no nó B):

  • O nó A do enxame recebe o pacote do cliente. IPVS / iptables traduz (src ip) -> (nó a ip) e (dst ip) -> (nó B ip)
  • O pacote é encaminhado para o nó B
  • O nó B envia sua resposta para o nó A (pois é isso que ele vê como o ip src)
  • O nó A traduz o src e dst de volta para os valores originais e encaminha a resposta ao cliente

Acho que o raciocínio por trás do SNAT é que a resposta deve passar pelo mesmo nó que a solicitação original veio (já que é onde o estado NAT / IPVS está armazenado). Como as solicitações podem vir de qualquer nó, o SNAT é usado para que o nó de serviço saiba por qual nó encaminhar a solicitação de volta. Em uma configuração IPVS com um único nó de balanceamento de carga, isso não seria um problema.

Portanto, a questão é como evitar o SNAT e, ao mesmo tempo, permitir que todos os nós tratem das solicitações de entrada do cliente. Não tenho certeza de qual é a melhor abordagem. Talvez haja uma maneira de ter uma tabela de estado no nó de serviço para que ele possa usar o roteamento de política para direcionar as respostas em vez de depender do SNAT. Ou talvez algum tipo de encapsulamento possa ajudar (VXLAN?). Ou, o método de roteamento direto de IPVS pode ser usado. Isso permitiria que o nó de serviço respondesse diretamente ao cliente (em vez de por meio do nó que recebeu a solicitação original) e permitiria adicionar novos IPs flutuantes para serviços. No entanto, também significaria que o serviço só pode ser contatado por meio do IP flutuante e não pelos IPs de nós individuais (não tenho certeza se isso é um problema para qualquer caso de uso).

Descoberta muito interessante @dack !

Esperançosamente, será encontrada uma solução para pular esse SNAT todos juntos.

Nesse ínterim, talvez haja uma solução alternativa que foi confirmada não muito tempo atrás, que introduz uma publicação de porta em nível de host com PublishMode , efetivamente contornando a rede de entrada.

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

Ei, obrigado pela grande quantidade de feedback - analisaremos este problema em profundidade após o fim de semana.

Enquanto isso, algumas informações:

@tlvenn : @mrjana é o autor principal por trás do recurso de rede de ingresso. A origem reside principalmente em docker / libnetwork, alguns em SwarmKit

@dack : é realmente apoiado por IPVS

@tlvenn , até onde eu sei, o Docker Swarm usa mascaramento, uma vez que é a maneira mais direta e com garantia de funcionamento na maioria das configurações. Além disso, este é o único modo que realmente permite mascarar portas também [re: @dack], o que é útil. Em teoria, esse problema poderia ser resolvido usando o modo de encapsulamento IPIP - o fluxo do pacote será assim:

  • Um pacote chega ao servidor de gateway - no nosso caso, qualquer nó do enxame - e o IPVS nesse nó determina que ele é de fato um pacote para um serviço virtual, com base em seu endereço IP de destino e porta.
  • O pacote é encapsulado em outro pacote IP e enviado ao servidor real que foi escolhido com base no algoritmo de balanceamento de carga.
  • O servidor real recebe o pacote envolvente, desencapsula-o e vê o IP do cliente real como origem e o IP do serviço virtual como destino. Todos os servidores reais devem ter um apelido de interface não ARPable com o IP de serviço virtual, de modo que eles presumam que esse pacote é realmente destinado a eles.
  • O servidor real processa o pacote e envia a resposta de volta para o cliente diretamente. O IP de origem, neste caso, será o IP do serviço virtual , portanto, nenhuma resposta marciana envolvida, o que é bom.

Existem, é claro, muitas advertências e coisas que podem dar errado, mas geralmente isso é possível e o modo IPIP é amplamente utilizado na produção.

Esperando que uma solução possa ser encontrada em breve para isso, já que a fixação de IP e outras verificações de segurança precisam ser capazes de receber o IP externo correto.

Assistindo. Nosso produto aproveita as informações de IP de origem para segurança e análise.

@aluzzardi alguma atualização para nós?

bump, precisamos que isso funcione para um projeto muito grande que começaremos no início do próximo ano.

Examinando o fluxo, parece que atualmente funciona assim (neste exemplo, o nó A recebe o tráfego de entrada e o nó B está executando o contêiner de serviço):

  • o nó A executa DNAT para direcionar o pacote para o namespace de rede ingress_sbox (/ var / run / docker / netns / ingress_sbox)
  • ingress_sbox no nó A executa IPVS no modo NAT, que executa DNAT para direcionar o pacote para o contêiner no nó B (por meio da rede de sobreposição de ingresso) e também SNAT para alterar o IP de origem para o IP de rede de sobreposição de ingresso
  • o pacote é encaminhado através da sobreposição para o servidor real
  • os pacotes de retorno seguem o mesmo caminho ao contrário, reescrevendo os endereços de origem / destino de volta aos valores originais

Acho que o SNAT poderia ser evitado com algo assim:

  • o nó A passa o pacote para ingress_sbox sem qualquer NAT (iptables / policy routing?)
  • nó A ingress_sbox executa IPVS no modo de roteamento direto, que envia o pacote para o nó B por meio da rede de sobreposição de ingresso
  • o contêiner no nó B recebe o pacote inalterado (o contêiner deve aceitar pacotes para todos os IPs públicos, mas não deve enviar ARP para eles. Existem várias maneiras de fazer isso, consulte os documentos IPVS).
  • os pacotes de retorno são enviados diretamente do nó B para o cliente (não precisa voltar pela rede de sobreposição ou nó A)

Como um bônus adicional, nenhum estado de NAT precisa ser armazenado e o tráfego de rede de sobreposição é reduzido.

@aluzzardi @mrjana Alguma atualização sobre isso, por favor? Agradeceríamos muito um feedback do Docker.

Assistindo. sem as informações de IP de origem, a maioria dos nossos serviços não funciona conforme o esperado

Como isso aconteceu ?
unassign_bug

@tlvenn parece um bug no Github?

@PanJ @tlvenn @vfarcic @dack e outros, PTAL # 27917. Introduzimos a capacidade de habilitar o modo de publicação de serviço = host que fornecerá uma maneira para o serviço contornar IPVS e trazer de volta docker run -p como o comportamento e irá reter o ip-fonte para os casos que preciso disso.

Por favor, tente 1.13.0-rc2 e forneça feedback.

ya muito estranho @mavenugo ..

Com relação ao modo de publicação, eu já havia vinculado isso do kit swarm acima, isso poderia ser uma solução alternativa, mas eu realmente espero que uma solução adequada venha com o Docker 1.13 para resolver esse problema para sempre.

Esse problema pode ser categorizado como um bug porque preservar o IP de origem é o comportamento que os usuários esperamos e é uma limitação muito séria dos serviços do docker no momento.

Acredito que @kobolog e @dack trouxeram algumas pistas em potencial sobre como resolver isso e já faz quase 2 semanas sem nenhum acompanhamento do lado do Docker.

Podemos ter alguma visibilidade sobre quem está investigando esse problema no Docker e uma atualização de status? Desde já, obrigado.

Além de # 27917, não há outra solução para 1.13. A funcionalidade de retorno direto precisa ser analisada para vários casos de uso e não deve ser tomada de ânimo leve para ser considerada como uma correção de bug. Podemos analisar isso para 1.14. Mas, isso também se enquadra na categoria de comportamento LB configurável, que inclui o algoritmo (rr vs 10 outros métodos), caminho de dados (LVS-DR, LVS-NAT e LVS-TUN). Se alguém estiver disposto a contribuir para isso, por favor, empurre um PR e podemos colocar isso em movimento.

Suponho que seja justo,

No mínimo, podemos alterar o documento para 1.13 para que ele deixe claro que, ao usar os serviços docker com o modo de publicação de entrada padrão, o ip de origem não é preservado e sugere o uso do modo de host se for um requisito para executar o serviço ?

Acho que vai ajudar as pessoas que estão migrando para os serviços a não se queimarem com esse comportamento inesperado.

Claro e sim, uma atualização de documento para indicar esse comportamento e a solução alternativa de usar a publicação mode=host será útil para tais casos de uso que falham no modo LVS-NAT.

Apenas checando para ver se não houve novos desenvolvimentos para resolver essa coisa real? Certamente é uma grande limitação para nós também

Existe uma solução no roteiro para o docker 1.14? Estamos atrasados ​​na implantação de nossas soluções usando docker devido em parte a esse problema.

Adoraria ver um cabeçalho personalizado adicionado à solicitação http / https que preserva o ip do cliente. Isso deveria ser possível, não deveria? Não me importo quando X_Forwarded_for é sobrescrito, só quero ter um campo personalizado que só é definido na primeira vez que a solicitação entra no enxame.

Adoraria ver um cabeçalho personalizado adicionado à solicitação http / https que preserva o ip do cliente. Isso deveria ser possível, não deveria? Não me importo quando X_Forwarded_for é sobrescrito, só quero ter um campo personalizado que só é definido na primeira vez que a solicitação entra no enxame.

O balanceamento de carga é feito em L3 / 4. Adicionar um cabeçalho http não é possível.

Uma correção envolverá a remoção da reconfiguração do endereço de origem.

@mavenugo Eu atualizei para docker 1.13 hoje e usei mode=host em meu serviço de proxy. Atualmente está funcionando, o IP do cliente está preservado, mas espero uma solução melhor :) Obrigado pelo seu trabalho!

Desculpe pela postagem dupla ...
Como posso usar um arquivo de pilha (yml v3) para obter o mesmo comportamento de quando eu usaria --publish mode=host,target=80,published=80 por meio da criação do serviço docker?

eu tentei

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

mas isso não está funcionando (usado o mesmo padrão de https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/#/ports)

Como posso usar um arquivo stack (yml v3) para obter o mesmo comportamento de quando eu usaria --publish mode = host, target = 80, posted = 80 via docker service create?

@hamburml - fique de olho em https://github.com/docker/docker/issues/30447 é um problema / recurso aberto.

Infelizmente, não posso usar mode=host como solução alternativa porque preciso que meu serviço se comunique com a rede swarm e também esteja ouvindo em todos os nós, não apenas na interface do host ...

@ tkeeler33 Acho que você deve ser capaz de implantar o serviço como um serviço global (que implanta uma instância em cada nó do enxame) e conectá-lo a uma rede de enxame para se comunicar com outros serviços do enxame

@thaJeztah - Sim, mas não consigo conectar um contêiner a uma rede overlay / swarm e ao host mode=host ao mesmo tempo. Essa é a minha maior limitação no momento.

@ tkeeler33 parece funcionar para mim;

$ 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

Teste se o serviço web pode se conectar ao serviço something na mesma rede;

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 - Obrigado! Depois de me aprofundar, percebi que meu problema era que criei minha rede docker usando a opção --opt encrypted , o que fez com que o contêiner falhasse nas conexões do host. Depois de tentar seus passos, consegui identificar rapidamente a causa raiz. Essa opção pode ser uma boa solução provisória, só preciso entender todas as implicações de segurança.

Agradeço muito a informação!

@ tkeeler33 --opt encrypted não deve afetar o mapeamento da porta do host. O único propósito da opção criptografada é criptografar o tráfego do túnel vxlan entre os nós. Do documento: "Se você está planejando criar uma rede de sobreposição com criptografia (--opt criptografado), também precisará garantir que o tráfego do protocolo 50 (ESP) seja permitido." Você pode verificar suas configurações para ter certeza de que ESP é permitido?
Além disso, a opção --opt encrypted é puramente criptografia de plano de dados. Todo o tráfego do plano de controle (trocas de roteamento, distribuição do Service Discovery, etc ...) são criptografados por padrão, mesmo sem a opção.

@mavenugo Você está certo. Quando criei uma nova rede com --opt encrypted ela funcionou bem. Quando comparei a rede recém-criada com a minha existente, percebi que "Internal": true estava definido. Provavelmente esse era o problema e foi um erro durante a criação inicial da rede ... Obrigado por sua ajuda e esclarecimento, foi um longo dia ...

@dack @kobolog Em implementações típicas de LVS-Tunnel e LVS-DR, o IP de destino no pacote de entrada será o serviço VIP que também é programado como um IP não ARP nos servidores reais. A malha de roteamento funciona de uma maneira fundamentalmente diferente, a solicitação de entrada pode ser para qualquer um dos hosts. Para que o servidor real aceite o pacote (em qualquer modo LVS), o IP de destino deve ser alterado para um IP local. Não há como o pacote de resposta do contêiner de back-end voltar com o endereço de origem correto. Em vez de retorno direto, podemos tentar obter o pacote de resposta de volta ao host de ingresso. Mas não há maneira limpa de fazer isso, exceto alterando o IP de origem, que nos leva de volta à estaca zero.

@thaJeztah Acho que devemos esclarecer isso na documentação, sugerir o uso do mod host se o IP do cliente tiver que ser preservado e fechar este problema.

@sanimej Ainda não vejo por que é impossível fazer isso sem NAT. Não poderíamos apenas ter a opção de usar, por exemplo, o fluxo LVS-DR regular? O Docker adiciona o vip não-ARP aos nós apropriados, o LVS direciona os pacotes de entrada para os nós e os pacotes de saída retornam diretamente. Por que é importante que o pacote de entrada possa atingir qualquer host? Isso não é diferente do LVS padrão com vários servidores front-end e vários servidores back-end.

@thaJeztah obrigado pela solução alternativa :)
Se você estiver implantando seu proxy com compor versão 3, a nova sintaxe de publicação não é suportada, então podemos corrigir o serviço implantado usando este comando (substitua nginx_proxy pelo nome do serviço)

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 No fluxo LVS-DR regular, o IP de destino será o VIP de serviço. Assim, o LB pode enviar o pacote para o backend sem qualquer alteração de IP de destino. Este não é o caso da malha de roteamento porque o IP de destino do pacote de entrada será um dos IP do host.

@sanimej algum feedback sobre a proposta acima de usar o modo de encapsulamento IPIP para resolver esse problema?

O túnel @tlvenn LVS-IP funciona de forma muito semelhante ao LVS-DR, exceto que o backend obtém o pacote por meio de um túnel IP em vez de um mac-rewrite. Portanto, tem o mesmo problema para o caso de uso da malha de roteamento.

Da proposta a que você se referiu ..
The real server receives the enclosing packet, decapsulates it and sees real client IP as source and virtual service IP as destination.

O IP de destino do pacote seria o IP do host para o qual o cliente enviou o pacote e não o VIP. Se não for reescrito, o servidor real o descartará após remover o cabeçalho IP externo. Se o IP de destino for regravado, a resposta do servidor real ao cliente terá um IP de origem incorreto, resultando em falha de conexão.

Obrigado pelo esclarecimento @sanimej. Você poderia implementar o protocolo PROXY ? Não seria uma solução perfeita, mas pelo menos ofereceria ao serviço uma solução para resolver o IP do usuário.

Existe uma maneira complicada de obter a preservação do IP de origem, dividindo o intervalo da porta de origem em blocos e atribuindo um bloco para cada host no cluster. Então é possível fazer uma abordagem híbrida NAT + DR, onde o host de ingresso faz o SNAT usual e envia o pacote para um servidor real. No host em que o servidor real está sendo executado, com base no IP de origem, faça um SNAT para alterar a porta de origem para uma porta no intervalo atribuído ao host de ingresso. Então, no pacote de retorno do contêiner, compare com o intervalo da porta de origem (e a porta de destino) e altere o IP de origem para aquele do host de entrada.

Tecnicamente, isso funcionaria, mas impraticável e frágil em implantações reais, onde os membros do cluster estão sendo adicionados e removidos rapidamente. Isso também reduz o espaço da porta significativamente.

A abordagem NAT + DR que mencionei não funcionaria porque o IP de origem não pode ser alterado no host de ingresso. Pode ser uma opção alterar apenas a porta de origem para uma no intervalo desse host específico e usar a política de roteamento do host de backend para obter o pacote de volta ao host de ingresso. Isso ainda tem outros problemas que mencionei anteriormente.

@thaJeztah
Existe alguma solução alternativa no momento para encaminhar o endereço IP real do contêiner Nginx para o contêiner da web?
Eu tenho o contêiner Nginx em execução no modo global e publicado em host , então o contêiner Nginx obtém um endereço IP correto. Ambos os contêineres se veem bem, no entanto, o contêiner da web obtém o endereço IP do contêiner Nginx, não um do cliente.
Nginx é um proxy reverso para a web, e a web executa uwsgi na porta 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 minha resposta acima + esta configuração funcional do nginx

@ pi0 Obrigado pela resposta

Estou usando a configuração nginx do link, mas o endereço IP ainda está errado, devo ter algo faltando na minha configuração

Eu tenho um cluster swarm docker ( 17.03.0-ce ) com rede overlay e dois serviços

    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

O contêiner Nginx usa o contêiner oficial mais recente https://hub.docker.com/_/nginx/
O contêiner da Web executa o servidor uwsgi na porta 8000

Estou usando nginx.conf global do link e conf.d/default.conf tem a seguinte aparência:

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

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

E então os registros do contêiner nginx:

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

Registros de contêiner da web:

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

O que está faltando aí?

O endereço IP ainda estará errado. Mas vai adicionar cabeçalhos HTTP que
contém o endereço IP real. Você deve configurar o seu servidor web de sua escolha
para confiar no proxy (use o cabeçalho em vez do IP de origem)
Na sexta-feira, 17 de março de 2560 às 19:36 Lukasz Pakula [email protected]
escreveu:

@ pi0 https://github.com/pi0 Obrigado pela resposta

Estou usando a configuração nginx do link, mas o endereço IP ainda é
errado, devo ter algo faltando na minha configuração

Eu tenho um cluster swarm docker ( 17.03.0-ce ) com rede de sobreposição e dois
Serviços

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

O contêiner Nginx usa o contêiner oficial mais recente
https://hub.docker.com/_/nginx/ http: // url
O contêiner da Web executa o servidor uwsgi na porta 8000

Estou usando o nginx.conf global do link e conf.d / default.conf parece
como se segue:

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

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

}

E então os registros do contêiner nginx:

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

Registros de contêiner da web:

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

O que está faltando aí?

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/docker/issues/25526#issuecomment-287342795 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ABtu97EFaCmLwAZiOrYT4nXi4oXPCbLQks5rmn43gaJpZM4Jf2WK
.

>

PanJ,
Panjamapong Sermsawatsri
Tel. (+66) 869761168

@lpakula Ah, há outra coisa que sua imagem web:newest deve honrar o cabeçalho X-Real-IP também. O nginx não altera automaticamente o IP do remetente, apenas envia um cabeçalho de dica.

@ pi0 @PanJ
Faz sentido, obrigado pessoal!

Ligue a porta usando o modo de host.

nginx oferece suporte à transparência de IP usando o módulo de kernel TPROXY .

@stevvooe O Docker também pode fazer algo assim?

nginx oferece suporte à transparência de IP usando o módulo de kernel TPROXY.
@stevvooe O Docker também pode fazer algo assim?

Improvável, pois a entrada precisa ser rastreada entre os nós. Vou deixar @sanimej ou @mavenugo.

O swarm pode fornecer a API REST para obter o endereço IP do cliente?

@tonysongtl que não está relacionado a este problema

Outra coisa a considerar é como o tráfego é entregue aos seus nós em uma configuração altamente disponível. Um nó deve ser capaz de ficar inativo sem criar erros para os clientes. A recomendação atual é usar um balanceador de carga externo (ELB, F5, etc) e balanceamento de carga na Camada 4 para cada nó Swarm, com uma verificação de integridade da Camada 4 simples. Eu acredito que o F5 usa SNAT, então o melhor caso nesta configuração é capturar o único IP do seu F5, e não o IP real do cliente.

Referências:
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

espelhando o comentário acima - o protocolo proxy não pode ser usado? Todos os balanceadores de carga de nuvem e haproxy usam isso para preservação de IP de origem.

Calico também tem modo ipip - https://docs.projectcalico.org/v2.2/usage/configuration/ip-in-ip - que é uma das razões pelas quais o github o usa. https://githubengineering.com/kubernetes-at-github/

Oi.

Para fins de compreensão e integridade, deixe-me resumir e, por favor, me corrija se eu estiver errado:

O principal problema é que os contêineres não estão recebendo o src-IP original, mas aglomeram o VIP. Eu repliquei esse problema com o seguinte cenário:

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:

Quando os serviços dentro do swarm estão usando a malha (padrão), o swarm faz o NAT para garantir que o tráfego da mesma origem seja sempre enviado para o mesmo serviço em execução do host?
Conseqüentemente, ele está perdendo o src-IP original e substituindo-o pelo serviço VIP do swarm.

Parece @kobolog https://github.com/moby/moby/issues/25526#issuecomment -258660348 e @dack https://github.com/moby/moby/issues/25526#issuecomment -260813865 propostas foram refutadas por @sanimej https://github.com/moby/moby/issues/25526#issuecomment -280722179 https://github.com/moby/moby/issues/25526#issuecomment -281289906 mas, TBH, seus argumentos não são totalmente claros para eu ainda, nem entendo porque o thread não foi fechado se isso é definitivamente impossível.

@sanimej não funcionaria ?:

  1. Swarm recebe mensagem com src-IP = A e destino = "my-service-virtual-address"
  2. O pacote é enviado a um nó de enxame executando aquele serviço, encapsulando a mensagem original.
  3. O nó encaminha para a mudança de destino da tarefa para o container-running-that-service-IP
    O enxame e os nós podem manter tabelas para garantir que o tráfego da mesma origem seja encaminhado para o mesmo nó sempre que possível.

Uma opção de habilitar "proxy reverso em vez de NAT" para serviços específicos não resolveria todos esses problemas satisfazendo a todos?

Por outro lado, IIUC, a única opção restante é usar https://docs.docker.com/engine/swarm/services/#publish -a-services-ports-direct-on-the-swarm-node, que -novamente IIUC- parece ser como não usar mesh, portanto , não vejo os benefícios de usar o modo enxame (vs compor). Na verdade, parece um enxame pré-1.12, precisando de _Consul_ e assim.

Obrigado por sua ajuda e paciência.
Cumprimentos

@sanimej
Ainda mais ... por que o Docker não está apenas fazendo um encaminhamento de porta NAT (alterando apenas o IP / porta de destino)?

  1. Enxame recebe mensagem "de A para meu serviço"
  2. O Swarm encaminha a mensagem para o host que executa esse serviço, definindo dest = node1
  3. O Nó1 recebe a mensagem "de A para o nó1" e encaminha a configuração dest = container1
  4. Container1 recebe mensagem "de A para container1"
  5. Para responder, o contêiner usa a rota do gateway padrão

Eu só gostaria de intervir; Embora eu entenda que não existe uma maneira fácil de fazer isso, não ter o endereço IP de origem preservado de alguma maneira dificulta vários casos de uso de aplicativos. Aqui estão algumas que consigo pensar de início:

  • Ser capaz de ter métricas que detalham a origem de seus usuários é vital para a engenharia de rede / serviço.

  • Em muitos aplicativos de segurança, você precisa ter acesso ao endereço IP de origem para permitir a lista negra dinâmica com base no abuso do serviço.

  • Os serviços de reconhecimento de localização geralmente precisam ser capazes de acessar o endereço IP para localizar a localização geral do usuário quando outros métodos falham.

Pela minha leitura deste tópico de problema, não parece que as soluções fornecidas funcionem muito bem quando você deseja ter serviços escalonáveis ​​dentro de um Docker Swarm. Limitar-se a uma instância por nó de trabalho reduz muito a flexibilidade da oferta. Além disso, manter uma abordagem híbrida de ter um LB / Proxy no limite executando como um contêiner orquestrado não-Swarm antes de alimentar os contêineres orquestrados Swarm parece voltar no tempo. Por que o usuário precisa manter 2 paradigmas diferentes para orquestração de serviço? Que tal ser capaz de dimensionar dinamicamente o LB / Proxy na borda? Isso teria que ser feito manualmente, certo?

A equipe do Docker poderia considerar esses comentários e ver se há alguma maneira de introduzir essa funcionalidade, mantendo a qualidade e a flexibilidade presentes no ecossistema do Docker?

Além disso, estou sendo atingido por isso agora. Eu tenho um aplicativo da web que encaminha solicitações autorizadas / autenticadas para um servidor da web downstream. Nossos técnicos de serviço precisam ser capazes de verificar se as pessoas acessaram o servidor downstream, para o qual gostam de usar os logs de acesso à web. No cenário atual, não há como fornecer essa funcionalidade, pois meu servidor proxy nunca vê o endereço IP de origem. Quero que meu aplicativo seja facilmente escalonável e não parece que posso fazer isso com as soluções alternativas apresentadas, pelo menos não sem lançar novas VMs para cada instância escalada.

@Jitsusama poderia o Kubernetes resolver seu problema?

@thaJeztah existe uma maneira de contornar o problema usando docker-compose?

eu tentei

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

Mas parece ter 172.xx1 como o IP de origem

@trajano , não faço ideia. O Kubernetes de alguma forma consegue contornar esse problema?

@Jitsusama
Sim, eles têm documentação referindo-se a como preservam o IP de origem . É funcional, mas não tão bonito se você não usar um balanceador de carga, pois o pacote é descartado nos nós sem esses terminais. Se você planeja usar o Rancher como seu balanceador de carga auto-hospedado, infelizmente ele ainda não oferece suporte .

@trajano

Mas parece ter 172.xx1 como o IP de origem

Se você estiver acessando seu aplicativo localmente, esse IP deve estar correto (se você usar swarm), uma vez que docker_gwbridge é a interface que interage com seu contêiner de proxy. Você pode tentar acessar o aplicativo de outra máquina dentro de sua rede IP para ver se ele obtém o endereço correto.

Quanto à solução alternativa de composição, é possível. Aqui, eu uso a imagem jwilder/nginx-proxy como meu proxy reverso de front-end (para simplificar os conceitos) junto com uma imagem de construção oficial de nginx como o serviço de back-end. Eu implanto a pilha no 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

Isso criará uma rede website_default para a pilha. Meu ponto de extremidade é definido na variável de ambiente VIRTUAL_HOST e acessar http://website.local me dá:

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"

Observe que o final do cabeçalho de website_nginx.1.vskh5941kgkb tem uma dica do IP original ( 172.18.0.1 ). X-Forwarded-For & X-Real-IP são definidos em nginx.tmpl de jwilder/nginx-proxy por padrão.

Para a porta 443 , não consegui adicionar as duas portas no arquivo docker-compose, então usei apenas:

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

enquanto também adiciono redes que desejo reverter o proxy com aplicativos que contêm a variável de ambiente VIRTUAL_HOST . Opções mais granulares são possíveis na documentação de jwilder/nginx-proxy , ou você pode criar sua própria configuração.

Os controladores de entrada no Kubernetes fazem essencialmente a mesma coisa, já que os gráficos de entrada (geralmente) têm suporte para X-Forwarded-For e X-Real-IP com um pouco mais de flexibilidade com escolha e tipo de entradas e também suas réplicas de implantação.

Portanto, a documentação do kubernetes não está completa. Outra forma que é ser
muito comumente é na verdade protocolo ingresso + proxy.

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

O protocolo proxy é um protocolo amplamente aceito que preserva a fonte
em formação. Haproxy vem com suporte embutido para protocolo proxy. Nginx
pode ler, mas não injetar protocolo de proxy.

Uma vez que o protocolo de proxy é configurado, você pode acessar essas informações a partir de qualquer
serviços downstream como
https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/proxy-protocol/README.md

Até mesmo o openshift aproveita isso para informações de IP de origem
https://docs.openshift.org/latest/install_config/router/proxy_protocol.html

Esta é a entrada haproxy mais recente para k8s que injeta protocolo de proxy.

IMHO, a maneira de fazer isso no swarm é tornar o ingresso capaz de ler o proxy
protocolo (no caso de estar recebendo tráfego de um LB upstream que tem
protocolo de proxy já injetado), bem como protocolo de proxy injetado
informações (no caso de todo o tráfego realmente atingir o ingresso primeiro).

Não sou a favor de fazer de outra forma, especialmente quando há um
padrão geralmente aceito para fazer isso.

O Traefik adicionou suporte a proxy_protocol algumas semanas atrás e está disponível a partir de v1.4.0-rc1.

Isso precisa ser feito no nível de entrada do docker swarm. Se a entrada
não injeta dados de protocolo de proxy, nenhum dos serviços downstream
(incluindo traefix, nginx, etc) será capaz de lê-lo.

Em 10 de setembro de 2017, 21:42, "monotykamary" [email protected] escreveu:

Traefik adicionou suporte a proxy_protocol
https://github.com/containous/traefik/pull/2004 algumas semanas atrás e é
disponível a partir de v1.4.0-rc1.

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-328352805 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU3jj5dJcpMDysjIyGQK7SGx8GwWbks5shApqgaJpZM4Jf2WK
.

também estou confuso sobre a relação desse bug com o infrakit. por exemplo, https://github.com/docker/infrakit/pull/601 alguém pode comentar sobre a direção que o docker swarm vai tomar?

O enxame vai se acumular no infrakit? Estou especialmente interessado no lado do ingresso.

Também estamos enfrentando esse problema. Queremos saber o ip do cliente e o IP solicitado para conexões de entrada. Por exemplo, se o usuário realizar uma conexão TCP bruta com nosso servidor, queremos saber qual é o seu IP e a qual ip em nossa máquina ele está conectado.

@blazedd Conforme comentado anteriormente e em outros tópicos, isso é realmente possível usando publishMode. ou seja: os serviços não são gerenciados pela rede mesh.

IIUC, há algum progresso em andamento para melhorar a forma como o ingresso lida com isso, mas essa é, na verdade, a única solução.

Começamos a implantar nosso serviço nginx usando o modo de publicação e

@mostolog Obrigado pela sua resposta. Apenas algumas notas:

  1. publishMode não resolve o problema de forma alguma. A conexão do soquete de entrada ainda resolve para a rede local que o swarm configura. Pelo menos quando você usa a lista de portas mode: host
  2. nginx não é realmente uma boa solução. Nosso aplicativo é baseado em TCP, mas não é um servidor web. Não há cabeçalhos que possamos usar sem codificá-lo manualmente.
  3. Se eu usar docker run --net=host ... , tudo funcionará bem.
  4. A única solução que vi que funciona até agora é usar: https://github.com/moby/moby/issues/25873#issuecomment -319109840

@blazedd Em nossa pilha temos:

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

e assim, aposto que obteremos IPs reais em nossos logs.

@mostolog Não funciona pelo menos no Windows. Ainda estou obtendo o endereço 172.0.0.x como a fonte.

@mostolog mode: host não expõe seu contêiner à rede host. Ele remove o contêiner da rede de entrada, que é como o Docker normalmente opera ao executar um contêiner. Ele replicaria o --publish 8080:8080 usado em um comando docker run. Se o nginx estiver obtendo ips reais, não é o resultado do soquete estar conectado a esses ips diretamente. Para testar isso, você deve considerar seriamente o uso de uma implementação TCP bruta ou servidor HTTP, sem uma estrutura, e verificar o endereço relatado.

Por que não usar a rede de rota IPVS para o contêiner diretamente? vincule todos os ips da interface de sobreposição do nó do swarm como ips virtuais, use ip rule from xxx table xxx para fazer multi-gateway, então os nós do swarm podem rotear o cliente para o contêiner diretamente (DNAT), sem nenhum daemon de proxy de rede do espaço de usuário (dockerd)

@blazedd Você já experimentou? Estou obtendo endereços IP externos ao seguir o exemplo de @mostolog .

Estou enfrentando esse problema novamente.

Minha configuração é a seguinte:

  • balanceador de carga ipvs no modo DR (externo ao docker swarm)
  • 3 nós docker, com IP de destino adicionado a todos os nós e arp configurado apropriadamente para roteamento IPVS DR

Eu gostaria de implantar uma pilha para o enxame e fazer com que ele ouça na porta 80 no IP virtual sem mutilar os endereços.

Quase consigo chegar lá fazendo isto:
portas:
- alvo: 80
publicado: 80
protocolo: tcp
modo: host

O problema aqui é que ele não permite que você especifique a qual endereço IP vincular - ele apenas se vincula a todos. Isso cria problemas se você deseja executar mais de um único serviço usando essa porta. Ele precisa se vincular apenas a um IP. Usar portas diferentes não é uma opção com balanceamento de carga de DR. Parece que os desenvolvedores presumiram que o mesmo IP nunca existirá em vários nós, o que não é o caso ao usar um balanceador de carga de DR.

Além disso, se você usar a sintaxe curta, ela ignorará o IP de vinculação e continuará vinculando a todos os endereços. A única maneira que encontrei de vincular a um único IP é executar um contêiner não agrupado (não um serviço ou pilha).

Portanto, agora estou de volta a ter que usar contêineres autônomos e gerenciá-los sozinho, em vez de depender de recursos de serviço / pilha para fazer isso.

Temos o mesmo problema.
Eu votaria em uma solução transparente no ingresso do docker que permitisse que todos os aplicativos (alguns usando UDP / TCP bruto, não especialmente HTTP) funcionassem conforme o esperado.

Eu poderia usar a solução alternativa "modo = publicação de porta de host", pois meu serviço é implantado globalmente.
No entanto, parece que isso é incompatível com o uso do driver de rede macvlan, que eu preciso por alguns outros motivos.
Recebemos registros como "driver macvlan não suporta mapeamentos de porta".
Tentei usar várias redes, mas não adiantou.

Criei um tíquete específico aqui: https://github.com/docker/libnetwork/issues/2050
Isso me deixa sem solução por agora: '(

Oi, pessoal
Existe uma solução alternativa por enquanto? Sem tê-lo como uma porta de host publicada
porta?

Em 11 de janeiro de 2018 00:03, "Olivier Voortman" [email protected] escreveu:

Temos o mesmo problema.
Eu votaria por uma solução transparente dentro da entrada do docker que permitiria todos
aplicativos (alguns usando UDP / TCP bruto, não especialmente HTTP) para funcionar como
esperado.

Eu poderia usar a solução alternativa "modo = publicação da porta do host", pois meu serviço é
implantado globalmente.
No entanto, parece que isso é incompatível com o uso do macvlan
driver de rede, que eu preciso por alguns outros motivos.
Recebemos registros como "driver macvlan não suporta mapeamentos de porta".
Tentei usar várias redes, mas não adiantou.

Criei um tíquete específico aqui: docker / libnetwork # 2050
https://github.com/docker/libnetwork/issues/2050
Isso me deixa sem solução por agora: '(

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-356693751 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUzlM-BMbEsDYAiYH6hKLha-aRqerks5tJQJngaJpZM4Jf2WK
.

É uma pena que não seja possível obter o IP do cliente. isso não torna utilizável a maioria dos recursos interessantes do docker swarm.

Na minha configuração, a única maneira de obter o IP do cliente é usar network_mode:host e não usar o swarm.

usando mode=host port publishing ou um docker run -p "80:80" ... tradicional não funcionou

Algumas soluções foram sugeridas em https://github.com/moby/moby/issues/15086, mas a única solução que funcionou para mim foi a rede "host" ...

Outro problema de não ter o IP correto é que a limitação da taxa nginx não funciona corretamente e, portanto, não pode ser usada com o balanceador de carga docker swarm, porque as solicitações estão sendo limitadas por taxa e negadas, pois o nginx conta todas elas conforme vêm de um único usuário / IP. Portanto, a única solução alternativa é usar mode = host, mas, dessa forma, perco os recursos de balanceamento de carga e preciso apontar o DNS para instâncias específicas.

Talvez o docker não seja a ferramenta ideal para este trabalho, eu estava procurando no vagrant para configurar os servidores HTTP frontais e colocar o IP do cliente como parte dos cabeçalhos de solicitação HTTP.

Até que o Docker seja capaz de passar informações do cliente sobre redes de sobreposição, pode-se usar um proxy como o Docker Flow Proxy ou Traefik, publicar as portas desejadas no modo host nesse serviço e conectar os serviços de aplicativo a ele. Não é uma solução completa, mas funciona muito bem e permite o balanceamento de carga de serviços de aplicativos / recuperação de IP do cliente.

@ deeky666 Traefik e similares funcionam apenas se não encaixados

Não vejo suporte udo no traefik

Enviado do meu iPhone

Finalmente desistimos do contêiner docker. Não está pronto para produção!

Na quarta-feira, 24 de janeiro de 2018 às 5h43, Efrain [email protected] escreveu:

Não vejo suporte udo no traefik

Enviado do meu iPhone

>

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-360091189 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AHf7rvMcH2iFBxcExfO_Ol0UttCspuTnks5tNwlkgaJpZM4Jf2WK
.

O problema parece parcialmente resolvido em 17.12.0-ce usando mode=host .

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

Tem algumas limitações (sem malha de roteamento), mas funciona!

@goetas mode=host funcionou por um tempo como uma solução alternativa, então eu não diria que o problema está resolvido de alguma forma. O uso de mode = host tem muitas limitações, a porta está sendo exposta, não é possível usar o balanceamento de carga de swarm, etc.

@darklow Eu conheço as limitações, mas para o meu caso de uso está bom (se não melhor ainda!). Em 17.09.1-ce não estava funcionando de jeito nenhum, então para mim já é uma melhoria!

A grande desvantagem dessa solução alternativa é não ser possível evitar o tempo de inatividade durante a atualização.
Atualmente, temos que optar por desistir da estabilidade ou do endereço IP de origem.

Eu concordo. O Swarm precisa de uma maneira de alta disponibilidade para preservar o IP de origem.

Provavelmente usando protocolo proxy. Não acho que seja um grande esforço adicionar
suporte de protocolo proxy para docker swarm.

Alguém está investigando isso?

Em 28 de janeiro de 2018, 22:39, "Genki Takiuchi" [email protected] escreveu:

A grande desvantagem dessa solução alternativa é não ser possível evitar a queda
tempo durante a atualização.
Atualmente, temos que escolher desistir de estabilidade ou IP de origem
Morada.

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-361078416 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU-or7fnhKTg7fhjtZYjGYHBFRE7Dks5tPKnYgaJpZM4Jf2WK
.

@sandys eu concordo. O protocolo proxy seria uma ótima ideia.
@thaJeztah @aluzzardi @mrjana esse problema pode chamar a atenção, por favor? Não houve resposta da equipe por um tempo. Obrigada.

O protocolo Proxy parece a melhor solução para mim. Esperançosamente, a equipe irá considerar isso.

@goetas funcionou em um ponto pelo menos eu vi funcionar, mas parece ter voltado ao comportamento 172.xxx novamente no docker 1.12.6

Isso é MUITO ruim, atenua qualquer limitação de taxa, prevenção de fraude, registro, logins seguros, monitoramento de sessão, etc.!
Ouvir com mode: host funciona, mas não é uma solução real, pois você perde o balanceamento de carga da malha e apenas o loadbalanacer do software no host que tem o ip público tem que lidar com todo o tráfego sozinho.

este é um bug muito crítico e importante para nós e está bloqueando nosso go-live com o Swarm. Também acreditamos que o protocolo proxy é a solução certa para isso. A entrada do Docker deve passar o ip de origem no protocolo de proxy.

No Twitter, uma das soluções propostas é usar o Traefik como entrada gerenciada fora do Swarm . Isso é altamente abaixo do ideal para nós - e não uma sobrecarga que gostaríamos de gerenciar.

Se os desenvolvedores do Swarm quiserem verificar como implementar o protocolo de proxy no Swarm-ingress, eles devem verificar todos os bugs que estão sendo discutidos no Traefik (por exemplo, https://github.com/containous/traefik/issues/2619)

Eu fiz isso funcionar de forma consistente usando "compor" em vez do modo de enxame. Talvez algo em que pensar.

Algumas preocupações com o protocolo de proxy:

Ele é decodificado pelo próprio docker ou pelo aplicativo? Se dependermos do aplicativo para implementar o protocolo de proxy, essa não é uma solução geral para todos os aplicativos e só funciona para servidores da web ou outro aplicativo que implementa o protocolo de proxy. Se o docker desembrulhar o protocolo de proxy e traduzir o endereço, ele também terá que rastrear o estado da conexão e realizar a tradução inversa nos pacotes de saída. Não sou a favor de uma solução específica para a web (contando com o protocolo de proxy do aplicativo), pois o docker também é útil para muitos aplicativos que não são da web. Este problema deve ser resolvido para o caso geral de qualquer aplicativo TCP / UDP - nada mais no docker é específico da web.

Como com qualquer outro método de encapsulamento, há também a preocupação com questões de tamanho de pacote / MTU. No entanto, acho que isso provavelmente será uma preocupação com praticamente qualquer solução para esse problema. A resposta provavelmente será certificar-se de que sua rede swarm suporta um MTU grande o suficiente para permitir a sobrecarga. Eu acho que a maioria dos enxames são executados em redes locais, então isso provavelmente não é um grande problema.

@trajano - sabemos que funciona com rede de host (que é provavelmente o que sua solução de composição está fazendo). No entanto, isso elimina todas as vantagens de rede de cluster do swarm (como balanceamento de carga).

@dack Backends deve conhecer o protocolo de proxy.
Eu acho que isso resolve a maioria dos casos e pelo menos você pode colocar um proxy semelhante a uma passagem fina que processa o cabeçalho do protocolo na frente de seus back-ends dentro de contêineres.
Como a falta de informação é um problema mortal, acredito que seja necessário resolvê-lo o mais rápido possível antes de outra solução simples.

protocolo proxy tem ampla aceitação. verifique o número de ferramentas suportadas - https://www.haproxy.com/blog/haproxy/proxy-protocol/
ele nem mesmo cobre os balanceadores de carga em nuvem (ELB, Google LB) e ferramentas mais recentes como o Traefik.

Além disso - este é praticamente o padrão no kubernetes: https://github.com/kubernetes/ingress-nginx#proxy -protocol

Neste ponto, o protocolo proxy é o padrão mais amplamente aceito para resolver esse problema. Não vejo um valor enorme em reinventar isso e quebrar a compatibilidade com os nginxes do mundo.

Esses são protocolos L7. A entrada do enxame é L4. Não há nada sendo reinventado aqui, é tudo IPVS usando DNAT.

@ cpuguy83 não entendeu o que você quis dizer.

O protocolo proxy é a camada 4.
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

O objetivo do protocolo PROXY é preencher as estruturas internas do servidor com o
informações coletadas pelo proxy que o servidor teria sido capaz de obter
por si só se o cliente estava se conectando diretamente ao servidor em vez de por meio de um
proxy. As informações transportadas pelo protocolo são aquelas que o servidor faria
obter usando getsockname () e getpeername ():

  • família de endereços (AF_INET para IPv4, AF_INET6 para IPv6, AF_UNIX)
  • protocolo de socket (SOCK_STREAM para TCP, SOCK_DGRAM para UDP)
  • endereços de origem e destino da camada 3
  • portas de origem e destino da camada 4, se houver

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

aceitar proxy

Impõe o uso do protocolo PROXY em qualquer conexão aceita por qualquer um dos
os soquetes declarados na mesma linha. Versões 1 e 2 do protocolo PROXY
são suportados e detectados corretamente. O protocolo PROXY dita a camada
3/4 endereços da conexão de entrada a serem usados ​​em todos os lugares onde um endereço é
usado, com a única exceção das regras de "conexão de solicitação tcp" que
veja apenas o endereço de conexão real. Os registros refletirão os endereços
indicado no protocolo, a menos que seja violado, caso em que o real
o endereço ainda será usado. Esta palavra-chave combinada com suporte externo
componentes podem ser usados ​​como uma alternativa eficiente e confiável para o
Mecanismo X-Forwarded-For que nem sempre é confiável e nem sempre
utilizável. Consulte também "conexão tcp-request expect-proxy" para obter uma descrição mais detalhada
definição de qual cliente tem permissão para usar o protocolo.

Você quis dizer que existe uma maneira melhor do que o protocolo de proxy? isso é totalmente possível e adoraria saber mais no contexto da preservação do IP de origem no docker swarm. No entanto, o protocolo de proxy é mais amplamente suportado por outras ferramentas (como nginx, etc) que serão downstream para swarm-ingress ... bem como ferramentas como AWS ELB que farão upstream para swarm-ingress. Esse foi meu único $ 0,02

@sandys O protocolo proxy se parece com o encapsulamento (pelo menos no início da conexão), o que requer conhecimento do encapsulamento do receptor até o final da pilha. Essa abordagem traz muitos trade-offs.

Eu não gostaria de oferecer suporte a isso no núcleo, mas talvez tornar o ingresso plugável seja uma abordagem válida.

@sandys https://github.com/sandys O protocolo de proxy parece
encapsulamento (pelo menos no início da conexão), que requer conhecimento
do encapsulamento do receptor até o final da pilha. Lá
Existem muitos trade-offs para essa abordagem.

Isso é verdade. É basicamente por isso que é um padrão com um RFC. Há
impulso por trás disso, porém - praticamente toda a importância do componente
suporta isso. IMHO não é uma má decisão apoiá-lo.

Eu não gostaria de apoiar isso no núcleo, mas talvez fazendo o ingresso
plugável seria uma abordagem interessante.

Esta é uma discussão mais ampla - no entanto, devo acrescentar que a maior
vantagem do Docker Swarm sobre os outros é que ele tem todas as baterias
construídas em.

Eu ainda solicitaria que você considere o protocolo de proxy como uma ótima solução para
este problema que tem suporte da indústria.

Não é possível simular um roteador L3 no Linux e LxCs (não especificamente docker)

A simulação
Por exemplo, uma opção (ex: --use-proxy-protocol ) pode ser fornecida para serviços que precisam do endereço IP do cliente e sabem como tratar pacotes encapsulados, como nginx.

Como funciona atualmente, o nó docker que recebe o pacote executa o SNAT e encaminha o pacote para o nó com o contêiner do aplicativo. Se alguma forma de encapsulamento / encapsulamento foi usada em vez de SNAT, então deve ser possível passar o pacote original não alterado para o aplicativo.

Este é um problema resolvido em outros projetos. Por exemplo, com o OpenStack você pode usar túneis como GRE e VXLAN.

Alguém na parte recente deste tópico está aqui para representar a equipe do docker e pelo menos dizer que 'ouvimos você'? Parece algo que um recurso que você esperaria estar 'pronto para uso' e de tanto interesse para a comunidade ainda não foi resolvido depois de ser relatado pela primeira vez em 9 de agosto de 2016, cerca de 18 meses atrás.

Alguém na parte recente deste tópico está aqui para representar a equipe do docker e pelo menos dizer que 'ouvimos você'?

/ cc @GordonTheTurtle @thaJeztah @riyazdf @aluzzardi

@bluejaguar @ruudboon Faço parte do Docker. Este é um problema bem conhecido. No momento, a equipe de rede está focada em bugs de longa data com estabilidade de rede sobreposta. É por isso que não houve realmente novos recursos de rede nos últimos lançamentos.

Minha sugestão seria apresentar uma proposta concreta na qual você esteja disposto a trabalhar para resolver o problema ou, pelo menos, uma proposta boa o suficiente para que qualquer pessoa possa pegá-la e executá-la.

@ cpuguy83 tenho seguido alguns dos recursos do protocolo proxy de entrada no k8s. Por exemplo, https://github.com/kubernetes/kubernetes/issues/42616 (PS curiosamente, o protocolo de proxy aqui está fluindo do Google Kubernetes Engine, que oferece suporte nativo ao protocolo de proxy no modo HTTPS).

Além disso, o ELB adicionou suporte para Proxy Protocol v2 em novembro de 2017 (https://docs.aws.amazon.com/elasticloadbalancing/latest/network/doc-history.html)

Openstack Octavia LB-as-a-service (semelhante ao nosso ingresso) protocolo de proxy mesclado em abril passado - http://git.openstack.org/cgit/openstack/octavia/commit/?id=bf7693dfd884329f7d1169eec33eb03d2ae81ace

Aqui estão algumas das documentações sobre o protocolo de proxy em openstack - https://docs.openshift.com/container-platform/3.5/install_config/router/proxy_protocol.html
Algumas das nuances são em torno do protocolo de proxy para https (nos casos em que você está encerrando certificados na entrada ou não).

Alguma atualização / solução alternativa em relação a este problema? realmente precisamos saber o ip do cliente no modo docker swarm.
Qualquer ajuda seria muito apreciada.

Minha versão:

Cliente:
Versão: 18.02.0-ce
Versão API: 1.36
Versão Go: go1.9.3
Git commit: fc4de44
Construído: Quarta, 7 de fevereiro, 21:16:33 de 2018
OS / Arch: linux / amd64
Experimental: falso
Orquestrador: enxame

Servidor:
Motor:
Versão: 18.02.0-ce
Versão da API: 1.36 (versão mínima 1.12)
Versão Go: go1.9.3
Git commit: fc4de44
Construído: Quarta, 7 de fevereiro, 21:15:05 2018
OS / Arch: linux / amd64
Experimental: falso

@adijes e outros usuários que estão enfrentando esse problema. Você pode vincular os contêineres à rede bridge (conforme mencionado por alguém neste tópico).

version: "3.4"

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

networks:
  bridge:
    external:
      name: bridge

Nosso frontend está vinculado a bridge e sempre fica em um host exato, cujo IP está vinculado ao nosso domínio público. Isso permite que ele receba o IP real do usuário. E como também está vinculado à rede default , ele será capaz de se conectar a serviços apoiados.

Você também pode escalar frontend , contanto que você o mantenha ativo naquele único host. Isso faz com que o host seja um Ponto Único de Falha, mas (eu acho) está OK para sites pequenos.

Editado para adicionar mais informações:

Meus contêineres nginx estão atrás de https://github.com/jwilder/nginx-proxy , eu também uso https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion para habilitar SSL. O nginx-proxy é executado por meio do comando docker run , não por um serviço docker swarm. Talvez seja por isso que recebi IP real dos clientes. A rede bridge é necessária para permitir que meus contêineres nginx se comuniquem com o nginx-proxy.

FWIW, estou 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

A configuração acima também funciona em outra configuração, que está executando:

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 que não funciona para mim eu recebo

a "ponte" da rede é declarada como externa, mas não está no escopo correto: "local" em vez de "enxame"

eu tenho um mestre e três nós de trabalho

@trajano , veja minha atualização.

@ letientai299 na verdade, eu estava me perguntando como você conseguiu que bridge funcionasse no modo enxame . ou seja, você não obteve o erro que eu tenho.

@dack quando você diz rede de host, presumo que você queira dizer ter

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

Infelizmente, quando executado no modo docker stack deploy , ele não funciona e ainda perde o IP de origem, enquanto o docker-compose up funciona corretamente.

Eu também tentei o seguinte com base em @goetas

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

Ainda não teve sorte em obter o IP de origem: Server Version: 17.12.0-ce

Parece algo que todos iriam querer em algum momento, e como o uso de redes de sobreposição junto com uma rede de ponte / host não é realmente possível, esse é um bloqueador nos casos em que você realmente precisa do IP do cliente por vários motivos.

Cliente:
Versão: 17.12.0-ce
Versão API: 1.35
Versão Go: go1.9.2
Git commit: c97c6d6
Construído: Quarta, 27 de dezembro, 20:03:51 de 2017
OS / Arch: darwin / amd64

Servidor:
Motor:
Versão: 17.12.1-ce
Versão da API: 1.35 (versão mínima 1.12)
Versão Go: go1.9.4
Git commit: 7390fc6
Construído: Ter 27 de fevereiro 22:17:54 2018
OS / Arch: linux / amd64
Experimental: verdadeiro

É 2018. Há algo mais recente sobre esse problema?
No modo de enxame, não posso usar o limite de req do nginx. $ remote_addr sempre pegou 10.255.0.2.
Este é um problema realmente sério sobre o docker swarm.
Talvez eu deva tentar o kubernetes desde hoje.

@Maslow eu postei onde estamos apenas alguns comentários acima.

Podemos relaxar a verificação para

networks:
  bridge:
    external:
      name: bridge

ou estendê-lo como

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

e as redes scope: local só são permitidas se o modo de rede for host

a "ponte" da rede é declarada como externa, mas não está no escopo correto: "local" em vez de "enxame"

ou permitir

networks:
  bridge:
    driver: bridge

Para não falhar com

falha ao criar serviço trajano_serv: Resposta de erro do daemon: A rede trajano_bridge não pode ser usada com serviços. Apenas redes com escopo para o swarm podem ser usadas, como aquelas criadas com o driver overlay.

ao ter mode: host nas portas publicadas.

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

@trajano Você pode usar redes com escopo não-swarm já com o swarm ... por exemplo, isso 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

Você testou isso em um enxame com mais de um trabalhador com implantação de pilha do docker. Eu sei que funciona com a composição.

Em 18 de março de 2018, às 20h55, Brian Goff [email protected] escreveu:

@trajano Você pode usar redes com escopo não-swarm já com o swarm ... por exemplo, isso funciona:

versão: '3.4'

Serviços:
teste:
imagem: alpino
comando: top
portas:
- alvo: 32555
publicado: 32555
protocolo: tcp
modo: host
redes:
- Ponte

redes:
Ponte:
externo:
nome: ponte
-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub ou ignore a conversa.

Sim, estou fazendo isso por meio de enxame ...

Na segunda-feira, 19 de março de 2018 às 9h12, Archimedes Trajano <
notificaçõ[email protected]> escreveu:

Você testou isso em um enxame com mais de um trabalhador com docker stack
implantar. Eu sei que funciona com a composição.

Em 18 de março de 2018, às 20h55, Brian Goff [email protected]
escreveu:

@trajano Você pode usar redes com escopo não-swarm já com o swarm ...
por exemplo, isso funciona:

versão: '3.4'

Serviços:
teste:
imagem: alpino
comando: top
portas:

  • alvo: 32555
    publicado: 32555
    protocolo: tcp
    modo: host
    redes:
  • Ponte

redes:
Ponte:
externo:
nome: ponte
-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub ou ignore a conversa.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-374206587 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAwxZsm3OohKL0sqUWhlgUNjCrqR0OaVks5tf67YgaJpZM4Jf2WK
.

-

  • Brian Goff

+1

Tendo este problema com o seguinte balanceamento de carga docker swarm com 3 nós:

rede de sobreposição <-> nginx proxy jwilder docker <-> nginx web head docker

Segui as sugestões e os logs continuam retornando o ip 10.255.0.3 da rede docker em vez do IP do cliente real.

+1

@ cpuguy83 isto começou a se tornar um bloqueador para nossas configurações de enxame maiores. conforme começamos a aproveitar mais a nuvem (onde o protocolo de proxy está sendo usado de fato por balanceadores de carga), estamos perdendo essa informação que é muito importante para nós.

Você tem alguma ideia de um ETA? isso nos ajudaria muito.

@sandys Um ETA para quê exatamente?

@ cpuguy83 oi, obrigado pela sua resposta. Estou ciente de que não existe um amplo acordo sobre como você deseja resolvê-lo. Estou comentando como a equipe tem se ocupado com os problemas de estabilidade e não está liberada para esse problema.
Quando você acha que esse assunto seria abordado (se for o caso)?

Observe que você pode resolver esse problema executando um serviço global e publicando portas usando PublishMode = host. Se você sabe em qual nó as pessoas estarão se conectando, você nem mesmo precisa disso, apenas use uma restrição para fixá-lo naquele nó.

@kleptog Parcialmente você não pode. Ele não pode evitar o tempo de inatividade durante a atualização do serviço.

Cenário de teste - uma análise mais detalhada de lvs / ipvs.

  • nsenter no contêiner de entrada oculto e exclua a regra snat
  • nsenter no serviço com portas publicadas, exclua o gw padrão e adicione a rota padrão ao ip dos contêineres de entrada.

Agora o ip de origem será preservado.

Ainda estou tentando entender as implicações da sobrecarga, mantendo o roteamento baseado em política dentro de cada contêiner de serviço em vez de ter apenas a regra snat no contêiner de ingresso.
Seria realmente um alívio ter isso funcionando.

Desculpe pela minha manipulação ingênua, mas alguém poderia ( Indicar o código do docker, onde isso é feito?

Ah, agora eu entendi. Em um enxame multinó, o IP tem que ser dos diretores lvs, para encontrar o caminho de volta para o nó correto a solicitação veio ...

Seria interessante ver o código de qualquer maneira. Isso poderia me poupar algum tempo, se alguém já soubesse. Obrigado

Quaisquer atualizações sobre isso, tendo três clusters em países diferentes, e até mesmo o Azure Traffic Manager precisa de IPs de usuário real, caso contrário, ele não redirecionará o usuário para um bom cluster etc. Alguém, em breve ou nunca, irá verificar isso? Obrigado

Também preciso de uma atualização sobre isso - esta é uma grande pegadinha - a única maneira que encontrei de contornar isso é adicionar outro proxy na frente e enviar x-forwarded-for para a pilha, meio que significa que o Swarm não é uma opção para o público enfrentando o tráfego para muitos cenários.

@ cpuguy83 @trajano
Posso confirmar que o seguinte não 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

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

versão 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
Tente recriar o enxame. Eu também tive um erro. Após o enxame de reinicialização, tudo funcionou para mim.
Meu arquivo 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

meu 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

Desculpe pelo meu Inglês.

@ Mobe91 foi isso que usei, mas implantei no "portainer" ou na máquina Linux. Não consigo implantá-lo corretamente no 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

A principal diferença é que eu uso host vez de bridge No meu caso, também estou executando meus hosts como VMs do VirtualBox e uso o roteador que faz o roteamento NAT e que preserva o IP de entrada por todo o caminho para o contêiner.

Claro que não há capacidade de balanceamento de carga. Eu acho que se você quiser balanceamento de carga, você precisa ter algo na frente como um roteador L3 que faria o balanceamento de carga

@trajano está certo, o cliente Windows era o problema, a implantação com o cliente Linux funcionou.

Mas eu não entendo por que você precisa da rede host ou bridge ?
O seguinte funciona perfeitamente para mim, ou seja, eu obtenho endereços IP de clientes reais no nginx:

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

@ Mobe91, obrigado, queria abrir uma edição para isso. Basicamente, empate com https://github.com/moby/moby/issues/32957, uma vez que ainda ocorria com o cliente 18.03-ce para Windows.

Alguém usou Cilium? http://cilium.readthedocs.io/en/latest/gettingstarted/docker/ .

Parece que ele pode consertar isso sem vincular os serviços ao host.

@sandys good find - Estou prestes a começar a testá-lo, funcionou para você? Estou prestes a tirar o nginx do meu enxame se não conseguir consertar isso ...

Conseguimos isso ao reprojetar nossa implantação para evitar a fixação de proxies a hosts individuais (que, na produção, se vinculam a uma interface por outros motivos e, portanto, "pegam" o IP do cliente como um subproduto).

Em nosso ambiente de teste, podemos melhorar apenas implementando para gerentes por restrição e definindo mode = global para garantir que cada gerente obtenha uma instância em execução. Ainda é necessário estar ciente de uma sobrecarga extra, especialmente se perdermos um nó de gerenciador e algo estiver direcionando nosso tráfego para ele. No entanto, é melhor do que estar preso a um único host.

@sandys , você experimentou Cilium? É semelhante ao Weave, que parece sofrer o mesmo problema pelo menos com k8s: https://github.com/kubernetes/kubernetes/issues/51014

Não tenho conseguido usar o Cilium, mas procurei o Cilium
devs para ajudar na configuração do swarm. Mas estou muito animado com o Cilium
porque o ingresso é um problema declarado que ele deseja resolver (ao contrário do tecido)

Em quinta-feira, 10 de maio de 2018, 17:24, James Green, [email protected] escreveu:

Conseguimos isso ao reprojetar nossa implantação para evitar a fixação de proxies para
hosts individuais (que, em produção, se ligam a uma interface para outros
razões e, portanto, "pegar" o IP do cliente como um subproduto).

Em nosso ambiente de teste, podemos melhorar apenas implantando para gerentes por
modo de restrição e configuração = global para garantir que cada gerente obtenha uma
instância em execução. Ainda é uma sobrecarga extra para ter que estar ciente,
particularmente se perdermos um nó gerenciador e algo está direcionando nosso
tráfego para ele. No entanto, é melhor do que estar preso a um único host.

@sandys https://github.com/sandys você experimentou o Cilium? Se parece com
Weave, que parece sofrer o mesmo problema pelo menos com k8s:
kubernetes / kubernetes # 51014
https://github.com/kubernetes/kubernetes/issues/51014

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-388032011 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK
.

Em 10 de maio de 2018, 17:24, "James Green" [email protected] escreveu:

Conseguimos isso ao reprojetar nossa implantação para evitar a fixação de proxies para
hosts individuais (que, em produção, se ligam a uma interface para outros
razões e, portanto, "pegar" o IP do cliente como um subproduto).

Em nosso ambiente de teste, podemos melhorar apenas implantando para gerentes por
modo de restrição e configuração = global para garantir que cada gerente obtenha uma
instância. Ainda é uma sobrecarga extra para ter que estar ciente, especialmente se
perdemos um nó gerenciador e algo está direcionando nosso tráfego para ele.
No entanto, é melhor do que estar preso a um único host.

@sandys https://github.com/sandys você experimentou o Cilium? Se parece com
Weave, que parece sofrer o mesmo problema pelo menos com k8s:
kubernetes / kubernetes # 51014
https://github.com/kubernetes/kubernetes/issues/51014

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-388032011 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK
.

  • 1

Oi, pessoal,
se você quiser suporte Docker Swarm em Cilium (especialmente para entrada e
em torno deste problema específico), comente / curta este bug -
https://github.com/cilium/cilium/issues/4159

Na sexta-feira, 11 de maio de 2018 às 12h59, McBacker [email protected] escreveu:

>

  • 1

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-388159466 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU_18F_cNttRUaAwaRF3gVpMZ-3qSks5txJUfgaJpZM4Jf2WK
.

para mim com a versão atual funciona assim:
então posso acessar os outros nós do enxame, pois também está na rede 'padrão'

  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

Posso confirmar que a chave é usar ports.mode: host . Na documentação (https://docs.docker.com/compose/compose-file/#long-syntax-1):

modo: host para publicar uma porta de host em cada nó ou ingresso para uma porta de modo de enxame para ter a carga balanceada.

Então, usando mode: host pare de ser balanceado pela entrada e o IP real aparecerá. Por exemplo, aqui estão meus logs do nginx:

  • com 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
  • sem 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

E se você se pergunta por que o último log é uma resposta 403 Forbidden, isso é devido ao uso de uma lista de permissões no nginx ( allow 62.4.X.X e deny all ).

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

Eu confirmo o que @nperron disse.
Usar o modo host permite obter o ip do cliente.

Docker versão 18.03.1-ce, compilação 9ee9f40
Ubuntu 16.04.4 LTS

Posso confirmar que está funcionando.

Docker versão 18.03.1-ce, compilação 9ee9f40
Ubuntu 16.04.4 LTS

AVISO: ISTO NÃO FUNCIONARÁ SE VOCÊ TIVER CONFIGURADO IPTABLES = FALSE!
Você pode ter feito isso (ou pelo menos eu fiz) se estiver usando o UFW para proteger as portas e descobrir que o docker swarm está substituindo essas configurações do UFW.

Existem alguns tutoriais que sugerem definir iptables = false por meio de comando ou em /etc/docker/daemon.json

Espero que isso evite a frustração pela qual acabei de passar!

as pessoas realmente deveriam parar de dizer "Mode: host" = working, porque isso não está usando o Ingress. Isso torna impossível ter apenas um contêiner com um serviço em execução no enxame, mas ainda ser capaz de acessá-lo por meio de qualquer host. Você ou tem que tornar o serviço "Global" ou você só pode acessá-lo no host que ele está executando, o que meio que frustra o propósito do Swarm.

TLDR: "Modo: Host" é uma solução alternativa, não uma solução

@ r3pek Embora eu concorde com você que você perde o Ingress se usar o modo Host para resolver essa situação, eu diria que isso dificilmente anula todo o propósito do Swarm, que faz muito mais do que uma rede de entrada voltada para o público. Em nosso cenário de uso, temos o mesmo enxame de sobreposição:
gerenciamento de containers replicados que só devem ser acessados ​​pela intranet -> não precisam do ip do chamador, portanto são configurados "normalmente" e tiram proveito do ingresso.
contêineres não expostos -> nada a dizer sobre eles (acredito que você está subestimando o poder de acessá-los por meio do nome do serviço).
serviço voltado para o público -> este é um proxy nginx que faz roteamento baseado em https e url. Ele foi definido como global antes mesmo da necessidade de x-forward-for o ip real do cliente, então nenhum problema real aí.

Ter nginx global e não ter entrada significa que você pode acessá-lo por meio de qualquer ip do cluster, mas não é com balanceamento de carga ou tolerante a falhas, então adicionamos um balanceador de carga L4 Azure muito barato e fácil de configurar na frente do nginx serviço.

Como você disse, Host é uma solução alternativa, mas dizer que ativá-lo anula completamente o propósito do Docker Swarm é um pouco exagerado.

Oi roberto
Eu não acho que seja exagerado - porque o modo host expõe pontos únicos
de fracasso. Além disso, espera camadas adicionais de gerenciamento para carga
balanceamento fora do ecossistema de enxame.

Ao dizer que você mesmo usou azure lb, você meio que validou que
argumento.

É o mesmo que dizer que "para executar o swarm com propagação de IP do cliente,
certifique-se de usar um balanceador de carga externo que você configurou ... Ou use
um dos serviços em nuvem ".

Não estamos dizendo que não seja uma solução temporária ... Mas seria
ignorando a promessa do Swarm se todos nós não reconhecermos categoricamente o
deficiência.

Em quinta, 5 de julho de 2018, 14h16 Roberto Fabrizi, notificaçõ[email protected]
escreveu:

@ r3pek https://github.com/r3pek Embora eu concorde com você que você perde
Ingress, se você usar o modo Host para resolver essa situação, eu diria que
dificilmente derrota todo o propósito do Swarm, que faz muito mais que um
rede de entrada voltada para o público. Em nosso cenário de uso, temos o mesmo
overlay swarm:
gerenciamento de contêineres replicados que só devem ser acessados ​​no
intranet -> eles não precisam do ip do chamador, portanto estão configurados
"normalmente" e aproveite o ingresso.
recipientes não expostos -> nada a dizer sobre estes (eu acredito que você é
subestimar o poder de acessá-los por meio de seu serviço
embora nome).
contêiner voltado para o público -> este é um proxy nginx que faz https e url
roteamento baseado. Ele foi definido como global antes mesmo da necessidade de x-forward-for
o ip real do cliente, então nenhum problema real aí.

Ter nginx global e não ter entrada significa que você pode alcançá-lo via
qualquer ip do cluster, mas não tem balanceamento de carga, então adicionamos um muito
barato e fácil de configurar L4 Azure Load Balancer na frente do nginx
serviço.

Como você disse, o Host é uma solução alternativa, mas dizendo que ativá-lo completamente
derrota o propósito de Docker Swarm é um pouco exagerado imo.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-402650066 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU_ogRzwM6X0PMknXxsxmZLLTtfraks5uDdJlgaJpZM4Jf2WK
.

É claro que um balanceador de carga ruim (IPVS) foi escolhido para a entrada do Docker Swarm. Se ele fosse compatível com pelo menos o protocolo de proxy L4 , isso não seria um problema. Exceto que ainda seria um balanceador de carga L4 (TCP) sem todos os recursos extras que o L7 lb pode oferecer.

No Kubernetes, há balanceadores de carga L4 (TCP) -L7 (HTTP) como nginx ingress , haproxy ingress, que permitem o uso do protocolo de proxy L4 ou cabeçalhos L7 HTTP para garantir que X-Forwarded-For seja aproveitado para passar o real do usuário IP para o back-end.

Estou me perguntando o que diriam os desenvolvedores do Docker Swarm ingress. Provavelmente, alguém precisa mover este caso para https://github.com/docker/swarmkit/issues ?

No Kubernetes, há balanceadores de carga L4 (TCP) -L7 (HTTP), como entrada nginx, entrada haproxy, que permitem o uso do protocolo proxy L4 ou cabeçalhos HTTP L7 para garantir que X-Forwarded-For seja aproveitado para passar o IP real do usuário para o backend.

AFAICS, esses serviços LB não são incorporados ao K8s, mas serviços que precisam ser implementados explicitamente. Você também pode fazer o mesmo com o Docker swarm. Não vejo diferença aqui. (Além disso, o controlador de entrada nginx parece ser "oficial".)

Pelo que eu sei, a diferença é que mesmo se você implantar esse serviço de balanceamento de carga, ele será 'chamado' do balanceador de carga do swarmkit e, assim, você perderá o ip dos usuários. Portanto, você não pode desativar o balanceador de carga swarmkit se não estiver usando o modo de host.

para ser justo - em k8s, é possível ter uma entrada personalizada. em enxame
não é.

swarm considera que tudo está "embutido". O mesmo é o caso com
redes - no k8s, você precisa configurar o weave, etc ... no swarm está embutido.

então o ponto que o andrey está fazendo (e eu meio que concordo) é que -
enxame deve fazer esses recursos como parte da entrada, uma vez que o usuário tem
nenhum controle sobre isso.

No sábado, 28 de julho de 2018 às 17h07, Seti [email protected] escreveu:

Tanto quanto eu sei, a diferença é que mesmo se você implantar tal
serviço de balanceamento de carga será 'chamado' do balanceador de carga swarmkit
e assim você perde o ip dos usuários. Então você não pode desativar o swarmkit
loadbalancer, se não estiver usando hostmode.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-408601274 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU1-Ism_S1Awml8lO8N0Aq6rtrLH4ks5uLEzugaJpZM4Jf2WK
.

Achei que tínhamos acabado de limpar nossas rugas de enxame, mas então chegamos ao estágio e percebemos que todo acesso externo ao contêiner do servidor web aparece como o IP de rede de entrada.

Estou executando minha pilha em um enxame de nó único e farei isso pelo menos nos próximos meses. Você pode recomendar a solução alternativa menos ruim para nosso caso de uso atual (enxame de nó único)? Não posso ficar sem o IP do cliente - depende muito dele.

Nossa abordagem temporária tem sido executar um contêiner de proxy simples no modo "global" (que IIRC pode obter o IP da NIC real) e, em seguida, encaminhar todas as conexões para o serviço interno em execução na rede de sobreposição de enxame com cabeçalhos de proxy adicionados.

Se obter um cabeçalho x-forwarded-for é suficiente para você, essa configuração deve funcionar AFAICT.

Obrigado, @maximelb. O que você acabou fazendo (por exemplo, nginx, haproxy)?

@jamiejackson é onde as coisas serão um pouco diferentes. Em nosso caso, estamos executando um servidor que hospeda conexões SSL de longa duração e um protocolo binário personalizado por baixo, de modo que os proxies HTTP não eram possíveis. Portanto, criamos um encaminhador TCP simples e usamos um cabeçalho “msgpack” que poderíamos descompactar manualmente no servidor interno.

Não estou muito familiarizado com proxies HTTP, mas suspeito que a maioria deles resolveria o problema para você. : - /

oi maxime,
isso é muito interessante para nós. Você pode compartilhar seu docker-compose por qualquer
chance ?

Estou tentando entender como isso funciona. Hoje temos o nginx como reverso
proxy (como um serviço) e vários serviços docker por trás dele.

No seu caso - o nginx se torna o proxy de "modo global"? ou é um
encaminhador TCP especial. Assim, conforme você escala o número de nós, o proxy forwarder
vai em cada nó. De alguma forma, pensei que nesta situação o x-encaminhado para
cabeçalho é perdido .. porque a rede de entrada mata o ip externo
(uma vez que não há protocolo proxy).

Ficaríamos muito gratos se você pudesse nos ajudar com mais alguns detalhes.

Saudações
sandeep

Na quarta-feira, 8 de agosto de 2018 às 7h18 Maxime Lamothe-Brassard <
notificaçõ[email protected]> escreveu:

Nossa abordagem temporária tem sido executar um contêiner de proxy simples em
Modo "global" (o qual IIRC pode obter o IP da NIC real) e, em seguida, tê-lo
encaminhar todas as conexões para o serviço interno em execução no enxame
rede de sobreposição com cabeçalhos de proxy adicionados.

Se obter um cabeçalho x-forwarded-for é suficiente para você, essa configuração deve
trabalho AFAICT.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411257087 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUx3DOjXb79FNjsuZ-RZVqkkhHAbYks5uOkOHgaJpZM4Jf2WK
.

@sandys claro, aqui está um trecho de nosso docker-compose com os contêineres relevantes.

Esta é a entrada docker-compose do proxy reverso:

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

Esta é a entrada do serviço de back-end:

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

O destino do proxy reverso (o lado do backend) seria tasks.backendservice (que tem registros A para cada réplica). Você pode pular a parte networks se o serviço de back-end estiver na rede de sobreposição swarm padrão.

O bit global diz "implante este contêiner exatamente uma vez em cada nó de swarm do Docker. As portas mode: host são as que dizem" vincular ao NIC nativo do nó ".

Espero que ajude.

Você está usando o modo host. Basicamente, você tem um balanceador de carga externo
na frente de tudo.
Você não pode mais depender do Swarm porque está no modo host.

Na verdade, esse é o problema do qual falamos há algum tempo :(

Quarta, 8 de agosto de 2018, 20:47 Maxime Lamothe-Brassard, <
notificaçõ[email protected]> escreveu:

@sandys https://github.com/sandys claro, aqui está um trecho de nosso
docker-compose com os contêineres relevantes.

Esta é a entrada docker-compose do proxy reverso:

proxy reverso:
imagem: yourorg / repo- proxy: mais recente
redes:
- network_with_backend_service
implantar:
modo: global
portas:
- alvo: 443
publicado: 443
protocolo: tcp
modo: host

Esta é a entrada do serviço de back-end:

backendservice:
imagem: yourorg / repo- backend: mais recente
redes:
- network_with_backend_service
implantar:
réplicas: 2

O destino do proxy reverso (o lado do back-end) seria
tasks.backendservice (que tem registros A para cada réplica). Você pode
pule a parte das redes se o serviço de back-end estiver no enxame padrão
rede de sobreposição.

O bit global diz "implante este contêiner exatamente uma vez em cada Docker
nó de enxame. O modo de portas: host é aquele que diz "vincular ao nativo
NIC do nó ".

Espero que ajude.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411442155 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU8N7KAFtOp_cPO8wpbBQqzDfpBWOks5uOwEkgaJpZM4Jf2WK
.

Não temos 100% de certeza do que você quer dizer, mas externamente usamos um DNS com um registro A por nó de cluster. Isso fornece um "balanceamento" barato sem ter uma parte móvel externa. Quando um cliente faz uma solicitação, ele escolhe um registro A aleatório e se conecta a 443 em um dos nós do cluster.

Lá, o proxy reverso que está em execução naquele nó específico e atendendo em 443 obtém uma conexão nativa, incluindo o IP do cliente real. Esse contêiner de proxy reverso então adiciona um cabeçalho e encaminha a conexão para outro contêiner interno usando a rede de sobreposição de swarm (tasks.backend). Como ele usa o destino tasks.backend, ele também obterá um registro A aleatório para um serviço interno.

Portanto, no sentido estrito, é contornar a magia da rede de sobreposição que redireciona a conexão. Em vez disso, meio que replica esse comportamento com o proxy reverso e adiciona um cabeçalho. O efeito final é o mesmo (em um sentido amplo) que a magia da rede de sobreposição. Ele também faz isso em paralelo à execução do swarm, o que significa que posso executar todos os meus outros serviços que não exigem o IP do cliente no mesmo cluster sem fazer nada para eles.

De forma alguma, uma solução perfeita, mas até que uma correção seja feita (se for o caso), você fica sem componentes externos ou configuração principal do docker.

@jamiejackson a solução alternativa "menos ruim" que encontramos é usar o Traefik como um serviço global no modo host. Eles têm um bom exemplo genérico em seus documentos . Vimos alguns bugs que podem ou não estar relacionados a esta configuração, mas o Traefik é um ótimo projeto e parece bastante estável no Swarm. Há um tópico inteiro na página de problemas deles (que volta aqui :)), com soluções alternativas semelhantes:
https://github.com/containous/traefik/issues/1880

Espero que isto ajude. Também não podemos usar uma solução que não nos permite verificar os IPs reais do solicitante, portanto, estamos presos a essa correção de kludge até que algo mude. Parece uma necessidade bastante comum, pelo menos por razões de segurança.

Entendido (e uma versão solta disso é o que usamos).

No entanto - a agenda desse bug em particular era solicitar aos desenvolvedores
para construir isso na rede de sobreposição mágica (talvez usando proxy
protocolo ou outros mecanismos)

Quarta, 8 de agosto de 2018, 21:22 Maxime Lamothe-Brassard, <
notificaçõ[email protected]> escreveu:

Não temos 100% de certeza do que você quer dizer, mas externamente usamos um DNS com um A
registro por nó do cluster. Isso fornece "balanceamento" barato sem ter um
parte móvel externa. Quando um cliente faz uma solicitação, eles escolhem um A aleatório
registrar e conectar-se a 443 em um dos nós do cluster.

Lá, o proxy reverso que está sendo executado naquele nó específico e
ouvir em 443 obtém uma conexão nativa, incluindo o IP do cliente real.
Esse contêiner de proxy reverso então adiciona um cabeçalho e encaminha a conexão
para outro contêiner interno usando a rede de sobreposição de enxame
(tasks.backend). Uma vez que usa o destino tasks.backend, ele também obterá um
random Um registro para um serviço interno.

Portanto, no sentido estrito, é contornar a magia da rede de sobreposição que
redireciona a conexão. Em vez disso, meio que replica esse comportamento com
o proxy reverso e adiciona um cabeçalho. O efeito final é o mesmo (em um
sentido livre) como a magia da rede de sobreposição. Ele também faz isso em
paralelo à execução do swarm, o que significa que posso executar todos os meus outros serviços que
não exija o IP do cliente no mesmo cluster sem fazer nada
mais para aqueles.

De forma alguma é uma solução perfeita, mas até que uma correção seja feita (se houver), ela fica
sem componentes externos ou configuração principal do docker.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411455384 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU5RKjGc3hEk6bk-doicDa1MbYGAyks5uOwlIgaJpZM4Jf2WK
.

TBH Não tenho certeza por que a rede de entrada não está sendo corrigida para adicionar ip
dados no protocolo proxy.

É incremental, não vai quebrar as pilhas existentes, é um bem definido
padrão, é amplamente suportado até mesmo pelos grandes fornecedores de nuvem, é amplamente
suportado por estruturas de aplicativos.

É um esforço de desenvolvimento significativo?

Na quarta-feira, 8 de agosto de 2018, 21:30 Matt Glaser, [email protected] escreveu:

@jamiejackson https://github.com/jamiejackson o "menos ruim"
A solução alternativa que descobrimos é usar o Traefik como um serviço global no modo host.
Eles têm um bom exemplo genérico em seus documentos
https://docs.traefik.io/user-guide/cluster-docker-consul/#full-docker-compose-file_1 .
Vimos alguns bugs que podem ou não estar relacionados a esta configuração, mas
Traefik é um ótimo projeto e parece bastante estável no Swarm. Há um
tópico inteiro em sua página de problemas (que volta aqui :)), com
soluções alternativas semelhantes:
contencioso / traefik # 1880
https://github.com/containous/traefik/issues/1880

Espero que isto ajude. Também não podemos usar uma solução que não nos permite
verifique os IPs reais do solicitante, então estamos presos a essa correção de kludge até
algo muda. Parece uma necessidade muito comum, por razões de segurança
pelo menos.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-411458326 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU7NNbsW44L95VYCvlyL_Bje-h6L9ks5uOwsUgaJpZM4Jf2WK
.

Bem, o Docker atualmente não toca no tráfego de entrada, então definitivamente pelo menos não insignificante para adicionar.
Tenha em mente também que este é um projeto de código aberto, se você realmente deseja algo, geralmente será você quem decide implementá-lo.

1, isso realmente é um empecilho.
Eu acredito que a maioria das aplicações precisa do ip de clientes reais. Pense em uma pilha de servidor de e-mail - você não pode aceitar e-mails de hosts arbitrários.

Mudamos para o modo de host de instância de fluxo global proxy_protocol nginx, que está encaminhando para o aplicativo replicado proxy_nginx. Isso funciona bem o suficiente no momento.

serviço 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;
    }
}

serviço 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;
    }
}

Seria possível passar toda a configuração do nginx para nginx_stream e
nginx_proxy com suas configurações Swarm?

Isso é incrível se funcionar!

Na terça-feira, 11 de setembro de 2018, 17:14 rubot, notificaçõ[email protected] escreveu:

Mudamos para a instância de fluxo global proxy_protocol nginx, que é
encaminhando para o aplicativo proxy_nginx replicado. Isso funciona bem o suficiente
para o momento.

serviço global nginx_stream

Stream {
resolver_timeout 5s;
# 127.0.0.11 é servidor docker swarms dns
resolvedor 127.0.0.11 válido = 30s;
# set não funciona no módulo stream, usando o mapa aqui
map '' $ upstream_endpoint {
proxy_ nginx padrão
}

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

}

serviço replicado nginx_proxy

servidor {
ouvir 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;
}

}

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-420244262 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU5K-gK09XdI9NxLlT36IrJP7U7_cks5uZ6IrgaJpZM4Jf2WK
.

@sandys Eu tenho uma solução baseada em haproxy para a parte do protocolo de proxy que é configurada por meio de variáveis ​​de ambiente.

Seria possível passar toda a configuração nginx para nginx_stream e nginx_proxy com suas configurações Swarm? Isso é incrível se funcionar!

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

enfrentando o mesmo problema, isso será resolvido? parece uma funcionalidade básica que deveria ser lançada.

implantar:
modo: global
portas:

  • alvo: 443 publicado: 443 protocolo: modo tcp: host

Seguir este conselho corrige o problema, pois o docker swarm balancer está fora da equação.
Para mim é uma solução válida, pois ainda é HA e eu já tinha haproxy (dentro do contêiner de proxy de fluxo do docker).
O único problema é que as estatísticas do haproxy são distribuídas entre todas as réplicas, portanto, preciso agregar de alguma forma essas informações ao monitorar o tráfego de todo o cluster. No passado, eu só tinha uma instância haproxy que estava atrás do balanceador docker swarm.
Saúde,
Jacq

Ao ler a solicitação do OP ( @PanJ ), parece que os recursos atuais já resolvem esse problema, como vinham sendo sugeridos há meses. O OP não pediu roteamento de entrada + IP do cliente AFAIK, eles pediram uma maneira de ter um serviço de enxame em réplica / obter IPs do cliente global, o que agora é factível. Duas áreas principais de melhoria permitem que isso aconteça:

  1. Agora podemos criar um serviço Swarm que "publica" uma porta para o IP do host, ignorando a camada de roteamento de entrada
  2. Esse mesmo serviço pode se conectar a outras redes como sobreposição ao mesmo tempo, para que possa acessar outros serviços com benefícios de sobreposição

Para mim, com motor 18.09, recebo o melhor dos dois mundos nos testes. Um único serviço pode se conectar a redes de sobreposição de back-end e também publicar portas na placa de rede do host e ver o IP do cliente real entrando no IP do host. Estou usando isso com o proxy reverso do traefik para registrar o tráfego IP do cliente no traefik que é destinado a serviços de back-end . Acho que isso pode resolver a maioria das solicitações que já vi para "registrar o IP real".

@PanJ isso resolve para você?

A chave é publicar portas em mode: host vez de mode: ingress (o padrão).

A vantagem desse modo é que você obtém IPs de clientes reais e desempenho de NIC de host nativo (uma vez que está fora do encapulamento IPVS AFAIK). O con é que ele ouvirá apenas no (s) nó (s) que executam as réplicas.

Para mim, a solicitação de "Eu quero usar o roteamento IPVS de entrada e também ver o IP do cliente" é uma solicitação de recurso diferente da libnetwork.

O que mudou aqui? Porque temos usado o modo host para fazer isso por
muito tempo agora. Na verdade, essa é a solução alternativa sugerida neste tópico como
Nós vamos.

O problema é que, claro, você deve bloquear esse serviço para um determinado
host para que o Swarm não possa agendá-lo em outro lugar. Qual era o problema
inteiramente - aquele protocolo de proxy / IPVS, etc. resolve este problema.

Na sexta-feira, 4 de janeiro de 2019, 09:34, Bret Fisher < notificaçõ[email protected] escreveu:

Ao ler a solicitação do OP ( @PanJ https://github.com/PanJ ), ele
parece que os recursos atuais agora resolvem esse problema, como foi sugerido para
meses. O OP não pediu roteamento de entrada + IP AFAIK do cliente, eles pediram
para ter um serviço de enxame em réplica / global, obter IPs do cliente,
que agora é factível. Duas áreas principais de melhoria permitem que isso aconteça:

  1. Agora podemos criar um serviço Swarm que "publica" uma porta para o
    IP do host, pulando a camada de roteamento de entrada
  2. Esse mesmo serviço pode ser anexado a outras redes, como sobreposição no
    ao mesmo tempo, para que possa acessar outros serviços com benefícios de sobreposição

Para mim, com motor 18.09, recebo o melhor dos dois mundos nos testes. UMA
um único serviço pode se conectar a redes de sobreposição de back-end e também publicar
portas na placa de rede do host e ver os IPs reais do cliente entrando no IP do host. Eu estou
usando isso com o proxy reverso traefik para registrar o tráfego IP do cliente no traefik
que se destina a serviços de back-end
https://github.com/BretFisher/dogvscat/blob/7e9fe5b998f2cf86951df3f443714beb413d63fb/stack-proxy-global.yml#L75-L83 .
Eu sinto que isso poderia resolver a maioria das solicitações que tenho visto para "registrar o real
IP ".

@PanJ https://github.com/PanJ isso resolve para você?

A chave é publicar portas no modo: host em vez de modo: ingress (o
predefinição).

A vantagem deste modo é que você obtém IPs reais do cliente e NIC de host nativo
desempenho (uma vez que está fora do encapulamento IPVS AFAIK). O contra é isso
escutará apenas no (s) nó (s) executando as réplicas.

Para mim, a solicitação de "Eu quero usar o roteamento IPVS de entrada e também ver
cliente IP "é uma solicitação de recurso diferente da libnetwork.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451348906 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUzs15UVWOVl54FLwBJSZJKX-9D0jks5u_tLPgaJpZM4Jf2WK
.

@BretFisher o mode: host é apenas uma solução alternativa, mas não a solução. Como @sandys disse que a solução alternativa tem poucas ressalvas, não devemos considerar esse problema como corrigido.

Não tenho certeza se houve alguma melhoria desde que a solução alternativa foi descoberta. Mudei para o Kubernetes por um longo tempo e ainda fico surpreso que o problema ainda esteja aberto por mais de dois anos.

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. Do meu
perspectiva, mesmo a declaração de mudança para kubernetes não é adequada
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento. Você também
ter um LB externo ou usar algo como proxy de entrada nginx que deve
executar como daemonset. Por favor, me corrija se eu estiver errado, mas nós temos o mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguem poderia
verificar e empacotar minha solução de fluxo tcp proposta descrita acima para obter
algo como o comportamento do proxy nginx. Basta aceitar, esse enxame precisa ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é apenas um
solução alternativa, mas não a solução. Como @sandys https://github.com/sandys
disse que a solução alternativa tem poucas ressalvas, não devemos considerar esse problema
como corrigido.

Não tenho certeza se houve alguma melhoria, já que a solução alternativa foi
descoberto. Mudei para o Kubernetes por um longo tempo e ainda sou
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
.

Você pode até estender o projeto dockerflow e adicionar uma variante nginx para iniciar
kubernetes-ingressproxy para swarn. Definitivamente, tudo isso embalado com enxame
levantaria um contêiner de sistema adicional, pois você sabe que há um monte de
-los com kubernetes. Não é a força do enxame para recursos escassos
projetos para serem enxutos?

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

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. Do meu
perspectiva, mesmo a declaração de mudança para kubernetes não é adequada
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento. Você também
ter um LB externo ou usar algo como proxy de entrada nginx que deve
executar como daemonset. Por favor, me corrija se eu estiver errado, mas nós temos o mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguem poderia
verificar e empacotar minha solução de fluxo tcp proposta descrita acima para obter
algo como o comportamento do proxy nginx. Basta aceitar, esse enxame precisa ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é apenas um
solução alternativa, mas não a solução. Como @sandys https://github.com/sandys
disse que a solução alternativa tem poucas ressalvas, não devemos considerar esse problema
como corrigido.

Não tenho certeza se houve alguma melhoria, já que a solução alternativa foi
descoberto. Mudei para o Kubernetes por um longo tempo e ainda sou
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
.

Essas são soluções complexas - o protocolo de proxy apenas adiciona cabeçalho adicional
informações e é um padrão muito conhecido - haproxy, nginx, AWS elb,
etc todos seguem. https://www.haproxy.com/blog/haproxy/proxy-protocol/

A área de superfície da mudança seria limitada ao Enxame embutido
entrada (onde este suporte seria adicionado). E todos os serviços terão
acessível.

Na sexta-feira, 4 de janeiro de 2019, 14h36, rubot < [email protected] escreveu:

Você pode até estender o projeto dockerflow e adicionar uma variante nginx para iniciar
kubernetes-ingressproxy para swarn. Definitivamente, tudo isso embalado com enxame
levantaria um contêiner de sistema adicional, pois você sabe que há um monte de
-los com kubernetes. Não é a força do enxame para recursos escassos
projetos para serem enxutos?

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

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. Do meu
perspectiva, mesmo a declaração de mudança para kubernetes não é adequada
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento. Vocês
qualquer
ter um LB externo ou usar algo como proxy de entrada nginx que deve
executar como daemonset. Por favor, me corrija se eu estiver errado, mas nós temos o mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguem poderia
verificar e empacotar minha solução de fluxo tcp proposta descrita acima para obter
algo como o comportamento do proxy nginx. Basta aceitar, esse enxame precisa ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é apenas um
solução alternativa, mas não a solução. Como @sandys https://github.com/sandys
disse que a solução alternativa tem poucas ressalvas, não devemos considerar isso
edição
como corrigido.

Não tenho certeza se houve alguma melhoria, já que a solução alternativa foi
descoberto. Mudei para o Kubernetes por um longo tempo e ainda
ser
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ou
mudo
o segmento
<
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK
.

Como eu disse, verifique a solução de fluxo tcp acima, que já utiliza proxy
protocolo.
Adicionar protocolo de proxy exigiria também configuração dentro do contêiner se
adicionado ao enxame rio acima. Não vejo valor, além de um limpador e talvez melhor
meta documentada em sua solicitação

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

Essas são soluções complexas - o protocolo de proxy apenas adiciona cabeçalho adicional
informações e é um padrão muito conhecido - haproxy, nginx, AWS elb,
etc todos seguem. https://www.haproxy.com/blog/haproxy/proxy-protocol/

A área de superfície da mudança seria limitada ao Enxame embutido
entrada (onde este suporte seria adicionado). E todos os serviços terão
acessível.

Na sexta-feira, 4 de janeiro de 2019, 14h36, rubot < [email protected] escreveu:

Você pode até estender o projeto dockerflow e adicionar uma variante nginx para
começar
kubernetes-ingressproxy para swarn. Definitivamente, tudo isso embalado com enxame
levantaria um contêiner de sistema adicional, pois você sabe que há um monte de
-los com kubernetes. Não é a força do enxame para recursos escassos
projetos para serem enxutos?

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

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. Do meu
perspectiva, mesmo a declaração de mudança para kubernetes não é adequada
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento. Vocês
qualquer
ter um LB externo ou usar algo como proxy de entrada nginx que
deve
executar como daemonset. Por favor, me corrija se eu estiver errado, mas nós temos o mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguem poderia
verificar e empacotar minha solução de fluxo tcp proposta descrita acima para obter
algo como o comportamento do proxy nginx. Basta aceitar, esse enxame precisa
ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é apenas um
solução alternativa, mas não a solução. Como @sandys <
https://github.com/sandys>
disse que a solução alternativa tem poucas ressalvas, não devemos considerar isso
edição
como corrigido.

Não tenho certeza se houve alguma melhoria, já que a solução alternativa foi
descoberto. Mudei para o Kubernetes por um longo tempo e ainda
ser
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ,
ou
mudo
o segmento
<

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

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ou
mudo
o segmento
<
https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
.

A solução acima requer a vinculação do modo de host. Esse é o grande problema. Isto
elimina a possibilidade de usar o programador docker para alocar contêineres
para hosts diferentes - não faço mais parte da rede mesh.

Na sexta-feira, 4 de janeiro de 2019, 17:28, rubot < [email protected] escreveu:

Como eu disse, verifique a solução de fluxo tcp acima, que já utiliza proxy
protocolo.
Adicionar protocolo de proxy exigiria também configuração dentro do contêiner se
adicionado ao enxame rio acima. Não vejo valor, além de um limpador e talvez melhor
meta documentada em sua solicitação

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

Essas são soluções complexas - o protocolo de proxy apenas adiciona cabeçalho adicional
informações e é um padrão muito conhecido - haproxy, nginx, AWS elb,
etc todos seguem. https://www.haproxy.com/blog/haproxy/proxy-protocol/

A área de superfície da mudança seria limitada ao Enxame embutido
entrada (onde este suporte seria adicionado). E todos os serviços terão
isto
acessível.

Na sexta-feira, 4 de janeiro de 2019, 14h36, rubot < [email protected] escreveu:

Você pode até estender o projeto dockerflow e adicionar uma variante nginx para
começar
kubernetes-ingressproxy para swarn. Definitivamente, tudo isso embalado com
enxame
levantaria um contêiner de sistema adicional, pois você sabe que há vários
do
-los com kubernetes. Não é a força do enxame para recursos escassos
projetos para serem enxutos?

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

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. Do meu
perspectiva, mesmo a declaração de mudança para kubernetes não é um
adequado
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento. Vocês
qualquer
ter um LB externo ou usar algo como proxy de entrada nginx que
deve
executar como daemonset. Por favor, corrija-me se eu estiver errado, mas nós temos o
mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguém
poderia
verificar e empacotar minha solução de fluxo tcp proposta descrita acima para obter
algo como o comportamento do proxy nginx. Basta aceitar, esse enxame precisa
ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é apenas
uma
solução alternativa, mas não a solução. Como @sandys <
https://github.com/sandys>
disse que a solução alternativa tem poucas ressalvas, não devemos considerar
isto
edição
como corrigido.

Não tenho certeza se há alguma melhoria, uma vez que a solução alternativa
estive
descoberto. Eu mudei para o Kubernetes por um longo tempo e
ainda
ser
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ,
ou
mudo
o segmento
<

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

>

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ou
mudo
o segmento
<

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

.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 ou
mudo
o segmento
<
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451424992 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK
.

Como eu disse, o kubernetes nginx ingress também precisa da vinculação do modo de host, chamada
daemonset. LB externo se conecta a nodeports, que também requerem modo de host
em serviço ou configure manualmente o protocolo de proxy em serviço. Kubernetes
lida com os mesmos problemas, ainda.
Uma possível solicitação de recurso do meu ponto de vista para o enxame seria
tornar o provedor de rede conectável. Isso tornaria possível usar
outras técnicas além de lvs / iptables

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

A solução acima requer a vinculação do modo de host. Esse é o grande problema. Isto
elimina a possibilidade de usar o programador docker para alocar contêineres
para hosts diferentes - não faço mais parte da rede mesh.

Na sexta-feira, 4 de janeiro de 2019, 17:28, rubot < [email protected] escreveu:

Como eu disse, verifique a solução de fluxo tcp acima, que já utiliza proxy
protocolo.
Adicionar protocolo de proxy exigiria também configuração dentro do contêiner
E se
adicionado ao enxame rio acima. Não vejo valor, além de um limpador e talvez
Melhor
meta documentada em sua solicitação

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan.
2019,
11h37:

Essas são soluções complexas - o protocolo de proxy apenas adiciona
cabeçalho
informações e é um padrão muito conhecido - haproxy, nginx, AWS
cotovelo,
etc todos seguem.
https://www.haproxy.com/blog/haproxy/proxy-protocol/

A área de superfície da mudança seria limitada ao Enxame embutido
entrada (onde este suporte seria adicionado). E todos os serviços terão
isto
acessível.

Na sexta-feira, 4 de janeiro de 2019, 14h36, rubot < [email protected] escreveu:

Você pode até estender o projeto dockerflow e adicionar uma variante nginx para
começar
kubernetes-ingressproxy para swarn. Definitivamente, tudo isso embalado com
enxame
levantaria um contêiner de sistema adicional, pois você sabe que há vários
do
-los com kubernetes. Não é a força do enxame para magro
recurso
projetos para serem enxutos?

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

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. A partir de
minha
perspectiva, mesmo a declaração de mudança para kubernetes não é um
adequado
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento.
Vocês
qualquer
ter um LB externo ou usar algo como proxy de entrada nginx
que
deve
executar como daemonset. Por favor, corrija-me se eu estiver errado, mas nós temos o
mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguém
poderia
verificar e embalar minha solução de fluxo tcp proposta descrita acima para
pegue
algo como o comportamento do proxy nginx. Apenas aceite, esse enxame precisa
para
ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é

uma
solução alternativa, mas não a solução. Como @sandys <
https://github.com/sandys>
disse que a solução alternativa tem poucas ressalvas, não devemos considerar
isto
edição
como corrigido.

Não tenho certeza se há alguma melhoria, uma vez que a solução alternativa
estive
descoberto. Eu mudei para o Kubernetes por um longo tempo e
ainda
ser
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
< https://github.com/moby/moby/issues/25526#issuecomment -451382365
,
ou
mudo
o segmento
<

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

>

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ,
ou
mudo
o segmento
<

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

>

.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 ou
mudo
o segmento
<

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

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451424992 ou
mudo
o segmento
<
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451426276 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK
.

E só para esclarecer, a solução acima tem tcp stream na frente do serviço
proxy. Portanto, sua solicitação definitivamente não é um bug, mas uma solicitação de recurso. E
este recurso só poderia ser implementado em enxame, se o modo de rede fosse
mudar, pois o principal problema continua em perder ip no nível Nat / host

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

Como eu disse, o kubernetes nginx ingress também precisa da vinculação do modo de host, chamada
daemonset. LB externo se conecta a nodeports, que também requerem modo de host
em serviço ou configure manualmente o protocolo de proxy em serviço. Kubernetes
lida com os mesmos problemas, ainda.
Uma possível solicitação de recurso do meu ponto de vista para o enxame seria
tornar o provedor de rede conectável. Isso tornaria possível usar
outras técnicas além de lvs / iptables

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

A solução acima requer a vinculação do modo de host. Esse é o grande problema. Isto
elimina a possibilidade de usar o programador docker para alocar
containers
para hosts diferentes - não faço mais parte da rede mesh.

Na sexta-feira, 4 de janeiro de 2019, 17:28, rubot < [email protected] escreveu:

Como eu disse, verifique a solução de fluxo tcp acima, que já utiliza proxy
protocolo.
Adicionar protocolo de proxy exigiria também configuração dentro do contêiner
E se
adicionado ao enxame rio acima. Não vejo valor, além de um limpador e talvez
Melhor
meta documentada em sua solicitação

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan.
2019,
11h37:

Essas são soluções complexas - o protocolo de proxy apenas adiciona
cabeçalho
informações e é um padrão muito conhecido - haproxy, nginx, AWS
cotovelo,
etc todos seguem.
https://www.haproxy.com/blog/haproxy/proxy-protocol/

A área de superfície da mudança seria limitada ao Enxame embutido
entrada (onde este suporte seria adicionado). E todos os serviços vão
tenho
isto
acessível.

Na sexta-feira, 4 de janeiro de 2019, 14h36, rubot < [email protected] escreveu:

Você pode até estender o projeto dockerflow e adicionar uma variante nginx para
começar
kubernetes-ingressproxy para swarn. Definitivamente, tudo isso embalado com
enxame
levantaria contêiner de sistema adicional, pois você sabe que há um
Monte
do
-los com kubernetes. Não é a força do enxame para magro
recurso
projetos para serem enxutos?

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

Ainda estou um pouco surpreso, porque as pessoas pensam que isso é um bug. A partir de
minha
perspectiva, mesmo a declaração de mudança para kubernetes não é um
adequado
responder. Como vejo, o kubernetes tem exatamente o mesmo problema / comportamento.
Vocês
qualquer
ter um LB externo ou usar algo como proxy de entrada nginx
que
deve
executar como daemonset. Por favor, corrija-me se eu estiver errado, mas nós temos o
mesmo
situação exata aqui, mas nenhuma autossolução preparada aqui. Alguém
poderia
verificar e embalar minha solução de fluxo tcp proposta descrita acima para
pegue
algo como o comportamento do proxy nginx. Apenas aceite, aquele enxame
precisa de
ser
personalizado por você

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

@BretFisher https://github.com/BretFisher o modo: host é

uma
solução alternativa, mas não a solução. Como @sandys <
https://github.com/sandys>
disse que a solução alternativa tem poucas ressalvas, não devemos considerar
isto
edição
como corrigido.

Não tenho certeza se há alguma melhoria, uma vez que a solução alternativa
estive
descoberto. Eu mudei para o Kubernetes por um longo tempo e
ainda
ser
surpreso que a questão ainda está em aberto há mais de dois anos.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
<
https://github.com/moby/moby/issues/25526#issuecomment-451382365>,
ou
mudo
o segmento
<

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

>

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ,
ou
mudo
o segmento
<

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

>

.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451409453 ,
ou
mudo
o segmento
<

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

.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451424992 ou
mudo
o segmento
<
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-451426276 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK
.

  1. depois de um longo segmento, eu estava tentando documentar o conjunto de recursos atual com um exemplo completo.
  2. Não vejo sua necessidade específica na solicitação do OP. @PanJ pediu para ver os IPs do cliente

Quer você chame isso de bug ou de solicitação de recurso, a malha de entrada sem o nat de origem é (na minha opinião) essencial. Existem muitos aplicativos que quebram quando não conseguem ver o verdadeiro IP de origem. Claro, no caso de servidores da web, você pode reverter o proxy usando um nó de host e adicionar cabeçalhos de IP do cliente. No entanto, isso adiciona sobrecarga e provavelmente não é uma opção para aplicativos não baseados na web. Com um aplicativo que realmente precisa que o IP de origem real no pacote esteja correto, a única opção é não usar a malha de ingresso. Isso elimina grande parte do benefício de usar o enxame em primeiro lugar.

Informe-nos quando esse problema for corrigido ou não?!
devemos usar kuberneties em vez disso?

Corri o mesmo problema ... não encontrei uma solução no momento.

Quando alguém encontrar uma solução para este comportamento, comunique aqui.

Obrigado!

Eu tenho o mesmo problema. Eu tenho um servidor apache httpd e quero registrar todos os acessos para extrair estatísticas mais tarde sobre de quais países estamos recebendo solicitações.

Eu me deparei com esse problema enquanto tentava descobrir por que php: apache não estava registrando o campo de cabeçalho do host corretamente. Estou chocado e desapontado por isso ainda não estar funcionando depois de todos esses anos. Como devemos usar o modo Swarm para hospedagem na web quando o campo host continua registrando o IP do proxy do userland? Não consegui encontrar uma maneira de contornar isso com o Modo Swarm. Suponho que poderia usar Classic Swarm (baseado em contêiner) e algo como Consul, mas sinto que está retrocedendo.

Encontrei uma solução aceitável para o meu cenário:

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

Isso fará com que o apache escute no computador host em vez de atrás da rede overlay (lendo o endereço IP remoto apropriado), enquanto ainda envia solicitações para outros serviços por meio das opções networks e atinge "alta disponibilidade" por tê-lo correndo em todos os lugares

@rafaelsierra - aqui está o problema que eu tenho com isso (e me corrija se eu estiver errado), mas essa configuração permite apenas que um contêiner Apache / PHP seja executado e vinculado à porta 80 no nó do host. Preciso executar muitos e muitos contêineres Apache com um contêiner Nginx vinculado à porta 80/443 e, em seguida, hospedá-los em vhost.

@SysEngDan sim, é verdade que você só pode ter um único contêiner vinculado às portas 80/443, mas no meu caso isso não é um problema porque o contêiner que se liga a esta porta é responsável apenas por enviar por proxy todas as solicitações para outros contêineres que estão sendo executados por trás da rede de sobreposição.

Você provavelmente pode usar a mesma solução tendo um único contêiner nginx / apache recebendo todas as solicitações e fazendo proxy para o contêiner adequado com base no vhost, e esses contêineres não precisam se vincular ao host

@rafaelsierra - Respeitosamente, não tenho certeza se você entende o problema documentado neste tíquete. Se eu configurar serviços como você mencionou no último parágrafo, o problema é que o IP do cliente não é passado para os contêineres que escutam apenas na rede de sobreposição. Se eu ligar diretamente para o host, não é um problema. Se dependermos do proxy da rede docker de externo (host) para interno (sobreposição), o contêiner Apache de destino não receberá o endereço IP do cliente original, mas sim o IP do proxy (da rede docker).

@SysEngDan Eu entendo o problema e, uma vez que não há solução nos últimos 2 anos (e eu honestamente não tenho certeza se isso é "corrigível"), eu tive que encontrar uma solução alternativa que se adequasse à minha necessidade (acesso restrito com base no endereço IP remoto).

Ter um único contêiner escutando na porta 80/443 no host e, em seguida, fazer proxy para outros contêineres (com cabeçalhos HTTP apropriados que não mencionei porque estão fora do escopo deste problema) resolveu meu problema e eu queria compartilhar esta solução para as pessoas que enfrentam um problema semelhante devido a redes sobrepostas não serem capazes de passar o endereço IP remoto

Oh, eu vejo o que você fez lá ... desculpe, eu perdi isso. Você corta a rede de sobreposição e, em vez disso, conecta seu contêiner externo diretamente à rede de serviço (aquela que é criada automaticamente quando você inicia um novo serviço sem especificar uma rede). Ok, acho que funciona. A sobrecarga adicional é a tarefa de adicionar a rede de serviço ao arquivo docker-compose. Eu me pergunto o que acontece quando o host-container é iniciado e um desses serviços não está disponível?

Nesse caso, você receberá um 502.

Não tenho um único docker-compose.yml, tenho várias pilhas com vários serviços que se comunicam entre si por meio de rede sobreposta e tenho o serviço público que está vinculado ao servidor host, mas ainda tenho acesso ao todas as outras redes sobrepostas para que ele possa fazer proxy de todas as solicitações.

A solução alternativa do modo de host já foi discutida várias vezes sobre esse problema. Embora possa ser OK para alguns cenários limitados (como certas configurações de tráfego da Web de proxy reverso), não é uma solução geral para esse problema. Por favor, leia as postagens anteriores em vez de refazer o hash das mesmas "soluções" novamente.

@darrellenns, há mais de 200 comentários aqui, acho que seria melhor bloquear e limpar este problema fornecendo a solução básica "apenas use o vínculo do host se aplicável a você" enquanto nenhuma solução oficial for fornecida, caso contrário, mais pessoas como eu perderão isso e continuar comentando as mesmas coisas indefinidamente

Então, eu acredito que esse bug afeta a habilidade dos traefiks de colocar ips na lista de permissões. Isso é correto?

De qualquer forma, para quem deseja executar o modo swarm, este é um exemplo do uso do modo host para publicar portas.

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 Eu não sei exatamente o que isso afeta, mas no modo host eu só posso executar uma réplica do serviço traefik, e não acho que seja só eu. Desta forma, eu tenho que confiar totalmente na estabilidade do traefik sem retransmitir o recurso de modo de enxame para serviços.

Além disso, como relatado pela primeira vez, não tem tanto a ver com necessidades especiais traefik, foi testado com um serviço http genérico que não recebe o ip original, o que significa que o modo docker swarm está quebrado (falta este importante recurso), e parece que ninguém se importa com isso.

E eu quero continuar comentando sobre essas coisas, porque eu espero que o ruído esteja incomodando alguém que prefira consertar :) (desculpe, ele se aplica a mim dos meus usuários)

no modo host, só consigo executar uma réplica do serviço traefik e não acho que seja só eu. Desta forma, eu tenho que confiar totalmente na estabilidade do traefik sem retransmitir o recurso de modo de enxame para serviços.

Você pode executar uma instância por host

no modo host, só consigo executar uma réplica do serviço traefik e não acho que seja só eu. Desta forma, eu tenho que confiar totalmente na estabilidade do traefik sem retransmitir o recurso de modo de enxame para serviços.

Você pode executar uma instância por host

sim, mas traefik é forçado a trabalhar no nó do gerenciador, porque precisa disso para funcionar corretamente. Então, um nó gerenciador, um host, uma instância

traefik pode trabalhar com nós de gerenciamento de várias maneiras, incluindo o uso de um
docker socket proxy, remote socket ou traefik enterprise. aqui está um
exemplo de arquivo de pilha para saber como fazer isso:
https://github.com/BretFisher/dogvscat/blob/master/stack-proxy-global.yml

Sábado, 16 de março de 2019 às 17:25 Daniele Cruciani [email protected]
escreveu:

no modo host, só posso executar uma réplica do serviço traefik, e não
acho que sou só eu. Desta forma, eu tenho que confiar totalmente na estabilidade do Traefik
sem retransmitir no recurso de modo de enxame para serviços.

Você pode executar uma instância por host

sim, mas traefik é forçado a trabalhar no nó gerenciador, porque precisa disso
para funcionar corretamente. Então, um nó gerenciador, um host, uma instância

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-473593956 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAwW31DHIwEJE1EqN3-8qj44WopocuQTks5vXWE_gaJpZM4Jf2WK
.

É interessante saber, mas veja, esse recurso está disponível no kubernetes, mas não no modo docker swarm, e você insiste que há opções para executar várias instâncias do traefik, mas em vários nós, se eu quiser executar várias instâncias em um único nó, não é possível, porque isso não é suportado.
Além disso, qualquer outro serviço, que não apenas faça pedidos de proxy, não tem permissão para mapear nenhuma porta, porque precisa de um tipo especial de configuração que precisa mapear todos os hosts para ele e, de qualquer forma, precisa de vários nós, pelo menos um por instância .

E assim por diante. Você pode rolar esta discussão para cima e encontrar outras informações sobre isso. Eu não acho que isso poderia ser reduzido a uma demonstração de quão bom você é em produzir uma solução alternativa, porque essa continua sendo uma solução alternativa difícil de manter e difícil de seguir. E todo o tempo gasto para manter uma solução alternativa de caso especial é melhor gasto para corrigir o problema.

Por outro lado, se esse tipo de recurso for um problema de segurança para o modelo de docker swarm, basta marcá-lo como wontfix e planejo mudar para o kubernetes; se for o caso, não acho que haja conflito entre os projetos, está apenas dizendo explicitamente que isso nunca aconteceria, e para que todos possam agir, se possível antes da escolha do modo docker swarm para qualquer tipo de coisa de enxame de nós

Existem muitos recursos no kubernetes que não estão no swarm e vice-versa. Todos nós tomamos decisões sobre qual orquestrador usar para uma solução específica com base em muitos fatores, incluindo recursos. Nenhuma ferramenta resolve todos os problemas / necessidades.

Sou apenas um membro da comunidade tentando ajudar. Se você não gosta das soluções atuais para esse problema, parece que você deve procurar outras maneiras de resolvê-lo, possivelmente com algo como kubernetes. Esse é um motivo razoável para escolher um orquestrador em vez de outro, se você acha que a maneira do kubernetes de resolvê-lo é mais do seu agrado.

Historicamente, os mantenedores do moby e do swarm não fecham questões como essa porque amanhã alguém da comunidade pode lançar um PR com uma solução para o problema. Além disso, acho que discutir as maneiras de contornar isso até então é um uso válido desse tópico de discussão. :)

Embora não seja um mantenedor de swarm, posso dizer que historicamente a equipe não divulga planos de recursos futuros além do que você pode ver atualmente recebendo commits nos repositórios.

Esqueci de dizer que é claro que seu comentário é bem-vindo (ou disse de forma obscura, desculpe). Mas gosto de reforçar o relatório @PanJ original:

Nesse ínterim, acho que tenho que fazer uma solução alternativa que é executar um contêiner de proxy fora do modo de enxame e encaminhá-lo para a porta publicada no modo de enxame (a terminação SSL deve ser feita neste contêiner também), o que quebra o propósito de enxame modo de autocura e orquestração.

Quero dizer que isso "quebra o propósito do modo enxame", é claro, apenas neste tópico específico, é suficiente para merecer mais atenção.

Estou tentando fazer minha equipe construir um PR que adiciona o protocolo de proxy para
a rede de entrada. Não somos programadores Golang, então achamos que é um pouco
complicado.

Mas espero fervorosamente que a equipe do Docker concorde que o melhor e o mais
solução compatível (em todo o ecossistema) é a camada no protocolo de proxy
suporte à rede de entrada.

A complexidade vem no fato de que a rede de entrada não só tem que
injetar seus próprios cabeçalhos, mas deve apoiar o fato de que pode haver
cabeçalhos de protocolo de proxy upstream já inseridos (por exemplo, Google LB ou
AWS ELB).

No domingo, 17 de março de 2019, 12h17 Daniele Cruciani, [email protected]
escreveu:

Esqueci de dizer que é claro que seu comentário é bem-vindo (ou disse isso em um
forma obscura, desculpe). Mas gosto de reforçar o @PanJ original
https://github.com/Relatório PanJ:

Nesse ínterim, acho que tenho que fazer uma solução alternativa que está executando um
contêiner proxy fora do modo swarm e deixe-o encaminhar para a porta publicada
no modo swarm (a terminação SSL deve ser feita neste contêiner também), que
quebra o propósito do modo enxame para autocura e orquestração.

Quero dizer, isso "quebra o propósito do modo enxame", é claro, apenas neste
tópico específico, é suficiente para merecer mais atenção.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-473621667 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUwNWJsGKlLejcNzS2pR0awBB4OVlks5vXeTugaJpZM4Jf2WK
.

https://stackoverflow.com/questions/50585616/kubernetes-metallb-traefik-how-to-get-real-client-ip
Conforme solicitado para k8s onde está em camadas, completamente e configurável

Para qualquer um executando o nginx no digitalocean com docker swarm e tentando obter o $remote_addr real em vez de apenas 10.255.0.2 dentro de seus logs do nginx; você pode usar a solução de @coltenkrauter. O problema é que você só pode executar um contêiner nginx no host com esta solução, que deve estar ok para a maioria das pessoas.

Basta alterar seu arquivo docker-compose.yml :

INCORRETA

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

CORRETO

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

_edit: agora todos temos a garantia de obter a resposta certa_

Não usar o ingresso ( mode: host ) não é uma solução alternativa, quando o problema indica que o problema ocorre com a rede de ingresso.
Ninguém usaria apenas um único host como proxy reverso. Você quer vários hosts com um ip flutuante, e o swarm-mesh é obrigatório para realizar esta configuração.

Talvez não seja possível, mas pensei, modificar as regras do iptables para fazer MASQUERADE em algum estágio das cadeias de INGRESS seria uma solução alternativa para preservar o ip de origem real. Não existem alguns especialistas em iptables / netfilter por aí?

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, o swarm não pode simplesmente pegar o ip de origem original e criar um cabeçalho X-Forwarded-For ?

Ninguém usaria apenas um único host como proxy reverso. Você quer vários hosts com um ip flutuante, e o swarm-mesh é obrigatório para realizar esta configuração.

Cada nó no enxame pode executar uma instância do proxy reverso e rotear o tráfego para os serviços subjacentes em uma rede de sobreposição (mas apenas o proxy saberia sobre o endereço IP original).

Certifique-se de ler todo o tópico (vejo que o GitHub esconde alguns comentários úteis, então você terá que expandi-los: decepcionado :);

Como alternativa, o swarm não pode simplesmente pegar o ip de origem original e criar um cabeçalho X-Forwarded-For ?

Consulte https://github.com/moby/moby/issues/25526#issuecomment -367642600; X-Forwarded-For é o protocolo L7; A entrada do enxame é L4, usando IPVS com DNAT

@ port22 geralmente concordamos que uma solução alternativa não é uma solução, uma solução é torná-la em camadas, consulte a proposta de @sandys no comentário # 25526

Como alternativa, não podemos enxamear apenas pegar o ip de origem original e criar

um cabeçalho X-Forwarded-For?
Veja # 25526 (comentário)
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Forwarded-For é o protocolo L7; A entrada do enxame é L4, usando IPVS com DNAT

a solução certa aqui é o protocolo proxy injetado em L4. há alguns
discussões prós e contras relevantes no Envoy para o mesmo caso de uso
https://github.com/envoyproxy/envoy/issues/4128 e
https://github.com/envoyproxy/envoy/issues/1031

Na quarta-feira, 10 de abril de 2019 à 1h40 Sebastiaan van Stijn <
notificaçõ[email protected]> escreveu:

Ninguém usaria apenas um único host como proxy reverso. Você quer múltiplos
hosts com ip flutuante, e o swarm-mesh é obrigatório para conseguir isso
configurar.

Cada nó do enxame pode executar uma instância do proxy reverso e rotear
tráfego para os serviços subjacentes em uma rede de sobreposição (mas apenas o
proxy saberia sobre o endereço IP original).

Certifique-se de ler todo o tópico (vejo que o GitHub esconde alguns
comentários, então você terá que expandi-los 😞);

Como alternativa, não podemos enxamear apenas pegar o ip de origem original e criar
um cabeçalho X-Forwarded-For?

Veja # 25526 (comentário)
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Forwarded-For é o protocolo L7; A entrada do enxame é L4, usando IPVS com DNAT

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-481415217 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsU5KdnWQ21hJx_xzc-QROJiWbAlulks5vfPOigaJpZM4Jf2WK
.

Cada nó do enxame pode executar uma instância do proxy reverso

Isso elimina o recurso do balanceador de carga swarm, que é o problema.
E meu problema para ser específico é que o traefik não é ágil em cluster. Ele deve ser executado de forma autônoma, a menos que você esteja usando o consul como back-end de configuração, o que limita o máximo de certificados a cerca de 100, o que não é aplicável para mim. Claro, você pode afirmar que este não é um problema de enxame, mas um problema de traefik. Curiosidade: traefik afirma que este é um problema de cônsul. cônsul afirma: traefik errou.

@ port22 geralmente concordamos que uma solução alternativa não é uma solução

Meu ponto é que NÃO usar o ingresso não é uma solução alternativa quando você PRECISA do ingresso. Uma solução alternativa seria algo que tornaria possível ainda usar o balanceador de carga swarm enquanto persiste o ip de origem, mesmo que isso exija algum hacking.

usando IPVS com DNAT

portanto, eu estava pensando que isso poderia ser feito com MASQUERADE dentro da regra / cadeia DNAT. ?

@ port22 Entendi , mas o docker gerencia suas redes sozinho, tentei fazê-lo funcionar com o shorewall, mas a única maneira é criar exceções para as regras / correntes do docker, e não tive sucesso com o modo docker swarm (mas está ok para docker no modo swarm, desde que eu desativei todos os serviços, exceto aqueles que correm para o swarm)
Talvez deva haver opções como as da rede de ponte https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
então, para simplificar a configuração, mas ainda assim o principal problema é a falta de suporte na rede de sobreposição. Portanto, as opções não estão lá, porque seriam ignoradas e o dockerd reescreverá as regras se modificadas externamente.

Apresentei um pedido de recurso para suporte de protocolo proxy para resolver o
problema neste bug.

Apenas no caso de alguém querer adicionar seus comentários.

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

Na quarta-feira, 10 de abril de 2019, 21:37 Daniele Cruciani, [email protected]
escreveu:

@ port22 https://github.com/port22 Entendi , mas docker manage
suas redes por si só, tentei fazê-lo funcionar com shorewall, mas o
única maneira é criar exceções para regras / correntes do docker, e eu não tinha
sucesso com o modo docker swarm (mas está ok para docker no modo swarm, como
até agora eu desabilito todos os serviços, exceto aqueles que correm para o enxame)
Talvez deva haver opções como existem para a rede de ponte
https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
para simplificar a configuração, mas ainda assim o principal problema é o
falta de suporte na rede de sobreposição. Portanto, as opções não estão lá, porque
aqueles seriam ignorados e o dockerd reescreverá as regras se modificadas a partir de
lado de fora.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526#issuecomment-481754635 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAEsUxsVQ7m9uiYbHhNKMMtkhTZV6iTNks5vfgwygaJpZM4Jf2WK
.

Após 3 anos, nenhuma correção?

Eu também estou tendo o mesmo problema, mas com haproxy. Embora não haja problema em ter servidores proxy no modo host e HA usando keepalived, a única parte que falta seria o balanceamento de carga, que acho que não é um grande problema para um proxy da web simples. A menos que scripts complicados sejam incluídos ou proxy e back-end não estejam na mesma máquina física e o tráfego de rede seja muito alto para um NIC e ...

Portanto, não é realmente possível ver o endereço IP de origem de uma solicitação de fora de um Docker Swarm em vez do endereço privado da rede de sobreposição interna? Ainda?

@thaJeztah Pode alguém da equipe da Docker Inc nos atualizar sobre o status desse problema. Ainda está sendo considerado e / ou trabalhado? Qualquer hora prevista de chegada? Ou isso foi completamente ignorado desde a integração do Docker com o Kubernetes? Foi relatado há quase 3 anos: /

@thaJeztah https://github.com/thaJeztah Pode alguém no Docker Inc
equipe nos atualize sobre o status deste problema. Ainda está sendo considerado
e / ou trabalhado? Qualquer hora prevista de chegada? Ou isso é completamente ignorado desde Docker
integração com Kubernetes? Foi relatado há quase 3 anos: /

Seria muito bom obter esta declaração ("não consertará") para que eu possa totalmente
justificar uma migração para kubernetes. Que vergonha.

Obrigado.

>

há uma proposta de solicitação de melhoria que deve corrigir isso - https://github.com/moby/moby/issues/39465

por favor, adicione seus pensamentos e comentários lá

Já venho comentando sobre esse assunto :-)

Este tem sido um bloqueador para mim há algum tempo. Preciso passar pelos endereços IP e depois de muita pesquisa (uau quase 3 anos pesquisando junto com os outros neste tópico ...) ainda não encontrei nenhuma solução que seja viável com o swarm.

Não consegui usar o swarm na produção devido a esse problema e estou aguardando uma resposta oficial se isso pode ser adicionado ou não. Se isso não for adicionado, as soluções propostas alternativas são bem-vindas.

Estamos enfrentando o mesmo problema usando o traefik por trás do haproxy. Fiquei surpreso ao ver que havia 254 comentários desde 2016.

@Betriebsrat Por que não permitir que o traefik lide com as solicitações imediatamente? A haproxy é realmente necessária ou apenas um hábito? Se você expor traefik no modo host, você verá os endereços IP do cliente e então está tudo bem :)

Acredito que essa "solução" tenha sido mencionada várias vezes, mas as pessoas continuam perdendo isso.

Também sei que às vezes não é uma opção, mas acredito que na maioria das vezes isso deveria ser possível.

@ajardan essa solução que tentei e não é viável para mim, pois tenho mais de um único host para responder no frontend. Idealmente, quero que todo o enxame seja capaz de encaminhar as solicitações. Concordo que, para operações de pequena escala, simplesmente mudar um serviço para o modo host e usá-lo como um servidor de ingestão pode funcionar bem.

Colocar algo como traefik no modo host nega os benefícios que estamos tentando tirar proveito do uso do swarm, embora na maioria dos casos :(

@pattonwebz O modo de host pode ser habilitado para um serviço que executa vários contêineres em vários hosts, você pode até fazer isso com mode = global. Em seguida, o traefik será executado em todos os nós do swarm e aceitará conexões com portas especificadas e, em seguida, encaminhará as solicitações internamente para os serviços que precisam ver essas conexões.

Usei essa configuração com um serviço no modo global, mas limitado a nós de gerenciamento, e estava funcionando perfeitamente bem para dezenas de milhares de solicitações / s

Eu ficaria feliz em explicar se mais detalhes forem necessários.

@pattonwebz @ajardan Estou usando um serviço haproxy configurável para todos esses casos. O haproxy usa apenas 2 MB de RAM no meu caso. Eu acho que isso é insignificante.

@pattonwebz Além da solução de @ajardan acima, você pode executar https://hub.docker.com/r/decentralize/swarm-tcp-proxy no modo global com rede de host para adicionar suporte ao protocolo PROXY para o tráfego de entrada, e, em seguida, encaminhe-o para o Traefik configurado para decodificar os cabeçalhos do protocolo proxy.

Deve ser apenas um sinalizador como parte do Docker Swarm, não todos esses
soluções complicadas IMHO.

Nós apenas usamos o haproxy para gerenciar certificados e descarregar SSL.
As pessoas continuam perdendo que a solução "rodar no modo host" não é uma solução.
Eles querem que ele funcione com a rede de entrada para tirar proveito do balanceamento de carga do docker.
O tópico inteiro é basicamente um 'use hostmode' -> 'não é possível porque o círculo de "razões"' está acontecendo há 3 anos.

Vou olhar para swarm-tcp-proxy como uma alternativa viável aqui novamente, porém, olhando para coisas semelhantes no passado, algo sempre acabou sendo um copo para mim com tais idéias.

Em um mundo perfeito, meu enxame existente (e funcionando bem, com exceção de nenhuma capacidade de recuperar o IP do cliente real) estaria apenas trabalhando e passando pelos dados de IP sem a necessidade de camadas de serviço adicionais ou mais proxies sobre proxies.

As pessoas continuam perdendo que a solução "rodar no modo host" não é uma solução.

Não é uma solução por si só , mas pode ser usada (e está sendo usada) com muito sucesso como uma solução alternativa. Você ainda pode usar o balanceador de carga nativo do Docker - tudo o que você está fazendo é adicionar uma camada à pilha de rede do host antes de atingir a malha de serviço do Docker.

@Betriebsrat traefik pode fazer certificados e SSL muito bem, então ainda não tenho certeza de por que isso é necessário.

Também como mencionado por @matthanley antes, o balanceamento de carga do docker não desaparece. Se você não gosta de como o traefik equilibra suas solicitações no backend, pode instruí-lo a usar o LB do swarm, e ele apenas enviará as solicitações para o serviço VIP, onde o swarm cuidará disso mais tarde.

Isso é configurável até mesmo por serviço, então você é bastante flexível.

Você pode tentar definir outro servidor Nginx fora do cluster docker swarm e encaminhar a solicitação para o serviço swarm. nesta conf Niginx, basta adicionar os cabeçalhos anteriores. por exemplo.
localização / {
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 não há solução para obter o IP do cliente real no modo docker swarm.

Vimos o mesmo problema e o contornamos implementando:
https://github.com/moby/moby/issues/25526#issuecomment -475083415

É uma solução não ideal, pois não podemos executar vários contêineres de entrada em um único nó (acho que eles são globais agora)

A dificuldade é que o Docker lida com TCP / UDP, embora este seja um problema de protocolo HTTP. No mínimo, eu gostaria que o docker "falsificasse" o IP de origem como o host remoto em vez de fornecer seu próprio IP interno do Swarm Mesh ... mas isso provavelmente quebraria as coisas, já que o tráfego de retorno estaria indo para o lugar errado.

A maneira mais fácil seria adicionar o cabeçalho do IP original para cada solicitação http.

Correto. Apenas para ser específico - como um cabeçalho de protocolo proxy que funciona em l4
e l7 e é aceito pela maioria dos softwares de aplicativos conhecidos (bem como pelo
grandes provedores de nuvem).

Eu registrei um bug separado para isso, que está vinculado a alguns comentários
acima de. Adicione a esse bug se você estiver interessado

Na quinta-feira, 5 de setembro de 2019, 18:56 Vladimir, [email protected] escreveu:

A maneira mais fácil seria adicionar o cabeçalho do IP original para cada
solicitação de http.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/25526?email_source=notifications&email_token=AAASYU7APUNJPLZ6AJ6XXMDQIECIJA5CNFSM4CL7MWFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD57COLA#issuecomment-528361260 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AAASYU4VZGKUFLL5STZ44GDQIECIJANCNFSM4CL7MWFA
.

É 2019 e isso ainda é um problema ?? Faz com que a lista de permissões de ip no traefik seja uma dor. Eu não deveria precisar de portas de host em cada nó.

@kaysond nossa posição é desistir do Swarm. Estamos mudando para AWS e ECS. Só lamento não poder postar algo mais construtivo, mas, no final das contas, precisamos de algo que funcione; este não é o único grande bug do Swarm (ou falta de recurso) que nos afeta e outros que não receberam nenhuma correção / feedback aparente nos últimos anos. Mais decepcionante, mas ali.

@jmkgreen estamos na mesma posição e passamos os últimos 6+ meses mudando do docker swarm para outras coisas por causa deste problema ainda em curso. Já dediquei dezenas de horas a mim mesmo e centenas de horas de membros da equipe a isso, sem nunca encontrar uma solução alternativa aceitável. A vinculação a todas as portas do host anula totalmente o propósito de nossos LBs flutuantes :(

Qual é o seu problema com a solução alternativa? Você declara seu serviço no modo host + global e configura seu LB para atingir todos os nós, ele funciona. Como o proxy é leve (eu uso o nginx porque faço o descarregamento de https e outras coisas), o fato de ser implantado em todos os servidores não é um problema, ele usa menos de 1% de um recurso do servidor. Posso ajudar se você encontrar algum erro durante o processo ([email protected]).

Qual é o seu problema com a solução alternativa? Você declara seu serviço no modo host + global e configura seu LB para atingir todos os nós, ele funciona.

@RemiBou Quando o próprio proxy precisa ser atualizado / reiniciado, o balanceador de carga externo não detecta imediatamente a interrupção e continua enviando solicitações para o (s) nó (s) onde o proxy ainda está reiniciando. Portanto, há uma interrupção de aproximadamente 30 segundos, dependendo da configuração do LB externo.

Também não há como no Swarm colocar um gancho no processo de atualização do serviço para chamar o balanceador de carga externo e tirar um nó de serviço durante a atualização. Você também não pode acionar um script para ser executado dentro do contêiner antes de ser atualizado (por exemplo, para remover um sinalizador " i_am_healthy " e permitir que o LB externo descubra que está fora de serviço por meio de pesquisa).

Qual é o seu problema com a solução alternativa?

Meu problema é que, com essa solução alternativa, é impossível para mim executar vários serviços do mesmo (ou vários serviços que desejam as mesmas portas) no host. Essa é uma necessidade para os projetos nos quais trabalho.

Na verdade, mas você não pode implantar um serviço de proxy que faria apenas isso e, em seguida, quando o ip estiver dentro do swarm. Você pode encaminhá-lo como cabeçalho http para seus outros serviços?

Na verdade, mas você não pode implantar um serviço de proxy que faria apenas isso e, em seguida, quando o ip estiver dentro do swarm. Você pode encaminhá-lo como cabeçalho http para seus outros serviços?

Sim ... e desde que esse serviço de proxy fino nunca precise ser reconfigurado ou atualizado, é possível atualizar os componentes por trás dele usando o Swarm LB para evitar o tempo de inatividade.

Alguém apontou para https://hub.docker.com/r/decentralize/swarm-tcp-proxy que usa haproxy para fazer isso.

Mas é meio chato. E se você tiver que atualizar o proxy, você ainda tem tempo de inatividade.

@ ms1111 A imagem docker do Nginx é inicializada em alguns segundos, e se este serviço gerenciar apenas esta parte, você não precisará atualizá-lo com frequência. IMHO a desvantagem não é muito importante, mas pode ser diferente no seu caso

Qual é o seu problema com a solução alternativa?

Em nosso caso, é a combinação dessa solução alternativa com a incapacidade de vincular uma porta exposta ao host a um endereço IP específico. Em vez disso, todos os serviços internos que precisam do IP do visitante real e oferecem suporte ao protocolo PROXY, têm sua porta exposta em 0.0.0.0 no host, que é menos do que ideal.

Outro é o impacto não desprezível de desempenho quando você tem centenas de novas conexões por segundo - todas as portas expostas são na verdade regras DNAT em iptables que requerem conntrack e têm outros problemas (atinge k8s também, mas o Swarm tem isso nível adicional de NATs que o tornam pior).

Para Docker,

Acordar! Há um problema óbvio devido ao número de pessoas envolvidas nesta questão (há outras com a mesma causa). Tudo o que recebemos são pessoas que repetem continuamente que existe uma solução alternativa, embora tenha sido explicado algumas vezes por que essa solução alternativa não é uma solução. A própria palavra "solução alternativa" indica que é um problema temporário que será resolvido mais tarde. Já se passaram mais de 3 anos desde que o problema foi criado e durante todo esse tempo a resposta foi "há uma solução alternativa".

Para todos os usuários do Swarm,

Vamos ser realistas. A triste verdade é que ninguém, incluindo Docker, realmente se preocupa com o Swarm. Todos mudaram para k8s e não há investimentos "reais" no Swarm. O projeto está em suporte de vida esperando para morrer, então não espere que esse problema seja corrigido. Seja inteligente e mude para K8s.

Este problema parece ter sido ignorado por muito tempo. Parece que nunca será implementado. Basta ir direto ao ponto e usar k8s.

@leojonathanoh você pode explicar como exatamente o k8s resolve esse problema em particular :)?

Simples: protocolo proxy

@ajatkj Como disse. Ou, se isso não for possível, um balanceador de carga externo e externalTrafficPolicy: Local no recurso Service . É tudo o que direi aqui. E estou cancelando a inscrição no tópico.

Por que as pessoas esperam que outras pessoas façam o trabalho por elas?

Adoraria ser o herói e cuidar disso, mas a realidade é que estou trabalhando em muitas outras coisas e isso não tem efeito no meu dia a dia. Isso afeta seu dia a dia? Adoraríamos receber ajuda para resolver isso!

Eu também olhei isso várias vezes e realmente não parece que há uma maneira de fazer isso funcionar com IPVS NAT, que é o que o roteamento de enxame mágico está usando.

Eu concordo que o k8s é muito mais flexível aqui. Se for mais adequado às suas necessidades, use-o.
Reclamar que não foi corrigido e depois ameaçar mudar para o k8s realmente não tem lugar em nosso rastreador de problemas e geralmente é inútil.

As pessoas ajudam com o conhecimento que possuem. Nem todos têm o conjunto de habilidades para alterar o código por conta própria, então eles criam problemas como este para ajudar a alcançar um consenso sobre a mudança necessária.

Ninguém aqui está argumentando que você precisa fazer as mudanças especificamente, mas nem mesmo nas questões abertas por @sandys sobre o protocolo de proxy, a equipe principal concordou com as mudanças. Então, como alguém pode trabalhar nisso se não sabe se a mudança será aceita?

A melhor maneira é apresentar uma proposta, ou seja, como você espera que a arquitetura fique depois que o trabalho for concluído. O que isso traz? O que perdemos?

A melhor maneira é apresentar uma proposta, ou seja, como você espera que a arquitetura fique depois que o trabalho for concluído. O que isso traz? O que perdemos?

Já feito aqui: # 39465

tente a rede no modo host

Por favor, leia todo o tópico antes de comentar

"Use o protocolo de proxy", embora de fato interessante, não estabelece o que
mudanças precisam ser feitas na base de código.

Talvez seja uma pergunta ingênua, mas por que é necessário reescrever o ip de origem para começar? O tráfego não seria retornado por meio do gateway padrão da interface de qualquer maneira? Mesmo que tenha vindo por meio do balanceador de carga swarm, o gateway poderia simplesmente retorná-lo por meio do balanceador de carga que já sabe de onde o tráfego veio ...

Talvez seja uma pergunta ingênua, mas por que é necessário reescrever o ip de origem para começar? O tráfego não seria retornado por meio do gateway padrão da interface de qualquer maneira? Mesmo que tenha vindo por meio do balanceador de carga swarm, o gateway poderia simplesmente retorná-lo por meio do balanceador de carga que já sabe de onde o tráfego veio ...

É necessário saber de qual IP está vindo a solicitação. Talvez um usuário específico queira limitar o ip, e você não pode fazer isso fora do serviço em execução, ou seja, o traefik não sabe o conteúdo da solicitação que pode especificar qual usuário está fazendo isso, por isso não pode excluir algum usuário e aceita outro baseado apenas em ip (porque a política neste exemplo é ip + request-content => allow / disallow).

Ou, mais frequentemente, apenas para conexão de registro. Preciso cobrar o cliente pelo uso do meu serviço e preciso fornecer em forma de tabela: hora da solicitação, quantidade de recurso, IP de origem da solicitação. Quase todos os serviços faturados fornecem esse tipo de relatório.

Eu acho que você entendeu mal minha pergunta. Eu entendo porque os serviços gostariam de ver o verdadeiro ip de origem. Quero saber por que o Docker o altera antes de chegar a um contêiner

Em 1º de novembro de 2019, 01h47, às 01h47, Daniele Cruciani [email protected] escreveu:

Talvez seja uma pergunta ingênua, mas por que é necessário reescrever
o ip de origem para começar? O tráfego não seria retornado por meio do
gateway padrão da interface de qualquer maneira? Mesmo que tenha vindo através da carga de enxame
balanceador, o gateway poderia simplesmente retorná-lo por meio do balanceador de carga que
já sabe de onde veio o tráfego ...

É necessário saber de qual IP está vindo a solicitação. Talvez um
usuário específico deseja limitar o ip, e você não pode fazer isso fora do
serviço em execução, ou seja, traefik não sabe o conteúdo do pedido
que pode especificar qual usuário está fazendo isso, portanto, não pode excluir alguns
usuário e aceita outro baseado apenas em ip (porque a política neste
exemplo é ip + request-content => allow / disallow).

Ou, mais frequentemente, apenas para conexão de registro. Eu preciso faturar o cliente
para o meu uso de serviço, e preciso fornecer em forma tabular: tempo de
solicitação, quantidade de recurso, IP de origem da solicitação. Quase todos os serviços
faturados fornecem este tipo de relatório.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/moby/moby/issues/25526#issuecomment -548711563

@kaysond Não é um bom lugar para perguntar.

Você está essencialmente fazendo duas perguntas,

  1. Como o IPVS funciona tecnicamente, e
  2. Por que a libnetwork escolheu o IPVS para começar

Ambos são difíceis de responder de maneiras diferentes.

Eu me pergunto onde é o melhor lugar para fazer essas perguntas, porque agora estou muito intrigado em ler a história dessas escolhas e como tudo funciona para que possa obter um pouco mais de contexto aqui.

@kaysond Não é um bom lugar para perguntar.

Você está essencialmente fazendo duas perguntas,

  1. Como o IPVS funciona tecnicamente, e
  2. Por que a libnetwork escolheu o IPVS para começar

Ambos são difíceis de responder de maneiras diferentes.

Qualquer atualização?

Eu tenho seguido este tópico por um tempo porque me deparei com o mesmo problema, mas depois de girar alguns contêineres whoami em um enxame atrás do traefik , vi que estava funcionando. A questão é que estávamos por trás do cloudflare e tínhamos que encaminhar os cabeçalhos do CF. (sim, usamos ipvs e nossos serviços são replicados em swarm).

Tentei novamente com:

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

e a seguinte composição do docker:

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"

a saída do whoami foi:

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

Então não. ainda não funciona

Por curiosidade ... algum desenvolvedor pode me indicar o código que gerencia a rede swarm?

Tentei novamente com:

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

e a seguinte composição do docker:

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"

a saída do whoami foi:

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

Então não. ainda não funciona

você pode usar o traefik pelo modo host para obter ip real

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

ainda está aberto?
08-05-2020

ainda está aberto?
08-05-2020

Sim, ainda aberto. Há questões arquitetônicas observadas no tópico que destacam por que isso não pode ser resolvido tão facilmente quanto parece que deveria ser na superfície. Neste ponto, é provável que esses problemas não possam ser superados.

Se você precisar obter IP de usuário real, algumas alternativas podem ser adequadas neste tópico. O modo HOST para serviços parece a abordagem mais simples, mas não é adequado para alguns que precisam de escalabilidade em nós individuais.

Tivemos sucesso ao usar o protocolo PROXY com DigitalOcean LB -> Traefik -> container Apache. O contêiner Apache foi capaz de registrar os IPs reais dos usuários que acessaram o serviço. Teoricamente, deve funcionar desde que todas as camadas de proxy suportem o protocolo PROXY.

https://docs.traefik.io/v1.7/configuration/entrypoints/#proxyprotocol

O serviço Traefik está em uma rede Docker chamada 'ingress', o serviço Apache tem sua própria rede de pilha, mas também faz parte da rede 'ingress' como externa.

https://autoize.com/logging-client-ip-addresses-behind-a-proxy-with-docker/

2020 e ainda não corrigido, que chatice. parece ser um recurso muito importante

Isso é muito necessário. Colocar algum modo de host é apenas um patch, às vezes é necessário executar o NGINX atrás da rede (dependendo do uso e da configuração). Por favor, corrija isso.

Acho que uma solução alternativa para isso e para que um docker swarm seja executado sem configurar o host é obter o IP no lado do cliente. ex. usando js para clientes da web e móveis e aceite apenas de fontes confiáveis. ex. js -> get ip, backend só aceita ips que incluem token de usuário ou etc. O ip pode ser definido no cabeçalho e criptografado por meio de https. no entanto, eu não sei sobre desempenho

@ Damidara16 é exatamente o que não queremos fazer. É muito inseguro fazer isso. Você pode ignorá-lo como quiser.

Para piorar, este ainda é um problema em aberto, infelizmente ... não parece que será corrigido em breve

Para piorar, este ainda é um problema em aberto, infelizmente ... não parece que será corrigido em breve

Acho que será fechado pelo bot em breve. Como o github lançou esse recurso, muitos bugs podem ser ignorados.

Para piorar, este ainda é um problema em aberto, infelizmente ... não parece que será corrigido em breve

Acho que será fechado pelo bot em breve. Como o github lançou esse recurso, muitos bugs podem ser ignorados.

Este é o melhor recurso para equipes inchadas de empresas obterem o controle da comunidade.

Há muito pouca chance de que isso seja consertado. AFAIK todos consideram que k8s venceram a "corrida" e enxame não é necessário, mas eu diria que ambos podem coexistir e ser usados ​​adequadamente dependendo das necessidades e habilidades da equipe que os usa. Enxame RIP :)

Eu uso um HAIP gerenciado, mas você poderia usar outra coisa na frente do enxame, um balanceador de carga nginx autônomo que aponta para os IPs do seu enxame.
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

Em seu enxame, o proxy reverso precisa disso:

server {
        listen 443 ssl proxy_protocol;
        location / {
        proxy_set_header   X-Real-IP $proxy_protocol_addr;  # this is the real IP address 

Se você estiver executando um swarm, precisará de um balanceador de carga para fazer o round-robin das solicitações para seu swarm (ou sticky, etc).

Até agora, essa decisão arquitetônica pode parecer uma "peça que faltava", no entanto, isso adiciona flexibilidade ao fornecer opções e remover a necessidade de desabilitar a funcionalidade embutida para substituí-la por algo mais adequado às necessidades do aplicativo.

Acredito ter encontrado uma solução alternativa para esse problema, com a limitação _current_ de que todas as réplicas do contêiner de serviço devem ser implantadas em um único nó, por exemplo com --constraint-add = 'node.hostname == mynode', ou com um conjunto de enxames, cada um consistindo de um único nó.

O problema

O problema subjacente é causado pela regra SNAT na tabela iptables nat no namespace ingress_sbox, que faz com que todas as solicitações de entrada sejam vistas pelos contêineres para ter o endereço IP do nó na rede de ingresso (por exemplo, 10.0.0.2, 10.0.0.3,. .., na configuração de rede de entrada padrão), por exemplo:

iptables -t nat -A POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j SNAT --to-source 10.0.0.2

No entanto, remover esta regra SNAT significa que, embora os contêineres ainda recebam pacotes de entrada - agora originados do IP de origem original - os pacotes de saída enviados de volta para o IP de origem original são enviados por meio do gateway padrão do contêiner, que não está na mesma rede de entrada, mas em a rede docker_gwbridge (por exemplo, 172.31.0.1), e esses pacotes são perdidos.

A solução alternativa

Portanto, a solução alternativa compreende: 1. remover (na verdade, inibir) essa regra SNAT no namespace ingress_sbox; e 2. criar uma regra de roteamento de política para contêineres de serviço de enxame, que força esses pacotes de saída de volta para o endereço IP de rede de entrada do nó para o qual teria voltado (por exemplo, 10.0.0.2); 3. automatizar a adição das regras de roteamento de política, de modo que cada novo container de serviço as tenha prontamente instaladas na criação.

  1. Para inibir a regra SNAT, criamos uma regra anteriormente na tabela que evita que o SNAT usual seja alcançado:
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

(Fazemos isso dessa forma, em vez de apenas excluir a regra SNAT existente, pois o docker parece recriar a regra SNAT várias vezes durante o curso da criação de um serviço. Essa abordagem apenas substitui essa regra, o que a torna mais resiliente).

  1. Para criar a regra de roteamento da política de contêiner:
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. Por fim, juntando os itens acima com docker event , automatizamos o processo de modificação das regras SNAT e observamos os contêineres recém-iniciados e adicionamos as regras de roteamento de política por meio deste 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

Agora, quando as solicitações chegam às portas publicadas para o nó único, seus contêineres verão o endereço IP original da máquina que está fazendo a solicitação.

Uso

Execute o ingress-routing-daemon como root em _cada e cada um_ de seus nós de enxame _antes_ de criar seu serviço. (Se o seu serviço já foi criado, certifique-se de dimensioná-lo para 0 antes de redimensioná-lo para um número positivo de réplicas.) O daemon inicializará o iptables, detectará quando o docker criar novos contêineres e aplicará novas regras de roteamento a cada novo contêiner.

Teste, casos de uso e limitações

O acima foi testado usando várias réplicas restritas a um único nó em um serviço executado em um enxame de vários nós.

Ele também foi testado usando vários nós, cada um com um serviço por nó separado restrito a esse nó, mas isso vem com a limitação de que diferentes portas publicadas devem ser usadas para cada serviço por nó. Ainda assim, isso pode funcionar para alguns casos de uso.

O método também deve funcionar usando vários nós, se cada um for configurado como um único nó em seu próprio enxame. Isso traz a limitação de que os enxames de docker não podem mais ser usados ​​para distribuir contêineres entre nós, no entanto, ainda pode haver outros benefícios de administração do uso de serviços de docker, como réplica de contêiner e gerenciamento de ciclo de vida.

Melhorar a solução alternativa para lidar com outros casos de uso

Com o desenvolvimento posterior, este método deve ser capaz de escalar para vários nós sem a necessidade de serviços separados por nó ou dividir o enxame. Posso pensar em duas abordagens possíveis: 1. Organizar o Docker, ou um daemon personalizado, para remover todos os IPs não locais da tabela ipvsadm de cada nó. 2. Estendendo as regras de roteamento de política para acomodar pacotes de saída de roteamento de volta para o nó correto.

Para 1, poderíamos pesquisar ipvsadm -S -n para procurar novos IPs adicionados a qualquer serviço, verificar se cada um é local e remover os que não são. Isso permitiria que cada nó funcionasse como um balanceador de carga para seus próprios contêineres dentro do serviço geral, mas sem que as solicitações que chegassem a um nó pudessem ser encaminhadas para outro. Isso certamente satisfaria meu próprio caso de uso, em que temos nosso próprio balanceador de carga IPVS sentado na frente de um conjunto de servidores, cada um executando um aplicativo da web, que gostaríamos de substituir por várias instâncias em contêineres com balanceamento de carga do mesmo aplicativo , para permitir a implementação de atualizações sem perder um servidor inteiro.

Para 2, poderíamos usar iptables para atribuir um TOS por nó em cada iptable ingress_sbox de nó (por exemplo, para o byte final do IP de rede de entrada de nó); em seguida, no contêiner, organize para mapear o valor TOS para uma marca de conexão e, em seguida, de uma marca de conexão para uma marca de firewall para pacotes de saída e, para cada marca de firewall, selecione uma tabela de roteamento diferente que roteie os pacotes de volta para o nó de origem. As regras para isso serão um pouco complicadas, mas imagino que devam ser escalonadas para 2 a 16 nós.

Espero que o acima seja útil. Eu também terei uma chance em (2), e se eu fizer progresso postarei uma nova atualização.

Abaixo está uma versão aprimorada do daemon de roteamento de ingresso, ingress-routing-daemon-v2 , que estende o modelo de regra de roteamento de política para permitir que cada contêiner roteie seus pacotes de saída de volta para o nó correto, sem a necessidade de SNAT.

O modelo melhorado

Além de inibir a regra SNAT de acordo com o modelo anterior, o novo modelo requer uma regra iptables no namespace ingress_sbox em cada nó que você pretende usar como um endpoint balanceador de carga IPVS (normalmente seus nós de gerenciador ou um subconjunto deles nós gerenciadores), que atribui um valor de TOS por nó a todos os pacotes destinados a qualquer nó na rede de ingresso. (Usamos o byte final do IP de rede de entrada do nó.)

Como o valor TOS é armazenado dentro do pacote, ele pode ser lido pelo nó de destino para o qual a solicitação de entrada foi direcionada e o pacote foi enviado.

Em seguida, no contêiner no nó de destino, organizamos o mapeamento do valor TOS em qualquer pacote de entrada para uma marca de conexão, usando o mesmo valor.

Agora, como os pacotes de saída na mesma conexão terão a mesma marca de conexão, mapeamos a marca de conexão em qualquer pacote de saída para uma marca de firewall, novamente usando o mesmo valor.

Finalmente, um conjunto de regras de roteamento de política seleciona uma tabela de roteamento diferente, projetada para rotear os pacotes de saída de volta ao nó de extremidade do balanceador de carga necessário, de acordo com o valor da marca do firewall.

Agora, quando as solicitações do cliente chegam às portas publicadas para qualquer nó do enxame, o contêiner (seja no mesmo e / ou em outros nós) para o qual a solicitação é direcionada verá o endereço IP original do cliente que fez a solicitação, e ser capaz de rotear a resposta de volta ao nó do balanceador de carga de origem; que, por sua vez, será capaz de encaminhar a resposta de volta para o cliente.

Uso

Configurando

Gere um valor para INGRESS_NODE_GATEWAY_IPS específico para o seu enxame, executando ingress-routing-daemon-v2 como root em cada um dos nós do seu enxame _que você gostaria de usar como um endpoint balanceador de carga_ (normalmente apenas o seu gerente nós, ou um subconjunto de seus nós gerenciadores), observando os valores mostrados para INGRESS_DEFAULT_GATEWAY . Você só precisa fazer isso uma vez ou sempre que adicionar ou remover nós. Seu INGRESS_NODE_GATEWAY_IPS deve ser semelhante a 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 (de acordo com a sub-rede definida para a rede de entrada e o número de nós).

Executando o daemon

Execute INGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 --install como root em _cada e em cada um dos nós do swarm (gerentes e trabalhadores) _antes_ de criar seu serviço. (Se o seu serviço já foi criado, certifique-se de dimensioná-lo para 0 antes de redimensioná-lo para um número positivo de réplicas.) O daemon inicializará o iptables, detectará quando o docker criar novos contêineres e aplicará novas regras de roteamento a cada novo contêiner.

Se você precisar restringir as atividades do daemon a um serviço específico, modifique [ -n "$SERVICE" ] para [ "$SERVICE" = "myservice" ] .

Desinstalando regras de iptables

Execute ingress-routing-daemon-v2 --uninstall em cada nó.

Testando

O script ingress-routing-daemon-v2 foi testado com 8 réplicas de um serviço da web implantado em um enxame de quatro nós.

As solicitações de Curl para o serviço, direcionadas a qualquer um dos IPs de nó de endpoint com carga balanceada especificados, retornaram respostas bem-sucedidas e o exame dos logs do contêiner mostrou que o aplicativo viu as solicitações de entrada como originadas do IP do cliente Curl.

Limitações

Como o valor de TOS pode armazenar um número de 8 bits, este modelo pode, em princípio, suportar até 256 nós de terminal do balanceador de carga.

No entanto, como o modelo requer que cada contêiner seja instalado com uma regra de mangle iptables + uma regra de roteamento de política + uma tabela de roteamento de política por nó de terminal do gerenciador, pode haver alguma degradação de desempenho à medida que o número de tais nós de terminal aumenta (embora a experiência sugira que isso seja improvável que seja perceptível com <= 16 nós de endpoint do balanceador de carga em hardware moderno).

Se você adicionar nós de terminais balanceadores de carga ao seu enxame - ou quiser começar a usar nós de gerenciamento existentes como terminais balanceadores de carga - você precisará agir com cuidado, pois os contêineres existentes não serão capazes de rotear o tráfego de volta para os novos nós de terminais. Tente reiniciar INGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 com o valor atualizado para INGRESS_NODE_GATEWAY_IPS , em seguida, execute uma atualização contínua de todos os contêineres antes de usar o novo ponto de extremidade do balanceador de carga.

Escopo para integração nativa do Docker

Não estou familiarizado com a base de código do Docker, mas não consigo ver nada que ingress-routing-daemon-v2 faça que não possa, em princípio, ser implementado pelo Docker nativamente, mas vou deixar isso para a equipe do Docker considere, ou como um exercício para alguém familiarizado com o código do Docker.

O script do daemon de roteamento de entrada v2

Aqui está o novo 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

Olá @struanb , não entendo como funciona a seção de desinstalação do seu script v2, está faltando alguma coisa?

Olá @jrbecart. Espero que não. Antes de as regras de iptables serem instaladas, você verá que há dois loops while que excluem quaisquer regras pré-existentes, usando iptables -D . Esta é uma medida de segurança, caso o script seja executado com --install várias vezes sucessivamente, sem qualquer chamada intermediária com --uninstall .

Como tal, quando o script é chamado com --uninstall, no momento em que o script sai, essas regras terão sido removidas e novas regras ainda não adicionadas.

espero que isso responda sua pergunta.

Olá a todos, quero dizer que descobri uma solução para esse problema, sem instalar e configurar nada além de definir bem a configuração do NGINX. Eu sei que todos nós tentamos abordagens diferentes. Este foi descoberto por engano. Para ser honesto, desisti disso há muito tempo. Bem, até hoje. Enquanto estava implementando um sistema de monitoramento, consegui pegar o IP de origem, o IP de origem real, usando o log do NGINX, então comecei a depurar como isso era possível.

Aqui está um exemplo desse 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: Existem vários IPs de origem se você estiver usando proxies (ou seja, Cloudfare e outros).

A informação estava lá, meu verdadeiro IP estava lá. Em seguida, revisei o formato de registro NGINX para saber como a mágica era possível e descobri o seguinte:

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"';

Isso significa que a mágica está aqui -> $http_x_forwarded_for

Depois disso, mudei os cabeçalhos de proxy como proxy_set_header X-Real-IP $http_x_forwarded_for; .

E finalmente, o último teste, usando essa informação em um projeto NodeJS, dentro do sistema de produção, usando Docker Swarm com uma rede overlay, com cerca de 4 VMs, e adivinha, funcionou! Finalmente consegui obter o endereço IP real.

Estou muito feliz porque esse problema foi aberto há muito tempo, mas acho que esta é a resposta. As versões que usei são:

Docker version: 19.03.8
NGINX version: nginx/1.14.2

Vou esperar seu feedback. Espero que você possa ter os mesmos resultados que eu.

Saúde!
Sebastián.

PS: Tente usar outra interface de rede, ou seja, fora do localhost, porque você encontrará um "-" no log, em vez do seu endereço IP real. Experimente testá-lo na Internet, totalmente fora da sua rede doméstica.

Bônus: Eu também poderia mapear o endereço IP para uma geolocalização, usando uma tabela de pesquisa, contá-los e colocá-los em um mapa, então a resposta é sim, é isso que estávamos procurando pessoal :)

@sebastianfelipe é uma grande reivindicação depois de todos esses anos. Tem certeza de que não está usando o modo host ou outras soluções alternativas neste tópico?

@sebastianfelipe é uma grande reivindicação depois de todos esses anos. Tem certeza de que não está usando o modo host ou outras soluções alternativas neste tópico?

Tenho certeza. Não estou usando o host de rede em todos os serviços conectados. Acabei de implantar uma pilha, com uma rede de sobreposição em um ambiente de produção, incluindo um balanceador de carga Digital Ocean e funcionou. Quer dizer, não posso testar melhor do que isso. É 100% real.

@sebastianfelipe Estou supondo que o balanceador de carga Digital Ocean está anexando o endereço IP do usuário ao cabeçalho X-Forwarded-For. Esta é uma solução alternativa conhecida que não resolve o problema de recuperar o IP do usuário no modo Docker Swarm independente.

@beornf Eu estava tentando dormir e então li sua notificação, então tive que acordar e tentar uma abordagem sem um balanceador de carga Digital Ocean e falhou. Você está certo, a Digital Ocean adiciona uma magia lá quando um balanceador de carga é adicionado. Isso acontece com a variável $http_x_forwarded_for . O balanceador de carga Digital Ocean adiciona informações a outra variável NGINX, informações que não são adicionadas diretamente pelo Docker Swarm. Provavelmente, isso poderia levar a uma abordagem "simulada" para ter uma solução real para cada caso. Pelo menos os clientes da Digital Ocean podem ficar felizes em saber como lidar com isso neste momento.

@beornf @sebastianfelipe Adicionando ao contexto, CloudFlare também adiciona X-Forwarded-For e é amplamente gratuito.

@beornf @sebastianfelipe Adicionando ao contexto, CloudFlare também adiciona X-Forwarded-For e é amplamente gratuito.

Acho que isso pode funcionar para muitos de nós que precisam de uma saída para obter o IP real. Cloudfare pode ser ajustado como proxy ou apenas DNS apenas. Ele se encaixa perfeitamente para nenhum cliente Digital Ocean. É a solução alternativa mais limpa até agora. Mas concordo com @beornf , precisamos de uma solução real, sem depender da Digital Ocean ou da Cloudfare para fazer isso.

Obrigado!

Esta página foi útil?
0 / 5 - 0 avaliações