在 Jenkins 流水线库中查找未使用的端口

Posted

技术标签:

【中文标题】在 Jenkins 流水线库中查找未使用的端口【英文标题】:Find unused port in Jenkins Pipeline Library 【发布时间】:2018-04-03 15:41:24 【问题描述】:

我目前正在改进我的 Jenkins 流水线,它启动一个带有暴露端口的 docker 容器。但是由于许多人和他们的项目大量使用 Jenkins 实例,我遇到了问题,暴露的端口映射已经在使用中。

我的想法是确定主机上未使用的端口,以规避这个问题。为了做到这一点,我想扩展我们的 Jenkins 共享库,用一种简单的方法来检查并从主机系统返回第一个未使用的端口。

有人知道如何实现这一目标吗?

我目前的解决方案是利用一个 shell 函数,它以某种方式使用 netstat 工具。

文件:getRandomFreePort.groovy

def call() 
sh '''
    #!/bin/bash
    while
    [[!-z $CHECK]]; do
    PORT = $(((RANDOM % 60000) + 1025))
    CHECK = $(sudo netstat - ap | grep $PORT)
    done

    echo $PORT
'''

【问题讨论】:

plugin that's supposed to do this 仍然不支持管道:( 【参考方案1】:

使用ServerSocket,您可以通过以下命令获取未使用的端口:

try 
    def serverSocket = new ServerSocket(0);
    System.out.println("listening on port: " + serverSocket.getLocalPort());
    //Do anything
    serverSocket.close()
 catch (IOException ex) 
    System.err.println("no available ports");

如果您需要在某个范围内找到可用端口,请查看此帖子:How to find an available port in a range?

【讨论】:

【参考方案2】:

我花了很多时间寻找在未经批准的情况下这样做的可能性。 并在 Groovy 中使用 Python 找到了它。

String port = sh(script: 'echo $(python -c \'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()\');', returnStdout: true)

该解决方案看起来不是很干净,但效果很好。

【讨论】:

无需特定授权即可正常工作,socket 包含在python 中。对于格式化,这样阅读会更容易:````groovy sh ( script: """ echo \$(python -c 'import socket; s=socket.socket(); s.bind(("" , 0)); print(s.getsockname()[1]); s.close()') """, returnStdout: true ).trim() ```【参考方案3】:

一个简单的单行:

def port = new ServerSocket(0).withCloseable  socket -> socket.getLocalPort() 

创建一个绑定到 0 的套接字会分配一个任意的空闲端口。

请注意,如果启用了安全性,则需要script approval。

也没有预留机制,所以虽然它在分配给套接字时是空闲的,但在这段代码运行后可能会有其他东西占用它。

【讨论】:

以上是关于在 Jenkins 流水线库中查找未使用的端口的主要内容,如果未能解决你的问题,请参考以下文章

史上最全 Jenkins Pipeline流水线详解

使用 Jenkins 实现集群化管理以及配置流水线

如何使用 Jenkins 的脚本化流水线(Pipeline)

Jenkins 流水线(Pipeline)

Jenkins之Pipeline代码流水线

Jenkins的流水线(Pipeline)