在前面的学习中,我们已经通过手动的打包、制作镜像、推送镜像仓库、部署k8s的形式完成了对RuoYICloud项目的部署:https://blog.csdn.net/DreamsArchitects/article/details/121121109
但是这种方式过于复杂繁琐。现在我们来学习一下通过流水线来自动化部署RuoYICloud项目。
前提需要部署好MySQL、Nacos、Redis 服务。
Nacos 上云部署
完整流程:
先推送一个服务把整个流程走完
需要创建镜像仓库凭证
以QQ邮箱为例:
点击 如何设置:http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=369
收到的邮件没有动态取值$BUILD_NUMBER
。
我们需要修改body:
将单引号修改为双引号:
查看容器运行日志:
需要在构建镜像、推送镜像、部署k8s时候 添加并行阶段
。
注意 在前端项目执行流水线时我们需要指定nodejs
容器,不是maven
容器。
KubeSphere 的 内置四种容器模板
在ruoyi-ui
目录下创建deploy
目录,创建deploy.yml
文件
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ruoyi-ui
name: ruoyi-ui
namespace: ruoyi #一定要写名称空间
spec:
progressDeadlineSeconds: 600
replicas: 1
selector:
matchLabels:
app: ruoyi-ui
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
type: RollingUpdate
template:
metadata:
labels:
app: ruoyi-ui
spec:
imagePullSecrets:
- name: aliyun-docker-hub #提前在项目下配置访问阿里云的账号密码
containers:
- image: $REGISTRY/$ALIYUNHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER
# readinessProbe:
# httpGet:
# path: /actuator/health
# port: 8080
# timeoutSeconds: 10
# failureThreshold: 30
# periodSeconds: 5
imagePullPolicy: Always
name: app
# 前端的端口为80 不是8080
ports:
- containerPort: 80
protocol: TCP
resources:
limits:
cpu: 300m
memory: 600Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: ruoyi-ui
name: ruoyi-ui
namespace: ruoyi
spec:
ports:
- name: http
# Service 暴露 80 端口
port: 80
protocol: TCP
targetPort: 80
nodePort: 32248
selector:
app: ruoyi-ui
sessionAffinity: None
type: NodePort
在ruoyi-ui
目录下创建Dockerfile
文件。
Dockerfile
文件的内容是基于nginx
镜像 复制编译后的dist
文件夹下的文件到容器内的/usr/share/nginx/html/
目录,最后暴露80
端口。
FROM nginx
#将dist目录内容复制到nginx容器html内部
COPY dist /usr/share/nginx/html/
EXPOSE 80
pipeline {
agent {
node {
label 'nodejs'
}
}
stages {
stage('拉取代码') {
agent none
steps {
container('nodejs') {
git(url: 'https://gitee.com/L1692312138/RuoYi-Cloud.git', credentialsId: 'gitee-lsh', branch: 'master', changelog: true, poll: false)
sh 'ls -al ruoyi-ui/'
}
}
}
stage('项目编译') {
agent none
steps {
container('nodejs') {
sh 'npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/'
sh 'npm install --registry=https://registry.npm.taobao.org'
sh 'cd ruoyi-ui/'
sh 'npm run build '
sh 'ls -al'
}
}
}
stage('构建镜像') {
agent none
steps {
container('nodejs') {
sh 'ls'
sh 'docker build -t ruoyi-ui:latest -f ruoyi-ui/Dockerfile ./ruoyi-ui'
}
}
}
stage('推送镜像') {
agent none
steps {
container('nodejs') {
withCredentials([usernamePassword(credentialsId : 'aliyun-docker-registry' ,usernameVariable : 'DOCKER_USER_VAR' ,passwordVariable : 'DOCKER_PWD_VAR' ,)]) {
sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
sh 'docker tag ruoyi-ui:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER'
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER'
}
}
}
}
stage('部署到dev环境') {
agent none
steps {
kubernetesDeploy(configs: 'ruoyi-ui/deploy/**', enableConfigSubstitution: true, kubeconfigId: 'demo-kubeconfig')
}
}
stage('邮件确认') {
agent none
steps {
mail(to: '[email protected]', subject: 'RuoyiCloud流水线执行结果', body: 'RuoyiCloud UI DevOps流水线 第 "$BUILD_NUMBER" 次 执行成功! ', cc: '[email protected]')
}
}
}
environment {
DOCKER_CREDENTIAL_ID = 'dockerhub-id'
GITHUB_CREDENTIAL_ID = 'github-id'
KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
GITHUB_ACCOUNT = 'kubesphere'
APP_NAME = 'devops-java-sample'
}
}
pipeline {
agent {
node {
label 'maven'
}
}
stages {
stage('拉取代码') {
agent none
steps {
container('maven') {
git(url: 'https://gitee.com/L1692312138/RuoYi-Cloud.git', credentialsId: 'gitee-lsh-monitor', branch: 'master', changelog: true, poll: false)
sh 'ls -al'
}
}
}
stage('项目编译') {
agent none
steps {
container('maven') {
sh 'mvn clean package -Dmaven.test.skip=true'
sh 'ls -al'
}
}
}
stage('构建monitor镜像') {
agent none
steps {
container('maven') {
sh 'ls -l ruoyi-visual/ruoyi-monitor/target/'
sh 'docker build -t ruoyi-monitor:latest -f ruoyi-visual/ruoyi-monitor/Dockerfile ./ruoyi-visual/ruoyi-monitor/'
}
}
}
stage('推送monitor镜像') {
agent none
steps {
container('maven') {
withCredentials([usernamePassword(credentialsId : 'aliyun-repository' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
sh 'docker tag ruoyi-monitor:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
}
}
}
}
stage('monitor部署k8s') {
agent none
steps {
kubernetesDeploy(enableConfigSubstitution: true, deleteResource: false, kubeconfigId: 'demo-kubeconfig', configs: 'ruoyi-visual/ruoyi-monitor/deploy/**')
}
}
stage('邮件确认') {
agent none
steps {
mail(to: '[email protected]', subject: 'RuoyiCloud流水线执行结果', body: "RuoyiCloud Monitor服务 DevOps流水线 第 $BUILD_NUMBER 次 执行成功!", cc: '[email protected]')
}
}
}
environment {
DOCKER_CREDENTIAL_ID = 'dockerhub-id'
GITHUB_CREDENTIAL_ID = 'github-id'
KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
GITHUB_ACCOUNT = 'kubesphere'
APP_NAME = 'devops-java-sample'
}
parameters {
string(name: 'TAG_NAME', defaultValue: '', description: '')
}
}
pipeline {
agent {
node {
label 'maven'
}
}
stages {
stage('拉取代码') {
agent none
steps {
container('maven') {
git(url: 'https://gitee.com/L1692312138/RuoYi-Cloud.git', credentialsId: 'gitee-lsh-monitor', branch: 'master', changelog: true, poll: false)
sh 'ls -al'
}
}
}
stage('项目编译') {
agent none
steps {
container('maven') {
sh 'mvn clean package -Dmaven.test.skip=true'
sh 'ls -al'
}
}
}
stage('构建monitor镜像') {
agent none
steps {
container('maven') {
sh 'ls -l ruoyi-visual/ruoyi-monitor/target/'
sh 'docker build -t ruoyi-monitor:latest -f ruoyi-visual/ruoyi-monitor/Dockerfile ./ruoyi-visual/ruoyi-monitor/'
}
}
}
stage('推送monitor镜像') {
agent none
steps {
container('maven') {
withCredentials([usernamePassword(credentialsId : 'aliyun-repository' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
sh 'docker tag ruoyi-monitor:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
}
}
}
}
stage('monitor部署k8s') {
agent none
steps {
kubernetesDeploy(enableConfigSubstitution: true, deleteResource: false, kubeconfigId: 'demo-kubeconfig', configs: 'ruoyi-visual/ruoyi-monitor/deploy/**')
}
}
stage('邮件确认') {
agent none
steps {
mail(to: '[email protected]', subject: 'RuoyiCloud流水线执行结果', body: "RuoyiCloud Monitor服务 DevOps流水线 第 $BUILD_NUMBER 次 执行成功!", cc: '[email protected]')
}
}
}
environment {
DOCKER_CREDENTIAL_ID = 'dockerhub-id'
GITHUB_CREDENTIAL_ID = 'github-id'
KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
GITHUB_ACCOUNT = 'kubesphere'
APP_NAME = 'devops-java-sample'
}
parameters {
string(name: 'TAG_NAME', defaultValue: '', description: '')
}
}
注意创建名称空间
,及修改app、name及拉取的镜像名称。
还需要注意拉取镜像时候使用的镜像仓库的凭证imagePullSecrets
。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ruoyi-monitor
name: ruoyi-monitor
namespace: ruoyi #一定要写名称空间
spec:
progressDeadlineSeconds: 600
replicas: 1
selector:
matchLabels:
app: ruoyi-monitor
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
type: RollingUpdate
template:
metadata:
labels:
app: ruoyi-monitor
spec:
imagePullSecrets:
- name: aliyun-docker-hub #提前在项目下配置访问阿里云的账号密码
containers:
- image: $REGISTRY/$ALIYUNHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER
# readinessProbe:
# httpGet:
# path: /actuator/health
# port: 8080
# timeoutSeconds: 10
# failureThreshold: 30
# periodSeconds: 5
imagePullPolicy: Always
name: app
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: 300m
memory: 600Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: ruoyi-monitor
name: ruoyi-monitor
namespace: ruoyi
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
# 使用NodePort方式暴露端口 固定端口
# nodePort: 30887
selector:
app: ruoyi-monitor
sessionAffinity: None
type: ClusterIP
# type: NodePort