一、系统环境
IP |
角色 |
主机名 |
Pod |
192.168.2.198 |
Master |
k8s-master1 |
无 |
192.168.2.199 |
Master |
k8s-master2 |
无 |
192.168.2.200 |
Master |
k8s-master3 |
无 |
192.168.2.195 |
Node |
k8s-node1 |
Jenkins |
192.168.2.196 |
Node |
k8s-node2 |
Jenkins |
192.168.2.197 |
Node |
k8s-node3 |
Jenkins |
192.168.2.201 |
NFS |
k8s-nfs |
无 |
注:本教程使用kubernetes v1.27.6版本,其他版本请自行测试。
二、部署NFS
1、安装NFS
[root@k8s-nfs ~]# yum -y install rpcbind nfs-utils
2、创建共享目录
[root@k8s-nfs ~]# mkdir -p /data/jenkins
3、配置exports
[root@k8s-nfs ~]# cat >>/etc/exports <<EOF
/data/jenkins 192.168.2.0/24(rw,no_root_squash,no_all_squash,sync)
EOF
4、启动rpcbind、nfs服务
[root@k8s-nfs ~]# systemctl start rpcbind
[root@k8s-nfs ~]# systemctl start nfs
[root@k8s-nfs ~]# systemctl enable rpcbind
[root@k8s-nfs ~]# systemctl enable nfs
5、查看共享目录
[root@k8s-nfs ~]# showmount -e 192.168.2.201
Export list for 192.168.2.201:
/data/jenkins 192.168.2.0/24
三、创建StorageClass、Namespace
1、创建StorageClass
[root@k8s-master1 ~]# mkdir kube-devops && cd kube-devops
[root@k8s-master1 kube-devops]# vim kube-devops-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: devops-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
[root@k8s-master1 kube-devops]# kubectl apply -f kube-devops-storageclass.yaml
storageclass.storage.k8s.io/devops-storage created
2、创建Namespace
[root@k8s-master1 kube-devops]# vim kube-devops-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: kube-devops
labels:
app: devops
[root@k8s-master1 kube-devops]# kubectl apply -f kube-devops-namespace.yaml
namespace/kube-devops created
3、Node节点安装nfs-utils
[root@k8s-node1 ~]# yum -y install nfs-utils
[root@k8s-node2 ~]# yum -y install nfs-utils
[root@k8s-node3 ~]# yum -y install nfs-utils
四、部署Jenkins
1、创建PV、PVC
[root@k8s-master1 kube-devops]# vim kube-devops-nfs.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Delete
nfs:
server: 192.168.2.201
path: /data/jenkins
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: kube-devops
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
[root@k8s-master1 kube-devops]# kubectl apply -f kube-devops-nfs.yaml
persistentvolume/jenkins-pv unchanged
persistentvolumeclaim/jenkins-pvc created
2、创建角色授权
[root@k8s-master1 kube-devops]# vim kube-devops-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-admin
namespace: kube-devops
labels:
name: jenkins
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins-admin
labels:
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins-admin
namespace: kube-devops
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
[root@k8s-master1 kube-devops]# kubectl apply -f kube-devops-rbac.yaml
serviceaccount/jenkins-admin created
clusterrolebinding.rbac.authorization.k8s.io/jenkins-admin created
3、创建Deployment
[root@k8s-master1 kube-devops]# vim kube-devops-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: kube-devops
labels:
app: jenkins
spec:
selector:
matchLabels:
app: jenkins
replicas: 1
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins-admin
containers:
- name: jenkins
image: jenkins/jenkins:lts
securityContext:
runAsUser: 0
privileged: true
ports:
- name: http
containerPort: 8080
- name: jnlp
containerPort: 50000
resources:
limits:
memory: 2Gi
cpu: "1000m"
requests:
memory: 1Gi
cpu: "500m"
env:
- name: LIMITS_MEMORY
valueFrom:
resourceFieldRef:
resource: limits.memory
divisor: 1Mi
- name: "JAVA_OPTS"
value: "
-Xmx$(LIMITS_MEMORY)m
-XshowSettings:vm
-Dhudson.slaves.NodeProvisioner.initialDelay=0
-Dhudson.slaves.NodeProvisioner.MARGIN=50
-Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
-Duser.timezone=Asia/Shanghai
"
volumeMounts:
- name: data
mountPath: /var/jenkins_home
volumes:
- name: data
persistentVolumeClaim:
claimName: jenkins-pvc
[root@k8s-master1 kube-devops]# kubectl apply -f kube-devops-deployment.yaml
deployment.apps/jenkins created
4、创建Service
[root@k8s-master1 kube-devops]# vim kube-devops-service.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: kube-devops
labels:
app: jenkins
spec:
type: NodePort
ports:
- name: http
port: 8080
targetPort: 8080
nodePort: 32001
- name: jnlp
port: 50000
targetPort: 50000
nodePort: 32002
selector:
app: jenkins
[root@k8s-master1 kube-devops]# kubectl apply -f kube-devops-service.yaml
service/jenkins created
5、查看Pod和Service
[root@k8s-master1 kube-devops]# kubectl get pod,svc -n kube-devops
6、访问Jenkins
1)浏览器输入http://192.168.2.198:32001,如下图所示
2)获取Jenkins初始化生成密码
[root@k8s-master1 kube-devops]# kubectl logs -n kube-devops jenkins-6dd7dddb8-kkgr9
3)登录Jenkins
4)安装推荐插件
5)使用admin登录
6)实例配置
7)进入Jenkins界面
8)修改密码
9)重启Jenkins加载中文插件
# 浏览器输入http://192.168.2.198:32001,如下图所示
10)使用新密码重新登录Jenkins
五、部署CI/CD
# 这里采用脚本部署,也可以在Jenkins上安装Kubernetes插件
1、Pipeline简介
Pipeline,简单来说,就是一套运行在Jenkins上的工作流框架,将原来独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。
Jenkins Pipeline有几个核心概念:
- Node:节点,一个Node就是一个Jenkins节点,Master或者Agent,是执行Step的具体运行环境,比如我们之前动态运行的Jenkins Slave就是一个Node节点
- Stage:阶段,一个Pipeline可以划分为若干个Stage,每个Stage代表一组操作,比如:Build、Test、Deploy,Stage 是一个逻辑分组的概念,可以跨多个Node
- Step:步骤,Step是最基本的操作单元,可以是打印一句话,也可以是构建一个Docker镜像,由各类Jenkins插件提供,比如命令:sh 'make',就相当于我们平时shell终端中执行make命令一样。
Pipeline的使用:
- Pipeline脚本是由Groovy语言实现的
- Pipeline支持两种语法:Declarative(声明式)和Scripted Pipeline(脚本式)语法
- Pipeline也有两种创建方法:可以直接在Jenkins的Web UI界面中输入脚本;也可以通过创建一个Jenkinsfile脚本文件放入项目源码库中
- 一般我们都推荐在Jenkins中直接从源代码控制(SCMD)中直接载入 Jenkinsfile Pipeline这种方法
2、创建Pipeline任务
脚本内容:
node {
stage('Clone') {
echo "1.Clone Stage"
}
stage('Test') {
echo "2.Test Stage"
}
stage('Build') {
echo "3.Build Stage"
}
stage('Deploy') {
echo "4. Deploy Stage"
}
}
3、执行Pipeline任务
# 构建结果,如下图
4、部署完整应用
部署应用的流程如下:
1)拉取代码
2)编译打包
3)编写Dockerfile
4)构建Docker镜像
5)推送Docker镜像到镜像仓库
6)编写Kubernetes YAML文件
7)更改yaml文件中Docker镜像tag号
8)执行kubectl工具部署应用
9)测试人员验证
10)完整应用部署流程,如下图所示
若文章图片、下载链接等信息出错,请在评论区留言反馈,博主将第一时间更新!如本文“对您有用”,欢迎随意打赏,谢谢!
评论