星路

追寻那一缕星光,在漆黑夜晚前行

0%

安装Jenkins及二级目录反向代理访问

安装Jenkins整体还算顺利,只是Nginx配置二级目录反代访问后,会有”It appears that your reverse proxy set up is broken.”告警提示。看官网配置样例其访问URL是根目录,而实际环境有多个业务系统反代需求而要采用二级目录区分;网上搜索这个问题挺普遍的,但一一试了都不适用,虽然不少人提及不会影响、是一个bug之类的,但还是尝试解决掉了。


1. 环境

  • 软件
    1. centos 7.7
    2. docker 19.03.12
    3. Jenkins 2.249.1
  • 网络
    外网-> 防火墙(8099:80) -> Nginx(80)-> Jenkins(8080)

    配置信息

    后面涉及的域名、IP、端口号等配置请根据实际情况自行调整。


2. 安装过程

安装没什么大坑,按照官网教程来即可。我是采用docker方式安装,用docker-compose管理,相关配置见附录。

注意

Nginx采用二级目录反代,为保证Jenkins服务器的context path与Nginx的Location一致,需通过增加Jenkins启动参数--prefix来指定。

### 2.1. 首次访问卡"Please wait while Jenkins is getting ready to work"提示界面 ### - 浏览器访问Jenkins,会出现"Please wait while Jenkins is getting ready to work ..."提示,等待很长时间无进展。 - 按网上方案,编辑`/var/jenkins_home/hudson.model.UpdateCenter.xml`文件,将`"https://updates.jenkins.io/update-center.json"` 修改为 `"http://mirror.xmission.com/jenkins/updates/update-center.json"`,重启服务解决。 ### 2.2. 出现"It appears that your reverse proxy set up is broken."告警 ## - 登陆Jenkins后,点击manager菜单会提示 - 进浏览器控制台查看发现有测试url返回404 - 直接访问测试url发现有少一个'/'符号 - 网上搜索Nginx是有对请求URL进行了处理,通过设置`merge_slashes off;`后,URL正常

注意

该项配置service nginx reload不能生效,需要执行service nginx restart

- 再观察测试页面,正常应该是http://{host:port}/jk/manage作为参数传递,但Nginx反代访问Jenkins服务器的URL地址是解码后的地址,所以造成Jenkins无法处理。经查Nginx确实会对URL进行解码,所以proxy_pass地址应使用$request_uri重新组装。

3. 附录

3.1 docker-compose主要配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
jenkins:
container_name: container_jenkins # 容器名称
image: jenkinsci/blueocean # 官方建议镜像,带Blue Ocean插件
user: root
# ports:
# - "8080:8080" # Nginx容器在相同网络可用容器名称访问,可不映射端口出来
# - "50000:50000"
volumes:
- "/etc/localtime:/etc/localtime"
- "./jenkins:/var/jenkins_home" # 数据文件目录映射,按需更改'./jenkins'本地存储路径
command:
- "--prefix=/jk" # 二级目录访问,配置context
- "--httpPort=8080" # 可更改端口
restart: always

3.2 Nginx反代配置

基本参照官网配置样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 配置文件/etc/nginx/conf.d/default.conf

upstream jenkins {
server container_jenkins:8080; # 通过容器名称访问jenkins
}

server {
listen 80;
listen [::]:80;
server_name localhost;
merge_slashes off;

location /jk/ { # 外网通过二级目录/jk进行访问
sendfile off;
proxy_pass http://jenkins$request_uri; # 传递原始的uri
# proxy_redirect default; # 注释掉,不然和上方proxy_pass配置冲突:"cannot be used with "proxy_pass" directive with variables"
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host:8099; # 因为外部防火墙又进行了一次映射,Nginx并不能知晓外部端口,需要手动指定
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_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}