关注回复【学习交流群】加入【安全开发运维】答疑交流群
目录:
0x00 前言简述
描述: 当前在企业内部开发中最常用的CI/CD
(持续集成和交付),总是可以看到Jenkins(大叔)的身影,其作为老牌开源的CI/CD工具,它可以完成自动化构建、测试和部署应用程序等阶段,并且Jenkins 拥有庞大的插件生态系统,提供了丰富的功能扩展和集成选项。无论是构建工具、测试框架、代码质量工具还是部署工具,都可以通过插件轻松集成到Jenkins中。此外Jenkins具有直观的用户界面和易于使用的操作,使得团队成员可以快速上手并参与到持续集成的过程中,Jenkins也提供了丰富的构建和测试报告功能,可以实时监控构建状态和测试结果,并生成易于理解的可视化报告,所以Jenkins在企业开发运维中具有重要的意义。
但是由于容器及云原生技术
的发展,各 CI/CD 的工具雨后春笋般的出来,我们作为运维人员肯定选择最合适,最简单,最容易上手的,只是当下作者企业为了适应业务开发测试的需要,已经将CI/CD
工具从Jenkins
转为Tekton+ArgoCD
,使之更加方便管理和运行,此处并不是说Jenkins不好,只是针对云原生环境可以使用其他CI/CD工具(有学习成本呀
)来代替Jenkins。
为了总结经验及方便后续运维学习者,此处作者将自己企业CI/CD迁移前的GitOps
安装环境Jenkins + Gitlab + Harbor + Kubernetes
和部署流程做一个实践总结,还分享Jenkins生产线上的流水线Pipeline
(带企业微信或者UME信息推送,Gitlab 流水线同步
)、以及自行构建Jenkins-agent所需镜像
、在Jenkins配置Kubernetes支持使之实现动态工作节点的生成
,最后为了各位运维同道中人在自己企业中在使用Jenkins
工具搭建快速部署GitOps环境,减少工作量以及学习时间,遂有了此篇文章,希望大家多多支持。
温馨提示: 本文是作者原创文章,作者熬夜花费了许多精力进行实践和总结,为了防止恶意爬虫和伸手党直接转发
,所以作者将此文设为付费文章(请作者喝一瓶可乐🍺 精神精神
),希望大家理解并多多支持,作者后续将持续更新更多secdevops方面的文章
,此外各位付费的朋友可以加入我们的【微信交流群
】(关注后回复此关键即可)一起进行学习,相关问题讨论。
温馨提示: 此处,先来看看本文章,将实现的企业Jenkins持续集成与交付的Pipeline流水线
,其构建部署结果如下所示:
1.Pipeline流水线构建参数
2.Pipeline流水线CI/CD完整流程执行结果
3.Pipeline流水线消息通知
温馨提示: 在文章末尾获取JenkinsPipeline
流线脚本以及Jenkins-Agent
镜像构建所需软件(镜像支持git openssh maven 3.9.4、jdk8/jdk11 gitlab-cli 0.15.0 nodejs
等工具环境)。
1.GitOps 介绍
什么是GitOps?
答: GitOps是一种软件开发和运维的方法论,它将代码的版本控制和应用程序的部署、管理、监控等操作紧密结合在一起,通过使用Git作为唯一的源代码存储库,实现了基础设施即代码的理念。
通过GitOps,开发团队可以通过提交代码来触发应用程序的部署和更新,而不需要手动进行部署操作。这样可以减少人为因素带来的错误,并保证了环境的一致性和可重复性。同时,GitOps还提供了自动化的监控和报警机制,可以及时发现并解决问题。
GitOps的核心原则包括:
基础设施即代码:将基础设施配置和操作以代码的形式存储和管理。
自动化:通过自动化工具和流程实现将代码变更应用到基础设施的过程。
可观察性:通过监控、日志和报警等手段来保证系统的可观察性,及时发现和解决问题。
声明式配置:使用声明式配置来描述期望的系统状态,由系统自动将实际状态与期望状态保持一致。
2.Jenkins 介绍
描述: Jenkins是一个开源的持续集成(CI)工具,它允许开发人员自动化构建、测试和部署软件项目。Jenkins提供了一个易于使用的Web界面,可以通过配置任务来实现自动化流程。
Jenkins的主要功能包括:
自动化构建:Jenkins可以从代码仓库(如Git、SVN等)中获取最新的代码,并自动进行构建、编译和打包。它支持各种编程语言和构建工具,如Java、Python、Maven、Gradle等。
持续集成:Jenkins可以在代码提交后自动触发构建和测试过程,以快速发现和解决代码集成问题。它可以与版本控制系统集成,如监测代码库的提交并触发自动构建。
测试和部署:Jenkins可以集成各种测试框架,并在构建过程中运行自动化测试。它还可以与云平台和容器技术集成,如Docker和Kubernetes,实现自动化部署和扩展。
插件生态系统:Jenkins有一个丰富的插件生态系统,提供了各种功能和集成选项。通过安装插件,可以扩展Jenkins的能力,满足特定项目的需求。
可扩展性:Jenkins是一个可扩展的平台,可以通过编写自定义插件和脚本来满足特定需求。它还支持分布式构建和部署,可以在多个节点上并行执行任务,提高效率。
总结: Jenkins的使用非常广泛,许多软件开发团队都使用它来实现持续集成和部署。它的灵活性和可扩展性使得开发人员可以根据自己的需求定制和扩展工作流程。
官方网站: https://www.jenkins.io
版本说明: https://www.jenkins.io/changelog-stable/
3.前置知识
描述: 前面作者提到本章是为实现在Jenkins中实现GitOps所示搭建部署的环境,所使用到的技术栈有 Jenkins + Gitlab + Harbor + Kubernetes (Docker)
,所以此基础上,你可能需要先安装配置 Kubernetes 、Gitlab 、Harbor、Docker(可选在构建镜像时以及使用其部署jenkins-agent时会用到)
等环境, 此处作者假设你们已经安装完毕,若不了解的
或者没有安装部署的朋友
,可以查看作者往期文章或者下面的链接。
Kubernetes
是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它提供了一种可靠的方式来运行、管理和扩展容器化应用程序,使开发人员可以专注于应用程序的开发,而无需过多关注底层基础设施的管理。关注公众号回复【
Kubernetes学习之路
】进行Kubernetes的学习(作者的入门学习K8S路线以及经验笔迹
)。
云原生 | 企业DevOps实践之使用kubeadm方式安装高可用k8s集群v1.23.7(点击访问)GitLab
是一个基于Git的版本控制和源代码管理平台。它提供了一个集成的Web界面,让团队能够协作开发、管理代码存储库、进行代码审查和问题跟踪等操作。GitOps实践 | 快速在银河麒麟KylinOS国产系统部署最新Gitlab-CE企业私有代码仓库(点击访问)
Harbor
是一个开源的企业级容器镜像注册表,它提供了一个安全可靠的方式来存储、分发和管理容器镜像。它是基于Docker Registry开发的,但在其基础上添加了一些额外的功能和特性。GitOps实践 | 快速在银河麒麟KylinOS国产系统部署最新Harbor企业私有镜像仓库(点击访问)
Docker
是一种开源的容器化平台,用于构建、发布和运行应用程序。它基于Linux容器技术,通过隔离应用程序的进程、文件系统和网络等资源,实现了应用程序的轻量级虚拟化。关注公众号回复【
Docker学习之路
】进行Docker的学习(作者的入门学习Docker路线以及经验笔迹
)。
Docker 的安装请参考此篇【0x01-Docker-安装实践
】文章 [https://blog.weiyigeek.top/2019/5-3-455.html#0x01-Docker-安装实践]或者Docker官网。
0x01 在 Jenkins 部署 GitOps 环境实践
1.环境说明
实践环境说明:
# K8S 高可用集群主机 x 4 & Docker 版本 & Jenkins 版本
系统发行版: Ubuntu 20.04
Kubernetes v1.23.17
集群SVC: https://kubernetes.default.svc.cluster.prod
Docker 20.10.3 (已经在其中一台工作节点上安装)
Jenkins 2.387.3 (其agent需要运行在JDK11以上,作者当时升级后到CI/CD不能用,只能重新构建agent镜像,当前极度痛苦)
# Gitlab 代码仓库 & Harbor 镜像仓库主机 x 2
系统发行版: Kylin Linux Advanced Server V10
gitlab-server 10.20.176.250 | Gitlab v16.2.0
harbor-server 10.20.176.251 | Harbor v2.8.2
Docker v24.0.4 | containerd v1.6.21 | Docker-compose v2.20.2
温馨提示:
Jenkins 2.387.3
为 2.3x 的最后一个版本,在2023年发布的我们实践的Jenkins版本还是比较新的,Jenkins 版本发布查看 [https://www.jenkins.io/changelog-stable]
温馨提示: 若你的基础环境使用的Ubuntu 22.04/20.04
或者是CentOS8
可以使用如下文章所示的脚本进行安全加固(线上环境必须,过保必须)
网安等保 | 主机安全之Ubuntu 22.04/20.04服务器配置优化与安全加固基线文档脚本分享 [https://mp.weixin.qq.com/s/dO1bV0tfXKn4ZmqlMcUrrQ]
网安等保 | 主机安全之CentOS8服务器配置优化与安全加固基线文档脚本分享 [https://mp.weixin.qq.com/s/WrwzkNaTGQ_xss727_ag9g]
2.在Kubernetes中快速安装配置Jenkins
描述: 此小节主要实践在K8S集群中安装部署我们的Jenkins工具。
操作部署
Step 1.使用 deployments 控制器安装 Jenkins 其部署配置清单yaml如下所示:
tee jenkins-deployments.yaml <<'EOF'
# 创建devops名称空间
apiVersion: v1
kind: Namespace
metadata:
name: devops
---
# 创建PV、PVC,为Jenkins提供数据持久化支持,storage-class 需要根据实际情况进行修改.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: devops
annotations:
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
---
# 创建ServiceAccount以及在devops名称空间中资源角色访问授权绑定
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-sa
namespace: devops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jenkins-cr
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-crd
roleRef:
kind: ClusterRole
name: jenkins-cr
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: jenkins-sa
namespace: devops
---
# 使用Deployment控制器部署Jenkins以及Service的创建
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: devops
spec:
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
terminationGracePeriodSeconds: 10
serviceAccount: jenkins-sa
containers:
- name: jenkins
image: docker.io/jenkins/jenkins:2.387.3-alpine # 升级时其自行备份数据已经指定Jenkins版本的镜像即可
imagePullPolicy: IfNotPresent
env:
- name: JAVA_OPTS
value: -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 2
memory: 4Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
readinessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
volumeMounts:
- name: jenkinshome
mountPath: /var/jenkins_home
securityContext:
fsGroup: 1000
volumes:
- name: jenkinshome
persistentVolumeClaim:
claimName: jenkins-pvc
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: devops
labels:
app: jenkins
spec:
selector:
app: jenkins
type: NodePort
ports:
- name: web
port: 8080
targetPort: web
nodePort: 30001
- name: agent
port: 50000
targetPort: agent
EOF
Step 2.使用kubectl命令创建的 PVC 持久卷创建、集群中角色创建绑定以及 Jenkins deployment
和 Services
服务,执行的命令: kubectl create -f jenkins-deployments.yaml
。
Step 3.查看创建的PVC、POD以及SVC
~$ kubectl get pvc,pod,svc -n devops
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# persistentvolumeclaim/jenkins-pvc Bound pvc-3cd916df-91cb-470d-b9ef-e9b4f115223d 5Gi RWX managed-nfs-storage 23m
# NAME READY STATUS RESTARTS AGE
# pod/jenkins-689775956-nph9z 1/1 Running 0 15m
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/jenkins NodePort 10.104.214.1 <none> 8080:30001/TCP,50000:30465/TCP 15m
# 使用 exec 命令进入到Shell终端中
~$ kubectl exec -n devops -it jenkins-689775956-nph9z bash
$ ps aux # 可看到有两个进程正在运行
# PID USER TIME COMMAND
# 1 jenkins 0:39 /sbin/tini -- /usr/local/bin/jenkins.sh # 主运行文件
# 6 jenkins 57:00 java -Duser.home=/var/jenkins_home -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai -Djenkins.model.Jenkins.slaveAgentPort=50000 -jar /usr/share/jenkins/jenkins.war # 运行 jenkins.war 的命令
Step 4.在资源清单中配置的NodePort类型端口为30001,我们直接在浏览器用这个端口访问Jenkins UI,
# Jenkins 初始化密码获取的两种方式;
# 方式1.认证
$ kubectl logs -n devops pod/jenkins-689775956-nph9z | grep -A 2 "following password"
# Please use the following password to proceed to installation:
# c45f558fa237472f9f8f954ceb3a323e 获取到首次登录密码
Step 5.此处按照【Jenkins入门学习之持续化集成与部署】[https://blog.weiyigeek.top/2020/12-28-513.html] 文章的操作进行初始化, 当然您也可以选择自定义插件安装 -> Languages (两项插件)
先进行汉化。
设置 Jenkins URL
操作:
Create First Admin User -> Instance Configuration (Jenkins URL) -> Save -> Restart 安装成功
配置: Jenkins URL: http://jenkins.weiyigeek.top:30001/ # 注意需要添加解析