一、部署Harbor镜像仓库
二、jenkins镜像打包
1、书写dockerfile(添加检测jenkins健康检测脚本)
cat > Jenkins.df <<EOF
FROM jenkins/jenkins:latest
ADD healthcheck.sh /healthcheck.sh
EXPOSE 8080
EOF
2、书写healthcheck.sh 健康检查脚本
cat > healthcheck.sh <<EOF
#!/bin/bash
pod_name=$1
healthcheck_url=$2
status_code=`curl http://${healthcheck_url} -o /dev/null -w '%{http_code}\n' -s`
dingding_token=$3
check_type=$4
failure_time=3
message="报警康检查异常:$pod_name
\n检查类型:$check_type
\n检查时间:$(date +%F_%T |awk -F "_" '{print $1,$2}')
\n检查地址:$healthcheck_url
\n状态码: $status_code
\n错误次数:$failure_time
\nPod名称: $POD_NAME
"
json="{
\"actionCard\": {
\"title\": \"健康检查异常\",
\"text\": \"$message\",
\"hideAvatar\": \"0\",
\"btnOrientation\": \"0\",
\"btns\": [{\"title\": \"容器服务异常\",\"actionURL\": \"http://$healthcheck_url\"}]},
\"msgtype\": \"actionCard\"}"
if [ "$status_code" == "200" ];then
echo "健康检查OK"
else
curl 'https://oapi.dingtalk.com/robot/send?access_token='$dingding_token \
-H 'Content-Type: application/json' \
-d "$json"
fi
EOF
3、修改权限
chmod 777 healthcheck.sh
4、Jnekins打包镜像
docker build -f Jenkins.df -t 192.168.11.128:4430/library/jenkins:latest ./
4、上传到镜像仓库
- 上传
docker push 192.168.11.128:4430/library/jenkins:latest
- 登录
docker login https://192.168.11.128:4430 -uadmin -pHarbor12345
- 再次上传
docker push 192.168.11.128:4430/library/jenkins:latest
三、搭建持久性存储卷(网络存储)
具体可查看 搭建NFS
1、 创建持久卷目录
mkdir -p /root/DevOps/data
2、共享路径放到nfs共享配置文件中
/root/DevOps/data 192.168.11.0/24(rw,no_root_squash,async) >> /etc/exports
3、 加载NFS的共享配置文件
exportfs -arv
四、kubernetesc持久卷(作用:存储基本的詹金斯数据)
1、书写资源清单
vim volume.yaml
apiVersion: v1
kind: PersistentVolume #设置控制器为PV
metadata:
name: jenkins-pvdate #定义pv名称
namespace: jenkins
labels:
name: jenkins-pvdate
spec:
nfs: #定义存储类型为nfs
path: /root/DevOps/data #nfs共享路径
server: 192.168.11.128 #nfs共享服务service
storageClassName: nfs #存储类名
persistentVolumeReclaimPolicy: Retain #卷的策略(保留)
accessModes: #访问模式
- ReadWriteMany #该卷可以被许多节点读写安装
capacity: #容量
storage: 20Gi #存储大小
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs
2、生成资源清单
kubectl apply -f volume.yaml
3、查看卷情况
kubectl get pv,pvc -n jenkins
五、 Jenkins集群角色资源
1、考虑安全与权限问题对Jenkins授权进行限制
vim Jenkinsrbac.yaml
apiVersion: v1
kind: ServiceAccount #在jenkins名称空间下生成sa服务账号
metadata:
name: jenkins-pipeline #sa的名称
namespace: jenkins #名称空间
---
kind: ClusterRole #集群角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins-pipeline
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-pipeline
namespace: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole #绑定集群角色
name: jenkins-pipeline #绑定集群角色名称
subjects:
- kind: ServiceAccount #绑定类型(这里绑定的是sa)
name: jenkins-pipeline #sa名称
namespace: jenkins #绑定sa隶属于名称空间间
2、生成角色清单
kubectl apply -f Jenkinsrbac.yaml
3、查看集群角色信息
kubectl describe clusterrole jenkins-pipeline && kubectl describe clusterrolebindings.rbac.authorization.k8s.io jenkins-pipeline
六、部署Jenkins
1、书写资源清单
vim jenkins-deployment.yaml
apiVersion: apps/v1
kind: Deployment #控制器
metadata:
name: jenkins-pipeline #这个标签为启动pod时候的名字
namespace: jenkins
spec:
replicas: 1 #启动副本数
selector: #设置标签
matchLabels:
app: jenkins-pipeline #这个标签相当于分组,查看(kubectl get pods --show-labels)
minReadySeconds: 5 #等待设置的时间后才进行升级,(如果没有设置该值,在某些极端情况下可能会造成服务不正常运行)
revisionHistoryLimit: 2 #要保留以允许回滚的旧复制集数
strategy: #策略
type: RollingUpdate #默认为滚动更新(可以不写)
rollingUpdate: #滚动更新
maxSurge: 1 #升级过程中最多可以比原先设置多出的POD数量
maxUnavailable: 1 #升级过程中最多有多少个POD处于无法提供服务的状态(该不为0)
template: #模板(相当于定义好的一个python中的模块)
metadata:
labels:
app: jenkins-pipeline #这个标签需要selector定义的标签一个,划分在同一个组
spec:
serviceAccount: jenkins-pipeline #指定sa服务账号的权限
containers: #模板(容器模板)
- name: jenkins-pipeline #node节点启动的容器名字(kind控制器名字+标签名)
image: 192.168.11.128:4430/library/jenkins:latest #镜像名
imagePullPolicy: IfNotPresent #拉取镜像(选择方式——直接使用本地拥有的镜像)
ports:
- containerPort: 8080 #容器开放的监听端口
name: pipeline
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 1
memory: 2000Mi
requests:
cpu: 0.5
memory: 1000Mi
livenessProbe: #判断容器是否存活、如果livenessProbe检查不健康就杀死该容器
exec:
command: ['bash','/healthcheck.sh','jenkins-pipeline','127.0.0.1:8080/login','cf9097584cce8031df74d29f45eeae01c6712da0c4f842faf303c24a3000d118','3']
initialDelaySeconds: 70 #初始化探测的延迟时间(容器启动立即探测会报错—容器启动也需要时间哇
timeoutSeconds: 5 #探测时候始终没有响应等待多久时长(默认为一秒)
failureThreshold: 3 #探测多少次失败才失败(默认为3次)
periodSeconds: 3 #认周期探测时长,多久去探测一次(默认为10秒一次)
readinessProbe: #判断容器是否可用性, 达到ready状态的pod才可以接收请求,当为false时候,这个容器将从ep的列表中移除,这样就不会照成用户访问返回不正常的状态码(3xx、4xx、5xx)
exec:
command: ['bash','/healthcheck.sh','jenkins-pipeline','127.0.0.1:8080/login','cf9097584cce8031df74d29f45eeae01c6712da0c4f842faf303c24a3000d118','3']
initialDelaySeconds: 60 #初始化探测的延迟时间(容器启动立即探测会报错—容器启动也需要时间哇
timeoutSeconds: 5 #探测时候始终没有响应等待多久时长(默认为一秒)
failureThreshold: 3 #探测多少次失败才失败(默认为3次)
periodSeconds: 3 #认周期探测时长,多久去探测一次(默认为10秒一次)
startupProbe: #startupProbe探测成功后再交给livenessProbe探针
exec:
command: ['bash','/healthcheck.sh','jenkins-pipeline','127.0.0.1:8080/login','cf9097584cce8031df74d29f45eeae01c6712da0c4f842faf303c24a3000d118','3']
initialDelaySeconds: 60 #容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认是 0 秒(建议时间设置大于1分钟有些程序运行较慢不适合立马进行探针)
periodSeconds: 3 #每多少秒执行一次活动性探测, 执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。
timeoutSeconds: 1 #探测的超时后等待多少秒。默认值是 1 秒。最小值是 1
failureThreshold: 3 #当探测失败时,Kubernetes 的重试次数。默认值是 3。最小值是 1。
env:
- name: JAVA_OPTS
value: -Duser.timezone=GMT+08
-Xms1512m
-Xmx1512m
- name: POD_NAME #容器的环境变量名称
valueFrom:
fieldRef:
fieldPath: metadata.name #Pod名称
volumeMounts:
- name: jenkinshome
subPath: jenkins #在挂载目录下规划到生成的子目录下(jenkins)
mountPath: /var/jenkins_home
- name: timezone #时间同步
mountPath: /etc/localtime
securityContext: #属主组权限
fsGroup: 1000
volumes:
- name: jenkinshome
persistentVolumeClaim:
claimName: jenkins-pvc #pvc的名称
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
imagePullSecrets:
- name: docek-harbor
restartPolicy: Always #重新启动pod中所有容器的策略
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-pipeline
namespace: jenkins
labels:
app: jenkins-pipeline
spec:
selector:
app: jenkins-pipeline
type: NodePort
ports:
- name: jenkins-pipeline
port: 8080
targetPort: pipeline
nodePort: 30081
- name: agent
targetPort: agent
port: 50000
2、配置拉取镜像私仓认证
kubectl create secret docker-registry docek-harbor --docker-server=https://192.168.11.128:4430 --docker-username=admin --docker-password=Harbor12345 --docker-email=2216170240@qq.com
3、生成资源清单
kubectl apply -f jenkins-deployment.yaml
4、排查日志信息
kubectl logs -n jenkins jenkins-pipeline-7486dfd7d7-mv6jg
上面提示权限问题, 上面Yaml文件中已经设置securityContext , 而我们nsf进行是挂载共享目录 /root/DevOps/data ,此目录的权限是root。所以造成提示权限问题。 OK,进行权限修改即可处理。
5、修改/root/DevOps/data 权限
chown -R 1000 /root/DevOps/data
七、访问Jenkins界面
1、获取Jenkins对外暴露端口
kubectl get po,svc -n jenkins
2、访问web界面
3、登录
上面我们做了nfs网络共享一个持久卷/root/DevOps/data 目录吗? 我们将这个共享路径映射到容器的 /var/jenkins_home目录。所以提示路径是/var/jenkins_home。 根据分析提示获取登录密码。
cat /root/DevOps/data/jenkins/secrets/initialAdminPassword
4、安装
可能有些插件会安装失败。可以跳过等真的需要插件再进行安装即可
5、更新Jenkins.war包(我的war太老了)
接下来点击更新(自动升级版本
)
目前jenkins部署完成。