CI/CD系列之 Jenkins [1] - 安装篇

本文仅介绍Jenkins的安装,优先使用LTS版本。

资源需求

最小资源

  • 内存:512 MB +
  • 存储:1 GB +

推荐资源

  • 内存:4096 MB +
  • 存储:50 GB +
更多关于资源请参考:https://www.jenkins.io/doc/book/scaling/hardware-recommendations/

Linux

Debian/Ubuntu

安装JAVA 11

$ sudo apt update
$ sudo apt install openjdk-11-jre
$ java -version
提示:当前Jenkins版本1.8版本已不支持。

安装Jenkins LTS版本

curl -fsSL https://pkg.jenkins.io/debian-stable/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-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins

缺省端口为:8080,如果需要更改,前往systemd文件声明JENKINS_PORT环境变量即可。

[Service]
Environment="JENKINS_PORT=8081"

RHEL/CentOS 7

安装 JDK-11

sudo yum install java-11-openjdk

安装Jenkins

wget -O /etc/yum.repos.d/jenkins.repo \
        https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum upgrade
systemctl daemon-reload
systemctl enable jenkins --now

如果系统中存在多个JAVA版本可以使用以下命令进行版本切换。

 alternatives --config java 

如果开启了防火墙,需要把8080端口放行。

firewall-cmd --permanent --new-service=jenkins
firewall-cmd --permanent --service=jenkins --set-short="Jenkins ports"
firewall-cmd --permanent --service=jenkins --set-description="Jenkins port exceptions"
firewall-cmd --permanent --service=jenkins --add-port=8080/tcp
firewall-cmd --permanent --service=jenkins --add-service=jenkins
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload

与上述debian分支一样,若需要自定义业务端口,传入JENKINS_PORT变量即可:

# vim /etc/sysconfig/jenkins
JENKINS_PORT="8081"

Docker

拉取镜像

docker pull jenkins/jenkins:lts-jdk11

运行容器实例

docker run -d \
    -u root \
    --name jenkins \
    -p 8080:8080 \
    -p 50000:50000 \
    -v /data/jenkins:/var/jenkins_home:rw \
    -v /etc/localtime:/etc/localtime:ro \
    -e JAVA_OPTS=-Duser.timezone=Asia/Shanghai \
  jenkins/jenkins:lts-jdk11

也可以直接使用jenkinsci/blueocean容器镜像,如:

mkdir -p /data/jenkins
chown -R 1000:1000 /data/jenkins
docker run \
  -u root \
  --rm \
  -d \
  -p 8080:8080 \
  -p 50000:50000 \
  -v /opt/jenkins-data:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e JAVA_OPTS=-Duser.timezone=Asia/Shanghai \
  jenkinsci/blueocean:1.25.3

docker-compose

  • Dockerfile
FROM jenkins/jenkins:alpine
USER root
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    && apk update \
    && apk add docker
  • docker-compose.yaml
version: "3.0"
services:
  jenkins:
    build: ./
    image: jenkins/jenkins:alpine
    container_name: jenkins
    ports:
      - "8080:8080"
      - "50000:50000"
    environment:
      - JAVA_OPTS="-Xmx1500m -Duser.timezone=GMT+8 -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Dhudson.model.UpdateCenter.updateCenterUrl=https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/"
    volumes:
      - /data/jenkins:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
#    user: root
    restart: always
提示:如果后续不需要使用docker构建镜像,可以不需要在镜像中安装docker工具。比如使用kaniko工具替代docker。

Kubernetes[推荐]

添加官方helm源

helm repo add jenkinsci https://charts.jenkins.io/
helm repo update

拉取chart包

helm pull jenkinsci/jenkins --version 4.1.13

将默认定义的values值进行更新,如容器镜像版本、超级管理员密码、JAVA_OPTS、Pod资源等。

tar axvf jenkins-4.1.13.tgz
cd jenkins

vim values.yaml
<...>
controller:
  componentName: "jenkins-controller"
  image: "jenkins/jenkins"
  tag: lts-jdk11
  tagLabel: jdk11
  imagePullPolicy: "IfNotPresent"
  imagePullSecretName:
  adminSecret: true

  hostNetworking: false
  adminUser: "admin"
  adminPassword: "密码"
  <...>
  javaOpts: "-Xms2048m -Xmx2048m -Duser.timezone=Asia/Shanghai"
  <...>

安装

kubectl create namespace jenkins
heml -n kenkins install jenkins-master .

查看Jenkins运行的Pod状态

# kubectl -n jenkins get pod
NAME               READY   STATUS    RESTARTS   AGE
jenkins-master-0   2/2     Running   0          9m28s

负载均衡

我们前面的几种方式都是介绍Jenkins服务安装的方式,无论是Linux系统环境还是容器环境,作为一个正常的运维服务,相对不太友好的:

  • 非标端口
  • 使用明文

鉴于此,我们会在Jenkins服务前面添加一个负载均衡器。

Nginx

假设jenkins的业务域名为: https://jenkins.vqiu.cn

#server {
#    listen 80;
#    return 301 https://$host$request_uri;
#}

server {

    listen 443 ssl http2;
    server_name jenkins.vqiu.cn;

    ssl_certificate           /etc/nginx/cert.crt;
    ssl_certificate_key       /etc/nginx/cert.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:Jenkins:1m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers off;

    access_log   /var/log/nginx/jenkins.access.log;

    location / {

      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_pass          http://JENKINS节点:8080;
      proxy_read_timeout  90;

      proxy_redirect      http://JENKINS节点:8080 https://jenkins.vqiu.cn;
      
      allow 172.16.0.0/12;
      deny  all;
    }
  }
OpenSSL 版本为1.1.1

Ingress(nginx)

创建TLS证书secret

apiVersion: v1
data:
  tls.crt: <...>
  tls.key: <...>
kind: Secret
metadata:
  name: tls-jenkins.vqiu.cn
  namespace: jenkins
type: IngressTLS

创建Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
    nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
    nginx.ingress.kubernetes.io/enable-cors: "true"

spec:
  rules:
  - http:
      paths:
       - backend:
          serviceName: jekins-master
          servicePort: 8080
        path: /
  tls:
  - hosts:
    - jenkins.vqiu.cn
    secretName: tls-jenkins.vqiu.cn

Ingress(istio)

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: jenkins-gw
  namespace: jenkins
spec:
  selector:
    custom: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "jenkins.vqiu.cn"
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key
    hosts:
    - "jenkins.vqiu.cn"
  
  ---
  apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: jenkins-vs
  namespace: jenkins
spec:
  gateways:
  - jenkins-gw
  hosts:
  - 'jenkins.vqiu.cn'
  http:
  - headers:
      request:
        set:
          x-forwarded-port: "443"
          x-forwarded-proto: https 
    match:
    - uri:
        prefix: /jekins
    route:
    - destination:
        host: jenkins-master.jenkins.svc.cluster.local
        port:
          number: 8080

初始密码

如果未定义密码,初始密码被写入/var/lib/jenkins/secrets/initialAdminPassword文件中。

关于插件

关于避免后续安装插件的麻烦,我们可以直接在dockerfile文件中定义我们需要安装的插件:

FROM jenkins/jenkins:lts-jdk11
LABEL maintainer="Qiu Shuhui<shuhui@vqiu.cn>"

RUN set -xe jenkins-plugin-cli --plugins git \
                                         htmlpublisher \
                                         greenballs \
                                         simple-theme-plugin \
                                         email-ext \
                                         kubernetes \
                                         gitlab-plugin \
                                         violation-comments-to-gitlab \
                                         timestamper \
                                         git-changelog \
                                         build-pipeline \
                                         pipeline-utility-steps \
                                         role-strategy

VOLUME /var/jenkins_home

USER jenkins

上述构建的镜像地址为registry.cn-shenzhen.aliyuncs.com/shuhui/jenkins-plugins:lts-jdk11,可以直接拉取使用。

参考引用