You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EMR on EKS的Flink Docker镜像启动SQL客户端失败求助

解决EMR on EKS Flink镜像启动SQL客户端时的端口获取失败问题

问题现象

使用EMR on EKS提供的Flink镜像public.ecr.aws/emr-on-eks/flink/emr-6.15.0-flink:latest启动SQL客户端时,抛出端口获取失败的异常,官方Flink镜像无此问题:

06:33:00.495 [main] ERROR org.apache.flink.table.client.SqlClient - SQL Client must stop. Unexpected exception. This is a bug. Please consider filing an issue.
java.lang.RuntimeException: Could not find a free permitted port on the machine.
        at org.apache.flink.util.NetUtils.getAvailablePort(NetUtils.java:177) ~[flink-dist-1.17.1-amzn-1.jar:1.17.1-amzn-1]
        at org.apache.flink.table.client.SqlClient$EmbeddedGateway.create(SqlClient.java:257) ~[flink-sql-client-1.17.1-amzn-1.jar:1.17.1-amzn-1]
        at org.apache.flink.table.client.SqlClient.start(SqlClient.java:108) ~[flink-sql-client-1.17.1-amzn-1.jar:1.17.1-amzn-1]
        at org.apache.flink.table.client.SqlClient.startClient(SqlClient.java:228) [flink-sql-client-1.17.1-amzn-1.jar:1.17.1-amzn-1]
        at org.apache.flink.table.client.SqlClient.main(SqlClient.java:179) [flink-sql-client-1.17.1-amzn-1.jar:1.17.1-amzn-1]
Exception in thread "main" org.apache.flink.table.client.SqlClientException: Unexpected exception. This is a bug. Please consider filing an issue.
        at org.apache.flink.table.client.SqlClient.startClient(SqlClient.java:242)
        at org.apache.flink.table.client.SqlClient.main(SqlClient.java:179)
Caused by: java.lang.RuntimeException: Could not find a free permitted port on the machine.
        at org.apache.flink.util.NetUtils.getAvailablePort(NetUtils.java:177)
        at org.apache.flink.table.client.SqlClient$EmbeddedGateway.create(SqlClient.java:257)
        at org.apache.flink.table.client.SqlClient.start(SqlClient.java:108)
        at org.apache.flink.table.client.SqlClient.startClient(SqlClient.java:228)
        ... 1 more

问题根源

异常由NetUtils.getAvailablePort()方法导致:该方法循环50次尝试获取随机可用端口,同时为端口创建FileLock防止冲突。如果无法成功创建FileLock(比如临时目录权限不足、被容器安全策略限制),就会抛出异常。

public static Port getAvailablePort() {
    for (int i = 0; i < 50; i++) {
        try (ServerSocket serverSocket = new ServerSocket(0)) {
            int port = serverSocket.getLocalPort();
            if (port != 0) {
                FileLock fileLock = new FileLock(NetUtils.class.getName() + port);
                if (fileLock.tryLock()) {
                    return new Port(port, fileLock);
                } else {
                    fileLock.unlockAndDestroy();
                }
            }
        } catch (IOException ignored) {
        }
    }

    throw new RuntimeException("Could not find a free permitted port on the machine.");
}

尽管相关工单提到修改文件权限可解决,但部分场景下该方案无效,核心问题在于容器内/tmp目录的FileLock操作被限制。

解决方案

1. 手动指定SQL客户端网关端口

绕过自动端口检测逻辑,直接指定一个确定可用的端口:

  • 启动SQL客户端时添加参数:
    ./sql-client.sh embedded -Dsql-client.gateway.port=8083
    
  • 或者在flink-conf.yaml中配置固定端口:
    sql-client.gateway.port: 8083
    
    注意选择未被占用的端口,避开Flink默认的8081、8082等端口。

2. 切换自定义临时目录

确保临时目录有足够的读写权限,且不受容器安全策略限制:

  • 启动容器时挂载主机临时目录到容器内:
    docker run -v /host/your-tmp-dir:/container-tmp -e TMPDIR=/container-tmp public.ecr.aws/emr-on-eks/flink/emr-6.15.0-flink:latest ./sql-client.sh
    
  • 或者启动SQL客户端时通过JVM参数指定临时目录:
    ./sql-client.sh embedded -Djava.io.tmpdir=/container-tmp
    
    确保目录对容器内运行的用户拥有读写执行权限。

3. 检查容器权限与安全策略

  • 进入容器查看当前用户及/tmp目录权限:
    docker exec -it <container-id> whoami
    docker exec -it <container-id> ls -ld /tmp
    
    确保用户对/tmp有读写权限。
  • 如果是K8s环境,检查Pod的securityContext配置:
    • 若readOnlyRootFilesystem设为true,需挂载emptyDir到/tmp目录:
      securityContext:
        readOnlyRootFilesystem: true
      volumes:
        - name: tmp-dir
          emptyDir: {}
      volumeMounts:
        - name: tmp-dir
          mountPath: /tmp
      
    • 检查是否有容器安全策略限制了文件锁操作。

4. 临时调整端口重试次数(不推荐)

如果有能力修改镜像,可以修改NetUtils.getAvailablePort()方法中的循环次数(比如从50改为100),增加成功概率,但这只是临时 workaround,优先使用前面的方案。


内容的提问来源于stack exchange,提问作者Jaehyeon Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:57:37