1. 实验环境
1.1 k8s环境
1)Kubernetes 集群版本是 1.20.6
2)k8s控制节点:
IP:192.168.140.130
主机名:k8s-master
配置:4C6G
3)k8s工作节点
节点1:
IP:192.168.140.131
主机名:k8s-node1
配置:4C7.5G
节点2:
IP:192.168.140.132
主机名:k8s-node2
配置:4C11G
1.2 GitLab 环境
地址:http://192.168.140.132:8001/
代码仓库地址: http://192.168.140.132:8001/root/jenkins-sample.git
代码下载链接:https://pan.baidu.com/s/1xbW-zUf23tu0YSV-5c1dew?pwd=lmzf
提取码:lmzf
GitLab安装过程参考:Yum一键安装GitLab_yum gitlab-****博客
1.3 Harbor环境
IP:192.168.140.132
1.4 Jenkins环境
版本:Jenkins 2.394
对应的jnlp软件下载地址如下:
链接:https://pan.baidu.com/s/1bNYiZCHWT099eOEdhDmJ3Q?pwd=lmzf
提取码:lmzf
备注:docker load -i jenkins-slave-latest.tar.gz 镜像即为jenkins-slave-latest:v1
2. 安装环境
2.1 安装 nfs 服务
1)三个节点分别安装nfs服务,k8s-master作为服务端
[root@k8s-master ~]# yum -y install nfs-utils
[root@k8s-master ~]# systemctl enable nfs --now
[root@k8s-node1 ~]# yum -y install nfs-utils
[root@k8s-node1 ~]# systemctl enable nfs --now
[root@k8s-node2 ~]# yum -y install nfs-utils
[root@k8s-node2 ~]# systemctl enable nfs --now
2)k8s-master上创建共享目录
[root@k8s-master ~]# mkdir /data/v2 -p
[root@k8s-master ~]# vim /etc/export
/data/v2 192.168.140.0/24(rw,no_root_squash)
[root@k8s-master ~]# exportfs -arv
[root@k8s-master ~]# systemctl restart nfs
2.2 在 kubernetes 中部署 jenkins
1)创建名称空间
[root@k8s-master ~]# kubectl create namespace jenkins-k8s
2)创建 pv
[root@k8s-master ~]# kubectl apply -f pv.yaml
# pv.yaml文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-k8s-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.140.130
path: /data/v2
3)创建pvc
[root@k8s-master ~]# kubectl apply -f pvc.yaml
# pvc.yaml文件
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkins-k8s-pvc
namespace: jenkins-k8s
spec:
resources:
requests:
storage: 10Gi
accessModes:
- ReadWriteMany
4)查看 pvc 是否创建成功
[root@k8s-master ~]# kubectl get pvc -n jenkins-k8
[root@k8s-master ~]# kubectl get pvc -n jenkins-k8s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jenkins-k8s-pvc Bound jenkins-k8s-pv 10Gi RWX 8h
5)创建一个 sa 账号
[root@k8s-master ~]# kubectl create sa jenkins-k8s-sa -n jenkins-k8s
6)把上面的 sa 账号做 rbac 授权
[root@k8s-master ~]# kubectl create clusterrolebinding jenkins-k8s-sa-cluster -n jenkins-k8s --clusterrole=cluster-admin --serviceaccount=jenkins-k8s:jenkins-k8s-sa
7)Jenkins文件夹授权
[root@k8s-master ~]# chown -R 1000.1000 /data/v2
8)deployment 部署 jenkins
[root@k8s-master ~]# kubectl apply -f jenkins-deployment.yaml
# jenkins-deployment.yaml文件
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.394
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
nodeName: k8s-node1
备注:
a. image: jenkins/jenkins:2.394 通过在k8s-node1节点直接下载获取
[root@k8s-node1 ~]# docker pull jenkins/jenkins:2.394
b. nodeName: k8s-node1: 本文指定部署在node1j节点
9)查看 jenkins 是否创建成功,如下所示表明创建成功
[root@k8s-master ~]# kubectl get pods -n jenkins-k8s
NAME READY STATUS RESTARTS AGE
jenkins-5558b49ff5-dqhz5 1/1 Running 2 9h
10)把 jenkins 前端加上 service,提供外部网络访问
[root@k8s-master ~]# kubectl apply -f jenkins-service.yaml
# jenkins-service.yaml文件
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
2.3 配置 Jenkins
1)浏览器访问Jenkins页面:http://192.168.140.132:30002/
2)获取管理员密码
[root@k8s-master ~]# cat /data/v2/jenkins-home/secrets/initialAdminPassword
把上面获取到的密码拷贝到上面管理员密码下的方框里
点击继续,出现如下界面
3)安装推荐的插件
插件安装好之后显示需要创建用户
4)创建管理员用户
点击保存并完成,出现如下界面
点击保存并完成,出现如下界面
2.4 测试Jenkins的CICD
1)在 Jenkins 中安装 kubernetes 和blueocean插件
Manage Jnekins------>插件管理------>可选插件------>搜索 kubernetes------>出现如下
选中 kubernetes 之后------>点击下面的直接安装------>安装之后选择重新启动 jenkins--->
http://192.168.40.180:30002/restart-->重启之后登陆 jenkins,插件即可生效
备注:blueocean插件安装流程和安装kubernetes插件一致
2)配置 jenkins 连接到我们存在的 k8s 集群
访问地址 http://192.168.140.130:30002/configureClouds/,新增一个云,在下拉菜单中选择 kubernets 并添加
3)填写kubenetes信息
kubenetes地址:https://192.168.140.130:6443
4)测试 jenkins 和 k8s 是否可以通信
点击连接测试,如果显示 Connection test successful 或者Connected to Kubernetes v1.20.6,说明测试成功, Jenkins 可以和 k8s 进行通信。
Jenkins地址:http://jenkins-service.jenkins-k8s.svc.cluster.local:8080
配置 k8s 集群的时候 jenkins 地址需要写上面域名的形式,配置之后执行如下:应用------>保存
5)配置pod template
访问地址 http://192.168.140.130:30002/configureClouds/,
按照如下配置:
6)在上面的 pod template 下添加容器
添加容器------>Container Template------>按如下配置
备注:Docker镜像jenkins-slave-latest:v1为 docker load -i jenkins-slave-latest.tar.gz获取,jenkins-slave-latest.tar.gz需要上传到工作节点。
7)在每一个 pod template 右下脚都有一个高级,点击高级,出现如下
在 Service Account 处输入 jenkins-k8s-sa,这个 sa 就是我们最开始安装 jenkins 时的 sa
8)给上面的 pod template 添加卷
添加卷------>选择 Host Path Volume
/var/run/docker.sock
/var/run/docker.sock
/root/.kube
/home/jenkins/.kube
上述配置好之后, Apply(应用)------>Save(保存)
9)添加docker harbor凭证
首页------>系统管理→Manage Credentials(管理凭据)
用户名:admin
密码:Harbor12345
ID:dockerharbor
2.5 Jenkins 部署应用发布到 k8s 开发环境、测试环境
1)在 k8s-master 的控制节点创建名称空间:
[root@ks-master ~]# kubectl create ns devlopment
[root@ks-master ~]# kubectl create ns qatest
[root@ks-master ~]# kubectl create ns production
2) jenkins创建任务
pipeline文件
node('lmzf') {
stage('Clone') {
echo "1.Clone Stage"
git url: "http://192.168.140.132:8001/root/jenkins-sample.git"
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
}
}
stage('Test') {
echo "2.Test Stage"
}
stage('Build') {
echo "3.Build Docker Image Stage"
sh "docker build -t 192.168.140.132/jenkins-demo/jenkins-demo:${build_tag} ."
}
stage('Push') {
echo "4.Push Docker Image Stage"
withCredentials([usernamePassword(credentialsId: 'dockerharbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
sh "docker login 192.168.140.132 -u ${dockerHubUser} -p ${dockerHubPassword}"
sh "docker push 192.168.140.132/jenkins-demo/jenkins-demo:${build_tag}"
}
}
stage('Deploy to dev') {
echo "5. Deploy DEV"
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('Promote to qa') {
def userInput = input(
id: 'userInput',
message: 'Promote to qa?',
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"
} else {
//exit
}
}
stage('Promote to pro') {
def userInput = input(
id: 'userInput',
message: 'Promote to pro?',
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"
}
}
}
3)立即构建--->点击左下角进度条---->Console Output