自动化CICD总览:
拉取代码 --> 代码编译 --> 单元测试 --> 构建镜像 --> 部署到K8S集群 --> 功能验证

前提条件:
- Jenkins部署在K8S集群中(非集群中需要配置jenkins可以连接当前的K8S集群);
- Gitlab服务正常启动;
- Harbor服务正常启动;
一、成果概览¶
原数据信息:

参数化构建:

构建过程:

自动发布到Kubernetes集群:

流程结束:

二、部署Jenkins(v2.504.1)¶
1、定义控制器文件
(1)定义jenkins-deploy-svc.yaml文件
[root@master01 4]# vim jenkins-deploy-svc.yaml
---
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: registry.cn-hangzhou.aliyuncs.com/abroad_images/jenkins:2.387.2-lts
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 2000m
memory: 3Gi
requests:
cpu: 500m
memory: 1Gi
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
env:
- name: JAVA_OPTS
value: -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Duser.timezone=Asia/Shanghai -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
securityContext:
#ifsGroup: 1000
runAsUser: 0
volumes:
- name: jenkinshome
persistentVolumeClaim:
claimName: jenkins-pvc
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: devops
labels:
app: jenkins
spec:
selector:
app: jenkins
type: ClusterIP
ports:
- name: web
port: 8080
targetPort: web
- name: agent
port: 50000
targetPort: agent
默认情况下,Jenkins生成代理是保守的。
例如,如果队列中有两个构建,它不会立即生成两个执行器。它将生成一个执行器,并等待某个时间释放第一个执行器,然后再决定生成第二个执行器。Jenkins确保它生成的每个执行器都得到了最大限度的利用。
如果你想覆盖这个行为,并生成一个为每个构建队列不等待的执行器,所以在Jenkins启动时候添加这些参数
- -Dhudson.slaves.NodeProvisioner.initialDelay=0
- -Dhudson.slaves.NodeProvisioner.MARGIN=50
- -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
(2)定义jenkins-rbac.yaml
[root@master01 4]# vim jenkins-rbac.yaml
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
说明:新版本rbac已经不支持rbac.authorization.k8s.io/v1beta1
(3)定义jenkins-pvc.yaml
[root@master01 4]# vim jenkins-pvc.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Delete
nfs:
server: 192.168.1.66
path: /opt/sharedata/data/jenkins
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: devops
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
(4)定义jenkins-ing.yaml
[root@master01 4]# vim jenkins-ing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/enable-cors: 'true'
nginx.ingress.kubernetes.io/proxy-body-size: 50M
name: jenkins-ingress
namespace: devops
spec:
ingressClassName: nginx
rules:
- host: jenkins.zhang-qing.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: jenkins
port:
number: 8080
2、Jenkins使用NFS做数据持久化
#在nfs机器上创建相关目录
[root@node01 ~]# mkdir -p /opt/sharedata/data/jenkins
#在nfs机器上修改/etc/exports文件
[root@node01 ~]# vim /etc/exports
/opt/sharedata 192.168.1.0/24(rw,sync,insecure,no_subtree_check,no_root_squash)
/opt/sharedata/data/jenkins 192.168.1.0/24(rw,sync,insecure,no_subtree_check,no_root_squash)
#在nfs机器配置生效
[root@k8s-node01 ~]# exportfs -r
#在nfs机器重新加载NFS
[root@k8s-node01 ~]# systemctl reload nfs-server
3、开始部署
(1)创建ns
[root@master01 4]# k create ns devops
(2)部署
[root@master01 ~]# cd /root/4
[root@master01 4]# kaf jenkins-deploy-svc.yaml,jenkins-rbac.yaml,jenkins-pvc.yaml,jenkins-ing.yaml
(3)查看
#查看pod
[root@master01 4]# kgp -n devops -owide | grep jenkins
jenkins-b6bf6dd-vwrhz 1/1 Running 0 41m 172.31.112.148 master01 <none> <none>
#查看pvc
[root@master01 4]# kg pvc -n devops | grep jenkins
jenkins-pvc Bound pvc-d0a1cc4a-789e-4129-9e51-102fe701f0e5 10Gi RWX nfs-storage 141m
#查看svc
[root@master01 4]# kg svc -n devops | grep jenkins
jenkins ClusterIP 10.0.6.148 <none> 8080/TCP,50000/TCP 141m
4、登录测试
初始化的密码我们可以在 jenkins 的容器的日志中进行查看,也可以通过指定数据位置查看:
# 方式一:在日志中查看
[root@master01 harbor]# k logs -f jenkins-b6bf6dd-vwrhz -n devops
...
...
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
61a0d866a86c4add9a79d85c7c994d2b
...
...
# 方式二:指定数据位置查看
[root@master01 4]# kubectl exec -it jenkins-b6bf6dd-vwrhz -ndevops -- cat /var/jenkins\_home/secrets/initialAdminPassword
61a0d866a86c4add9a79d85c7c994d2b
需要在 nfs 共享数据目录下面把我们的目录权限重新分配下即可:
$ chown -R 1000 /opt/sharedata/data/jenkins
打开浏览器,输入http://jenkins.zhang-qing.com/后,填写管理员密码61a0d866a86c4add9a79d85c7c994d2b
点击【选择插件来安装】

选择【无】后,点击【安装】

配置管理员用户,配置完成后,选择【保存并完成】

配置Jenkins URL,点击【保存并完成】

上面配置完成后,代表Jenkins部署完成
