赞
踩
文章初衷:
## 在网上扒了一些文章,驴头不对马嘴,废话一堆,浪费时间,索性自己沉下心来,实现一下,分享出来给大家节省时间 ##
这里我们不详细探讨其网络模式,只说问题解决方案:
详细可参考:Docker容器之网络模式
host模式
容器不会虚拟出自己网卡,配置自己的主机ip等,而是使用宿主机的ip和端口
本案例主要讲解Docker - - bridge网络模式下,容器内部获取宿主机网卡ip的方式
说明:docker-compose + bridge 模式 + java (宿主机是centos7,其他系统未测试)
注意:下面案例获取的是网卡列表中的第一个
这里因为要在容器中获取宿主机的配置,所以要把这部分的宿主机配置挂载到容器中
volumes:
- /proc:/host/proc
docker-compose.yml
version: '3' services: stone-system: image: stone-system:${TAG} container_name: stone-system environment: - TZ=Asia/Shanghai volumes: - /proc:/host/proc privileged: true restart: always pid: "host" command: - --spring.profiles.active=${PROFILE} networks: - stone_net networks: stone_net: driver: bridge ipam: config: - subnet: 172.30.0.0/16
java代码
@GetMapping("/test/q4") public void test4() { String os = System.getProperty("os.name"); if(!os.toLowerCase().startsWith("win")){ getLinuxLocalIP(); }else { getWinLocalIP(); } } private static String getWinLocalIP() { String hostAddress = "127.0.0.1"; try { Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface ni = interfaces.nextElement(); if (ni.isLoopback() || ni.isVirtual() || !ni.isUp()) { continue; } Enumeration<InetAddress> addresses = ni.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress addr = addresses.nextElement(); hostAddress = addr.getHostAddress(); if (addr.isLinkLocalAddress() || addr.isLoopbackAddress() || addr.isMulticastAddress()) { continue; } return hostAddress; } } } catch (SocketException e) { e.printStackTrace(); } return hostAddress; } private static String getLinuxLocalIP() { String ipAddress = "127.0.0.1"; // 构造命令,获取所有网卡信息,并使用grep命令过滤掉docker、veth和br-等虚拟网卡,并过滤掉状态不为up的网卡 // String command = "ip addr show | grep -v docker | grep -v veth | grep -v br- | grep 'state UP'"; String command = "nsenter --mount=/host/proc/1/ns/mnt --net=/host/proc/1/ns/net ip addr"; String c1 = command + " | grep -v docker | grep -v br- | grep -v veth | grep 'state UP'"; try { // 执行命令并获取结果 Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", c1}); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder output = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { output.append(line).append("\n"); } String ipOutput = output.toString(); // 使用awk命令提取出物理网卡的名称,并输出第一个物理网卡的IP地址 String physicalNic = executeCommand("echo \"" + ipOutput + "\" | awk '/^[0-9]/ { print $2 }' | sed 's/://' | head -n 1"); System.out.println("physicalNic: ========" + physicalNic); ipAddress = executeCommand(command + " show dev " + physicalNic + " | grep \"inet \" | awk '{print $2}' | cut -d '/' -f 1"); System.out.println("ipAddress: =========" + ipAddress); } catch (IOException e) { e.printStackTrace(); } return ipAddress; } /** * 执行指定的命令并返回结果 */ private static String executeCommand(String command) throws IOException { Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", command}); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder output = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { output.append(line).append("\n"); } return output.toString().trim(); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。