Kubernetes从入门到精通(devops)06

目录

一、准备devops的环境

1、准备Harbor

[安装docker/docker compose](#安装docker/docker compose)

安装Harbor

创建仓库

集群所有节点配置Harbor信任

创建Harbor的Secret

2、准备jenkins

安装jdk21

安装Maven

安装docker

安装git

安装kubectl命令

安装jenkins

3、安装Gitlab

安装gitlab

修改密码

禁用注册功能

取消头像

汉化Gitlab

设置入站网络

[创建群组 / 项目 / 添加人员](#创建群组 / 项目 / 添加人员)

4、准备后端项目用到Mysql数据库

创建mysql初始化用到的configmap

创建Mysql

创建Java后端程序用得数据库连接地址

5、创建前端项目使用的configmap

创建nginx.conf

创建ConfigMap

二、配置Devops

1、jenkins添加凭据

创建集群的凭据

创建Gitlab的凭据

创建Harbor的凭据

添加全局工具配置

2、代码推送到Gitlab

本地生成公钥私钥

推送后端代码

推送前端代码

3、配置Jenkins流水线

配置后端流水线

[Create a job](#Create a job)

常规设置

配置触发事件Trigger

配置流水线

配置后端的webhook

配置前端流水线

[Create a job](#Create a job)

常规设置

配置触发事件Trigger

配置流水线

创建前端的webhook

三、使用Devops

1、后端项目创建相关配置文件

Jenkinsfile

Dockerfile

后端Yaml文件

[推送代码 打Tag使用](#推送代码 打Tag使用)

Jinkens页面查看流水线

查看集群是否部署

发布新功能版本

2、前端项目创建相关配置文件

Jenkinsfile

Dockerfile

前端Yaml文件

[推送代码 打Tag触发](#推送代码 打Tag触发)

Jenkins页面查看流水线

查看集群是否部署

发布新功能版本

3、使用参数化构建过程


一、准备devops的环境

项目拉取地址:git clone https://gitee.com/is-that-you/diagramhub.git

什么是Devops

软件开发最开始是由两个团队组成:

开发计划由开发团队从头开始设计和整体系统的搭建,需要系统不停的迭代更新。

运维团队将开发团队的Code进行测试后部署上线,希望系统稳定安全运行。

这看似两个目标不同的团队需要协同完成一个软件的开发。

在开发团队指定好计划完成coding后,需要提供到运维团队。

运维团队向开发团队反馈需要修复的BUG以及一些需要返工的任务。

这时开发团队需要经常等待运维团队的反馈,这无疑延长了事件并推迟了整个软件开发的周期。

会有一种方式,在开发团队等待的时候,让开发团队转移到下一个项目中,等待运维团队之前的代码提供反馈。

可是这样就意味着一个完整的项目需要一个更长的周期才能开发出最终代码。

基于现在的互联网现状,更推崇敏捷式开发,这样就导致项目的迭代速度更快,但是由于开发团队与运维团队的沟通问题,会导致新版本上线的时间成本很高,这又违背的敏捷式开发的最初的目的。

那么如果让开发团队和运维团队整合到成一个团队,协同应对一套软件呢?这就被称为DevOps。

DevOps,字面意思是Development & Operations的缩写,就是运维&开发。

虽然字面意思只涉及到了开发团队合运维团队,其实QA测试团队也是参与其中的。

网上可以查看到DevOps的符号类似于一个无穷大的符号

这表明DevOps是一个不断提高效率并且持续不断工作的过程

DevOps的方式可以让公司能够更快地应对更新和市场发展变化,开发可以快速交付,部署也更加稳定。

核心就在于++简化Dev和Ops团队之间德流程,使整体软件开发过程更快速。++

1、准备Harbor

安装docker/docker compose

复制代码
# 卸载旧版本
[root@k8s-node01 ~]# yum remove -y docker docker-client docker-compose

# 安装依赖
[root@k8s-node01 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

# 添加阿里云的docker源
[root@k8s-node01 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装docker
[root@k8s-node01 ~]# yum install -y docker-ce docker-ce-cli

# 设置开机自启
[root@k8s-node01 ~]# systemctl start docker && systemctl enable docker

# 安装docker-compose
[root@k8s-node01 ~]# curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
[root@k8s-node01 ~]# chmod +x /usr/local/bin/docker-compose
[root@k8s-node01 ~]# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 验证
[root@k8s-node01 ~]# docker --version
Docker version 26.1.4, build 5650f9b
[root@k8s-node01 ~]# docker-compose --version
Docker Compose version v5.1.4

安装Harbor

复制代码
# 下载安装包
[root@k8s-node01 ~]# wget https://github.com/goharbor/harbor/releases/download/v1.10.19/harbor-offline-installer-v1.10.19.tgz

# 解压
[root@k8s-node01 ~]# tar -zxf harbor-offline-installer-v1.10.19.tgz

# 编辑配置文件
[root@k8s-node01 ~]# vim harbor/harbor.yml 
hostname: 192.168.1.13              #访问的IP
  port: 8899                        #端口
harbor_admin_password: Tcloud123@  #密码
#把https段注释掉
#https:
#  # https port for harbor, default is 443
#  port: 443
#  # The path of cert and key files for nginx
#  certificate: /your/certificate/path
#  private_key: /your/private/key/path

# 安装
[root@k8s-node01 ~]# harbor/install.sh 
[Step 5]: starting Harbor ...
WARN[0000] /root/harbor/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion 
[+] up 10/10
 ✔ Network harbor_harbor       Created                                                                                                                                                                       0.0s
 ✔ Container harbor-log        Started                                                                                                                                                                       0.3s
 ✔ Container harbor-db         Started                                                                                                                                                                       0.7s
 ✔ Container registryctl       Started                                                                                                                                                                       0.7s
 ✔ Container registry          Started                                                                                                                                                                       0.7s
 ✔ Container harbor-portal     Started                                                                                                                                                                       0.6s
 ✔ Container redis             Started                                                                                                                                                                       0.7s
 ✔ Container harbor-core       Started                                                                                                                                                                       1.0s
 ✔ Container harbor-jobservice Started                                                                                                                                                                       1.3s
 ✔ Container nginx             Started                                                                                                                                                                       1.3s
✔ ----Harbor has been installed and started successfully.----

创建仓库

账号:admin

密码:Tcloud123@

仓库名字:diagramhub

集群所有节点配置Harbor信任

复制代码
[root@k8s-master01 ~]# cat > /etc/containerd/certs.d/192.168.1.13:8899/hosts.toml <<EOF
server = "http://192.168.1.13:8899"
[host."http://192.168.1.13:8899"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
EOF

[root@k8s-master01 ~]# systemctl restart containerd

创建Harbor的Secret

没有这个命名空间先创建这个命名空间

复制代码
[root@k8s-master01 DiagramHub]# kubectl create secret docker-registry harbor-secret --docker-server=192.168.1.13:8899 --docker-username=admin --docker-password=Tcloud123@ -n diagramhub

2、准备jenkins

安装jdk21

从Oracle官网下载JDK21上传到我们的服务器

https://www.oracle.com/JAVA

复制代码
# 创建存放目录
[root@k8s-node02 ~]# mkdir -p /opt/environment

# 解压
[root@k8s-node02 ~]# tar -zxvf jdk-21_linux-x64_bin.tar.gz -C /opt/environment/

# 配置环境变量
[root@k8s-node02 ~]# cat >> /etc/profile << EOF
# Set java environment
JAVA_HOME=/opt/environment/jdk-21.0.11
PATH=\$PATH:\$JAVA_HOME/bin
export JAVA_HOME PATH
EOF

# 刷新配置
[root@k8s-node02 ~]# source /etc/profile

# 查看Java版本
[root@k8s-node02 ~]# java -version
java version "21.0.11" 2026-04-21 LTS
Java(TM) SE Runtime Environment (build 21.0.11+9-LTS-211)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.11+9-LTS-211, mixed mode, sharing)

安装Maven

复制代码
# 下载Maven安装包
[root@k8s-node02 ~]# wget https://archive.apache.org/dist/maven/maven-3/3.9.16/binaries/apache-maven-3.9.16-bin.tar.gz

# 解压
[root@k8s-node02 ~]# tar -zxvf apache-maven-3.9.16-bin.tar.gz -C /opt/environment/

# 配置jar包依赖的存放位置
[root@k8s-node02 ~]# vim /opt/environment/apache-maven-3.9.16/conf/settings.xml 
# 把默认的注释添加这段
    <!--mirror>
      <id>maven-default-http-blocker</id>
      <mirrorOf>external:http:*</mirrorOf>
      <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
      <url>http://0.0.0.0/</url>
      <blocked>true</blocked>
    </mirror>-->
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>


# 配置环境变量
[root@k8s-node02 ~]# cat >> /etc/profile << EOF
# Set maven environment
MAVEN_HOME=/opt/environment/apache-maven-3.9.16
PATH=\$PATH:\$MAVEN_HOME/bin
export MAVEN_HOME PATH
EOF

# 生效
[root@k8s-node02 ~]# source /etc/profile

# 查看maven的版本
[root@k8s-node02 ~]# mvn -v
Apache Maven 3.9.16 (2bdd9fddda4b155ebf8000e807eb73fd829a51d5)
Maven home: /opt/environment/apache-maven-3.9.16
Java version: 21.0.11, vendor: Oracle Corporation, runtime: /opt/environment/jdk-21.0.11
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.4.226-1.el7.elrepo.x86_64", arch: "amd64", family: "unix"

安装docker

复制代码
# 下载docker的安装包
[root@k8s-node02 ~]# wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz

# 解压
[root@k8s-node02 ~]# tar -zxvf docker-20.10.7.tgz

# 添加到Path
[root@k8s-node02 ~]# mv docker/* /usr/bin
[root@k8s-node02 ~]# rm -rf docker-20.10.7.tgz docker

# system管理docker
[root@k8s-node02 ~]# cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
 
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
 
[Install]
WantedBy=multi-user.target
EOF

# 配置镜像加速和Harbor地址
[root@k8s-node02 ~]# mkdir -p /etc/docker
[root@k8s-node02 ~]# cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io"
  ],
  "insecure-registries": ["192.168.1.14:8899"]
}
EOF

# 设置开机自启动
[root@k8s-node02 ~]# systemctl daemon-reload
[root@k8s-node02 ~]# systemctl start docker && systemctl enable docker

# 测试访问Harbor
[root@k8s-node02 ~]# docker login 192.168.1.13:8899
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 推送测试
[root@k8s-node02 ~]# docker tag nginx:latest 192.168.1.13:8899/diagramhub/nginx:latest
[root@k8s-node02 ~]# docker push 192.168.1.13:8899/diagramhub/nginx:latest
The push refers to repository [192.168.1.13:8899/diagramhub/nginx]
271182c95b03: Pushed 
58a87cd80f7d: Pushed 
b77962fbff2d: Pushed 
8e0111b626dd: Pushed 
1f561b62ded0: Pushed 
5f120dc722b0: Pushed 
219a998c6050: Pushed 
latest: digest: sha256:ae33218af50e1d8613f388276f0f29aacdbb815da94cf85f30b13df070022bac size: 1778

# 在集群任意节点拉群镜像测试
[root@k8s-master01 certs.d]# crictl pull --creds admin:Tcloud123@ 192.168.1.13:8899/diagramhub/nginx:latest
Image is up to date for sha256:7aaca76c508f7d121ff29cbe9dd071012486d00c21e17655eb1a1dfb711e9330

安装git

复制代码
[root@k8s-node02 ~]# yum -y install git
[root@k8s-node02 ~]# git --version
git version 1.8.3.1

安装kubectl命令

复制代码
[root@k8s-node02 ~]# curl -LO https://dl.k8s.io/release/v1.36.1/bin/linux/amd64/kubectl
[root@k8s-node02 ~]# chmod +x kubectl
[root@k8s-node02 ~]# mv kubectl /usr/local/bin/

安装jenkins

复制代码
# 下载安装包
[root@k8s-node02 ~]# wget https://mirrors.jenkins.io/redhat-stable/jenkins-2.555.2-1.noarch.rpm

# 创建jenkins安装目录
[root@k8s-node02 ~]# mkdir -p /opt/server/jenkins

# 安装
[root@k8s-node02 ~]# mv jenkins-2.555.2-1.noarch.rpm /opt/server/jenkins/
[root@k8s-node02 ~]# cd /opt/server/jenkins/
[root@k8s-node02 jenkins]# rpm -ivh jenkins-2.555.2-1.noarch.rpm 

# 修改配置文件
[root@k8s-node02 jenkins]# vim /usr/lib/systemd/system/jenkins.service
#Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64"
Environment="JAVA_HOME=/opt/environment/jdk-21.0.11"      #添加我们的JAVA路径
Environment="JENKINS_PORT=8888"                       # 修改端口
User=root
Group=root

# 设置用户数组
[root@k8s-node02 jenkins]# chown -R root:root /var/lib/jenkins/ && chown -R root:root /var/cache/jenkins/

# 下载启动依赖 不然启动失败
[root@k8s-node02 jenkins]# yum install -y fontconfig

# 启动
[root@k8s-node02 jenkins]# systemctl daemon-reload 
[root@k8s-node02 jenkins]# systemctl start jenkins && systemctl enable jenkins

访问jenkins并安装插件

选择插件来安装------安装

创建管理员用户

安装插件

右上角设置------插件管理------Available plugins

复制代码
# 安装以下插件
Build Authorization Token Root
外部系统通过令牌安全触发 Jenkins 构建。
gitlab
联动 GitLab,代码提交自动触发构建,同步构建结果。
SonarQube Scanner
对接 SonarQube,完成代码质量、漏洞扫描。
Node and Label parameter
构建时选择代理节点 / 标签执行任务。
Kubernetes
对接 K8s,动态创建临时 Pod 作为构建代理,用完自动销毁。
maven integration
适配 Maven 项目,实现 Java 项目打包、解析测试报告。
Git Parameter
将 Git 分支、标签等作为构建参数,手动选择版本构建。
Config File Provider
统一管理配置文件,构建时自动加载下发。
Pipeline: Multibranch with defaults
增强多分支流水线,可设置默认流程,无 Jenkinsfile 也能构建。
docker
让 Jenkins 调用 Docker 能力,实现镜像构建、推送、运行等操作。
NodeJS
让Jenkins 调用本地的nodejs功能

安装完找到Download progress ------ 安装完重启jenkins(空闲)点击完自动重启

3、安装Gitlab

安装gitlab

复制代码
# 下载Gitlab的RPM包  下载完成上传到服务器
地址:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm

# 安装依赖
[root@k8s-node03 ~]# yum -y install policycoreutils-python

# 安装Gitlab
[root@k8s-node03 ~]# rpm -i gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm

# 编辑配置文件
[root@k8s-node03 ~]# vim /etc/gitlab/gitlab.rb
external_url 'http://192.168.1.15:9090'               # 访问地址
gitlab_rails['time_zone'] = 'Asia/Shanghai'           # 时区
puma['worker_processes'] = 2
sidekiq['max_concurrency'] = 8
postgresql['shared_buffers'] = "512MB"
postgresql['max_worker_processes'] = 4
prometheus_monitoring['enable'] = false

# 更新配置
[root@k8s-node03 ~]# gitlab-ctl reconfigure

# 启动
[root@k8s-node03 ~]# gitlab-ctl restart

# 获取密码 默认账号root
[root@k8s-node03 ~]# cat /etc/gitlab/initial_root_password

修改密码

右上角头像 > Perferences > Password

禁用注册功能

点击左上角三横 > Admin>Settings > General > Sign-up restrictions > 取消 Sign-up enabled > Save changes

取消头像

Settings > General > Account and limit > 取消 Gravatar enabled > Save changes

汉化Gitlab

Settings > Preferences > Localization > Default language > 选择简体中文 > Save changes

为当前用户设置中文 修改完记得刷新

右上角用户头像 > Preferences > Localization > Language > 选择简体中文 > Save changes

设置入站网络

设置>网络>出站请求>勾选>保存

不配置这个后面gitlab不能创建内网的webhook

创建群组 / 项目 / 添加人员

创建前后端项目

前端:DiagramHub-frontend

后端:DiagramHub-backend

创建开发人员添加到群组

左上角三条杠------管理员------用户------新用户

新用户的密码更改一下,用新用户登录Gitlab

4、准备后端项目用到Mysql数据库

创建mysql初始化用到的configmap

复制代码
# 创建命名空间
[root@k8s-master01 DiagramHub]# kubectl create ns diagramhub

# 创建configmap
[root@k8s-master01 DiagramHub]# kubectl create configmap mysql-init-sql --from-file=init.sql -n diagramhub

创建Mysql

注意集群需要有StorageClass

复制代码
[root@k8s-master01 DiagramHub]# kubectl get sc
NAME                  PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   nfs-provisioner   Delete          Immediate           false                  4h20m

[root@k8s-master01 DiagramHub]# vim mysql.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  namespace: diagramhub
spec:
  ports:
  - port: 3306
  clusterIP: None
  selector:
    app: mysql

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: diagramhub
spec:
  serviceName: mysql-service
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: docker.m.daocloud.io/library/mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
        - name: init-sql
          mountPath: /docker-entrypoint-initdb.d
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"
            cpu: "300m"
        livenessProbe:
          exec:
            command: ["mysqladmin", "-uroot", "-p123456", "ping", "-h", "localhost"]
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          exec:
            command: ["mysql", "-uroot", "-p123456", "-h", "127.0.0.1", "-e", "SELECT 1"]
          initialDelaySeconds: 15
          periodSeconds: 5
      volumes:
      - name: init-sql
        configMap:
          name: mysql-init-sql
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: managed-nfs-storage
      resources:
        requests:
          storage: 1Gi

# 创建
[root@k8s-master01 DiagramHub]# kubectl create -f mysql.yaml 


# 查看资源
[root@k8s-master01 DiagramHub]# kubectl get pod -n diagramhub 
NAME      READY   STATUS    RESTARTS   AGE
mysql-0   1/1     Running   0          29s
[root@k8s-master01 DiagramHub]# kubectl get svc -n diagramhub 
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
mysql-service   ClusterIP   None         <none>        3306/TCP   36s

创建Java后端程序用得数据库连接地址

复制代码
[root@k8s-master01 DiagramHub]# vim secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: diagramhub-secrets
  namespace: diagramhub
type: Opaque
stringData:
  db-username: "root"
  db-password: "123456"
  jwt-secret: "YourVeryLongJWTSecretKeyHere_Minimum32Chars_2024!"
  # 邮件配置(如不需要可留空)
  mail-host: "smtp.example.com"
  mail-port: "587"
  mail-username: "your-email@example.com"
  mail-password: "your-email-password"

# 创建
[root@k8s-master01 DiagramHub]# kubectl create -f secrets.yaml 

5、创建前端项目使用的configmap

创建nginx.conf

复制代码
[root@k8s-master01 DiagramHub]# vim nginx.conf

server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;
 
    # 前端路由支持(SPA)
    location / {
        try_files $uri $uri/ /index.html;
    }
 
    # API代理到后端服务
    location /api/ {
        # 使用K8S内部服务名
        proxy_pass http://backend-service:8080/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
 
    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
 
    # Gzip压缩
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    
    # 安全头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
}

创建ConfigMap

复制代码
# 创建
[root@k8s-master01 DiagramHub]# kubectl create configmap frontend-nginx-config   -n diagramhub   --from-file=default.conf=nginx.conf

# 查看
[root@k8s-master01 DiagramHub]# kubectl get configmaps -n diagramhub
NAME                    DATA   AGE
frontend-nginx-config   1      42s
kube-root-ca.crt        1      27h
mysql-init-sql          1      27h

二、配置Devops

1、jenkins添加凭据

创建集群的凭据

clouds

集群地址:config文件中的地址

https://192.168.1.100:8443

添加凭据

Secret file 把集群的config文件上传上去

ID:k8s-kubeconfig

测试连接------Save

创建Gitlab的凭据

系统管理------凭据管理------system(全局配置)------全局凭据------Add Credentials------Username with password

ID:gitlab-credentials

用户名:gwjcloud

密码:Tcloud123@

创建Harbor的凭据

系统管理------凭据管理------system(全局配置)------全局凭据------Add Credentials------Username with password

ID:harbor-credentials
用户名:admin

密码:Tcloud123@

添加全局工具配置

2、代码推送到Gitlab

本地生成公钥私钥

复制代码
# 生成公钥私钥
PS D:\Java-code\DiagramHub> ssh-keygen -t rsa

把id_rsa.pub的内容复制到gitlab的个人信息中

推送后端代码

推送前端代码

3、配置Jenkins流水线

配置后端流水线

Create a job

任务名称:DiagramHub-Backend

描述:DiagramHub 后端 - Spring Boot 应用

常规设置

在General区域找到参数化构建过程 勾选

名称:GITLAB_SECRET_TOKEN

默认值:留空 等下生成Token替换

描述:GitLab Webhook 后端验证密钥

字符参数

配置触发事件Trigger

勾选 Build when a change is pushed to GitLab. GitLab webhook URL ......

勾选:Push Events

取消勾选:Approved Merge Requests (EE-only)

取消勾选:Comments

高级------生成Secret Token

把生成的Token替换上面常规设置的默认值

记住url和Token等下创建后端的webhook使用

url:http://192.168.1.14:8888/project/DiagramHub-Backend

Token:f319fcac95cec19284b57fba17c28790

配置流水线

前端代码地址:bhttp://192.168.1.15:9090/cloud/diagramhubbend.githttp://192.168.1.15:9090/cloud/diagramhub-backend.gitbhttp://192.168.1.15:9090/cloud/diagramhubbend.git

选择之前创建的凭据:gitlab-credentials

构建分支:*/main

点击Additional Behaviours(其他行为),选择检出到指定的本地分支------应用保存

配置后端的webhook

url:http://192.168.1.14:8888/project/DiagramHub-Backend

Token:f319fcac95cec19284b57fba17c28790

选择标签推送事件

关闭SSL验证------添加Webhook

配置前端流水线

Create a job

任务名称:DiagramHub-Frontend

任务描述:DiagramHub 前端 - Spring Boot 应用

常规设置

在General区域找到参数化构建过程 勾选

字符参数

名称:GITLAB_SECRET_TOKEN

默认值:留空 等下生成去替换

描述:GitLab Webhook 前端验证密钥

配置触发事件Trigger

勾选 Build when a change is pushed to GitLab. GitLab webhook URL ......

勾选:Push Events

取消勾选:Approved Merge Requests (EE-only)

取消勾选:Comments

高级------生成Secret Token

把生成的Token替换上面常规设置的默认值

记住地址和Token,创建前端的webhook使用

地址:http://192.168.1.14:8888/project/DiagramHub-Frontend

Token:8bd9bd86e88ea5e195bf9a4314a1b3

配置流水线

前端代码地址:http://192.168.1.15:9090/cloud/diagramhub-backend.githttp://192.168.1.15:9090/cloud/diagramhub-frontend.githttp://192.168.1.15:9090/cloud/diagramhub-backend.git

选择之前创建的凭据:gitlab-credentials

构建分支:*/main

点击Additional Behaviours(其他行为),选择检出到指定的本地分支------应用保存

创建前端的webhook

地址:http://192.168.1.14:8888/project/DiagramHub-Frontend

Token:8bd9bd86e88ea5e195bf9a4314a1b3

选择标签推送事件

关闭SSL验证------添加Webhook

三、使用Devops

1、后端项目创建相关配置文件

Jenkinsfile

在后端项目的根目录创建Jenkinsfile

复制代码
pipeline {
    agent any
    
    tools {
        // 使用 Jenkins 全局工具配置的 Maven
        // 名称必须与 Jenkins → Manage Jenkins → Global Tool Configuration 中的 Name 一致
        maven 'MAVEN_HOME'
    }

    environment {
        DOCKER_REGISTRY = '192.168.1.13:8899'
        IMAGE_NAME = 'diagramhub/diagramhub-backend'
        K8S_NAMESPACE = 'diagramhub'
        GIT_CREDENTIALS_ID = 'gitlab-credentials'
        HARBOR_CREDENTIALS_ID = 'harbor-credentials'
        KUBECONFIG_CREDENTIALS_ID = 'k8s-kubeconfig'
        // 配置 Docker 允许 HTTP 私有仓库(Harbor 使用 HTTP)
        DOCKER_OPTS = '--insecure-registry 192.168.1.13:8899'
    }

    // 注意:Tag 推送触发器应在 Jenkins UI 的构建触发器中配置
    // 勾选 "Build when a change is pushed to GitLab" 并只选择 "Tag push events"
    // 不要在此处使用 triggers 块

    stages {
        stage('获取Tag版本') {
            steps {
                script {
                    // 优先使用 GitLab Webhook 传递的 tag 名称
                    if (env.gitlabTargetBranch) {
                        // GitLab Tag Push 事件:tag名称在 gitlabTargetBranch 中(格式:refs/tags/v1.0.2)
                        env.TAG_NAME = env.gitlabTargetBranch.replace('refs/tags/', '')
                        echo "📌 从 GitLab Webhook 获取到 tag: ${env.TAG_NAME}"
                    } else if (env.GIT_BRANCH && env.GIT_BRANCH.startsWith('refs/tags/')) {
                        // Jenkins Git 插件:从 GIT_BRANCH 提取
                        env.TAG_NAME = env.GIT_BRANCH.replace('refs/tags/', '')
                        echo "📌 从 GIT_BRANCH 获取到 tag: ${env.TAG_NAME}"
                    } else {
                        // 备用方案:使用 git describe
                        env.TAG_NAME = sh(
                                script: 'git describe --tags --abbrev=0 2>/dev/null || echo "latest"',
                                returnStdout: true
                        ).trim()
                        echo "📌 从 git describe 获取到 tag: ${env.TAG_NAME}"
                    }
                    // 移除 tag 的 'v' 前缀(如果有)
                    env.IMAGE_TAG = env.TAG_NAME.replaceFirst(/^v/, '')
                    echo "🏷️ 最终镜像版本: ${env.IMAGE_TAG}"
                }
            }
        }

        stage('代码检查') {
            steps {
                sh 'mvn checkstyle:check || true'
            }
        }
        
        stage('单元测试') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
            post {
                always {
                    junit(testResults: '**/target/surefire-reports/*.xml', allowEmptyResults: true)
                }
            }
        }
        
        stage('构建镜像') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: "${HARBOR_CREDENTIALS_ID}", usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS')]) {
                        sh """
                            # 1. 先使用Maven编译(在Jenkins宿主机上,不受Docker内存限制)
                            mvn clean package -DskipTests -Pprod
                            
                            # 2. 复制jar到Docker构建目录
                            cp target/*.jar .
                            
                            # 3. 登录Harbor
                            echo "${HARBOR_PASS}" | docker login http://${DOCKER_REGISTRY} \
                                -u ${HARBOR_USER} --password-stdin
                            
                            # 4. 构建镜像(不再需要MAVEN_OPTS参数)
                            docker build --pull --no-cache \
                                -t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG} .
                            
                            # 5. 推送镜像
                            docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG}
                        """
                    }
                }
            }
        }

        stage('部署到K8s') {
            steps {
                script {
                    withCredentials([file(credentialsId: "${KUBECONFIG_CREDENTIALS_ID}", variable: 'KUBECONFIG_FILE')]) {
                        sh """
                            # 设置KUBECONFIG环境变量
                            export KUBECONFIG=${KUBECONFIG_FILE}
                            
                            # 使用sed替换YAML中的镜像版本为当前构建版本
                            sed -i "s|image:.*diagramhub-backend:.*|image: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG}|" k8s/backend-deployment.yaml
                            
                            # 首次部署:应用完整的 K8s 配置(创建 Deployment、Service、PVC)
                            kubectl apply -f k8s/backend-deployment.yaml -n ${K8S_NAMESPACE}
                                            
                            # 等待滚动更新完成
                            kubectl rollout status deployment/diagramhub-backend \
                                -n ${K8S_NAMESPACE} --timeout=300s
                        """
                    }
                }
            }
        }
    }

    post {
        success {
            echo "✅ 后端部署成功!版本: ${env.IMAGE_TAG}"
        }
        failure {
            echo "❌ 后端部署失败!"
        }
    }
}

Dockerfile

后端项目根目录创建Dockerfile

复制代码
# 基础运行镜像(JRE17 轻量版)
FROM eclipse-temurin:17-jre-alpine

# 工作目录
WORKDIR /app

# 复制已编译好的 jar 包(需要Jenkins先mvn编译)
COPY *.jar app.jar

# 创建上传文件夹
RUN mkdir -p /app/uploads

# 设置时区(北京时间)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# JVM 优化参数
ENV JAVA_OPTS="-Xms256m -Xmx512m -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8"

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1

# 暴露端口
EXPOSE 8080

# 启动项目(强制使用 prod 配置)
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar --spring.profiles.active=prod"]

后端Yaml文件

后端项目根目录创建k8s目录下创建backend-deployment.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: diagramhub-backend
  namespace: diagramhub
  labels:
    app: diagramhub-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: diagramhub-backend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: diagramhub-backend
    spec:
      containers:
        - name: backend
          image: 192.168.1.14:8899/diagramhub/diagramhub-backend:latest
          ports:
            - containerPort: 8080
              name: http
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: "prod"
            - name: DB_USERNAME
              valueFrom:
                secretKeyRef:
                  name: diagramhub-secrets
                  key: db-username
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: diagramhub-secrets
                  key: db-password
            - name: JWT_SECRET
              valueFrom:
                secretKeyRef:
                  name: diagramhub-secrets
                  key: jwt-secret
            - name: MAIL_HOST
              value: "smtp.example.com"
            - name: MAIL_PORT
              value: "25"
            - name: MAIL_USERNAME
              value: ""
            - name: MAIL_PASSWORD
              value: ""
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          volumeMounts:
            - name: uploads
              mountPath: /app/uploads
      volumes:
        - name: uploads
          persistentVolumeClaim:
            claimName: backend-uploads-pvc
      imagePullSecrets:
        - name: harbor-secret
---
apiVersion: v1
kind: Service
metadata:
  name: backend-service
  namespace: diagramhub
spec:
  selector:
    app: diagramhub-backend
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: backend-uploads-pvc
  namespace: diagramhub
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: managed-nfs-storage

推送代码 打Tag使用

复制代码
# 1. 查看修改了哪些文件
git status

# 2. 添加所有修改的文件
git add .

# 3. 提交代码
git commit -m "fix: 你的提交说明"

# 4. 推送到远程 main 分支
git push origin main

# 5. 创建本地标签
git tag -a v1.0.0 -m "Release v1.0.0 - 你的版本说明"

# 6. 推送标签(触发 Jenkins 构建)
git push origin v1.0.0

Jinkens页面查看流水线

这里可以看到详细的构建历史,等待构建完成

查看集群是否部署

复制代码
# 查看pod
[root@k8s-master01 ~]# kubectl get pod -n diagramhub 
NAME                                  READY   STATUS    RESTARTS      AGE
diagramhub-backend-7bc8c7fd65-4gppf   1/1     Running   0             67s
mysql-0                               1/1     Running   8 (60m ago)   6h34m

# 查看pvc
[root@k8s-master01 ~]# kubectl get pvc -n diagramhub 
NAME                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          VOLUMEATTRIBUTESCLASS   AGE
backend-uploads-pvc   Bound    pvc-278ef6da-9461-491e-9be0-86a826b9c0b8   1Gi        RWO            managed-nfs-storage   <unset>                 95s
mysql-data-mysql-0    Bound    pvc-79a3bce3-17b1-4536-b43d-35c717a95737   1Gi        RWO            managed-nfs-storage   <unset>                 27h

# 查看svc
[root@k8s-master01 ~]# kubectl get svc -n diagramhub 
NAME              TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
backend-service   ClusterIP   10.96.86.74   <none>        8080/TCP   109s
mysql-service     ClusterIP   None          <none>        3306/TCP   26h


# 查看日志
[root@k8s-master01 ~]# kubectl logs -n diagramhub  diagramhub-backend-7bc8c7fd65-4gppf 
Defaulted container "backend" out of: backend, k8tz (init)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.0)

2026-05-30T17:22:58.060+08:00  INFO 1 --- [diagramhub-library] [           main] com.diagramhub.DiagramHubApplication     : Starting DiagramHubApplication v1.0.0 using Java 17.0.19 with PID 1 (/app/app.jar started by root in /app)
2026-05-30T17:22:58.067+08:00  INFO 1 --- [diagramhub-library] [           main] com.diagramhub.DiagramHubApplication     : The following 1 profile is active: "prod"
2026-05-30T17:23:23.246+08:00  INFO 1 --- [diagramhub-library] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2026-05-30T17:23:24.547+08:00  INFO 1 --- [diagramhub-library] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 1198 ms. Found 14 JPA repository interfaces.
2026-05-30T17:23:38.252+08:00  INFO 1 --- [diagramhub-library] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2026-05-30T17:23:38.368+08:00  INFO 1 --- [diagramhub-library] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2026-05-30T17:23:38.370+08:00  INFO 1 --- [diagramhub-library] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.16]
2026-05-30T17:23:39.965+08:00  INFO 1 --- [diagramhub-library] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2026-05-30T17:23:40.084+08:00  INFO 1 --- [diagramhub-library] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 40804 ms
2026-05-30T17:23:53.365+08:00  INFO 1 --- [diagramhub-library] [           main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
2026-05-30T17:23:53.755+08:00  INFO 1 --- [diagramhub-library] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2026-05-30T17:23:56.152+08:00  INFO 1 --- [diagramhub-library] [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@4abdd5e
2026-05-30T17:23:56.160+08:00  INFO 1 --- [diagramhub-library] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2026-05-30T17:23:57.262+08:00  WARN 1 --- [diagramhub-library] [           main] org.hibernate.orm.deprecation            : HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2026-05-30T17:24:16.149+08:00  INFO 1 --- [diagramhub-library] [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2026-05-30T17:24:23.152+08:00  INFO 1 --- [diagramhub-library] [           main] o.s.d.j.r.query.QueryEnhancerFactory     : Hibernate is in classpath; If applicable, HQL parser will be used.
2026-05-30T17:24:44.445+08:00  INFO 1 --- [diagramhub-library] [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 3 endpoint(s) beneath base path '/actuator'
2026-05-30T17:24:52.951+08:00  INFO 1 --- [diagramhub-library] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path ''
2026-05-30T17:24:53.049+08:00  INFO 1 --- [diagramhub-library] [           main] com.diagramhub.DiagramHubApplication     : Started DiagramHubApplication in 122.502 seconds (process running for 132.154)
2026-05-30T17:24:56.150+08:00  INFO 1 --- [diagramhub-library] [           main] c.d.config.AdminPasswordInitializer      : 管理员密码正确,无需重置

发布新功能版本

复制代码
# 这里比如我们发布了代码的新功能 要推送到代码仓库

PS D:\Java-code\DiagramHub\backend> cd D:\Java-code\DiagramHub\backend; git tag -a v1.0.3 -m "Release v1.0.3 - 新功能"; git push origin v1.0.3

等待查看流水线

复制代码
# 查看pod使用的镜像
[root@k8s-master01 DiagramHub]# kubectl get deployments.apps -n diagramhub -o wide
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                                  SELECTOR
diagramhub-backend   1/1     1            1           50m   backend      192.168.1.13:8899/diagramhub/diagramhub-backend:1.0.3   app=diagramhub-backend

已经更新成功

2、前端项目创建相关配置文件

Jenkinsfile

在前端项目根目录创建Jenkinsfile

复制代码
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = '192.168.1.13:8899'
        IMAGE_NAME = 'diagramhub/diagramhub-frontend'
        K8S_NAMESPACE = 'diagramhub'
        GIT_CREDENTIALS_ID = 'gitlab-credentials'
        HARBOR_CREDENTIALS_ID = 'harbor-credentials'
        KUBECONFIG_CREDENTIALS_ID = 'k8s-kubeconfig'
        // 配置 Docker 允许 HTTP 私有仓库(Harbor 使用 HTTP)
        DOCKER_OPTS = '--insecure-registry 192.168.1.13:8899'
    }

    // 注意:Tag 推送触发器应在 Jenkins UI 的构建触发器中配置
    // 勾选 "Build when a change is pushed to GitLab" 并只选择 "Tag push events"
    // 不要在此处使用 triggers 块

    stages {
        stage('获取Tag版本') {
            steps {
                script {
                    // 优先使用 GitLab Webhook 传递的 tag 名称
                    if (env.gitlabTargetBranch) {
                        // GitLab Tag Push 事件:tag名称在 gitlabTargetBranch 中(格式:refs/tags/v1.0.2)
                        env.TAG_NAME = env.gitlabTargetBranch.replace('refs/tags/', '')
                        echo "📌 从 GitLab Webhook 获取到 tag: ${env.TAG_NAME}"
                    } else if (env.GIT_BRANCH && env.GIT_BRANCH.startsWith('refs/tags/')) {
                        // Jenkins Git 插件:从 GIT_BRANCH 提取
                        env.TAG_NAME = env.GIT_BRANCH.replace('refs/tags/', '')
                        echo "📌 从 GIT_BRANCH 获取到 tag: ${env.TAG_NAME}"
                    } else {
                        // 备用方案:使用 git describe
                        env.TAG_NAME = sh(
                                script: 'git describe --tags --abbrev=0 2>/dev/null || echo "latest"',
                                returnStdout: true
                        ).trim()
                        echo "📌 从 git describe 获取到 tag: ${env.TAG_NAME}"
                    }
                    // 移除 tag 的 'v' 前缀(如果有)
                    env.IMAGE_TAG = env.TAG_NAME.replaceFirst(/^v/, '')
                    echo "🏷️ 最终镜像版本: ${env.IMAGE_TAG}"
                }
            }
        }

        stage('构建镜像') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: "${HARBOR_CREDENTIALS_ID}", usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS')]) {
                        sh """
                            # 1. 登录Harbor
                            echo "${HARBOR_PASS}" | docker login http://${DOCKER_REGISTRY} \\
                                -u ${HARBOR_USER} --password-stdin
                            
                            # 2. 构建镜像(Docker多阶段构建,内部完成npm install和build)
                            docker build --pull --no-cache \\
                                -t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG} .
                            
                            # 3. 推送镜像
                            docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG}
                        """
                    }
                }
            }
        }

        stage('部署到K8s') {
            steps {
                script {
                    withCredentials([file(credentialsId: "${KUBECONFIG_CREDENTIALS_ID}", variable: 'KUBECONFIG_FILE')]) {
                        sh """
                            # 设置KUBECONFIG环境变量
                            export KUBECONFIG=${KUBECONFIG_FILE}
                            
                            # 使用sed替换YAML中的镜像版本为当前构建版本
                            sed -i "s|image:.*diagramhub-frontend:.*|image: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG}|" k8s/frontend-deployment.yaml
                            
                            # 首次部署:应用完整的 K8s 配置(创建 Deployment、Service、PVC)
                            kubectl apply -f k8s/frontend-deployment.yaml -n ${K8S_NAMESPACE}
                                            
                            # 等待滚动更新完成
                            kubectl rollout status deployment/diagramhub-frontend \\
                                -n ${K8S_NAMESPACE} --timeout=300s
                        """
                    }
                }
            }
        }
    }

    post {
        success {
            echo "✅ 前端部署成功!版本: ${env.IMAGE_TAG}"
        }
        failure {
            echo "❌ 前端部署失败!"
        }
    }
}

Dockerfile

在前端项目根目录创建Dockerfile

复制代码
# 构建阶段
FROM node:18-alpine AS builder

WORKDIR /app

# 复制package文件
COPY package*.json ./

# 安装依赖
RUN npm install

# 复制源代码
COPY . .

# 构建生产版本
RUN npm run build

# 生产阶段
FROM nginx:alpine

# 复制构建产物到nginx
COPY --from=builder /app/dist /usr/share/nginx/html

# 复制nginx配置(如果有)
# COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

前端Yaml文件

后端项目根目录创建k8s目录下创建frontend-deployment.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: diagramhub-frontend
  namespace: diagramhub
  labels:
    app: diagramhub-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: diagramhub-frontend
  template:
    metadata:
      labels:
        app: diagramhub-frontend
    spec:
      imagePullSecrets:
        - name: harbor-secret
      containers:
        - name: diagramhub-frontend
          image: 192.168.1.13:8899/diagramhub/diagramhub-frontend:latest
          ports:
            - containerPort: 80
              name: http
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: default.conf
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5
      volumes:
        - name: nginx-config
          configMap:
            name: frontend-nginx-config
---
apiVersion: v1
kind: Service
metadata:
  name: diagramhub-frontend-service
  namespace: diagramhub
  labels:
    app: diagramhub-frontend
spec:
  type: ClusterIP
  selector:
    app: diagramhub-frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      name: http

推送代码 打Tag触发

复制代码
# 1. 查看修改了哪些文件
git status

# 2. 添加所有修改的文件
git add .

# 3. 提交代码
git commit -m "fix: 你的提交说明"

# 4. 推送到远程 main 分支
git push origin main

# 5. 创建本地标签
git tag -a v1.0.0 -m "Release v1.0.0 - 你的版本说明"

# 6. 推送标签(触发 Jenkins 构建)
git push origin v1.0.0

Jenkins页面查看流水线

查看集群是否部署

复制代码
# 查看pod
[root@k8s-master01 ~]# kubectl get pod -n diagramhub
NAME                                   READY   STATUS    RESTARTS      AGE
diagramhub-backend-55fb995596-r8jm7    1/1     Running   1 (76s ago)   14m
diagramhub-frontend-69d547cff8-d5j4n   1/1     Running   0             40s
mysql-0                                1/1     Running   4 (47s ago)   95m

# 查看service
[root@k8s-master01 ~]# kubectl get svc -n diagramhub
NAME                          TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
backend-service               ClusterIP   10.96.86.74   <none>        8080/TCP   4h15m
diagramhub-frontend-service   ClusterIP   10.96.68.23   <none>        80/TCP     23m
mysql-service                 ClusterIP   None          <none>        3306/TCP   31h

# 修改前端的service类型
[root@k8s-master01 ~]# kubectl edit svc -n diagramhub diagramhub-frontend-service
把 ClusterIP 修改为 NodePort

发布新功能版本

复制代码
PS D:\Java-code\DiagramHub\frontend> cd D:\Java-code\DiagramHub\frontend; git tag -a v1.0.1 -m "Release v1.0.1 - 新版本"; git push origin v1.0.1

等待查看流水线

复制代码
# 查看pod使用的镜像版本
[root@k8s-master01 ~]# kubectl get deployment -n diagramhub -o wide
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS            IMAGES                                                   SELECTOR
diagramhub-backend    1/1     1            1           5h    backend               192.168.1.13:8899/diagramhub/diagramhub-backend:1.0.3    app=diagramhub-backend
diagramhub-frontend   1/1     1            1           73m   diagramhub-frontend   192.168.1.13:8899/diagramhub/diagramhub-frontend:1.0.1   app=diagramhub-frontend

镜像更新成功

3、使用参数化构建过程

如果新发布的版本有Bug,这里添加指定tag来运行业务pod

在参数化构建这里添加git参数

这流水线这里选择上一个版本构建就回退了

相关推荐
shandianchengzi1 小时前
【记录】Claude Code|Ubuntu26给Claude Code新增任务消息提示音
运维·服务器·ubuntu·ai·大模型·音频·claude
蚰蜒螟2 小时前
从mkdir命令到磁盘:Linux内核目录创建过程深度解析
linux·运维·数据库
念何架构之路2 小时前
接入层Nginx
运维·nginx
wanhengidc2 小时前
云手机 跨设备无缝衔接
运维·服务器·人工智能·智能手机·云计算
sxlishaobin2 小时前
SSH远程免密登录的两种方式
运维·ssh
我命由我123453 小时前
SEO 与 GEO 极简理解
java·linux·运维·开发语言·学习·算法·运维开发
!沧海@一粟!3 小时前
Linux高并发内核优化
linux·运维·oracle
perfect123126453 小时前
轻量运维工具fastdp v6版本
linux·运维
:mnong3 小时前
DevOps 怎么用在企业信息系统开发里,持续集成和自动化部署是关键
devops·持续集成,自动化部署,企业信息系统