Docker + Pontes + DHCP

13

Eu tenho muitos contêineres de docker que precisam ser endereçados na mesma LAN dos seus hosts. Até agora, eu consegui isso usando a configuração de uma ponte, atribuindo-lhes IPs manualmente e gerenciando-os pessoalmente. Um exemplo de inicialização seria assim:

docker run \
--net="none" \ \
--lxc-conf="lxc.network.type = veth" \
--lxc-conf="lxc.network.ipv4 = 192.168.1.3/24" \
--lxc-conf="lxc.network.ipv4.gateway = 192.168.1.254" \
--lxc-conf="lxc.network.link = br0" \
--lxc-conf="lxc.network.name = eth0" \
--lxc-conf="lxc.network.flags = up" \
-d [Docker Image ID]

Com o host tendo a ponte definida no /etc/network/interfaces(ubuntu) da seguinte forma:

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
        address 192.168.1.2
        netmask 255.255.255.0
        gateway 192.168.1.254
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0

Desde que descobri servo , eu tenho tentado passar para usar a descoberta automática dentro dos recipientes, para que DHCP pode manter o controle de IPs e entregá-los aos recipientes. Eu mudei o comando de inicialização para:

docker run \
--net="none" \
--lxc-conf="lxc.network.type = veth" \
--lxc-conf="lxc.network.link = br0" \
--lxc-conf="lxc.network.flags = up" \
-d [Docker Image ID]
/bin/bash

e a ponte para:

auto br0
iface br0 inet dhcp
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0

Isso resultou na inicialização do contêiner, mas sem um IP. Então, recebi o conselho de uma publicação on-line que conseguiu fazer isso com o Fedora, ligando dhclient. Infelizmente isso não está funcionando para mim em contêineres baseados no ubuntu.

Abaixo estão as seguintes mensagens de erro que recebo em diferentes condições:

  • Em execução dhclientquando eu habilitei o --privilegedinício do contêiner:

    dhclient: error while loading shared libraries: libc.so.6: cannot open shared object file: Permission denied
    
  • Executando sudo dhclient eth0quando não estiver em--privileged

    RTNETLINK answers: Operation not permitted
    mv: cannot move '/etc/resolv.conf.dhclient-new.31' to '/etc/resolv.conf': Device or resource busy
    
  • Em execução sudo dhclientou dhclient(nenhuma interface especificada).

    Retorna imediatamente e ainda não há conectividade IP ou de rede.

Como posso fazer com que os contêineres do docker obtenham IPs dinâmicos da mesma sub-rede que seus hosts, para que eu possa implantar contêineres em vários hosts sem rastrear IPs?

Informação extra

  • Correndo DOCKER_OPTS="-e lxc"em/etc/default/docker
  • O host é Ubuntu 14.04
  • Os contêineres do Docker são criados usando from ubuntu:14.04o Dockerfile.
Programador
fonte

Respostas:

3

Parece que esse é um problema aberto e é específico dos contêineres e aparelhos do Ubuntu.

Uma solução alternativa foi publicada no bprodoehl:

  • Inicie o contêiner como privilegiado com --privileged
  • Adicione a seguinte linha ao dockerfile: RUN mv /sbin/dhclient /usr/sbin/dhclient
  • Execute dhclient eth0e você ainda verá a mensagem de erro:, mv: cannot move '/etc/resolv.conf.dhclient-new.29' to '/etc/resolv.conf': Device or resource busymas agora você terá um IP e poderá usar a rede.
Programador
fonte
funciona como um encanto para o meu caso, mas por que esse mv é necessário? Você pode explicar por favor?
Federico Bonelli
Foi isso que estava na solução que o cara postou (ao qual eu vinculei) e parece funcionar. Talvez alguém possa explicar.
Programster
1
@Federico Bonelli: A Apparmor aplica restrições de segurança aos aplicativos que gerencia. Ele gerencia apenas aplicativos para os quais possui definições de política. Essas políticas correspondem aos aplicativos com base em seu caminho. Quando você move dhclienta partir /sbinpara /usr/sbina definição de políticas Apparmor não irá corresponder mais e Apparmor não aplicar quaisquer restrições de segurança para esta aplicação "desconhecido".
paprika
Eu tive que recorrer ao "sudo apparmor_parser -R /etc/apparmor.d/sbin.dhclient", pois a solução alternativa não era, esse era um container fyi do ubuntu 14.04. No entanto, a mensagem de erro acima foi vista e um endereço IP foi atribuído.
Neil McGill
1

Eu encontrei um script

https://github.com/jkrauska/tech-notes/blob/master/docker-dhclient.md

isso faz exatamente o que você deseja (a solução alternativa mencionada pelo Programster).

O comando mv é necessário porque, quando você executa o contêiner de docker no modo privilegiado, o docker não define o perfil do AppArmor para contêiner. Portanto, o perfil do AppArmor padrão da máquina é usado e impede a execução do dhclient no caminho padrão.

Dmitriusan
fonte
1

se você estiver tentando obter um endereço dhcp em um contêiner do docker ubuntu, faça o seguinte:

  1. opção set dns no comando docker daemon ( --dns <my_dns_ip>)
  2. abra /etc/dhcp/dhclient.confe edite a linha que contém request subnet-mask, broadcast-address...e remova as palavrasdomain-name, domain-name-servers
  3. depois de aplicar, service networking restartvocê obterá um novo endereço dhcp sem mensagens de erro
user99240
fonte
-2

A outra possibilidade é usar "tubulações". Você precisa executá-lo fora do seu contêiner. https://github.com/jpetazzo/pipework

user90299
fonte
5
Olá e bem-vindo ao site! Gostamos de que as respostas sejam um pouco mais abrangentes aqui. Você poderia editar e explicar o que pipeworké, onde alguém pode encontrá-lo, como ele pode ser instalado, talvez dar um exemplo de seu uso? Tal como está, sua resposta é um comentário e não uma resposta.
terdon