Jenkins Slave 离线节点连接超时/关闭 - Docker 容器 - 重新启动步骤 - 配置正在选择旧端口

Jenkins Slave Offline Node Connection timed out / closed - Docker container - Relaunch step - Configuration is picking Old Port

詹金斯版本: 1.643.2

Docker 插件版本: 0.16.0

在我的 Jenkins 环境中,我有一个带有 2-5 个从节点服务器(slave1、slave2、slave3)的 Jenkins master。

这些从站中的每一个都使用 Docker 插件在 Jenkins 全局配置中进行配置。

此刻一切正常。

我看到我们的监控系统针对 slave3(前 IP:11.22.33.44)上的高 SWAP space 使用率发出一些警报,所以我 ssh 到那台机器并 运行:sudo docker ps 这给了我这台 slave3 机器上当前 运行 docker 容器的有效输出。

通过 运行 ps -eo pmem,pcpu,vsize,pid,cmd | sort -k 1 -nr | head -10 在目标从机的机器上(其中 4 个容器是 运行),我发现前 5 个占用所有 RAM 的进程是 java -jar slave.jar 运行 在每个容器内。所以我想为什么不 重新启动 狗屎并恢复一些记忆。在以下输出中,我看到了 docker restart <container_instance> 步骤前后 sudo docker ps 命令的状态。向右滚动,您会注意到在以 ...0a02 结尾的容器 ID 的第二行中,主机(slave3)机器上的虚拟端口(在标题 NAMES 下列出)是1053(映射到容器的虚拟 IP 端口 22 用于 SSH)。很酷,这意味着,当从 Jenkins Manage Node 部分开始时,如果您尝试重新启动从站的容器,Jenkins 将尝试连接到主机 IP 的 11.22.33.44:1053 并执行任何它应该成功启动从站的操作向上。所以,詹金斯在某处持有该端口(1053)。

CONTAINER ID        IMAGE                                                   COMMAND                  CREATED             STATUS              PORTS                  NAMES
ae3eb02a278d        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   26 hours ago        Up 26 hours         0.0.0.0:1048->22/tcp   lonely_lalande
d4745b720a02        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1053->22/tcp   cocky_yonath
bd9e451265a6        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1050->22/tcp   stoic_bell
0e905a6c3851        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1051->22/tcp   serene_tesla

sudo docker restart d4745b720a02; echo $?
d4745b720a02
0

CONTAINER ID        IMAGE                                                   COMMAND                  CREATED             STATUS              PORTS                  NAMES
ae3eb02a278d        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   26 hours ago        Up 26 hours         0.0.0.0:1048->22/tcp   lonely_lalande
d4745b720a02        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up 4 seconds        0.0.0.0:1054->22/tcp   cocky_yonath
bd9e451265a6        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1050->22/tcp   stoic_bell
0e905a6c3851        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1051->22/tcp   serene_tesla

在 运行 之后 sudo docker restart <instanceIDofContainer> 我 运行 free -h / grep -i swap /proc/meminfo 发现 RAM(之前已完全使用并且只显示剩余 230MB 可用空间) 现在有 1GB 的免费空间和 SWAP 大小,总共 1G,使用了 1G(我尝试了 swappiness 60 或 10),现在有 450MB 的交换空间 space 免费。所以警报的事情得到了解决。酷

但是,正如您从上面的 sudo docker ps 输出中注意到的那样,在重新启动步骤之后,对于那个容器 ID ...0a02,我现在得到了一个新的 PORT# 1054!!

当我转到“管理节点”>“尝试使该节点脱机”、停止它并重新启动它时,Jenkins 没有选择新端口 (1054)。它仍然以某种方式选择旧端口 1053(同时尝试在端口 1053(映射到容器的虚拟 IP 的端口#22(ssh))上与 11.22.33.44(主机的 IP)建立 SSH 连接。

如何在 Jenkins 中为这个从属容器更改此端口或配置,以便 Jenkins 看到新端口并成功重新启动?

PS: 在节点上单击“Configure”以查看其配置并没有向我显示任何其他信息名称 字段。通常在常规从站中有很多字段(您可以在其中定义标签、根目录、启动方法、属性环境变量、从站环境的工具,但我想对于这些 Docker 容器,我没有看到除了 Name 字段以外的任何内容)。单击 Jenkins 全局配置中的 Test Connection(在 Docker 插件部分)显示它已成功找到 Docker 版本 1.8.3

现在,由于 1053 端口 (telnet) 无法正常工作,因为它现在是此容器实例 ID 的 1054(在重启步骤之后),Jenkins 重新启动步骤在 SSH 连接步骤中失败(它首先通过 SSH 连接)方法)。

[07/27/17 17:17:19] [SSH] Opening SSH connection to 11.22.33.44:1053.
Connection timed out
ERROR: Unexpected error in launching a slave. This is probably a bug in Jenkins.
java.lang.IllegalStateException: Connection is not established!
    at com.trilead.ssh2.Connection.getRemainingAuthMethods(Connection.java:1030)
    at com.cloudbees.jenkins.plugins.sshcredentials.impl.TrileadSSHPasswordAuthenticator.canAuthenticate(TrileadSSHPasswordAuthenticator.java:82)
    at com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator.newInstance(SSHAuthenticator.java:207)
    at com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator.newInstance(SSHAuthenticator.java:169)
    at hudson.plugins.sshslaves.SSHLauncher.openConnection(SSHLauncher.java:1212)
    at hudson.plugins.sshslaves.SSHLauncher.call(SSHLauncher.java:711)
    at hudson.plugins.sshslaves.SSHLauncher.call(SSHLauncher.java:706)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
[07/27/17 17:19:26] Launch failed - cleaning up connection
[07/27/17 17:19:26] [SSH] Connection closed.

好的。 Zeeesus!

在 JENKINS_HOME(主服务器的)中,我搜索了哪个配置文件保存了 that/those 容器节点的旧端口号信息,这些节点现在显示为离线。

将目录更改为:$JENKINS_HOME 中的节点文件夹,发现每个节点都有 config.xml 个文件。

例如: $JENKINS_HOME/nodes/<slave3_node_IP>-d4745b720a02/config.xml

解析步骤

  1. Vim 编辑了文件以将旧端口更改为新端口。
  2. 管理 Jenkins > 从磁盘重新加载配置。
  3. 管理节点 > 选择离线的特定节点。
  4. 重新启动 slave,这次 Jenkins 选择了新端口并按预期启动了容器 slave(因为 SSH 连接到配置更改后可见的新端口)。

我认为这个页面:https://my.company.jenkins.instance.com/projectInstance/docker-plugin/server/<slave3_IP>/ 网页,它显示了所有容器信息(在给定的从机上以表格形式 运行ning),这个页面有一个按钮(最后一列)STOP 一个给定的 slave 的容器,但不是启动或重新启动。

有一个 STARTRESTART 按钮应该以某种方式执行我刚才在上面所做的操作。

更好的解决方案:

发生的事情是,slave3 上的所有 4 个长期存在的容器节点 运行ning 都在竞争获得所有可用的 RAM (11-12GB),并且随着时间的推移,JVM 进程 (java -jar slave.jar 重新启动步骤在目标容器的虚拟机(IP)上开始 运行ning 在 slave3 从服务器上)对于单个容器试图占用尽可能多的内存(RAM) .这导致 FREE 内存不足,因此 SWAP 被使用,并且也被使用到监控工具将开始通过发送通知等向我们尖叫的程度。

要解决这种情况,首先要做的是:

1) 在 Jenkins 全局配置下(管理 Jenkins > 配置系统 > Docker 插件部分,对于该从属服务器的 Image / Docker Template,在在 Advanced Settings 部分,我们可以放置 JVM 选项来告诉容器不要竞争所有 RAM。放置以下 JVM 选项有帮助。这些 JVM 设置将尝试保持堆 space 将每个容器放在一个较小的盒子中,以免耗尽系统的其余部分。

您可以从 3-4GB 开始,具体取决于 slave/machine 上基于容器的从属节点 运行 上的总 RAM。

2) 查找 slave.jar 的任何最新版本(可能有一些性能/维护改进,这将有所帮助。

3) 集成监控解决方案(Incinga/etc 你有)自动启动 Jenkins 工作(Jenkins 工作将 运行 一些动作 - BASH 一个班轮,Python shit or Groovy goodness,Ansible playbook 等)来解决与任何此类警报相关的问题。

4) 自动重新启动容器从属节点(即重新启动步骤)- 使从属离线、在线、重新启动步骤,因为这将使从属恢复到恢复活力的新鲜状态。我们所要做的就是,寻找一个空闲的奴隶(如果它没有运行宁任何工作)然后,让它离线>然后在线>然后使用Jenkins REST API通过一个小Groovy 脚本并将其全部放入 Jenkins 作业中,如果那些从属节点长期存在,则让它执行上述操作。

5) 或者可以动态地旋转基于容器的从站 - 每次 Jenkins 将作业排队到 运行 时使用并抛出 模型。