首页
解决 Jenkins 中使用代理来执行 npm install 的问题

问题背景

npm install 对于国内的开发者来说,一直都是个头痛的问题。虽然改成国内的源下载会好很多,但还是会出现一些莫名其妙的问题,比如node-sass的安装。所以干脆就用高速代理直接来安装。

但是Jenkins直接在 pipeline 的语法中加入export https_proxy=http://127.0.0.1:57194是没有起到作用的。

解决方案

1. 打通宿主机跟Docker容器的网络

首先想到的是 Jenkins 是用 Docker 来安装的,所以先要打通宿主机跟 Jenkins 所在 Docker的网络通信。

找到 docker proxy 这个章节,按照下面的文档配置了一下

image_1eau50akq1tdj32o18b85431jlh29.png-89.9kB

需要注意的是,这里的httpProxyhttpsProxy指的是代理服务器的地址。比如我在宿主机上开了代理,docker 的网络模式为 bridge 模式,这时候填http://127.0.0.1是有问题的,应该填写宿主机的局域网 ip 地址

这一步弄完后,以为可以正常使用了。进入 Jenkins 容器里面,使用curl https://www.google.com去测试网络,发现还是不通的。

这里卡了蛮久的,在同事的帮助下发现是代理软件的端口问题。始终要记住:Docker是一个独立的系统,虽然它跑在宿主机上,但还是完全隔离的。

所以我们需要注意代理软件的端口是否开放出来。

netstat -tlpn

发现 Local Address 显示的是127.0.0.1:57194,修改代理软件的配置,开放端口为0.0.0.0:57194

重启后进入 Docker 环境里面,再次运行curl https://www.google.com发现是可以访问的。

2. 打通容器跟Jenkins pipeline agent的容器网络

上一步做完后,在 Jenkins 中建了一个简单的 pipeline,执行了一下,发现是 ok 的,以为到这里就完了,但是在项目中实验发现是失败的。

这里忽略了一个问题,试验的时候建的 pipeline 里面只是执行了一下 shell 脚本,但项目中使用的 pipeline 使用的是 agent docker

agent {
    docker {
        image 'node8.11.3-ci:1.0.0'
    }
}

现在的问题是,宿主机中有一个 Jenkins 的 Docker,Jenkins 里面又有一个node8.11.3-ci:1.0.0的 Docker。也就是说在 Docker 中又跑了一个 Docker,[俄罗斯套娃?手动狗头]

我们之前打通了宿主机跟 Jenkins 容器的网络,现在要打通 Jenkins 容器跟node8.11.3-ci:1.0.0 容器的网络

翻阅文档,找到了一个args参数,可以传递参数给docker run,这是至关重要的信息。

image_1eb0smegk1ert72h11321v2j1242p.png-67kB

那么我们把https_proxy传递进去就 ok 了

 agent {
    docker {
        image 'node8.11.3-ci:1.0.0'
        args '-e https_proxy=http://192.168.0.200:57194'
    }
}

大功告成。终于可以在 Jenkins 中快乐地使用代理了。

注意事项

如果宿主机开启了防火墙会导致容器访问不了代理。最简单的方法是关闭防火墙,当然这样做不太安全,可以针对指定 ip 去开放端口。

# 开启防火墙
systemctl start firewalld.service
# 防火墙开机启动
systemctl enable firewalld.service
# 关闭防火墙
systemctl stop firewalld.service
# 查看防火墙状态
firewall-cmd --state
# 查看现有的规则
iptables -nL
firewall-cmd --zone=public --list-ports
# 重载防火墙配置
firewall-cmd --reload

参考资料:
1. firewall-cmd 常用命令