Skip to content

懒猫微服实战入门(二十八):如何获取懒猫微服的私有地址

在日常使用 懒猫微服(LazyCat Micro-Service) 的过程中,我们习惯于使用域名访问。如果你经常使用其他 NAS,就会问这个问题:如何知道一台机器在局域网里的私有地址?

很多朋友刚接触 NAS、Docker 或容器化环境时,都会觉得 IP 地址这种东西似乎理所当然。但等你真的要远程访问、配置代理或者排查网络时,就会发现,知道机器的私有地址是一件非常关键的事。

举几个典型的场景:

  • 想通过 SSH、HTTP 等方式访问运行在懒猫微服上的服务;

  • 需要进行 端口转发 或者把服务 内网穿透到公网;

  • Dockge 里启动容器后,访问的时候必须指定 IP 地址,否则反向代理会失败;

  • 排查网络时,需要确认到底是哪一个 IP 地址在被使用。

    换句话说,掌握如何获取私有地址,可以来排除一些域名上转发损失的问题。


image-20250928201444075

虽然在客户端中可以看到网络地址,但是有阵子我修改 br-lan 网桥之后这里就不再显示了。所以才想了个办法来记录网络地址。下面将结合 Python 代码,介绍几种常见的获取私有地址的方法。

下面我会结合 Python 代码和一些常见的工具,介绍几种获取私有地址的常见做法,并分析它们的优缺点。


1. 为什么是“私有地址”

首先我们要搞清楚:什么是 私有地址

私有地址是 RFC1918 标准定义的局域网网段,常见的有:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

这些 IP 地址不会直接出现在公网,而是专门留给局域网使用。比如:

  • 你家路由器分配给手机的 192.168.31.2
  • NAS 设备的 192.168.1.103
  • Docker 创建虚拟网络时分配的 172.18.0.2

所以,获取懒猫微服的“私有地址”,本质上就是找到它在局域网环境下的真实 IP。只有掌握了这个 IP,才能在排查问题的时候得心应手。


2. 最常用的快速方法:socket 连接法

在 Python 里,用 socket 模块就能很快拿到主要的私有 IP 地址。代码如下:

python
import socket

def get_primary_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # 不会真的发请求,只是借助路由表选择出网口
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    except Exception:
        ip = '127.0.0.1'
    finally:
        s.close()
    return ip

print(get_primary_ip())

运行后,输出大概是:

192.168.1.2

这就是懒猫微服当前在局域网里的主要出网地址。

image-20250928201025268

原理说明

  • 代码里 s.connect(('8.8.8.8', 80)) 看似是去连接 Google 的 DNS,其实并不会真正发起网络请求;
  • 系统只是会查一遍路由表,决定要走哪个网卡出去;
  • 然后 getsockname() 返回的就是这个网卡对应的本地 IP。

优缺点

  • 优点:跨平台通用,代码简洁,结果非常准确。
  • 缺点:依赖于有路由表,如果设备完全没有网络,可能就会返回 127.0.0.1

这种方法非常适合:家用网络 / 有默认出网口 / 多网卡机器


3. 另一种简单写法(但容易踩坑)

很多人还会写成:

python
import socket
print(socket.gethostbyname(socket.gethostname()))

这段代码通过 主机名解析 来获取 IP 地址,看似简单,但问题不少:

  • 在很多系统里,它直接返回 127.0.0.1
  • 依赖 /etc/hosts 或 DNS 配置,如果没配好,就会失效;
  • 在复杂网络环境下,很可能并不是你真正想要的地址。

所以,这种方法虽然一行就能搞定,但更适合在 主机名规范配置过的服务器,不太推荐在 NAS、容器、虚拟机这些环境里依赖。


4. 列出所有网卡的地址

如果环境比较复杂,比如同时有 Wi-Fi、以太网、虚拟网卡、容器网桥,只拿一个主要地址就不够了。这时候就需要直接列出所有接口的 IP,再从中筛选。

使用 ifaddr

安装:

bash
pip install ifaddr --root-user-action=ignore

代码:

python
import ifaddr

adapters = ifaddr.get_adapters()
for adapter in adapters:
    for ip in adapter.ips:
        print(f"{adapter.nice_name}: {ip.ip}")

输出是:

eth0: 192.168.5.203
docker0: 172.17.0.1
lo: 127.0.0.1

image-20250928201227351


使用 psutil

psutil 是更常见的运维库,信息更全面:

bash
pip install psutil --root-user-action=ignore

代码:

python
import psutil, socket

addrs = psutil.net_if_addrs()
for iface, addr_list in addrs.items():
    for addr in addr_list:
        if addr.family == socket.AF_INET:
            print(f"{iface}: {addr.address}")

输出会展示每一个网卡的 IPv4 地址:

image-20250928201319011

适合在 虚拟化/容器/复杂网络环境 中使用。


5. 如何区分私有地址与公网地址

如果列出来的地址很多,还混杂了公网 IP,怎么办?可以用 ipaddress 模块过滤:

python
import ipaddress

def is_private(ip):
    return ipaddress.ip_address(ip).is_private

print(is_private("192.168.5.203"))  # True
print(is_private("8.8.8.8"))        # False

这样就能快速区分哪些是真正的私有地址,避免混淆。

image-20250928202150762


6. 实战场景举例

说了这么多,回到实际应用。获取私有地址到底能帮我们解决什么?

  1. 为容器配置反向代理 在 Caddyfile 中写:

    reverse_proxy http://192.168.1.2:11434

    就必须确认 192.168.5.203 真的是懒猫微服的地址。

  2. 跨设备访问服务 想用手机访问 NAS 提供的 Web 服务 http://192.168.1.2:8080,也必须提前知道 IP。

  3. 排查网络问题 当遇到容器内服务报错(403、502)时,确认是不是反向代理到了错误的 IP,就靠这一步。


7. 方法对比表

方法示例代码优点缺点适用场景
UDP 连接法s.connect(('8.8.8.8', 80))跨平台、常用、结果准确需有路由/网络获取主要私有地址
主机名解析gethostbyname(gethostname())简单,一行搞定常返回 127.0.0.1,依赖配置主机名已配置正确
ifaddrifaddr.get_adapters()列出所有接口,跨平台需安装库多网卡、容器环境
psutilpsutil.net_if_addrs()常见运维库,信息全面需安装库系统监控、诊断
ipaddressip_address(ip).is_private能区分公网/私网需结合其他方法过滤私有地址

总结

获取懒猫微服的私有地址,其实就是获取机器在局域网里的 IP。

  • 快速场景:用 socket + 8.8.8.8 方法,几乎百分百靠谱;
  • 一行写法gethostbyname(gethostname()),但要注意经常只会返回 127.0.0.1
  • 复杂环境:用 ifaddrpsutil 列出所有接口,再结合 ipaddress 做筛选。

掌握这些方法,你就能在 部署服务、调试容器、配置代理 时快速定位到懒猫微服的真实 IP,避免因为地址不明导致的各种问题。

以后无论是写 Caddyfile 配置、手机访问 NAS 服务,还是排查 403/502 错误,你都能从容地第一时间确认:**我的懒猫微服,到底在哪个 IP 上运行。

❤️喜欢