繁体   English   中英

如何从 Docker 容器内部访问 IFCONFIG 的网络地址?

[英]How to access network address from IFCONFIG from inside a Docker Container?

我正在为超级账本 aca-py 代理使用 docker 容器,对于一个项目,我需要机器的网络地址用于 Internet 网络,它当前连接到。 要在 python 中访问 IFCONFIG,我在 Python 中使用“netifaces”库。 以下代码行在代理的 docker 容器之外运行良好,但在容器中运行时,它显示错误。 为什么会这样?

import netifaces as ni

...

net_add = ni.ifaddresses('wlp4s0')[2][0]['addr']
request_obj = requests.get('http://' + str(net_add) + ':8080/api/some_endpoint'))

错误信息 :

Shutting down agent ...
Faber      | 
Faber      | Shutting down
Faber      | Exited with return code 0
Traceback (most recent call last):
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/indy/demo/runners/university.py", line 803, in <module>
    asyncio.get_event_loop().run_until_complete(main(args))
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/asyncio/base_events.py", line 488, in run_until_complete
    return future.result()
  File "/home/indy/demo/runners/university.py", line 544, in main
    rll,
  File "/home/indy/demo/runners/university.py", line 82, in generate_credential_offer
    net_add = ni.ifaddresses('wlp4s0')[2][0]['addr']
ValueError: You must specify a valid interface name.

Docker 容器看不到主机网络接口或其他设置。 这是设计使然。 一个容器只能看到它的 Docker-private 网络设置,虽然 Docker 提供了一个 NAT 设置来建立出站连接,但一个容器无法找到主机的 IP 地址,或者它有哪些接口,或者通过名称查找主机接口.

作为操作员,您需要自己确定和注入这些信息。 在 docker-compose 中使用主机 ip建议如下配方:

# your_app.py
external_ip = os.environ['EXTERNAL_IP']
requests.get('http://' + external_ip + ':8080/api/some_endpoint')
# docker-compose.yml
services:
  your-app:
    environment:
      - EXTERNAL_IP # with no value, passed through from host
# at the shell prompt
export EXTERNAL_IP=$(hostname -I | awk '{print $1}')
docker-compose up -d

hostname -I调用可能是错误的! 但是以编程方式了解这一点几乎是不可能的。


让我们考虑一个在我当前系统上运行的容器。 该容器有一个 IP 地址; 说它是 172.17.0.2/16。 但这不是一个可路由的地址,它位于 Docker 私有 IP 空间内。 如果我可以查看它的主机环境,我会发现一个 IP 地址 192.168.65.3/24。 但那是 Docker Desktop Linux VM,而且该 IP 地址也不能路由。 如果我能跳出来,真正的物理主机的 IP 地址是 192.168.149.120/24; 但这也不是可路由的,它在我的家庭网络上。 我需要与路由器交谈以找到一个实际可路由的 Internet 可见 IP 地址,我的本地系统上根本不知道它。

+--------------------+          +-------------------------------+
|      192.168.149.1 |          | Host          192.168.149.120 |
|                    |          | +---------------------------+ |
|       Router       |          | | Docker VM    192.168.65.3 | |
|                    | <------- | | +-----------------------+ | |
|                    |          | | | Container  172.17.0.2 | | |
|                    |          | | +-----------^-----------+ | |
| 66.77.88.99        |          | +-------------|-------------+ |
+------^-------------+          +---------------|---------------+
       |                                        |
You need this address                  You are actually here

您可以想象其他网络环境,这会更加复杂。 在 Kubernetes 中,Pod 有一个 IP 地址,但您通常不使用它; 相反,客户端发送到转发到 Pod 的服务。 您可以通过内容交付网络运行基于 HTTP 的应用程序,其中您要发布的 URL 是 CDN 的 DNS 名称,而不是您环境中的任何内容。


禁用 Docker 网络可能会起作用,要么使用docker run --net host运行容器,要么在 Compose 中使用network_mode: host 这会禁用一些关键的 Docker 功能,因此您不能使用其他容器的名称作为主机名,也不能隐藏或重新映射应用程序的端口。 如果您在 Docker 桌面环境中(不是在本机 Linux 上),那么您将看到 Linux VM 的网络环境,它仍然不是主机环境。 同样,即使您确实获得了物理主机的网络接口,也不能保证它实际上会有一个可路由的 IP 地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM