Java ProcessBuilder执行kubectl端口转发与psql命令无法连接数据库
环境信息
操作系统:DISTRIB_ID=Ubuntu DISTRIB_RELEASE=20.04
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
psql:psql (PostgreSQL) 12.20 (Ubuntu 12.20-0ubuntu0.20.04.1)
Java:openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment (build 11.0.24+8-post-Ubuntu-1ubuntu320.04)
OpenJDK 64-Bit Server VM (build 11.0.24+8-post-Ubuntu-1ubuntu320.04, mixed mode, sharing)
命令行验证
在命令行执行以下两条命令可正常获取数据(当前用户无密码):
kubectl port-forward service/service-name 7432:5432 psql -h localhost -p 7432 -U username -d database -w -t -c "select id from foo.bar where id='1'"
实现代码
端口转发方法
public static Process portForward(String type, String deploymentName, String containerPort, String localPort) { Predicate<Process> readyPredicate = Objects::nonNull; String command = "kubectl port-forward " + type + "/" + deploymentName + " " + containerPort + ":" + localPort; ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash", "-c", command); Process process; try { process = processBuilder.start(); final Thread thread = new Thread(process::destroyForcibly); Runtime.getRuntime().addShutdownHook(thread); } catch (IOException e) { throw new RuntimeException(e); } if (!readyPredicate.test(process)) { final String errorMsg = String.format("Deployment '" + deploymentName + "' was not ready"); throw new IllegalStateException(errorMsg); } return process; }
命令行与Java ProcessBuilder启动的端口转发进程无差异。
psql查询方法
public static boolean psqlQuery() { final ProcessBuilder processBuilder = new ProcessBuilder("sh", "-c", "psql -h localhost -p 7432 -U username -d database -w -t -c \"select id from foo.bar where id='1'\""); try { Process process = processBuilder.start(); process.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); List<String> output = reader.lines().collect(Collectors.toList()); output.forEach(LOGGER::info); BufferedReader errorreader = new BufferedReader(new InputStreamReader(process.getErrorStream())); List<String> erroroutput = errorreader.lines().collect(Collectors.toList()); erroroutput.forEach(LOGGER::error); return output.stream().anyMatch(c -> c.contains("1")); } catch (IOException | InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } }
问题描述
先调用portForward方法,再调用psqlQuery方法时,程序提示无法连接数据库;但如果通过命令行启动端口转发,再执行psqlQuery方法则可正常工作,寻求问题解决方法。
内容的提问来源于stack exchange,提问作者kaprob
相关产品推荐
相关产品推荐

