Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

macos - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...