GNU/Linux >> Tutoriales Linux >  >> Linux

Sin conectividad de red hacia/desde el contenedor Docker CE en CentOS 8

Solución 1:

Después de pasar un par de días mirando registros y configuraciones para los componentes involucrados, estaba a punto de tirar la toalla y volver a Fedora 30, donde parece funcionar de inmediato.

Centrándome en el cortafuegos, me di cuenta de que deshabilitar firewalld parecía hacer el truco, pero preferiría no hacerlo. Al inspeccionar las reglas de la red con iptables , me di cuenta de que el cambio a nftables significa que iptables ahora es una capa de abstracción que solo muestra una pequeña parte del nftables normas. Eso significa que la mayoría, si no todos, de los firewalld la configuración se aplicará fuera del alcance de iptables .

Estaba acostumbrado a poder encontrar toda la verdad en iptables , por lo que tomará un tiempo acostumbrarse.

Para resumir, para que esto funcione, tuve que habilitar el enmascaramiento. Parecía dockerd ya lo hice a través de iptables , pero aparentemente esto debe habilitarse específicamente para la zona de firewall para iptables disfrazarse para trabajar:

# Masquerading allows for docker ingress and egress (this is the juicy bit)
firewall-cmd --zone=public --add-masquerade --permanent

# Specifically allow incoming traffic on port 80/443 (nothing new here)
firewall-cmd --zone=public --add-port=80/tcp
firewall-cmd --zone=public --add-port=443/tcp

# Reload firewall to apply permanent rules
firewall-cmd --reload

Reiniciar o reiniciar dockerd , y tanto la entrada como la salida deberían funcionar.

Solución 2:

Lo que falta en las respuestas anteriores es el hecho de que primero debe agregar su interfaz acoplable a la zona que configura, p. público (o agréguelo a la zona "confiable" que se sugirió aquí, pero dudo que sea prudente, desde una perspectiva de seguridad). Porque por defecto no está asignado a una zona. También recuerde recargar el demonio docker cuando haya terminado.

# Check what interface docker is using, e.g. 'docker0'
ip link show

# Check available firewalld zones, e.g. 'public'
sudo firewall-cmd --get-active-zones

# Check what zone the docker interface it bound to, most likely 'no zone' yet
sudo firewall-cmd --get-zone-of-interface=docker0

# So add the 'docker0' interface to the 'public' zone. Changes will be visible only after firewalld reload
sudo nmcli connection modify docker0 connection.zone public

# Masquerading allows for docker ingress and egress (this is the juicy bit)
sudo firewall-cmd --zone=public --add-masquerade --permanent
# Optional open required incomming ports (wasn't required in my tests)
# sudo firewall-cmd --zone=public --add-port=443/tcp
# Reload firewalld
sudo firewall-cmd --reload
# Reload dockerd
sudo systemctl restart docker

# Test ping and DNS works:
docker run busybox ping -c 1 172.16.0.1
docker run busybox cat /etc/resolv.conf
docker run busybox ping -c 1 yourhost.local

Solución 3:

Para poder establecer reglas detalladas para Docker, no necesitaba configurar docker0 en ninguna zona.

# 1. Stop Docker
systemctl stop docker
# 2. Recreate DOCKER-USER chain in firewalld. 
firewall-cmd --permanent \
             --direct \
             --remove-chain ipv4 filter DOCKER-USER

firewall-cmd --permanent \
             --direct \
             --remove-rules ipv4 filter DOCKER-USER

firewall-cmd --permanent \
             --direct \
             --add-chain ipv4 filter DOCKER-USER

# (Ignore any warnings)

# 3. Docker Container <-> Container communication

firewall-cmd --permanent \
             --direct \
             --add-rule ipv4 filter DOCKER-USER 1 \
             -m conntrack --ctstate RELATED,ESTABLISHED \
             -j ACCEPT \
             -m comment \
             --comment 'Allow docker containers to connect to the outside world'

firewall-cmd --permanent \
             --direct \
             --add-rule ipv4 filter DOCKER-USER 1 \
             -j RETURN \
             -s 172.17.0.0/16 \
             -m comment \
             --comment 'allow internal docker communication'

# Change the Docker Subnet to your actual one (e.g. 172.18.0.0/16)
# 4. Add rules for IPs allowed to access the Docker exposed ports.

firewall-cmd --permanent \
             --direct \
             --add-rule ipv4 filter DOCKER-USER 1 \
             -o docker0 \
             -p tcp \
             -m multiport \
             --dports 80,443 \
             -i eth0 \
             -o docker0 \
             -s 1.2.3.4/32 \
             -j ACCEPT \
             -m comment \
             --comment 'Allow IP 1.2.3.4 to docker ports 80 and 443'
# 5. log docker traffic (if you like)

firewall-cmd --direct \
             --add-rule ipv4 filter DOCKER-USER 0 \
             -j LOG \
             --log-prefix ' DOCKER: '
# 6. Block all other IPs. 
This rule has lowest precedence, so you can add allowed IP rules later.

firewall-cmd --permanent \
             --direct \
             --add-rule ipv4 filter DOCKER-USER 10 \
             -j REJECT \
             -m comment \
             --comment 'reject all other traffic to DOCKER-USER'
# 7. Reload firewalld, Start Docker again
firewall-cmd --reload
systemctl start docker

Esto termina en reglas definidas en /etc/firewalld/direct.xml:

<?xml version="1.0" encoding="utf-8"?>
<direct>
  <chain ipv="ipv4" table="filter" chain="DOCKER-USER"/>
  <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment 'Allow docker containers to connect to the outside world'</rule>
  <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-j RETURN -s 172.17.0.0/16 -m comment --comment 'allow internal docker communication'</rule>
  <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-p tcp -m multiport --dports 80,443 -s 1.2.3.4/32 -j ACCEPT -m comment --comment 'Allow IP 1.2.3.4 to docker ports 80 and 443'</rule>
  <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-j LOG --log-prefix ' DOCKER TCP: '</rule>
  <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="10">-j REJECT -m comment --comment 'reject all other traffic to DOCKER-USER'</rule>
</direct>

El inconveniente aún es que necesita instalar containerd.io desde CentOS7 como lo indica Saustrup


Linux
  1. Comprobar la conectividad de red en un servidor Linux

  2. Cómo crear una imagen de Docker a partir de un contenedor y un archivo Docker

  3. Cómo acceder al espacio de nombres de red del contenedor Docker desde el host

  4. Ejecutando docker en Ubuntu:el volumen de host montado no se puede escribir desde el contenedor

  5. La instalación de docker-ce en Ubuntu 18.04 interrumpe la conectividad a Internet del host

Cómo instalar Rancher Docker Container Manager en CentOS 7

Cómo crear una imagen de Docker desde un contenedor en ejecución

Cómo obtener la dirección IP del contenedor Docker

Cómo usar SSH en un contenedor Docker

Cómo crear una imagen personalizada desde un contenedor Docker

Actualice Python de 2.6 a 2.7 en Centos 6.5