该笔记将记录:与 Jenkins 安装、升级有关的内容,以及相关问题的解决办法;
on Linux | with Package Manager
依赖安装
安装 JDK/JRE 包(Jenkins 使用 Java 开发的,需要安装运行环境):
# Debian GNU/Linux 10 (buster) apt-get install -y openjdk-11-jre
on Ubuntu 20.04
Weekly release:
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io.key | sudo tee \ /usr/share/keyrings/jenkins-keyring.asc > /dev/null echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \ https://pkg.jenkins.io/debian binary/ | sudo tee \ /etc/apt/sources.list.d/jenkins.list > /dev/null sudo apt-get update sudo apt-get install jenkins
on CentOS 7.0
RedHat Linux RPM packages for Jenkins
# 12/27/2018
yum install wget yum install java-1.8.0-openjdk.x86_64 wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key yum install jenkins
访问服务器地址,开始配置你的的 Jenkins,首页是让你输入初始密码,并告诉你初时密码所在的文件;
on Debian 10
Jenkins Regular releases (Weekly)
# 08/19/2020
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | apt-key add - echo 'deb https://pkg.jenkins.io/debian binary/' > /etc/apt/sources.list.d/jenkins.list apt-get update apt-get install -y jenkins /lib/systemd/systemd-sysv-install enable jenkins systemctl start jenkins.service # 浏览器访问 http://127.0.0.1:8080 以进行初始化
on Debian 8.2
# 04/04/2019
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | apt-key add - echo "deb http://pkg.jenkins.io/debian-stable binary/" > /etc/apt/sources.list.d/jenkins.list apt-get update apt-get install -y jenkins # 如果你要手动指定自己的 JDK 版 # 修改 /etc/default/jenkin 文件,追加如下行在开始 JAVA_HOME="/opt/openjdk-1.8" PATH="$JAVA_HOME/bin:$PATH"
反向代理 | 通过 Nginx 暴露
Jenkins 配置为 Nginx 的后端代理
Running Jenkins behind Nginx
Hide a client request header with a Nginx reverse proxy server
参考 Running Jenkins behind Nginx 文档,以获取官方对反向代理的详细说明;
下面是配置文件(直接复制自官方,我们并未深入研究):
upstream jenkins { keepalive 32; # keepalive connections server 127.0.0.1:8080; # jenkins ip and port } server { listen 80; # Listen on port 80 for IPv4 requests server_name jenkins.example.com; #this is the jenkins web root directory (mentioned in the /etc/default/jenkins file) root /var/run/jenkins/war/; access_log /var/log/nginx/jenkins/access.log; error_log /var/log/nginx/jenkins/error.log; ignore_invalid_headers off; #pass through headers from Jenkins which are considered invalid by Nginx server. location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" { #rewrite all static files into requests to the root #E.g /static/12345678/css/something.css will become /css/something.css rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last; } location /userContent { #have nginx handle all the static requests to the userContent folder files #note : This is the $JENKINS_HOME dir root /var/lib/jenkins/; if (!-f $request_filename){ #this file does not exist, might be a directory or a /**view** url rewrite (.*) /$1 last; break; } sendfile on; } location / { sendfile off; proxy_pass http://jenkins; proxy_redirect default; proxy_http_version 1.1; proxy_set_header Host $host; 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 in Jenkins > 2.54 proxy_set_header Connection ""; # Clear for keepalive } }
on Docker | with Docker Compose | Jenkins 2.502-jdk17
docker pull jenkins/jenkins:2.502-jdk17 # openjdk 17.0.14
on Kubernetes | with Helm Chart
2.346.1 | on Kubernetes | with Helm Chart by Official
该笔记将记录:在 Kubernetes Cluster 中,如何部署 Jenkins 服务,重点将现有 Jenkins 服务迁移到 Kubernetes 中;
注 1:鉴于迁移是我们的重点工作,所以部署过程会涉及迁移相关的内容;
# 添加仓库 helm repo add jenkinsci https://charts.jenkins.io helm repo update helm search repo jenkinsci # 下载 # 我们 Jenkins 2.345 版本,但是没有该版本的 Chart 资源, # 而 4.1.12 对应 Jenkins 2.346.1 版本,最贴近(算是微小升级); helm pull jenkinsci/jenkins --version 4.1.12 # jenkins-4.1.12.tgz # 修改配置 helm show values ./jenkins-4.1.12.tgz > jenkins-4.1.12.helm-values.yaml ...(1)修改 storageClass 参数,以配置其使用的存储类; ...(2)修改 Ingress 参数,以保留服务提供 HTTP 访问; # 服务部署 helm --namespace jenkins \ install jenkins ./jenkins-4.1.12.tgz -f jenkins-4.1.12.helm-values.yaml \ --create-namespace # 查看密码 kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo # 服务登录 # admin:<password>
服务迁移:Docker Compose ⇒ Kubernetes
问题描述
在 Kubernetes 大为流行前,我们已经开始使用 Jenkins 服务,现在我们需要将 Jenkins 迁移到 Kubernetes 环境,而非重新部署 Jenkins 服务;
解决方案
目前(07/10/2022),我们的想法是:
1)首先,运行 rsync 容器,并创建 PV 与 PVC 资源,负责将数据复制到 PV 内;
2)在启动 Jenkins 服务,并在其中引用该 PVC 资源,并检查 Jenins 能够正常运行;
接下来是验证工作:
第一步、数据迁移
运行 rsync 容器,并完成数据同步:
kubectl apply -f - <<EOF --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: jenkins-claim spec: storageClassName: nfs-client accessModes: - ReadWriteMany resources: requests: storage: 100Gi --- apiVersion: v1 kind: Pod metadata: name: jenkins-migration spec: volumes: - name: jenkins-claim persistentVolumeClaim: claimName: jenkins-claim containers: - name: rsync image: eeacms/rsync command: ["sleep", "infinity"] volumeMounts: - mountPath: "/srv/jenkins/" name: jenkins-claim EOF # 进行数据同步 kubectl exec -it jenkins-migration -- sh rsync --delete -avz root@jenkins-old:/var/lib/jenkins/ /srv/jenkins/
第二步、创建 Jenkins 服务
按照前述步骤,通过 Helm 部署 Jenkins 服务:
1)修改 persistence.existingClaim: jenkins-claim 参数,以使用已创建的 PVC 资源;
2)修改 Ingress 配置,以暴露 Jenkins 服务;
3)最后,通过 Helm 进行部署(当启动时会自动下载安装部分插件,所以稍慢);
第三步、访问验证,问题修复
浏览器访问 Jenkins 服务,并检查是否正常运行,是否存在异常;
部分问题的出现,其与多种因素(诸如场景、版本、插件等等)相关,我们将描述我们遇到的问题。
针对插件依赖错误问题:
1)当迁移到 Kubernets 环境后,鉴于 Jenkins 版本未与原始版本完全匹配,外加某些未知因素,导致插件依赖出现问题。
2)按照提示,我们依次更新 Jackson 2 API Plugin、SnakeYAML API 插件(环境相关,具体问题具体分析)
3)如果插件升级失败,导致 Jenkins 显示 Error 页面,我们通过 rsync 重置 plugins 目录,然后再次尝试插件升级;
with Docker Compose | Jenkins 2.340-jdk8
如下配置,仅供参考:
version: '3' services: jenkins-master: image: 'jenkins/jenkins:2.340-jdk8' container_name: jenkins-master environment: - JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Dhudson.model.DirectoryBrowserSupport.CSP=''" volumes: - /etc/localtime:/etc/localtime - ./data:/var/jenkins_home ports: - 8088:8080 - 50000:50000 restart: always
注意,如果是迁移到 data 目录,则需要修改权限:chown 1000:1000 ./data -R
通过查看启动日志,获得默认密码,/var/jenkins_home/secrets/initialAdminPassword
Nginx Reverse Proxy
server { listen 80 default; server_name ci.devops.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; 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; client_max_body_size 10m; } }
在反向代理后,出现 HTTP Basic authentication 重复认证
Wikipedia/Basic access authentication
How to define the basic HTTP authentication using cURL correctly?
问题描述:
为了提高安全性,使用 Nginx 反向代理 Jenkins 后,又在 Nginx 中配置了 HTTP Basic Authentication 功能,但是出现了“认证窗口不停弹出”的问题;
关于 HTTP Basic Authentication 的配置参考 Restricting Access with HTTP Basic Authentication 一文;
问题原因:
使用 curl 命令请求(curl --user user:password http://),返回 401 认证失败页面,该页面是 Jenkins 返回的(页面上由 Jetty…… 等内容);
修改 Jenkins 调试等级并打开访问日志,请求日志中出现了 401 认证失败的请求;
前端 Nginx 将 Authorization 请求头传给 Jenkins 服务,但是 Jenkins 并没有配置认证,而导致认证失败;
但实际上,我们并不需要把 Authorization 头传递给 Jenkins 服务;
解决办法:
修改 Nginx 配置文件,在转发时移除 Authorization 头:proxy_set_header Authorization “”;
通过置空来移除头部,参考官方文档说明:「Module ngx_http_proxy_module/proxy_set_header」
with Docker Compose | Jenkins 2.373
2.373 ⇒ 2.375 ⇒ 2.387 ⇒ 2.401 ⇒ 2.414 ⇒ 2.426
参考 Jenkins LTS Upgrade Guide 文档,获取版本间的变化日志;
根据我们部署及配置,升级过程较为简单:
docker pull jenkins/jenkins:2.xxx vim docker-compose.yaml docker-compose up -d
with Docker Compose | Jenkins 2.426
Run 2.426 with Docker Compose
停止 Jenkins 服务,复制 /var/lib/jenkins/ 目录
通过 docker-compose.yaml 运行:
version: '3' services: jenkins-master: image: docker.io/jenkins/jenkins:2.469 container_name: jenkins-master environment: - JENKINS_JAVA_OPTS="-Duser.timezone=Asia/Shanghai" volumes: - /etc/localtime:/etc/localtime - ./data:/var/jenkins_home ports: - 60080:8080 - 50000:50000 restart: always
2.426 ⇒ 2.458
参考 Jenkins LTS Upgrade Guide 文档,获取版本间的变化日志;
根据我们部署及配置,升级过程较为简单:
docker pull jenkins/jenkins:2.xxx vim docker-compose.yaml docker-compose up -d
2.469 ⇒ 2.477
根据 Changelog/2.475 文档,需要升级 LDAP 插件:
https://github.com/jenkinsci/ldap-plugin/tree/733.vd3700c27b_043
停止服务。
然后,再升级到 2.477 版本。
2.477 ⇒ 2.487
1)数据备份
2)直接升级进行即可
废弃 | 在 Tomcat 中,运行 Jenkins 服务
Jenkins/Installing Jenkins
How to Install Jenkins on the Apache Tomcat Server
How to set Jenkins_Home hosted on apache tomcat
该笔记将记录:在 Tomcat 中,运行 Jenkins 服务,而不是运行独立的 Jenkins 服务;
注意,在实际的生产中,我们并未在 Tomcat 中部署 Jenkins 服务,该笔记属于实验性质。
第一步、安装 Tomcat 服务
我们直接从发行办的仓库中安装:
# 安装服务(Kali) apt-get install tomcat9 # 启动服务,并开机启动 systemctl enable tomcat9
发行版不同,安装方法不同,细节不再赘述;
第二步、安装 Jenkins 服务
wget -P /var/lib/tomcat9/webapps/ http://mirrors.jenkins.io/war-stable/latest/jenkins.war
然后最自动生成 jenkins 目录;
第三步、修改配置文件
为什么需要进行该步骤?
1)进行该步骤配置是因为发行版自带的 Tomcat 进行安全配置,执行命令 systemctl cat tomcat9.service 了解配置;
2)阅读 systemd.exec(5) 手册,了解 PrivateTmp= ReadWritePaths= 参数;
修改 /etc/tomcat9/context.xml 配置,设置 JENKINS_HOME 变量:
<Context> ... <Environment name="JENKINS_HOME" value="/var/lib/jenkins/" type="java.lang.String"/> ... </Context>
创建 JENKINS_HOME 目录
mkdir -pv /var/lib/jenkins/ chown -R tomcat: /var/lib/jenkins/
调整 tomcat9.service 配置
# systemctl edit tomcat9.service [Service] ReadWritePaths=/var/lib/jenkins/
第四步、启动 Tomcat 服务
systemcat start tomcat9
最后启动浏览器访问,http://<ip address>/jenkins/,按照提示进行初始化即可;