dolphinscheduler icon indicating copy to clipboard operation
dolphinscheduler copied to clipboard

[Improvement] [Doc] Failure to identify IPv6 addresses properly

Open qingzhongli opened this issue 4 months ago • 3 comments

Search before asking

  • [x] I had searched in the issues and found no similar issues.

What happened

Following https://dolphinscheduler.apache.org/zh-cn/docs/3.2.2/architecture/configuration, after adding the -Djava.net.preferIPv6Addresses=true, worker and master failed to correctly recognize the network interface's IPv6 address.

  • network interface
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:90:be:20:6a  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.164.100  netmask 255.255.255.0  broadcast 192.168.164.255
        inet6 fd15:4ba5:5a2b:1008:71bc:dd01:e661:e831  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::20c:29ff:feac:72e7  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:ac:72:e7  txqueuelen 1000  (Ethernet)
        RX packets 1838  bytes 264563 (258.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1555  bytes 426863 (416.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 2219  bytes 451669 (441.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2219  bytes 451669 (441.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • worker
****************************Worker Configuration**************************************
  listen-port -> 1234
  exec-threads -> 10
  max-heartbeat-interval -> PT10S
  host-weight -> 100
  tenantConfig -> TenantConfig(autoCreateTenantEnabled=true, distributedTenantEnabled=false, defaultTenantEnabled=true)
  server-load-protection -> BaseServerLoadProtection(enabled=true, maxSystemCpuUsagePercentageThresholds=0.9, maxJvmCpuUsagePercentageThresholds=0.9, maxSystemMemoryUsagePercentageThresholds=0.9, maxDiskUsagePercentageThresholds=0.9)
  registry-disconnect-strategy -> ConnectStrategyProperties(strategy=STOP, maxWaitingTime=PT0S)
  task-execute-threads-full-policy: REJECT
  address -> 127.0.0.1:1234
  registry-path: /nodes/worker/127.0.0.1:1234
****************************Worker Configuration**************************************
  • master
****************************Master Configuration**************************************
  listen-port -> 5678
  pre-exec-threads -> 10
  exec-threads -> 10
  dispatch-task-number -> 3
  host-selector -> LOWER_WEIGHT
  max-heartbeat-interval -> PT10S
  task-commit-retry-times -> 5
  task-commit-interval -> PT1S
  state-wheel-interval -> PT5S
  server-load-protection -> BaseServerLoadProtection(enabled=true, maxSystemCpuUsagePercentageThresholds=0.9, maxJvmCpuUsagePercentageThresholds=0.9, maxSystemMemoryUsagePercentageThresholds=0.9, maxDiskUsagePercentageThresholds=0.9)
  failover-interval -> PT10M
  kill-application-when-task-failover -> true
  registry-disconnect-strategy -> ConnectStrategyProperties(strategy=STOP, maxWaitingTime=PT0S)
  master-address -> 127.0.0.1:5678
  master-registry-path: /nodes/master/127.0.0.1:5678
  worker-group-refresh-interval: PT10S
  command-fetch-strategy: CommandFetchStrategy(type=ID_SLOT_BASED, config=CommandFetchStrategy.IdSlotBasedFetchConfig(idStep=1, fetchSize=10))
****************************Master Configuration**************************************

What you expected to happen

Worker and master correctly recognize the network interface's IPv6 address.

  • worker
****************************Worker Configuration**************************************
  listen-port -> 1234
  exec-threads -> 10
  max-heartbeat-interval -> PT10S
  host-weight -> 100
  tenantConfig -> TenantConfig(autoCreateTenantEnabled=true, distributedTenantEnabled=false, defaultTenantEnabled=true)
  server-load-protection -> BaseServerLoadProtection(enabled=true, maxSystemCpuUsagePercentageThresholds=0.9, maxJvmCpuUsagePercentageThresholds=0.9, maxSystemMemoryUsagePercentageThresholds=0.9, maxDiskUsagePercentageThresholds=0.9)
  registry-disconnect-strategy -> ConnectStrategyProperties(strategy=STOP, maxWaitingTime=PT0S)
  task-execute-threads-full-policy: REJECT
  address -> [fd15:4ba5:5a2b:1008:71bc:dd01:e661:e831]:1234
  registry-path: /nodes/worker/[fd15:4ba5:5a2b:1008:71bc:dd01:e661:e831]:1234
****************************Worker Configuration**************************************
  • master
****************************Master Configuration**************************************
  listen-port -> 5678
  pre-exec-threads -> 10
  exec-threads -> 10
  dispatch-task-number -> 3
  host-selector -> LOWER_WEIGHT
  max-heartbeat-interval -> PT10S
  task-commit-retry-times -> 5
  task-commit-interval -> PT1S
  state-wheel-interval -> PT5S
  server-load-protection -> BaseServerLoadProtection(enabled=true, maxSystemCpuUsagePercentageThresholds=0.9, maxJvmCpuUsagePercentageThresholds=0.9, maxSystemMemoryUsagePercentageThresholds=0.9, maxDiskUsagePercentageThresholds=0.9)
  failover-interval -> PT10M
  kill-application-when-task-failover -> true
  registry-disconnect-strategy -> ConnectStrategyProperties(strategy=STOP, maxWaitingTime=PT0S)
  master-address -> [fd15:4ba5:5a2b:1008:71bc:dd01:e661:e831]:5678
  master-registry-path: /nodes/master/[fd15:4ba5:5a2b:1008:71bc:dd01:e661:e831]:5678
  worker-group-refresh-interval: PT10S
  command-fetch-strategy: CommandFetchStrategy(type=ID_SLOT_BASED, config=CommandFetchStrategy.IdSlotBasedFetchConfig(idStep=1, fetchSize=10))
****************************Master Configuration**************************************

How to reproduce

  1. adding the -Djava.net.preferIPv6Addresses=true
  2. set dolphin.scheduler.network.interface.preferred to ens33 which is bound an IPv6 address
  3. start dolphinscheduler

Anything else

No response

Version

dev

Are you willing to submit PR?

  • [x] Yes I am willing to submit a PR!

Code of Conduct

qingzhongli avatar Aug 19 '25 01:08 qingzhongli

We should add it to docs instead of code since only a few users will use ipv6.

SbloodyS avatar Aug 19 '25 02:08 SbloodyS

Seems we have incorrect filter logic in NetUtils.

ruanwenjun avatar Aug 26 '25 03:08 ruanwenjun

Seems we have incorrect filter logic in NetUtils.

Yes. Perhaps there are three points that need adjustment, as follows:

  1. The isValidV6Address method in the NetUtils class should support IPv6 addresses with scope identifiers (e.g., fd15:4ba5:5a2b:1008:71bc:dd01:e661:e831%ens33) and exclude link-local addresses. Maybe like this:
    protected static boolean isValidV6Address(InetAddress address) {
        if (!(address instanceof Inet6Address)) {
            return false;
        }
        String name = address.getHostAddress();
        // remove scope
        int i = name.indexOf('%');
        if (i > 0) {
            name = name.substring(0, i);
        }
        return (name != null
                && InetAddressUtils.isIPv6Address(name)
                && !address.isAnyLocalAddress()
                && !address.isLoopbackAddress()
                && !address.isLinkLocalAddress());
    }
  1. The getIpv6Addresses method in the NetUtils class should remove scope identifiers from IPv6 addresses when they contain scope identifiers. Maybe like this:
    private static List<InetAddress> getIpv6Addresses(List<InetAddress> allInetAddresses) {
        if (CollectionUtils.isEmpty(allInetAddresses)) {
            return Collections.emptyList();
        }
        List<InetAddress> validIpv6Addresses = new ArrayList<>();
        for (InetAddress inetAddress : allInetAddresses) {
            if (!isValidV6Address(inetAddress)) {
                continue;
            }
            Inet6Address v6Address = (Inet6Address) inetAddress;
            InetAddress removedScopeV6Address = removeV6AddressScope(v6Address);
            validIpv6Addresses.add(removedScopeV6Address);
        }
        return validIpv6Addresses;
    }

    private static InetAddress removeV6AddressScope(Inet6Address address) {
        String addr = address.getHostAddress();
        int i = addr.lastIndexOf('%');
        if (i > 0) {
            try {
                return InetAddress.getByName(addr.substring(0, i));
            } catch (UnknownHostException e) {
                log.debug("Unknown IPV6 address: ", e);
            }
        }
        return address;
    }
  1. The getAddr method in the NetUtils class should add brackets for IPv6 address. Maybe like this:
    public static String getAddr(String host, int port) {
        if(InetAddressUtils.isIPv6Address(host)) {
            return String.format("[%s]:%d", host, port);
        }
        return String.format("%s:%d", host, port);
    }

qingzhongli avatar Aug 26 '25 04:08 qingzhongli