Neil
Neil

Reputation: 3036

How could I ping my docker container from my host

I have created a ubuntu docker container on my mac

CONTAINER ID  IMAGE   COMMAND      CREATED         STATUS         PORTS                 NAMES
5d993a622d23  ubuntu  "/bin/bash"  42 minutes ago  Up 42 minutes  0.0.0.0:123->123/tcp  kickass_ptolemy

I set port as 123.

My container IP is 172.17.0.2

docker inspect 5d993a622d23 | grep IP
"LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
                    "IPAMConfig": null,
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,

On my Mac I try to ping my container,

Ping 172.17.0.2, I got Request timeout for icmp_seq 0....

What should I do? So my local machine can ping the container I installed. Did I missing some app installation on my container, which is a plain ubuntu system?

Upvotes: 62

Views: 170735

Answers (6)

Matt
Matt

Reputation: 74660

You can't ping or access a container interface directly with Docker for Mac.

The current best solution is to connect to your containers from another container. At present there is no way we can provide routing to these containers due to issues with OSX that Apple have not yet resolved. we are tracking this requirement, but we cannot do anything about it at present.

lima

Lima can add host accessible interfaces on a VM via socket_vmnet (It's 2023 now, lima is used in rancher/podman desktop)

# Install
brew install lima socket_vmnet

# Customise the `shared` network if required. 
vi ~/.lima/_config/networks.yaml

# Set up the sudoers file for launching `socket_vmnet` from Lima
limactl sudoers >etc_sudoers.d_lima
sudo install -o root etc_sudoers.d_lima /etc/sudoers.d/lima

# Create a containerd VM on the `shared` network
echo | limactl start \
  --network lima:shared \
  --vm-type vz \
  --mount-type virtiofs \
  --set '.containerd.system = true | .containerd.user = false' \
  template://debian-12

# You may want to add this ip/mac address to /etc/bootptab
# so the IP address remains consistent on this VM. 
lima ip -j address show lima0 \
 | jq -r '.[0] as $if
    | "lima  1  \($if.address)  \($if.addr_info[] |select(.family == "inet") |.local)"'

# Setup network and route
lima sudo nerdctl network create ctr01 --subnet 10.2.3.0/24
sudo /sbin/route add 10.2.3.0/24 192.168.105.3 # or configured networks.yaml

# Test
lima sudo nerdctl run --detach --net ctr01 --ip 10.2.3.3 nginx
ping -c 2 10.2.3.3
curl http://10.2.3.3

Docker Toolbox/VirtualBox

When running Docker Toolbox, Docker Machine via VirtualBox or any VirtualBox VM (like a Vagrant definition) you can setup a "Host-Only Network" and access the Docker VMs network via that.

If you are using the default boot2docker VM, don't change the existing interface as you will stop a whole lot of Docker utilities from working, add a new interface.

You will also need to setup routing from your Mac to the container networks via your VM's new IP address. In my case the Docker network range is 172.22.0.0/16 and the Host Only adapter IP on the VM is 192.168.99.100.

sudo route add 172.22.0.0/16 192.168.99.100

Adding a permanent route to osx is bit more complex

Then you can get to containers from your Mac

machost:~ ping -c 1 172.22.0.2
PING 172.22.0.2 (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: icmp_seq=0 ttl=63 time=0.364 ms

--- 172.22.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.364/0.364/0.364/0.000 ms

Vagrant + Ansible setup

Here's my running config...

Vagrant.configure("2") do |config|
  config.vm.box = "debian/contrib-buster64"
  config.vm.hostname = "docker"
  config.vm.network "private_network", ip: "10.7.7.7", hostname: true
  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "4000"
    vb.cpus = "4"
  end
  config.vm.provision "ansible" do |ansible|
    ansible.verbose = "v"
    ansible.playbook = "tasks.yaml"
  end
end

The ansible tasks.yaml to configure a fixed network.

- hosts: all
  become: yes
  vars:
    ansible_python_interpreter: auto_silent
    docker_config:
      bip: 10.7.2.1/23
      host: ["tcp://10.7.7.7:2375"]
      userland-proxy: false
  tasks:

  - ansible.builtin.apt:
      update_cache: yes
      force_apt_get: yes
      pkg:
      - bridge-utils
      - docker.io
      - python3-docker
      - python-docker
      - iptables-persistent

  - ansible.builtin.hostname:
      name: docker

  - ansible.builtin.copy:
      content: "{{ docker_config | to_json }}"
      dest: /etc/docker/daemon.json

  - ansible.builtin.lineinfile:
      line: 'DOCKER_OPTS="{% for host in docker_config.host %} -H {{ host }} {% endfor %}"'
      regexp: '^DOCKER_OPTS='
      path: /etc/default/docker

  - ansible.builtin.systemd:
      name: docker.service
      state: restarted
  
  - ansible.builtin.iptables:
      action: insert
      chain: DOCKER-USER
      destination: 10.7.2.0/23
      in_interface: eth1
      out_interface: docker0
      jump: ACCEPT
  - ansible.builtin.shell: iptables-save > /etc/iptables/rules.v4

Add the route for the docker bridge network via the VM to the mac

$ sudo /sbin/route -n -v add -net 10.7.2.0/23 10.7.7.7

Then set DOCKER_HOST=10.7.7.7 in the environment to use the new VM.

$ export DOCKER_HOST=10.7.7.7 
$ docker run --name route_test --rm -d node:14-slim node -e "require('http').createServer((req, res) => {
 res.writeHead(200, {'Content-Type':'text/plain'})
 res.end('hello')
}).listen(3000)"
$ docker container inspect route_test -f '{{ .NetworkSettings.Networks.bridge.IPAddress }}'
$ curl http://10.7.2.3:3000
hello
$ docker rm -f route_test

You don't get volumes mapped from the host to the vm, but as a bonus it uses a lot less cpu than the Docker 2.5.x release.

Upvotes: 45

Gennady Krasnikov
Gennady Krasnikov

Reputation: 1

It is possible to run the containers of interest in one and the same network with an additional container with OpenVPN server, so that you can see containers over VPN connection from the host:

  • Use docker network create --subnet=172.19.0.0/24 my-net to create a network where containers will see each other.
  • Attach containers to it using --net my-net parameter for docker run.
  • Run an additional container with OpenVPN in the same network. This time you need a port mapping for VPN connection -p 1194:1194/udp.
  • Use OpenVPN client on the host to connect to this network with containers to ping them.

Also, you may need to comment out redirect-gateway instruction in OpenVPN client config file and add push "route 172.19.0.0 255.255.255.0" to (and remove other pushes from) the server config file.

Upvotes: 0

Ángel Ugarte
Ángel Ugarte

Reputation: 161

It works in this scenario:

  1. Windows host
  2. Linux VM installed on Windows host
  3. Docker container installed on Linux VM host

Now you have to note this. Containers are in a isolated network but connected to the internet throught your Docker container host adapter.So you have to tell kernel linux to be available in your network then in your Linux VM:

# sysctl net.ipv4.conf.all.forwarding=1
# sudo iptables -P FORWARD ACCEPT

Now in you Windows host you have to add a route for our container network: route add "Docker container network" "Linux VM IP" for example

# route add 172.17.0.0/16 192.168.1.20

Upvotes: 7

hakkican
hakkican

Reputation: 426

Let's say you have W-> windows machine, L-Linux Vbox VM (eth0,eth1) and docker app (using port 8989) running on this L-Linux Vbox VM. Provider does not have to Vbox anyway or W-> a win.You want to type http://app:8989 on your browser.There are two methods afak; easy way to run vagrant automatically or manually configure Vbox VM with port forwarding through "Host-only Adapter" which is actually eth1; normally eth0 is Vbox's default reserved 10.0.2.15 IP assignment.Or on command prompt on win/lin/mac through "VBoxManage" command you can set up networks or automate through scripts.

webtier.vm.network "forwarded_port", guest: 8989, host: 8989

run docker app

sudo docker run -p 8989:8989 ...

on windows explorer(W-> windows machine) browse your app

http://app:8989

You still can not ping "172.17.0.2" which is docker container IP in this situation from W-> windows machine.This could run cross-platform win/lin/mac.You might want to look into Vbox Manual and Vagrant Manual, particularly networks.

Upvotes: 0

Guru
Guru

Reputation: 1

setup:

PC-A a is docker host, PC-B is a another PC in the network. To ping/access docker's container from PC-B, run the below iptables-rules in the host.

iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT

iptables -A FORWARD -i eth0 -o docker0 -j ACCEPT

note: eth0 is host's interface and docker0 is docker's virtual default bridge.

Now add route in PC-B

route add -net <dockerip> netmask <net mask> gw <docker's host>

ping/access container services directly.

Upvotes: 0

Cesar Gomez Velazquez
Cesar Gomez Velazquez

Reputation: 471

As an alternative, if your container has a bash shell incorporated, you can access it through

docker exec -it <CONTAINER ID> bash

and then you can ping your virtual ip

Upvotes: 6

Related Questions