【问题标题】:Jenkins: How to configure Jenkins behind Nginx reverse proxy for JNLP slaves to connectJenkins:如何在 Nginx 反向代理后面配置 Jenkins 以供 JNLP 从站连接
【发布时间】:2016-12-08 08:30:06
【问题描述】:

我正在尝试设置一个 Jenkins 主节点和一个 Jenkins 从节点,其中 Jenkins 主节点位于具有 SSL 终止的不同服务器上的 Nginx 反向代理后面。 nginx配置如下:

upstream jenkins {
  server <server ip>:8080 fail_timeout=0;
}

server {
  listen 443 ssl;
  server_name jenkins.mydomain.com;
  ssl_certificate /etc/nginx/certs/mydomain.crt;
  ssl_certificate_key /etc/nginx/certs/mydomain.key;

  location / {
    proxy_set_header        Host $host:$server_port;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_redirect          http:// https://;
    proxy_pass              http://jenkins;
  }
}

server {
  listen 80;
  server_name jenkins.mydomain.com;
  return 301 https://$server_name$request_uri;
}

JNLP 代理的 TCP 端口在 Jenkins 主全局安全配置中设置为 50000。端口 50000 设置为可从主机上的任何位置访问。

使用以下命令启动 JNLP 从站:

java -jar slave.jar -jnlpUrl https://jenkins.mydomain.com/computer/slave-1/slave-agent.jnlp -secret <secret>

JNLP slave 无法连接到 master 上配置的 JNLP 端口:

INFO: Connecting to jenkins.mydomain.com:50000 (retrying:4)
java.net.ConnectException: Connection timed out
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at java.net.Socket.connect(Socket.java:538)
        at hudson.remoting.Engine.connect(Engine.java:400)
        at hudson.remoting.Engine.run(Engine.java:298)

JNLP slave连接Jenkins master需要什么配置?

【问题讨论】:

    标签: nginx jenkins proxy


    【解决方案1】:

    JNLP 端口似乎使用二进制协议,而不是基于文本的 HTTP 协议,所以很遗憾,它不能像正常的 Jenkins 页面那样通过 NGINX 进行反向代理。

    相反,您应该:

    1. 配置全局安全 > 选中“启用安全”并设置一个固定 “JNLP 从代理的 TCP 端口”。这将导致所有 Jenkins 页面 发出指定此端口的额外 HTTP 标头:X-Hudson-CLI-Port, X-Jenkins-CLI-Port、X-Jenkins-CLI2-Port。

    2. 允许您的固定 TCP JNLP 端口通过任何防火墙,因此 CLI 客户端和 JNLP 代理可以 直接到达后端的 Jenkins 服务器。

    3. 将系统属性hudson.TcpSlaveAgentListener.hostName 设置为 后端 Jenkins 服务器的主机名或 IP 地址。这 将导致所有页面发出额外的 HTTP 标头 (X-Jenkins-CLI-Host) 包含此指定的主机名。这告诉 CLI 客户端连接的位置,但应该不是 JNLP 代理。

    4. 对于您在节点列表中的每个构建从机 jenkins.mydomain.com/computer/使用Launch方式“Launch slave agents via Java Web Start”,点击电脑,点击Configure,点击Launch method下右侧的Advanced...按钮,并适当设置“Tunnel connection through”字段.阅读问号帮助。您可能只需要“HOST:”语法,其中 HOST 是后端 Jenkins 服务器的主机名或 IP 地址。

    参考资料:

    【讨论】:

    • 我正在使用 dockerized Jenkins,与 dockerized slaves 一起运行。 Jenkins 支持反向代理(使用注册器和领事模板)。目前它适用于对从端口进行硬编码,但我们想让它全部动态化。当我们在 Jenkins 运行之前不知道从端口时,您对配置 Jenkins 有什么建议吗?
    • @Brandon 我不熟悉注册器和领事模板。我认为您需要先确定一个固定的从端口,以便您可以打开防火墙中的针孔。如果您必须动态执行此操作,可能会找到存储它的 jenkins 设置 xml 文件(全局设置和每个从属设置)并想出修改这些文件的技巧,然后重新加载 jenkins 配置(或只是重新启动 jenkins ) 使其生效。
    • 如果您像我一样不知道在哪里设置第 3 步“设置系统属性 hudson.TcpSlaveAgentListener.hostName”,这就是它的完成位置和方式:wiki.jenkins.io/display/JENKINS/… 当您需要这样做时Jenkins master 在 Docker 中运行 github.com/jenkinsci/docker/blob/master/… 另一个小窍门是在此服务器值上包含端口(只是服务器 lan ip 或可解析的主机名)。
    • 这是准确的答案!我在 ALB 后面的 AWS 上运行 jenkins-master,所以第 4 步是通过二进制 JNLP 协议绕过流量的唯一方法(ALB 和 NLB 仅支持 TCP/TLS 协议)。
    • 值得一提的是,我还使用了 nGinx 代理。它禁止了一些危险的路线。它还将流量传递到 jenkins 进程,该进程强加在内部 (127.0.0.1) 接口中,并且无法从 Internet 访问。因此,在这种情况下,nGinx 配置还应该有一个适当的 server 来将流量路由到您配置的 JNLP 端口上的 jenkins-master,该端口应该 fixed/configureSecurity/页面
    【解决方案2】:

    自从 OP 提出这个问题已经快 4 年了,不过,如果您访问此页面并寻找合适的解决方案,那么,it's now possible

    我使用 Traefik 作为 Jenkins 的反向代理。 TCP 端口入站现在完全禁用。

    您唯一需要确保的是您的代理/从属设备信任 Jenkins 服务器证书(因为 webSocket 不能与 -disableHttpsCertValidation-noCertificateCheck 一起使用

    如果这是 Windows 代理,请使用:

    C:\Program Files (x86)\Java\jre1.8.0_251\bin\keytool.exe -import -storepass "changeit" -keystore "C:\Program Files (x86)\Java\jre1.8.0_251\lib\security\cacerts" -alias <cert_alias> -file "<path_to_cert>"
    

    (根据您的 java 版本更改路径)

    【讨论】:

    • 即使您使用 Kubernetes 插件,同样的选项也有效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 1970-01-01
    • 2017-07-17
    相关资源
    最近更新 更多