My docker container has no internet

Viewed 394883

I had it working allright but now it stopped. I tried the following commands with no avail:

docker run -dns 8.8.8.8 base ping google.com

docker run base ping google.com

sysctl -w net.ipv4.ip_forward=1 - both on the host and on the container

All I get is unknown host google.com. Docker version 0.7.0

Any ideas?

P.S. ufw disabled as well

33 Answers

I do not know what I am doing but that worked for me :

OTHER_BRIDGE=br-xxxxx # this is the other random docker bridge (`ip addr` to find)    
service docker stop

ip link set dev $OTHER_BRIDGE down
ip link set dev docker0 down
ip link delete $OTHER_BRIDGE type bridge
ip link delete docker0 type bridge
service docker start && service docker stop

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.18.0.0/16 -j MASQUERADE

service docker start

No internet access can also be caused by missing proxy settings. In that case, --network host may not work either. The proxy can be configured by setting the environment variables http_proxy and https_proxy:

docker run -e "http_proxy=YOUR-PROXY" \
           -e "https_proxy=YOUR-PROXY"\
           -e "no_proxy=localhost,127.0.0.1" ... 

Do not forget to set no_proxy as well, or all requests (including those to localhost) will go through the proxy.

More information: Proxy Settings in the Archlinux Wiki.

Tried all answers, none worked for me.

After a few hours of trying everything else I could find, this did the trick:

reboot

-_-

I was stumped when this happened randomly for me for one of my containers, while the other containers were fine. The container was attached to at least one non-internal network, so there was nothing wrong with the Compose definition. Restarting the VM / docker daemon did not help. It was also not a DNS issue because the container could not even ping an external IP. What solved it for me was to recreate the docker network(s). In my case, docker-compose down && docker-compose up worked.

Compose

This forces the recreation of all networks of all the containers:

docker-compose down && docker-compose up

Swarm mode

I suppose you just remove and recreate the service, which recreates the service's network(s):

docker service rm some-service

docker service create ...

If the container's network(s) are external

Simply remove and recreate the external networks of that service:

docker network rm some-external-network

docker network create some-external-network

for me, my problem was because of iptables-services was not installed, this worked for me (CentOS):

sudo yum install iptables-services
sudo service docker restart

On centos 8, My problem was that I did not install & start iptables before starting docker service. Make sure iptables service is up and running before you start docker service.

Sharing a simple and working solution for posterity. When we run a docker container without explicitly mentioning the --network flag, it connects to its default bridge network which prohibits connecting to the outside world. To resolve this issue, we have to create our own bridge network(user-defined bridge) and have to explicitly mention it with the docker run command.

docker network create --driver bridge mynetwork
docker run -it --network mynetwork image:version

Other answers have stated that the docker0 interface (bridge) can be the source of the problem. On Ubuntu 20.04 I observed that the interface was missing its IP address (to be checked with ip addr show dev docker0). Restarting Docker alone did not help. I had to delete the bridge interface manually.

sudo ip link delete docker0
sudo systemctl restart docker

For me it was an iptables forwarding rule. For some reason the following rule, when coupled with docker's iptables rules, caused all outbound traffic from containers to hit localhost:8080:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

I had the problem on Ubuntu 18.04. However the problem was with the DNS. I was in a corporate network that has its own DNS server and block other DNS servers. This is to block some websites (porn, torrents, ... so on )

To resolve your problem

  1. find your DNS on host machine
  2. use --dns your_dns as suggested by @jobin

    docker run --dns your_dns -it --name cowsay --hostname cowsay debian bash

For Ubuntu 19.04 using openconnect 8.3 for VPN, I had to symlink /etc/resolve.conf to the one in systemd (opposite of answerby wisbucky )

sudo ln -sf /etc/resolv.conf /run/systemd/resolve/resolv.conf

Steps to debug

  1. Connect to Company VPN
  2. Look for correct VPN settings in either /etc/resolv.conf or /run/systemd/resolve/resolv.conf
  3. Whichever has the correct DNS settings, we'll symlink that to the other file ( Hint: Place one with correct settings on the left of assignment )

Docker version: Docker version 19.03.0-rc2, build f97efcc

for me, using centos 7.4, it was not issue of /etc/resolve.conf, iptables, iptables nat rules nor docker itself. The issue is the host missing the package bridge-utils which docker require to build the bridge using command brctl. yum install -y bridge-utils and restart docker, solve the problem.

it help me:

sudo ip link delete docker0
sudo systemctl stop docker.socket
sudo systemctl stop docker.service

sudo systemctl start docker.socket
sudo systemctl start docker.service

NOTE: after this, interface docker0 must have ip adress smth like that:

inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

Just adding this here in case someone runs into this issue within a virtualbox container running docker. I reconfigured the virtualbox network to bridged instead of nat, and the problem went away.

There are lot of good answer already. I faced similar problem in my orange pi pc running armbian recently. Docker container was blocked to internet. This command solve the problem in my case. So I like to share it

docker run --security-opt seccomp=unconfined imageName

I've tried most answers in here, but the only thing that worked was re-creating the network:

$ docker network rm the-network
$ docker network create --driver=bridge the-network

I also needed to re-create the docker container that used it:

$ sudo docker create --name the-name --network the-network

Then it started with internet access.

I am on Arch Linux and after trying all the above answers I realized that I had a firewall enabled in my machine, nftables, and disabling it did the trick. I did :

sudo systemctl disable nftables
sudo systemctl stop nftables
sudo reboot

My network cards:

āžœ  ~ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 68:f7:28:84:e7:fe brd ff:ff:ff:ff:ff:ff
3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether d0:7e:35:d2:42:6d brd ff:ff:ff:ff:ff:ff
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:43:3f:ff:94 brd ff:ff:ff:ff:ff:ff
5: br-c51881f83e32: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:ae:34:49:c3 brd ff:ff:ff:ff:ff:ff
6: br-c5b2a1d25a86: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:72:d3:6f:4d brd ff:ff:ff:ff:ff:ff
8: veth56f42a2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 8e:70:36:10:4e:83 brd ff:ff:ff:ff:ff:ff link-netnsid 0

and my firewal configuration, /etc/nftables.conf, which I now disabled and will futurely try to improve so I can have the docker0 network card rules setup correctly:

#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:

# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.

table inet filter
delete table inet filter
table inet filter {
  chain input {
    type filter hook input priority filter
    policy drop

    ct state invalid drop comment "early drop of invalid connections"
    ct state {established, related} accept comment "allow tracked connections"
    iifname lo accept comment "allow from loopback"
    ip protocol icmp accept comment "allow icmp"
    meta l4proto ipv6-icmp accept comment "allow icmp v6"
    #tcp dport ssh accept comment "allow sshd"
    pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
    counter
  }
  chain forward {
    type filter hook forward priority filter
    policy drop
  }

I also encountered such an issue while trying to set up a project using Docker-Compose on Ubuntu.

The Docker had no access to internet at all, when I tried to ping any IP address or nslookup some URL - it failed all the time.

I tried all the possible solutions with DNS resolution described above to no avail.

I spent the whole day trying to find out what the heck is going on, and finally found out that the cause of all the trouble was the antivirus, in particular it's firewall which for some reason blocked Docker from getting the IP address and port.

When I disabled it - everything worked fine.

So, if you have an antivirus installed and nothing helps fix the issue - the problem could be the firewall of the antivirus.

I've had a similar problem for the last few days. For me the cause was a combination of systemd, docker and my hosting provider. I'm running up-to-date CentOS (7.7.1908).

My hosting provider automatically generates a config file for systemd-networkd. Starting with systemd 219 which is the current version for CentOS 7, systemd-networkd took control of network-related sysctl parameters. Docker seems to be incompatible with this version and will reset the IP-Forwarding flags everytime a container is launched.

My solution was to add IPForward=true in the [Network]-section of my provider-generated config file. This file might be in several places, most likely in /etc/systemd/network.

The process is also described in the official docker docs: https://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/#ip-forwarding-problems

After struggling for hours I finally solved my problem

The issue was of linux using old version of libseccomp2

Get signing keys to verify the new packages, otherwise they will not install

rpi ~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138

Add the Buster backport repository to apt sources.list

rpi ~$ echo 'deb http://httpredir.debian.org/debian buster-backports main contrib non-free' | sudo tee -a /etc/apt/sources.list.d/debian-backports.list

rpi ~$ sudo apt update
rpi ~$ sudo apt install libseccomp2 -t buster-backports

After this try

rpi ~$ docker run -it --rm alpine:3.15.0
(alpine shell)# apk update

apk update will fetch and hence your are connected to internet

I was using

Linux raspberrypi 5.10.63-v7l+ #1496 SMP Wed Dec 1 15:58:56 GMT 2021 armv7l GNU/Linux

you may check using uname -a

In my case, for some unknown reason, docker was configured (by someone else) to not generate the iptables rules containers need for networking. The docker container could only ping the host, nothing else. Most answers here did not help; recreating the bridge nor restarting the service changed anything.

But then, by pure chance, I found the following:

$ cat /etc/docker/daemon.json
{"iptables": false}

I deleted the file /etc/docker/daemon.json and restarted the daemon (default is to create the iptables rules). This solved the networking problem.

Below, the iptables rules before the fix:

$ iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Now, the iptables rules after the fix:

$ iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

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

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (2 references)
target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:8443

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

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

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

The only thing that works on my computer (which 8.8.8.8 didn't work)

  1. find out the dns used in your local machine:
$ netstat -ntpl | grep :53
tcp        0      0 10.194.128.1:53         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.2.1:53            0.0.0.0:*               LISTEN      -
  1. modify your docker config sudo vim /etc/docker/daemon.json based on the information above on your own computer
{
  "dns": ["192.168.122.1","10.194.128.1"]
}
  1. restart docker
sudo ip link delete docker0
sudo systemctl restart docker

If you're running Docker rootless and facing this issue, during its installation, iptables may not be configured properly, mainly because of using --skip-iptables option when Docker complained about iptables:

[ERROR] Missing system requirements. Run the following commands to
[ERROR] install the requirements and run this tool again.
[ERROR] Alternatively iptables checks can be disabled with --skip-iptables .

########## BEGIN ##########
sudo sh -eux <<EOF
# Load ip_tables module
modprobe ip_tables
EOF
########## END ##########

Let's check if this is the issue: is ip_tables kernel module loaded?

sudo modprobe ip_tables

If there is no output, this answer may not help you (you could try anyway). Otherwise, the output's something like this:

modprobe: FATAL: Module ip_tables not found in directory /lib/modules/5.18.9-200.fc36.x86_64

Let's fix it!

First, uninstall Docker rootless (no need to stop the service via systemctl, the script handles that):

dockerd-rootless-setuptool.sh uninstall --skip-iptables

Ensure iptables package is installed, although it's shipped by default by major distributions.

Now, make ip_tables module visible to modprobe and install it (thanks to this):

sudo depmod
sudo modprobe ip_tables

Now, re-install Docker rootless:

dockerd-rootless-setuptool.sh install

If it doesn't bother about iptables, you're done and problem should be fixed. Don't forget to enable the service (i.e. systemctl enable --user --now docker)!

Related