一、首先需要搭建好k8s集群以及在k8s集群中部署好Jenkins,这里就不做详细介绍如何搭建k8s集群和在k8s集群中部署Jenkins,(具体过程可以参考之前文章进行部署)
1、这里我使用公有GitHub作为代码仓库,首先需要将GitHub代码仓库以及harbor镜像仓库账户和密码在Jenkins添加上;(我这里是之前已经添加上了,如果没有点击凭据进行添加即可)
、
2、我们需要将代码上传到代码仓库,这里我使用rocketMQ-console为例,
1.我们先将源码克隆本地:
git clone https://github.com/apache/rocketmq-externals.git
2.进入源码目录
[root@k8s-master]# cd /usr/local/src/rocketmq-externals
[root@k8s-master rocketmq-externals]# ll -a
里面有一个.git隐藏文件:
3.进入.git文件编辑config配置文件:vim config
4.将源码上传到你自己GitHub仓库中;
git remote add origin https://github.com/houyi199208/rocketmq-console.git
git push -u origin master 这里master是分支
git push origin --tag 或者打tag号
执行完成后登陆自己代码仓库查看是否上有相关源码
3、上面工作做好后我们接下在Jenkins上面创建第一个Java项目流水线
注意:
如果没有参数化构建选项,需要安装插件:
安装pipeline参数化构建插件
Jenkins中-->系统管理--->管理插件--->可选插件--->搜索extended choice parameter---->点击直接安装
4、编辑pipeline脚本
node("slave") {
env.registry="192.168.111.161" //harbor地址
env.image="${registry}/${MODULE}/${APP_NAME}:${TAG}" //生成的镜像名称
if ( Operation == 'Deploy' ) {
stage('Get code'){
checkout([$class: 'GitSCM', branches: [[name: "${TAG}"]], doGenerateSubAPP_NAMEConfigurations: false, userRemoteConfigs: [[credentialsId: 'github', url: ' https://github.com/houyi199208/rocketmq-console.git']]]) //根据TAG号拉取代码
}
stage('Build code') {
sh "pwd"
sh "mvn clean package -Dmaven.test.skip=true -f rocketmq-console/pom.xml" //编译代码
sh '''
cat >Dockerfile<<EOF
FROM openjdk:8u232
RUN echo "ZONE=Asia/Shanghai" >/etc/timezone
COPY rocketmq-console/target/${APP_NAME}-ng-1.0.0.jar /opt/app/${MODULE}/${APP_NAME}/
WORKDIR /opt/app/${MODULE}/${APP_NAME}/
ENTRYPOINT ["java","-jar","${APP_NAME}-ng-1.0.0.jar"]
''' //制作Dockerfile
}
stage('mk image & push image'){
withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harborpasswd', usernameVariable: 'harboruser')]) {
sh "docker login ${env.registry} -u ${harboruser} -p ${harborpasswd}"
sh "docker build -t ${registry}/${MODULE}/${APP_NAME}:${TAG} -f ./Dockerfile . && docker push ${registry}/${MODULE}/${APP_NAME}:${TAG}"
}
}
stage('Deploy'){
sh "sed -e 's/APP_NAME/${APP_NAME}/g' -e 's/MODULE/${MODULE}/g' -e 's%IMAGE%${env.image}%g' -e 's/PORT/${PORT}/g' ../k8s/deploy-template.yml >../k8s/${MODULE}/${APP_NAME}-deploy.yml " //根据选项参数的值对部署文件进行替换
get_ns = sh returnStatus: true, script: "kubectl get ns ${MODULE}"
echo "${get_ns}"
if ( get_ns != 0 ){
sh "kubectl create ns ${MODULE}"
}
sh "kubectl apply -f ../k8s/${MODULE}/${APP_NAME}-deploy.yml --record=true"
}
}else if ( Operation == 'Rollback' ) {
stage('Rollback Previous Version'){
sh "kubectl describe deployment ${APP_NAME} -n mq-console |grep -w 'Image:'"
sh "kubectl rollout undo deployment ${APP_NAME} -n ${MODULE} "
sh "kubectl describe deployment ${APP_NAME} -n mq-console |grep -w 'Image:'"
}
}
}
5、后续准备工作
找到jenkins-slave的workspace目录,目录和文件是和pipeline配套的
[root@master workspace]# pwd
/data/jenkins-slave/workspace
[root@master workspace]# mkdir k8s && cd k8s
[root@master k8s]# mkdir mq-console #创建项目部署文件保存目录
[root@master k8s]# ls #deploy-template.yml是通用模板,修改后部署对应的项目
deploy-template.yml mq-console
[root@master k8s]# chmod o+w -R ./ #jenkins-slave默认用户是Jenkins,没有权限操作,后续创建的其他项目也需要关注权限问题,这个版本先用o+w解决
查看节点标签
[root@master k8s]# kubectl get node --show-labels
给调度的节点打标签
[root@master k8s]# kubectl label nodes node01 app=mq-console
6、模板文件(这里面所有的变量都是使用Jenkins上面定义的参数)
[root@master k8s]# cat deploy-template.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: APP_NAME
namespace: MODULE
spec:
selector:
matchLabels:
app: APP_NAME
replicas: 1
template:
metadata:
labels:
aliyun.logs.APP_NAME: stdout
app: APP_NAME
spec:
imagePullSecrets:
- name: regsecret #拉取镜像的secret,不同名称空间需要单独创建
hostNetwork: true
nodeSelector:
app: test-MODULE
terminationGracePeriodSeconds: 60
restartPolicy: Always
containers:
- name: APP_NAME
image: IMAGE
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "1Gi"
cpu: "0.5"
limits:
memory: "2Gi"
cpu: "8"
env:
- name: aliyun_logs_APP_NAME
value: "stdout"
livenessProbe:
tcpSocket:
port: PORT
initialDelaySeconds: 120
periodSeconds: 20
successThreshold: 1
failureThreshold: 2
volumeMounts:
- name: logs
mountPath: /opt/logs/
- name: time
mountPath: /etc/localtime
volumes:
- name: logs
hostPath:
path: /opt/logs/ #应用日志输出位置,根据应用进行调整,项目中规定的是/opt/logs,此次部署用不到,可以做参考
type: DirectoryOrCreate
- name: time
hostPath:
path: /etc/localtime #挂载时区文件
---
apiVersion: v1
kind: Service
metadata:
name: APP_NAME
labels:
app: APP_NAME
namespace: MODULE
spec:
selector:
app: APP_NAME
clusterIP: None
# type: NodePort
ports:
- name: APP_NAME
port: PORT
targetPort: PORT
# nodePort: PORT
7、以上部署没有问题就可以部署ingress了
[root@master mq]# cat mq-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: mq-ingess
namespace: mq-console
spec:
rules:
- host: mymq-ingress.com
http:
paths:
- backend:
serviceName: rocketmq-console
servicePort: 8080
path: /
8、编辑完成ingress的yaml文件后执行:
[root@k8s-master k8s]# kubectl apply -f mq-ingress.yaml
[root@k8s-master k8s]# kubectl get ingress -nmq-console
NAME HOSTS ADDRESS PORTS AGE
mq-ingress mymq-ingress.com 192.168.111.163 80 142m
最后通过浏览器访问即可: