簡體   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