18.8.1 Jenkins高可用架构方案与部署模式

Jenkins高可用架构方案与部署模式#

Jenkins以“控制器(Controller)+ 代理(Agent)”为核心,高可用需同时保证入口可用、配置一致、构建不中断与快速恢复。本节给出可落地的架构草图、部署示例、排错与练习。

一、原理草图与架构模式对比

文章图片
  • 单控制器+快速故障转移:主备控制器共享存储,故障切换到备机,避免多写冲突。
  • 双活控制器(共享存储):入口无单点,但对并发写入敏感,需严格限制写配置。
  • 多控制器分域:按业务拆分,降低单点影响,适合大规模组织。

二、部署模式示例(主备+共享存储)

1)NFS共享存储准备(JENKINS_HOME)

# NFS服务端(示例:10.0.0.10)
sudo yum -y install nfs-utils
sudo mkdir -p /data/jenkins_home
sudo chown -R 1000:1000 /data/jenkins_home  # Jenkins默认UID
echo "/data/jenkins_home 10.0.0.0/24(rw,sync,no_root_squash)" | sudo tee -a /etc/exports
sudo systemctl enable --now nfs-server
sudo exportfs -rv

# 预期:客户端可挂载共享目录

2)控制器节点挂载共享目录

# Jenkins节点A/B(10.0.0.11/10.0.0.12)
sudo yum -y install nfs-utils
sudo mkdir -p /var/lib/jenkins
sudo mount -t nfs 10.0.0.10:/data/jenkins_home /var/lib/jenkins

# 持久化挂载
echo "10.0.0.10:/data/jenkins_home /var/lib/jenkins nfs defaults 0 0" | sudo tee -a /etc/fstab

3)Jenkins安装(以RPM为例)

# 适用于RHEL/CentOS
sudo yum -y install java-11-openjdk
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum -y install jenkins
sudo systemctl enable --now jenkins

# 预期:Jenkins监听8080端口,JENKINS_HOME=/var/lib/jenkins

4)入口高可用(HAProxy + Keepalived)

HAProxy配置(/etc/haproxy/haproxy.cfg)

global
  log /dev/log local0
  maxconn 2000

defaults
  mode http
  timeout connect 5s
  timeout client  30s
  timeout server  30s

frontend jenkins_http
  bind *:80
  default_backend jenkins_nodes

backend jenkins_nodes
  balance roundrobin
  option httpchk GET /login
  server jenkins_a 10.0.0.11:8080 check
  server jenkins_b 10.0.0.12:8080 check

Keepalived虚IP(/etc/keepalived/keepalived.conf)

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 123456
  }
  virtual_ipaddress {
    10.0.0.100/24
  }
}

启动与验证

sudo systemctl enable --now haproxy keepalived
curl -I http://10.0.0.100/login

# 预期:返回200/302,切换主备仍可访问

三、容器化高可用示例(Kubernetes StatefulSet)

# jenkins-statefulset.yaml(简化示例)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: jenkins
spec:
  serviceName: jenkins
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: jenkins-home
          mountPath: /var/jenkins_home
  volumeClaimTemplates:
  - metadata:
      name: jenkins-home
    spec:
      accessModes: ["ReadWriteMany"]
      resources:
        requests:
          storage: 50Gi
kubectl apply -f jenkins-statefulset.yaml
kubectl get pods -l app=jenkins -o wide

# 预期:Pod运行,PVC已绑定,JENKINS_HOME持久化

四、关键命令解释与验证清单

  • JENKINS_HOME写入检查
# 在控制器节点执行
touch /var/lib/jenkins/ha-test.txt
ls -l /var/lib/jenkins/ha-test.txt

# 预期:文件在共享存储上,另一台节点可见
  • 会话保持与健康检查
# 验证HAProxy健康检查
echo "show stat" | sudo socat stdio /run/haproxy/admin.sock | head

# 预期:jenkins_a/jenkins_b状态为UP

五、常见故障排查(含命令)

1)控制器无法启动

sudo journalctl -u jenkins -n 200 --no-pager
# 重点看:端口占用、权限不足、插件不兼容

2)NFS挂载失败/权限问题

showmount -e 10.0.0.10
sudo mount -v -t nfs 10.0.0.10:/data/jenkins_home /var/lib/jenkins
# 检查:exports配置、SELinux、UID权限(1000:1000)

3)双活写冲突
- 症状:插件安装失败、config.xml损坏
- 处理:降为单写模式,使用JCasC/Git统一配置,避免并发修改。

4)负载均衡导致登录失效

# 检查LB是否启用会话保持
# HAProxy可使用cookie或源地址保持

六、练习与验证

1)练习1:主备切换演练
- 任务:停止主控制器服务,验证LB自动切换。

sudo systemctl stop jenkins
curl -I http://10.0.0.100/login
# 预期:仍可访问(由备节点提供服务)

2)练习2:配置一致性验证
- 任务:用JCasC导出配置并在备节点恢复。

# 备节点验证JCasC目录
ls /var/lib/jenkins/casc_configs

3)练习3:构建不中断验证
- 任务:运行流水线构建时切换LB,检查Agent任务是否持续。

七、最佳实践要点

  • 优先采用“单控制器+故障切换”减少配置冲突。
  • 使用JCasC + Git版本化配置与作业定义。
  • 代理节点弹性伸缩,避免控制器资源耗尽。
  • 定期演练故障转移与恢复流程,记录RTO/RPO。