如标题所示。我需要能够检索Docker主机的IP地址和从主机到容器的端口映射,并在容器内部进行操作。
如标题所示。我需要能够检索Docker主机的IP地址和从主机到容器的端口映射,并在容器内部进行操作。
Answers:
/sbin/ip route|awk '/default/ { print $3 }'
正如@MichaelNeale注意到的那样,没有必要使用此方法Dockerfile
(除非仅在构建时需要此IP),因为此IP将在构建时进行硬编码。
从版本18.03开始,您可以host.docker.internal
用作主机的IP。
工程在码头工人的Mac,多克尔用于Windows,也许其他平台以及。
这是Mac特定docker.for.mac.localhost
版本的更新,自版本17.06起提供,并且docker.for.mac.host.internal
自版本17.12起提供,也可以在该平台上使用。
请注意,与Mac和Windows文档中一样,这仅用于开发目的。
例如,我在主机上设置了环境变量:
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
docker.for.mac..
是没有用的,因为在大多数情况下,您公司中没有仅Linux或Mac的环境。混合使用,您有使用Linux,Mac和Windows的开发人员。该域没有意义,因为在99%的环境中,它是一个混合的Host OS环境。我不会在macOS下开发容器并将其部署到macOS服务器。我将其部署到Linux。这就是每个人都在做的。那么,整个意义docker.for.mac..
何在?
docker.for.mac.host.internal
不管是否使用Docker都无关紧要docker-compose
。我想在配置文件中使用固定主机。例如IDK,docker.host.internal
它始终指向主机IP地址。不管我使用哪个主机系统。这就是使用Docker的全部要点:我想自治。我知道这在macOS上更加棘手,因为主机系统和容器之间还有另一层。但是无论如何,docker.for.mac.host.internal
如果您只能将其用于macOS ,我认为这是没有用的。
更新:在Mac的Docker(版本18.03)上,您可以使用host.docker.internal作为主机的IP。请参阅allanberry的答案。对于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不冲突。
对于在AWS中运行Docker的用户,仍可以从容器内部获得主机的实例元数据。
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
ifconfig eth0 | grep -oP 'inet \K\S+'
唯一的方法是在创建容器时将主机信息作为环境传递
run --env <key>=<value>
-e "DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')"
使用从unix.stackexchange.com/questions/87468/…接受的答案)
这--add-host
可能是更干净的解决方案(但如果没有端口部分,则只能使用此解决方案来处理主机)。因此,在您的docker run
命令中,执行以下操作:
docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container]
对于大多数希望自动执行此操作的应用程序,标准的最佳做法是:不这样做。相反,让运行容器的人员注入外部主机名/ IP地址作为配置,例如作为环境变量或配置文件。允许用户注入它可以为您提供最便携的设计。
为什么这会这么困难?因为容器将通过设计将应用程序与主机环境隔离。默认情况下,网络仅将名称空间指定为该容器,并且主机的详细信息受到保护,以防止容器中运行的进程可能无法完全信任该进程。
根据您的具体情况,有不同的选择:
如果您的容器通过主机网络运行,则可以直接查看主机上的路由表以查看默认路由。根据这个问题,以下对我有用:
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'"
对于某些版本的Docker Desktop,他们将DNS条目注入了嵌入式VM:
getent hosts host.docker.internal | awk '{print $1}'
如果您在云环境中运行,则可以从云提供商(例如AWS提供商)检查元数据服务:
curl http://169.254.169.254/latest/meta-data/local-ipv4
如果您想使用外部/互联网地址,则可以查询远程服务,例如:
curl ifconfig.co
这些中的每一个都有局限性,并且仅在特定情况下有效。最可移植的选项仍然是使用注入的IP地址作为配置来运行容器,例如,以下是ip
在主机上运行较早的命令并将其作为环境变量注入的选项:
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
curl ifconfig.co
命令..谢谢:)
如果您要使用真实IP
地址(而不是bridge 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地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是出于开发目的,不适用于Docker for Windows之外的生产环境。
Alpine Linux
吗?如果不是,则检查与您的具体情况相同的项目linux distribution
。
linux containers
我而不在使用windows containers
。可以通过右键单击,docker icon
然后选择来执行此操作Switch to Linux containers
。我认为这在下载图像时可能很重要。如果您windows container
检查是否删除了旧nginx
图像并再次下载,将为您提供另一个容器。如果它对您仍然不起作用-那么您可以尝试安装nslookup
在ash
。
host.docker.internal
在容器内部使用此主机名()
docker run -it --rm alpine nslookup host.docker.internal
...打印主机的IP地址...
nslookup: can't resolve '(null)': Name does not resolve
Name: host.docker.internal
Address 1: 192.168.65.2
在Mac和Windows上,可以使用特殊的DNS名称host.docker.internal
。
主机的IP地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是出于开发目的,不适用于Docker Desktop for Mac以外的生产环境。
Mac版Docker 我想从容器连接到主机上的服务
主机的IP地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。
网关也可以通过gateway.docker.internal访问。 https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
如果启用了docker远程API(例如,通过)并且知道主机的主机名或IP地址,则可以通过大量的bash来完成。-H
tcp://0.0.0.0:4243
在我容器的用户内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解析返回的JSON DESIRED_PORT
。
HostPort
这里确实有用的信息,不幸的是,HostIp
可能是0.0.0.0
我有Ubuntu 16.03。为了我
docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [image]
它不工作(错误的IP被生成)
我的工作解决方案是:
docker run --add-host dockerhost:`docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge` [image]
AFAIK,对于适用于Linux的Docker(标准发行版),主机的ip地址始终为 172.17.0.1
。
最简单的方法是ifconfig
从主机通过(docker0接口):
ifconfig
在泊坞窗内部,泊坞窗的以下命令: ip -4 route show default | cut -d" " -f3
您可以使用以下命令行在docker中快速运行它:
# 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:19.10 bash -c "apt-get update && apt-get install iproute2 -y && ip -4 route show default | cut -d' ' -f3"
希望对您有所帮助。
在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'/.$//'`
hostname -I
发出警告,不要“对输出顺序做任何假设”。
这是Node.js中的一个简约实现,使用上面提到的EC2元数据实例,可以由谁在AWS EC2实例上运行主机。
const cp = require('child_process');
const ec2 = function (callback) {
const URL = 'http://169.254.169.254/latest/meta-data/local-ipv4';
// we make it silent and timeout to 1 sec
const args = [URL, '-s', '--max-time', '1'];
const opts = {};
cp.execFile('curl', args, opts, (error, stdout) => {
if (error) return callback(new Error('ec2 ip error'));
else return callback(null, stdout);
})
.on('error', (error) => callback(new Error('ec2 ip error')));
}//ec2
并用作
ec2(function(err, ip) {
if(err) console.log(err)
else console.log(ip);
})
如果您在Service Fabric群集上运行Windows容器,则可以通过环境变量使用主机的IP地址Fabric_NodeIPOrFQDN
。Service Fabric环境变量
也许我创建的容器也很有用https://github.com/qoomon/docker-host
您可以简单地使用容器名称dns来访问主机系统,例如curl http:// dockerhost:9200,因此无需麻烦使用任何IP地址。
我使用的解决方案基于一个“服务器”,该服务器在收到http请求时会返回Docker主机的外部地址。
在“服务器”上:
1)启动jwilder / nginx-proxy
# docker run -d -p <external server port>:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
2)启动ipify容器
# docker run -e VIRTUAL_HOST=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0
现在,当容器将http请求发送到服务器时,例如
# curl http://<external server name/address>:<external server port>
ipify通过HTTP标头“ X-Forwarded-For”返回Docker主机的IP地址
示例(ipify服务器的名称为“ ipify.example.com”并在端口80上运行,泊坞窗主机的IP为10.20.30.40):
# 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
尝试这个
docker运行--rm -i --net = host alpine ifconfig
在Ubuntu上,hostname
命令可以与以下选项一起使用:
-i
,--ip-address
主机名的地址-I
,--all-ip-addresses
主机的所有地址例如:
$ hostname -i
172.17.0.2
要分配给变量,可以使用以下单线:
IP=$(hostname -i)
使用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