Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从docker容器中获取docker主机的IP地址_Docker_Ip - Fatal编程技术网

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

如何从docker容器中获取docker主机的IP地址,docker,ip,Docker,Ip,正如标题所说。我需要能够检索docker主机的IP地址和从主机到容器的端口映射,并在容器内执行此操作 唯一的方法是在创建容器时将主机信息作为环境传递 run --env <key>=<value> / # nslookup host.docker.internal Name: host.docker.internal Address 1: 192.168.65.2 # docker run -e VIRTUAL_HOST=<external serv

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

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

run --env <key>=<value>
/ # nslookup host.docker.internal

Name:      host.docker.internal
Address 1: 192.168.65.2
# docker run -e VIRTUAL_HOST=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0
run--env=
正如@MichaelNeale所注意到的,在
Dockerfile
中使用此方法没有意义(除非我们仅在构建期间需要此IP),因为此IP将在构建期间硬编码。

添加主机可能是一个更干净的解决方案(但没有端口部分,只有主机可以使用此解决方案处理)。因此,在您的命令中,执行以下操作:

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

如果您启用了(通过
tcp://0.0.0.0:4243
例如)并知道主机的主机名或IP地址,这可以通过大量bash来完成

在我的容器的用户的
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


第三行卷曲到主机(假设您使用4243作为docker的端口),然后使用node解析
所需\u端口的返回JSON

对于在AWS中运行docker的用户,主机的JSON仍然可以从容器内部获得

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
$ hostname -i
172.17.0.2

a) $docker机器ip

b) 获取一台或多台计算机的IP地址

  $ docker-machine ip host_name

  $ docker-machine ip host_name1 host_name2

更新:从18.03版开始,在Mac的Docker上,您可以使用主机的IP。看见对于Docker For Mac的早期版本,以下答案可能仍然有用:

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

ipconfig getifaddr en0
这将显示Mac在其当前网络上的IP,docker容器也应该能够连接到此地址。如果此IP地址发生更改,这当然是一件痛苦的事情,但您可以通过在父计算机上执行类似操作,将容器认为不属于自己的自定义环回IP添加到Mac:

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。使用完此IP后,可以删除环回别名,如下所示:

sudo ifconfig lo0 -alias 192.168.46.49
需要注意的一件事是,如果docker容器认为流量的目的地是它自己,它就不会向父主机发送流量。因此,如果遇到问题,请检查容器内的环回接口:

sudo ip addr show lo

在我的例子中,这显示了
inet 127.0.0.1/8
,这意味着我不能使用
127.*
范围内的任何IP。这就是为什么我在上面的例子中使用了
192.168.*
。确保您使用的IP与您自己网络上的某个IP不冲突。

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

适用于Mac的Docker
适用于Windows的Docker,也可能适用于其他平台

这是从版本17.06起提供的Mac专用
docker.for.Mac.localhost
,以及版本17.12起提供的
docker.for.Mac.host.internal
,也可能在该平台上工作

注意,正如在和文档中一样,这仅用于开发目的

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

MONGO_SERVER=host.docker.internal
在我的
docker compose.yml
文件中,我有以下内容:

版本:“3”
服务:
应用程序编程接口:
构建:./api
卷数:
-/api:/usr/src/app:ro
端口:
- "8000"
环境:
-MONGO_服务器
命令:/usr/local/bin/gunicorn-c/usr/src/app/gunicorn_config.py-w 1-b:8000 wsgi

对于在AWS中运行Docker的用户,这里有另一个选项。此选项避免了使用apk添加curl包,并节省了宝贵的7mb空间。使用内置wget(单片总线箱二进制文件的一部分):


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

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

网关也可以通过gateway.docker.internal访问。

如果您在服务结构群集上运行Windows容器,则主机的IP地址可通过环境变量
Fabric\u NodeIPOrFQDN
获得

在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'/.$//'`

我是这样做的。在本例中,它在docker映像内的/etc/hosts中添加一个hosts条目,将taurus主机指向我的本地机器IP::

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

然后,在Docker容器内,脚本可以使用主机名taurus host进入托管Docker容器的本地计算机。

如果您希望在
Windows
上获得真实的
IP
地址(而不是网桥
IP
),并且您拥有Docker
18.03
(或更近版本),请执行以下操作:

curl http://169.254.169.254/latest/meta-data/local-ipv4
从映像名为
nginx
的主机在容器上运行bash(适用于
Alpine Linux发行版
):

然后在容器内运行

run --env <key>=<value>
/ # nslookup host.docker.internal

Name:      host.docker.internal
Address 1: 192.168.65.2
# docker run -e VIRTUAL_HOST=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0
192.168.65.2
是主机的IP,而不是像
spinus
中那样的网桥IP

我在这里使用:
# docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
# docker run -e VIRTUAL_HOST=ipify.example.com --detach --name ipify osixia/ipify-api:0.1.0
# curl http://ipify.example.com
10.20.30.40
$ hostname -i
172.17.0.2
IP=$(hostname -i)
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
docker run --rm --net host busybox /bin/sh -c \
  "ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'"
getent hosts host.docker.internal | awk '{print $1}'
docker run --add-host host.docker.internal:host-gateway ...
curl http://169.254.169.254/latest/meta-data/local-ipv4
curl ifconfig.co
export HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
docker run --rm -e HOST_IP busybox printenv HOST_IP
docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print  $3}'` [image]
docker run --add-host dockerhost:`docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge` [image]
docker run -it --rm alpine nslookup host.docker.internal
nslookup: can't resolve '(null)': Name does not resolve

Name:      host.docker.internal
Address 1: 192.168.65.2
ifconfig
# 1. Run an ubuntu docker
# 2. Updates dependencies (quietly)
# 3. Install ip package   (quietly)
# 4. Shows (nicely) the ip of the host
# 5. Removes the docker (thanks to `--rm` arg)
docker run -it --rm ubuntu:20.10 bash -c "apt-get update > /dev/null && apt-get install iproute2 -y > /dev/null && ip -4 route show default | cut -d' ' -f3"
docker run --rm -i --net=host alpine ifconfig
docker network inspect bridge -f '{{range .IPAM.Config}}{{.Gateway}}{{end}}'