Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

connect to container from a remote machine

I created a user defined network (bridge mode) hb1 and added 2 containers. However, I cannot connect to them from an external host on my network.

I checked and followed the instructions here and here as closely as I could.

pi@raspberrypi:~ $ docker network inspect hb1
[
    {
        "Name": "hb1",
        "Id": "278a4ba8bb7a4a34b25b5f5fde9a965a807ff896d5e57c2b1d7d39af60d0a046",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.32/27",
                    "Gateway": "192.168.1.33"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "7dc7be3ae45813450bb7f75a6e2c7b4d93e59aa147aa7d393061748b8201381a": {
                "Name": "modest_bohr",
                "EndpointID": "eda20bbb52319b10911f3da6f6afadbd2167298d5a9cfd5c91f933f4b6d5fe86",
                "MacAddress": "02:42:c0:a8:01:22",
                "IPv4Address": "192.168.1.34/27",
                "IPv6Address": ""
            },
            "f12fbc30bcf5e37737bfe8c7868dcd40e6c632bb3672f5641ffd6960ede4f777": {
                "Name": "infallible_torvalds",
                "EndpointID": "92d0ecfad597485c25ad309d48c3c77b9368f25ebbd851b1168f59a795c497f2",
                "MacAddress": "02:42:c0:a8:01:23",
                "IPv4Address": "192.168.1.35/27",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

when i ping from my docker host, it works as expected.

user@myhost: ~$ ping -c 1 192.168.1.34
PING 192.168.1.34 (192.168.1.34) 56(84) bytes of data.
64 bytes from 192.168.1.34: icmp_seq=1 ttl=64 time=0.474 ms

--- 192.168.1.34 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.474/0.474/0.474/0.000 ms

however, from a remote host, the container cannot be reached.

user@remotehost: ~$ ping -c 1 192.168.1.34
PING 192.168.1.34 (192.168.1.34) 56(84) bytes of data.
From 192.168.1.100 icmp_seq=1 Destination Host Unreachable

--- 192.168.1.34 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

how should I configure the docker user defined network or my local network so that i can acces the container on a seperate ip adress?

like image 689
Marc Wagner Avatar asked Oct 29 '22 16:10

Marc Wagner


1 Answers

I answered today on a very similar question, could you take a look on my answer here and follow it, it works perfectly for me.

Assign LAN IP address to Docker container different from host's IP address

Here is the answer:

Creating Persistence Network Bridge

The Bridge, is a device (in our case virtual device), which behaves similar to network swiches (operates mainly on network layer 2), i.e., it can connect two or more network interfaces to be on the same local area network (LAN) if they have the same subnet.

You are going to create new persistence bridge br0 (it will get started automatically on system boot), add your physical network interface into it (in my case it is eth0). Note that after you add your interface to the bridge, the interface doesn't need IP address anymore, because the bridge will get IP address and can be used instead of your interface, i.e., you can communicate using the bridge as if it were your physical interface and it will forward the in/out data packets to the correct destination. You don't need to assign any hardware (MAC address) to the bridge, it will automatically take the MAC of the first added interface.

Warning: It is highly recommended not to do these steps remotely except you have a physical access to your server! You may lose your connection to your server if you were not careful.

Install bridges managing utility:

sudo apt install bridge-utils

The system will not be able to create the bridge without bridge-utils package.

To create persistence bridge, edit interfaces file:

sudo vim /etc/network/interfaces

Add the follwing configuration to the end of the file (adapt them to suit your needs):

auto br0
iface br0 inet static
    bridge_ports eth0
    address 192.168.1.10
    netmask 255.255.255.0
    broadcast 192.168.1.255
    gateway 192.168.1.1

Now remove Docker's default bridge docker0, as we don't need it:

sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0

Edit Docker's service-start script to use your bridge (br0) instead of Docker's default bridge (docker0), and pass some important bridge parameters:

Ubuntu:

sudo vim /etc/systemd/multi-user.target.wants/docker.service

Adapt the file to look like this:

[Service]

ExecStart=/usr/bin/dockerd -H fd:// --bridge=br0 --fixed-cidr=192.168.1.32/27 --default-gateway=192.168.1.1

Now tell the system about the changes on that file:

sudo systemctl daemon-reload

Reboot the system:

sudo reboot

Now check your bridge, it should be there!

ip addr

Now create your container like bellow, this will lead to give your container a fix IP:

  docker run --name myContainer \
  -it --restart always --memory 100M \
  --network bridge --cap-add NET_ADMIN \
  --hostname client1.noureldin.local \
  --add-host "client1.noureldin.local client1":192.168.1.123 \
  mnoureldin/general-purpose:latest /bin/bash -c " \
  ip addr flush dev eth0; \
  ip addr add 192.168.1.123/24 brd + dev eth0; \
  ip route add default via 192.168.1.1 dev eth0; \
  /bin/bash"

The important part related to your network requirements is:

  --network bridge --cap-add NET_ADMIN \
  ip addr flush dev eth0; \
  ip addr add 192.168.1.123/24 brd + dev eth0; \
  ip route add default via 192.168.1.1 dev eth0; \

Of course be sure that you installed iproute2 net-tools iputils-ping packages in your container to be able to execute the common network commands (giving the fixed ip done by ip command).

For the first time you run the container, you may NOT notice any changes in IP address, because your conainer probably doesn't have iproute2 package (i.e. there is not ip command), just intall the mentioned packages and then restart the container and everything should be exactly as you want!

Hope that helps.

like image 164
Mohammed Noureldin Avatar answered Nov 15 '22 05:11

Mohammed Noureldin