Jenkins master和jenkins-slave都运行在k8s集群内,采用如下架构部署:
名称 | IP | 版本 |
---|---|---|
k8s-master61 | 192.168.223.61 | 1.21.0 |
k8s-node62 | 192.168.223.62 | 1.21.0 |
jenkins | 192.168.223.62 | 2.332.3 |
安装 nfs 服务,可以选择自己的任意一台机器,我选择的是 k8s 的控制节点 k8s-master61
1.1 在k8s-master61 和 k8s-node62 上安装 nfs 服务
注意:如果已经安装过 nfs,这个步骤可以忽略
[root@k8s-master61 ~]# yum install nfs-utils -y
[root@k8s-master61 ~]# systemctl start nfs
[root@k8s-master61 ~]# systemctl enable nfs
[root@k8s-node62 ~]# yum install nfs-utils -y
[root@k8s-node62 ~]# systemctl start nfs
[root@k8s-node62 ~]# systemctl enable nfs
1.2 在k8s-master61 上创建一个 nfs 共享目录
#1) 创建共享目录/data/v2
[root@k8s-master61 ~]# mkdir /data/v2 -p
[root@k8s-master61 ~]# cat /etc/exports
/data/v1 192.168.223.0/24(rw,no_root_squash)
/data/v2 192.168.223.0/24(rw,no_root_squash)
/data/nfs_yaml 192.168.223.0/24(rw,no_root_squash)
/data/myImages 192.168.223.0/24(rw,no_root_squash)
#根据自己需求进行创建
#/data/myImages 存放镜像
#/data/nfs_yaml 存放yaml文件
#2)使配置文件生效
[root@k8s-master61 ~]# exportfs -arv
[root@k8s-master61 ~]# systemctl restart nfs
[root@k8s-master61 ~]# kubectl create namespace jenkins-k8s
namespace/jenkins-k8s created
[root@k8s-master61 ~]# kubectl get ns |grep jenkins-k8s
jenkins-k8s Active 8s
# 应用资源配置清单
[root@k8s-master61 k8s-jenkins]# kubectl apply -f pv-pvc.yaml
[root@k8s-master61 k8s-jenkins]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
jenkins-k8s-pv 10Gi RWX Retain Available
#查看创建的pvc
[root@k8s-master61 k8s-jenkins]# kubectl get pvc -n jenkins-k8s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jenkins-k8s-pvc Bound jenkins-k8s-pv 10Gi RWX 43s
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-k8s-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.223.61
path: "/data/v2"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-k8s-pvc
namespace: jenkins-k8s
spec:
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteMany
注意: pvc可以属于某个命名空间,pv不属于任何命名空间
[root@k8s-master61 k8s-jenkins]# kubectl api-resources |grep pv
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
应用资源配置清单:
[root@k8s-master61 k8s-jenkins]# kubectl apply -f rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-k8s-sa
namespace: jenkins-k8s
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins-k8s-cluseterrole
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-k8s-sa-cluster
namespace: jenkins-k8s
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins-k8s-cluseterrole
subjects:
- kind: ServiceAccount
name: jenkins-k8s-sa
namespace: jenkins-k8s
参考jenkins官方文档:https://www.jenkins.io/doc/book/installing/kubernetes/
#)提前下载了该镜像
# docker pull jenkins/jenkins:2.332.3
#或者上传镜像到k8s 各 node 节点,并手动解压
# gunzip -c jenkins_2.332.3.tar.gz |docker load
更新资源清单文件
[root@k8s-master61 k8s-jenkins]# kubectl apply -f jenkins-deployment.yaml
deployment.apps/jenkins created
[root@k8s-master61 k8s-jenkins]# kubectl get pod -n jenkins-k8s
NAME READY STATUS RESTARTS AGE
jenkins-bddf8d8fb-gpmzr 0/1 CrashLoopBackOff 1 15s
#看到 jenkins-bddf8d8fb-gpmzr 是 CrashLoopBackOff 状态,查看日志:
[root@k8s-master61 k8s-jenkins]# kubectl logs jenkins-bddf8d8fb-gpmzr -n jenkins-k8s
touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
报错显示没有权限操作/var/jenkins_home/copy_reference_file.log 文件,解决办法如下:
#删除创建的pod
[root@k8s-master61 k8s-jenkins]# kubectl delete -f jenkins-deployment.yaml
deployment.apps "jenkins" deleted
#修改属主数组
[root@k8s-master61 k8s-jenkins]# chown -R 1000.1000 /data/v2
[root@k8s-master61 k8s-jenkins]# kubectl apply -f jenkins-deployment.yaml
deployment.apps/jenkins created
# 查看创建成功
[root@k8s-master61 k8s-jenkins]# kubectl get pod -n jenkins-k8s
NAME READY STATUS RESTARTS AGE
jenkins-bddf8d8fb-2vbn8 0/1 Running 0 15
kind: Deployment
apiVersion: apps/v1
metadata:
name: jenkins
namespace: jenkins-k8s
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccount: jenkins-k8s-sa
containers:
- name: jenkins
image: jenkins/jenkins:2.332.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 1Gi
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: jenkins-volume
subPath: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-volume
persistentVolumeClaim:
claimName: jenkins-k8s-pvc
更新资源清单文件
[root@k8s-master61 k8s-jenkins]# kubectl apply -f jenkins-service.yaml
service/jenkins-service created
[root@k8s-master61 k8s-jenkins]# kubectl get svc -n jenkins-k8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins-service NodePort 10.100.119.49 <none> 8080:30002/TCP,50000:30008/TCP 25s
#通过上面可以看到 service 的 8080 端口在物理机映射的端口是 30002
apiVersion: v1
kind: Service
metadata:
name: jenkins-service
namespace: jenkins-k8s
labels:
app: jenkins
spec:
selector:
app: jenkins
type: NodePort
ports:
- name: web
port: 8080
targetPort: web
nodePort: 30002
- name: agent
port: 50000
targetPort: agent
在 nfs 服务端,也就是我们的 k8s-master61 节点获取密码:
# cat /data/v2/jenkins-home/secrets/initialAdminPassword
5474b1dba2094710a2ebfb06df922570
(2)插件安装好之后显示如下
(3)创建第一个管理员用户
(4) 设置密码完成,点击保存并完成,并开始使用
接下来我们就需要来配置 Jenkins,让他能够动态的生成 Slave 的 Pod。
(1) 修改配置文件地址
#1) 进入配置目录
[root@k8s-master61 ~]# cd /data/v2/jenkins-home/updates/
[root@k8s-master61 updates]# ll
总用量 2872
-rw-r--r-- 1 1000 1000 2639693 6月 5 23:44 default.json
-rw-r--r-- 1 1000 1000 5569 6月 5 23:58 hudson.tasks.Ant.AntInstaller
-rw-r--r-- 1 1000 1000 6040 6月 5 23:44 hudson.tasks.Maven.MavenInstaller
-rw-r--r-- 1 1000 1000 279724 6月 5 23:58 hudson.tools.JDKInstaller
#2)替换为国内地址
[root@k8s-master61 updates]# sed -i 's/http:\/\/updates.jenkinsci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
[root@k8s-master61 updates]# sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
(2) 修改页面插件下载地址
最后,系统管理 --> 插件管理 --> 高级,把站点升级改为国内插件下载地址
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
(1)在 jenkins 中安装 k8s 插件
Manage Jnekins------>插件管理------>可选插件------>搜索 kubernetes------>出现如下
选中 kubernetes 之后------>点击下面的直接安装------>安装之后选择重新启动 jenkins—> http://192.168.223.61:30002/restart–>重启之后登陆 jenkins,插件即可生效
(2)安装 blueocean 插件
Manage Jnekins------>插件管理------>可选插件------>搜索 blueocean------>出现如下
选中 BlueOcean 之后------>点击下面的直接安装------>安装之后选择重新启动 jenkins—> http://192.168.223.61:30002/restart–>重启之后登陆 jenkins,插件即可生效
(1)访问 http://192.168.223.61:30002/configureClouds/
或者如下方式选择:系统管理–>节点管理
新增一个云,在下拉菜单中选择 kubernets 并添加
(3)测试 jenkins 和 k8s 是否可以通信
点击连接测试,如果显示 Connection test successful 或者
Connected to Kubernetes v1.21.0,说明测试成功,Jenkins 可以和 k8s 进行通信
http://jenkins-service.jenkins-k8s.svc.cluster.local:8080
配置 k8s 集群的时候 jenkins 地址需要写上面域名的形式,配置之后执行如下:
应用------>保存
(1)配置 pod template
访问 http://192.168.40.180:30002/configureClouds/
(2)在上面的 pod template 下添加容器
添加容器------>Container Template------>按如下配置------>
在 Service Account 处输入 jenkins-k8s-sa,这个 sa 就是我们最开始安装 jenkins 时的 sa
(3)给上面的 pod template 添加卷
添加卷------>选择 Host Path Volume
使容器能够宿主机docker:
/var/run/docker.sock
/var/run/docker.sock
使容器能够使用kubctl
/root/.kube
/home/jenkins/.kube
上面配置好之后,Apply(应用)------>Save(保存)
到这里我们的 Kubernetes Plugin 插件就算配置完成了。
Kubernetes 插件的配置工作完成了,接下来我们就来添加一个 Job 任务,看是否能够在 Slave Pod 中执行,任务执行完成后看 Pod 是否会被销毁。
在 Jenkins 首页点击create new jobs,创建一个测试的任务,输入任务名称,然后我们选择 Freestyle project 类型的任务:
echo "测试 Kubernetes 动态生成 jenkins slave"
echo "==============docker in docker==========="
docker info
echo "=============kubectl============="
kubectl get pods
现在我们直接在页面点击做成的 Build now 触发构建即可,然后观察 Kubernetes 集群中 Pod 的变化
下一篇: Jenkins+k8s+github实现DevOps流程