Como configurar um container docker para ter um IP dentro da rede fisica?

É cada vez mais comum que usuários façam o self-host de vários serviços, não só pelo valor dos serviços, mas por questões de segurança e privacidade. Ferramentas como Docker facilitaram muito isso, pela facilidade de uso, baixo recurso de rede, cpu e memoria, Como nem sempre é preciso 100% de disponibilidade, para usuários comuns, se tornou muito comum o uso de computadores antigos para criação de tais servidores.

Quando se tem um servidor desse tipo, é comum criarmos mais de um serviço dentro do mesmo servidor, assim podemos compartilhar recursos de hardware entre os serviços. Trabalhar dessa maneira usando Docker poderia ignorar alguns requisitos de segurança, ocorrer conflitos entre portas, e perder o monitoramento de rede e recurso de cada serviço.

Outro ponto que me levou a me aprofundar no assunto, é que eu venho de uma geração de maquinas virtuais, onde cada serviço possui uma maquina independente rodando cada serviço, e pensar no Docker tendo uma rede própria entre eles e direcionar a porta para cada um, não me parece algo muito seguro.

De qualquer forma eu encontrei o driver
macvlan
, que me possibilita criar uma interface única para cada container, fazendo assim cada container docker ter sua própria interface e seu próprio IP. Isso me pareceu bem mais profissional e seguro, então fui procurar algumas vantagens de usar esse drive:

- Acesso direto à rede: Ao atribuir um IP físico a um container Docker, ele terá acesso direto à rede, sem a necessidade de tradução de endereços de rede (NAT). Isso permite que o container se comunique diretamente com outros dispositivos ou serviços na rede, facilitando a integração e a comunicação

- Isolamento de rede: Usar IPs físicos em containers Docker permite que cada container tenha sua própria interface de rede isolada. Isso ajuda a evitar conflitos de endereços IP e permite que cada container seja tratado como um dispositivo separado na rede, aumentando a segurança e o controle sobre o tráfego de rede

- Monitoramento e solução de problemas: Atribuir um IP físico a um container Docker facilita o monitoramento e a solução de problemas de rede. Você pode rastrear o tráfego de rede, usar ferramentas de análise e depurar problemas com mais facilidade, pois o container está diretamente conectado à rede física

- Melhoria na latência: Como não existe roteamento e o container se conecta diretamente utilizando a interface de rede do host, isso tem melhorias consideráveis na latência

O primeiro passo para utilização do driver 
macvlan
é criar a rede no docker, com o comando:
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=enp5s0 macvlan-net
Onde:

-
192.168.1.0/24
é a faixa de IP de
192.168.1.1
à
192.168.1.255

-
192.168.1.1
é o gateway da minha rede
-
enp5s0
é a interface de rede do host
-
macvlan-net
é o nome da rede que estou criando

Agora você pode criar seu container normalmente, informando a rede e o IP do seu container, com os parametros
--network=macvlan-net
--ip=192.168.1.115
Agora seu container aparecerá como um dispositivo de rede para todos os computadores da rede

Se você, assim como eu, gosta de usar o composer, você deve informar a rede, e no serviço, informar o ip, algo assim:
version: '3.5'
services:

  php:
    container_name: php8.1-apache
    build: 
      context: ./php
      dockerfile: Dockerfile
    ports:
      - "80:80"
      - "443:443"
    volumes:
    - /home/user/www/:/var/www/html/
    environment:
      - ALLOW_OVERRIDE=true
    networks:
      macvlan_net:
        ipv4_address: 192.168.1.115

networks:
  macvlan_net:
    name: "macvlan-net"
    external: true
Complicações:

Aqui vale uma ressalva muito importante: O host não terá acesso ao ip do container docker. Se o host tentar dar um ping no ip
192.168.1.115
, ele não será alcançado. Essa é uma restrição do Kernel, onde as interfaces filhas só tem permissão de se comunicar diretamente com seus parentes.

Se você está utilizando esse hardware somente para este fim, considere não modificar isso, pois isso garantirá que seus containers estarão isolados do host.

Porem, se você está fazendo isso em sua propria maquina, primeiro que não faz muito sentido utilizar o vmaclan, mas, se ainda assim precisar utilizar, contornar esse problema não é tão difícil e possui uma boa explicação aqui.

Basicamente para contornar isso, é comum que se crie uma nova interface de rede, e essa interface sim, fará a comunicação com os container:
$ sudo -s
$ ip link add macvlan_host link eno1 type macvlan  mode bridge
$ ip addr add 192.168.1.224/32 dev macvlan_host
$ ip link set macvlan_host up
$ ip route add 192.168.1.0/24 dev macvlan_host