首页 文章

如何从docker容器中获取docker主机的IP地址

提问于
浏览
252

正如 Headers 所说 . 我需要能够检索docker托管的IP地址和从主机到容器的端口映射,并在容器内部执行此操作 .

14 回答

  • 2

    我就是这样做的 . 在这种情况下,它会在docker镜像中的/ etc / hosts中添加一个hosts条目,指向taurus-host到我的本地机器IP ::

    TAURUS_HOST=`ipconfig getifaddr en0`
    docker run -it --rm -e MY_ENVIRONMENT='local' --add-host "taurus-host:${TAURUS_HOST}" ...
    

    然后,从Docker容器中,脚本可以使用主机名taurus-host来到我托管docker容器的本地机器 .

  • 2

    随着https://docs.docker.com/machine/install-machine/

    a)$ docker-machine ip

    b)获取一台或多台机器的IP地址 .

    $ docker-machine ip host_name
    
      $ docker-machine ip host_name1 host_name2
    
  • 18
    /sbin/ip route|awk '/default/ { print $3 }'
    

    正如@MichaelNeale注意到的那样,在 Dockerfile 中使用这种方法是没有意义的(除非我们在构建时只需要这个IP),因为这个IP在构建期间将被硬编码 .

  • 0

    Docker for Mac 上,从版本18.03开始,您可以使用 host.docker.internal 作为主机的IP .

    注意,如documentation,"This is for development purpose[s] and will not work in a production environment outside of Docker for Mac."这是因为,在Docker for Mac中,"you cannot see a docker0 interface on the host. This interface is actually within the virtual machine."

    这是自版本17.06以来可用的 docker.for.mac.localhost 的更新,以及自版本17.12以来可用的 docker.for.mac.host.internal ,它可能仍然有效 .

    例如,我在主机上设置了环境变量:

    MONGO_SERVER=host.docker.internal
    

    在我的 docker-compose.yml 文件中,我有这个:

    version: '3'
    
    services:
      api:
        build: ./api
        volumes:
          - ./api:/usr/src/app:ro
        ports:
          - "8000"
        environment:
          - MONGO_SERVER
        command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi
    
  • 20

    更新:在 Docker for Mac 上,从版本18.03开始,您可以使用 host.docker.internal 作为主机的IP . 见allanberry's answer . 对于以前版本的Docker for Mac,以下答案可能仍然有用:

    在Docker for Mac上, docker0 桥不存在,因此这里的其他答案可能不起作用 . 但是,所有传出流量都通过父主机进行路由,因此只要您尝试连接到它识别为自身的IP(并且Docker容器本身并不认为),您就应该能够连接 . 例如,如果从父机器运行此命令:

    ipconfig getifaddr en0
    

    这应该会显示当前网络上Mac的IP,并且您的docker容器也应该能够连接到此地址 . 如果这个IP地址发生变化,这当然是一种痛苦,但你可以在你的Mac上添加一个自定义的环回IP,容器认为它本身不是通过在父机器上做这样的事情:

    sudo ifconfig lo0 alias 192.168.46.49
    

    然后,您可以使用telnet在docker容器中测试连接 . 在我的情况下,我想连接到远程xdebug服务器:

    telnet 192.168.46.49 9000
    

    现在,当流量进入您的Mac,寻址为192.168.46.49(并且所有离开您的容器的流量都通过您的Mac),您的Mac将假设IP本身 . 使用完此IP后,可以删除环回别名,如下所示:

    sudo ifconfig lo0 -alias 192.168.46.49
    

    需要注意的一件事是,如果docker容器认为流量的目的地本身就不会向父主机发送流量 . 如果遇到问题,请检查容器内的loopback接口:

    sudo ip addr show lo
    

    就我而言,这显示 inet 127.0.0.1/8 ,这意味着我无法在 127.* 范围内使用任何IP . 这就是我在上面的例子中使用 192.168.* 的原因 . 确保您使用的IP与您自己网络上的某些内容不冲突 .

  • 238

    对于在AWS中运行Docker的用户,主机的instance meta-data仍然可以从容器内部获得 .

    curl http://169.254.169.254/latest/meta-data/local-ipv4
    

    例如:

    $ docker run alpine /bin/sh -c "apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo"
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
    v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/alpine/v3.3/main]
    v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/alpine/v3.3/community]
    OK: 5855 distinct packages available
    (1/4) Installing openssl (1.0.2g-r0)
    (2/4) Installing ca-certificates (20160104-r2)
    (3/4) Installing libssh2 (1.6.0-r1)
    (4/4) Installing curl (7.47.0-r0)
    Executing busybox-1.24.1-r7.trigger
    Executing ca-certificates-20160104-r2.trigger
    OK: 7 MiB in 15 packages
    172.31.27.238
    
    $ ifconfig eth0 | grep -oP 'inet addr:\K\S+'
    172.31.27.238
    
  • 5

    唯一的方法是在创建容器时将主机信息作为环境传递

    run --env <key>=<value>
    
  • -4

    --add-host 可能是一个更清洁的解决方案(但没有端口部分,只有主机可以使用此解决方案处理) . 因此,在docker run命令中,执行以下操作:

    docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print  $3}'` [my container]
    

    (来自https://stackoverflow.com/a/26864854/127400

  • 0

    Docker for Mac 我想从容器连接到主机上的服务

    主机具有更改的IP地址(如果您没有网络访问权限,则为无) . 从18.03开始,我们建议连接到特殊DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址 .

    网关也可以作为gateway.docker.internal访问 . https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

  • 1

    如果您启用docker remote API(例如通过-H tcp://0.0.0.0:4243 )并知道主机的主机名或IP地址,则可以使用大量bash完成此操作 .

    在我的容器内's user' s bashrc

    export hostIP=$(ip r | awk '/default/{print $3}')
    export containerID=$(awk -F/ '/docker/{print $NF;exit;}' /proc/self/cgroup)
    export proxyPort=$(
      curl -s http://$hostIP:4243/containers/$containerID/json |
      node -pe 'JSON.parse(require("fs").readFileSync("/dev/stdin").toString()).NetworkSettings.Ports["DESIRED_PORT/tcp"][0].HostPort'
    )
    

    第二行从本地 /proc/self/cgroup 文件中获取容器ID .

    第三行卷曲到主机(假设你是're using 4243 as docker' s端口)然后使用node来解析 DESIRED_PORT 的返回JSON .

  • 78

    这是在AWS中运行Docker的人的另一个选择 . 此选项可避免使用apk添加curl包并节省宝贵的7mb空间 . 使用内置的wget(单片BusyBox二进制文件的一部分):

    wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4
    
  • 36

    在linux中你可以运行

    HOST_IP=`hostname -I | awk '{print $1}'`
    

    在macOS中,您的主机不是Docker主机 . Docker将在VirtualBox中安装它的主机操作系统 .

    HOST_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'`
    
  • 111

    如果你想要真正的 IP 地址(不是桥梁 IP )在 Windows 上你有docker 18.03 (或更近期)做以下事情:

    在主机上运行bash,映像名称为 nginx (适用于 Alpine Linux distribution ):

    docker run -it nginx /bin/ash
    

    然后在容器内运行

    / # nslookup host.docker.internal
    
    Name:      host.docker.internal
    Address 1: 192.168.65.2
    

    192.168.65.2 是主机的IP - 而不是 spinus 接受的答案中的桥接IP .

    我在这里使用host.docker.internal

    主机具有更改的IP地址(如果您没有网络访问权限,则为无) . 从18.03开始,我们建议连接到特殊DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址 . 这是出于开发目的,不适用于Docker for Windows之外的 生产环境 环境 .

  • 6

    如果在Service Fabric群集上运行Windows容器,则可以通过环境变量 Fabric_NodeIPOrFQDN 获取主机的IP地址 . Service Fabric environment variables

相关问题