K8s DevOps 工具链:Jenkins 2.426.3
基于 YAML 部署。
部署Jenkins
安装nfs服务
可以在任一台机器上部署nfs服务
yum install nfs-utils -y
systemctl start nfs
systemctl enable nfs
yum install nfs-utils -y
systemctl start nfs
systemctl enable nfs创建nfs共享目录
mkdir /data/v2 -p
tee -a /etc/exports<<'EOF'
/data/v2 *(rw,no_root_squash)
EOF
exportfs -arv准备前置资源
namespace
kubectl create namespace jenkins-k8sPV+PVC
- PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-k8s-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 172.16.183.100
path: /data/v2- PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkins-k8s-pvc
namespace: jenkins-k8s
spec:
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteMany- service account
kubectl create sa jenkins-k8s-sa -n jenkins-k8s
kubectl create clusterrolebinding jenkins-k8s-sa-cluster -n jenkins-k8s --clusterrole=cluster-admin --serviceaccount=jenkins-k8s:jenkins-k8s-sa- image
- jenkins主镜像:
docker.io/jenkins/jenkins:2.426.3 - jenkins slave pod镜像:
docker.io/library/jenkins.agent:v2
- jenkins主镜像:
部署deployment
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.426.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
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权限问题
报错显示没有权限操作/var/jenkins_home/copy_reference_file.log文件:
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?
解决办法如下:
kubectl delete -f jenkins-deployment.yaml chown -R 1000.1000 /data/v2 kubectl apply -f jenkins-deployment.yaml
部署service
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配置jenkins
登录
Nodeport暴露的jenkins服务,浏览器访问web ui:http://172.16.183.101:30002/login?from=%2F
在nfs服务端,PV存储里面获取到初始管理员密码:
cat /data/v2/jenkins-home/secrets/initialAdminPassword把密码输入到“解锁Jenkins”下面的“管理员密码”中。
初始化
- 登录后选择“安装推荐的插件”,创建第一个管理员用户,配置管理员密码。
- 实例配置中Jenkins URL填写http://172.16.183.101:30002
- 保存,提示Jenkins已就绪
安装必要插件
Manage Jnekins⇒插件管理⇒可选插件
- 搜索Kubernetes⇒选择Kubernetes安装,搜索blueocean⇒选择Blue Ocean安装
- 安装之后选择重新启动jenkins⇒ http://172.16.183.101:30002/restart⇒重启之后登陆jenkins,插件即可生效
Jenkins连接k8s集群
-
访问http://172.16.183.101:30002/configureClouds/,新增一个云,在下拉菜单中选择kubernetes并添加,kubernetes地址填https://172.16.183.100:6443 (master节点apiserver地址)
-
测试jenkins是否可以通信:Kubernetes名称空间填jenkins-k8s,点击连接测试,如果显示“Connected to Kubernetes”说明jenkins与k8s可以进行通信
-
Jenkins地址填svc的地址:http://jenkins-service.jenkins-k8s.svc.cluster.local:8080
-
点击保存
配置pod template
-
在已保存的云中选择刚创建的kubernetes,进去点击Pod Templates ⇒ Add a pod template
-
Pod Template Details中:
- 命名空间填jenkins-k8s
- 标签列表可以添加一个自定义的:testhan
-
点击容器列表下的添加容器,选container template:
- 名称:
jnlp(固定值,必须写jnlp) - Docker镜像:
docker.io/library/jenkins.agent:v2 - 工作目录:
/home/jenkins/agent - 运行的命令 和 命令参数 两行清空
- 分配伪终端:打勾
- 名称:
-
给pod template添加卷:
在卷中选择添加卷,添加5个Host Path Volume类型的卷:
- 主机路径:
/var/run/docker.sock,挂载路径:/var/run/docker.sock - 主机路径:
/root/.kube,挂载路径:/home/jenkins/.kube - 主机路径:
/usr/bin/docker,挂载路径:/usr/bin/docker - 主机路径:
/usr/bin/kubectl,挂载路径:/usr/bin/kubectl - 主机路径:
/etc/docker/daemon.json,挂载路径:/etc/docker/daemon.json
- 主机路径:
-
对工作节点上的docker.sock设置属主属组
chown 1000:1000 /var/run/docker.sock
chmod 777 /var/run/docker.sock
chmod 777 /usr/bin/docker
chown -R 1000.1000 /usr/bin/docker
chmod 777 /usr/bin/kubectl
chown -R 1000.1000 /usr/bin/kubectl- 把控制节点的.kube目录复制到工作节点
# 控制节点上
scp -r /root/.kube/ rn1:/root/
# 工作节点上
chown -R 1000.1000 /root/.kube/- 在Environment Variable ⇒ 高级中,勾选以最高权限运行。
- 在service account处填入
jenkins-k8s-sa,是一开始部署的sa - 配置好之后选择Create
连接harbor
- 首先需要安装 Harbor
- Jenkins中首页⇒系统管理⇒管理凭据⇒Stores scoped to Jenkins⇒全局⇒添加凭据
- 类型:Username with Password,范围:全局,用户名和密码:写harbor的用户名密码,ID:dockerharbor。
- 点击Create
编写Pipeline
-
harbor中新建项目
jenkins-demo -
新建一个任务⇒输入任务名称jenkins-harbor⇒流水线⇒确定⇒在Pipeline script处写入脚本:
node('jenkins-jenkins-agent') { stage('第1步:从gitee上下载源代码') { git url: "https://gitee.com/hangxu969/jenkins-sample" script { build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() } } stage('第2步:基于dockerfile文件制作镜像') { withCredentials([usernamePassword(credentialsId: 'harbork8s', passwordVariable: 'harborPassword', usernameVariable: 'harborUser')]) { sh "docker login harbor.hanxux.local -u ${harborUser} -p ${harborPassword}" sh "docker build -t harbor.hanxux.local/jenkins-demo/jenkins-demo:${build_tag} ." } } stage('第3步:把镜像上传到harbor私有仓库') { withCredentials([usernamePassword(credentialsId: 'harbork8s', passwordVariable: 'harborPassword', usernameVariable: 'harborUser')]) { sh "docker login harbor.hanxux.local -u ${harborUser} -p ${harborPassword}" sh "docker push harbor.hanxux.local/jenkins-demo/jenkins-demo:${build_tag}" } } stage('第4步:把pod部署到开发环境') { sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev-harbor.yaml" sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev-harbor.yaml" // sh "bash running-devlopment.sh" sh "kubectl apply -f k8s-dev-harbor.yaml --validate=false" } stage('第5步:把pod部署到测试环境') { def userInput = input( id: 'userInput', message: '确定部署到测试环境吗?输入yes确定', parameters: [ [ $class: 'ChoiceParameterDefinition', choices: "YES\nNO", name: 'Env' ] ] ) echo "This is a deploy step to ${userInput}" if (userInput == "YES") { sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa-harbor.yaml" sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa-harbor.yaml" //sh "bash running-qa.sh" sh "kubectl apply -f k8s-qa-harbor.yaml --validate=false" sh "sleep 6" sh "kubectl get pods -n qatest" // sh "cd /home/jenkins/agent/workspace/jenkins-harbor" // sh "/root/Python-3.12.5/python qatest.py" } else { //exit } } stage('第6步:pod部署到生产环境') { def userInput = input( id: 'userInput', message: '确定部署到生产环境吗?输入yes确定', parameters: [ [ $class: 'ChoiceParameterDefinition', choices: "YES\nNO", name: 'Env' ] ] ) echo "This is a deploy step to ${userInput}" if (userInput == "YES") { sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod-harbor.yaml" sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod-harbor.yaml" // sh "bash running-production.sh" sh "cat k8s-prod-harbor.yaml" sh "kubectl apply -f k8s-prod-harbor.yaml --record --validate=false" // sh "cd /home/jenkins/agent/workspace/jenkins-harbor" // sh "/root/Python-3.12.5/python smtp.py" } } } -
应用⇒保存⇒立即构建⇒打开blue ocean可以看到流程,可以在交互式输入中手动点击确认