Kubernetes实战——DevOps集成SpringBoot项目

news2024/11/25 9:49:07

目录

一、安装Gitlab

1、安装并配置Gitlab

1.1 、下载安装包

1.2、安装

1.3、修改配置文件

1.4、更新配置并重启

 2、配置

2.1、修改密码

2.2、禁用注册功能

2.3、取消头像

2.4、修改中文配置

2.5、配置 webhook

3、卸载 

二、安装镜像私服Harbor

1、下载安装包

 2、安装

三、安装代码质量扫描工具sonarqube

1、pgsql.yaml

2、sonarqube.yaml

 3、安装

四、安装Jenkins

1、构建带有maven和sonarqube的镜像

2、安装jenkins

2.1、创建Harbor secret

2.2、 jenkins-configmap.yaml

2.3、jenkins-pvc.yaml

2.4、jenkins-serviceAccount.yaml

2.5、jenkins-deployment.yaml

2.6、jenkins-service.yaml

2.7、创建资源

 3、配置

3.1 、获取初始密码

 3.2、安装插件

3.2.1、Build Authorization Token Root

3.2.2、Gitlab

3.2.3、SonarQube Scanner

3.2.4、Node and Label parameter

3.2.5、Kubernetes

3.2.6、Config File Provider

3.2.7、Git Parameter

3.3、插件配置

3.3.1、SonarQube Scanner配置

3.3.2、kubernetes配置

3.3.3、创建gitlab凭证

五、构建项目

1、创建gitlab的secret

2、配置jenkins任务

2.1、创建流水线Job

 2.2、配置流水线​编辑

2.3、配置gitlab的Webhooks​编辑

2.4、测试构建

 2.5、测试

3、构建SpringBoot项目 

3.1、配置项目流水线

 3.2、创建镜像私服全局凭证

 3.3、创建kubeconfig文件

 3.4、创建sonarqube的webhook

 3.5、 cicd-demo.yaml配置文件

 3.6、cicd-demo-dev.yaml

 3.7、Dockerfile

 3.8、Jenkinsfile

 3.9、完整代码见附录 

 3.10、部署成功效果

六、附录

1、Gitlab安装包

2、Harbor安装包

3、带有Maven的Jenkins镜像

4、源码地址


一、安装Gitlab

1、安装并配置Gitlab

这里使用安装包的方式安装,如果需要Docker方式安装请点击这里

1.1 、下载安装包

wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm

1.2、安装

rpm -i gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm

1.3、修改配置文件

vim /etc/gitlab/gitlab.rb 
#修改 external_url 访问路径
http://<ip>:<port>
例如我这里改为 
external_url 'http://192.168.139.184:9000'

# 修改时区
gitlab_rails['time_zone'] = 'Asia/Shanghai'

1.4、更新配置并重启

gitlab-ctl reconfigure
gitlab-ctl restart

 2、配置

2.1、修改密码

访问上面配置的external_url  http://192.168.139.184:9000/

查看默认密码

cat /etc/gitlab/initial_root_password

 默认账号是root 密码为查看到密码

右上角头像 > Perferences > Password

2.2、禁用注册功能

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

2.3、取消头像

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

2.4、修改中文配置

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

为当前用户设置中文,保存后刷新页面即可

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

2.5、配置 webhook

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

3、卸载 

# 停止服务
gitlab-ctl stop

# 卸载 rpm 软件(注意安装的软件版本是 ce 还是 ee)
rpm -e gitlab-ce

# 查看进程
ps -ef|grep gitlab 
# 干掉第一个 runsvdir -P /opt/gitlab/service log 进程

# 删除 gitlab 残余文件
find / -name *gitlab* | xargs rm -rf
find / -name gitlab | xargs rm -rf

二、安装镜像私服Harbor

1、下载安装包

#下载安装包
wget https://github.com/goharbor/harbor/releases/download/v1.10.19/harbor-offline-installer-v1.10.19.tgz

#解压
tar -zxf harbor-offline-installer-v1.10.19.tgz 

 2、安装

修改配置文件

vim harbor.yml

安装

 ./install.sh

   访问http://192.168.139.184:8899/ 默认账号为admin 密码为Harbor12345

 配置docker文件,并重启docker服务 。

{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
        "https://do.nark.eu.org",
        "https://dc.j8.work",
        "https://docker.m.daocloud.io",
        "https://dockerproxy.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://docker.nju.edu.cn"
    ],
"insecure-registries": ["http://192.168.139.184:8899"]  #新增的配置
}

三、安装代码质量扫描工具sonarqube

1、pgsql.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
  namespace: kube-devops
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "manager-nfs-storage"  #前面安装的storageclass
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-sonar
  namespace: kube-devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres-sonar
  template:
    metadata:
      labels:
        app: postgres-sonar
    spec:
      containers:
      - name: postgres-sonar
        image: postgres:14.2
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_DB
          value: "sonarDB"
        - name: POSTGRES_USER
          value: "sonarUser"
        - name: POSTGRES_PASSWORD 
          value: "123456"
        volumeMounts:
          - name: data
            mountPath: /var/lib/postgresql/data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: postgres-data
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-sonar
  namespace: kube-devops
  labels:
    app: postgres-sonar
spec:
  type: NodePort
  ports:
  - name: postgres-sonar
    port: 5432
    targetPort: 5432
    protocol: TCP
  selector:
    app: postgres-sonar

2、sonarqube.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonarqube-data
  namespace: kube-devops
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "manager-nfs-storage"
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sonarqube
  namespace: kube-devops
  labels:
    app: sonarqube
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sonarqube
  template:
    metadata:
      labels:
        app: sonarqube
    spec:
      initContainers:
      - name: init-sysctl
        image: busybox:1.28.4
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
      containers:
      - name: sonarqube
        image: sonarqube:9.9-community
        ports:
        - containerPort: 9000
        env:
        - name: SONARQUBE_JDBC_USERNAME
          value: "sonarUser"
        - name: SONARQUBE_JDBC_PASSWORD
          value: "123456"
        - name: SONARQUBE_JDBC_URL
          value: "jdbc:postgresql://postgres-sonar:5432/sonarDB"
        livenessProbe:
          httpGet:
            path: /sessions/new
            port: 9000
          initialDelaySeconds: 60
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /sessions/new
            port: 9000
          initialDelaySeconds: 60
          periodSeconds: 30
          failureThreshold: 6
        volumeMounts:
        - mountPath: /opt/sonarqube/conf
          name: data
        - mountPath: /opt/sonarqube/data
          name: data
        - mountPath: /opt/sonarqube/extensions
          name: data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: sonarqube-data 
---
apiVersion: v1
kind: Service
metadata:
  name: sonarqube
  namespace: kube-devops
  labels:
    app: sonarqube
spec:
  type: NodePort
  ports:
  - name: sonarqube
    port: 9000
    targetPort: 9000
    protocol: TCP
  selector:
    app: sonarqube

 3、安装

#创建资源
kubectl create -f pgsql.yaml -f sonarqube.yaml

#查看资源
kubectl get po,svc -n kube-devops -o wide

 

 访问该端口下的服务,默认账号密码admin/admin

 

四、安装Jenkins

1、构建带有maven和sonarqube的镜像

Dockerfile

FROM jenkins/jenkins:jdk17
ADD ./apache-maven-3.9.9-bin.tar.gz /usr/local/
ADD ./sonar-scanner-cli-4.8.0.2856-linux.zip /usr/local/

USER root

WORKDIR /usr/local/
RUN unzip sonar-scanner-cli-4.8.0.2856-linux.zip
RUN mv sonar-scanner-4.8.0.2856-linux sonar-scanner-cli
RUN ln -s /usr/local/sonar-scanner-cli/bin/sonar-scanner /usr/bin/sonar-scanner

ENV MAVEN_HOME=/usr/local/apache-maven-3.9.9
ENV PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH

RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
USER jenkins
#构建镜像
docker build -t 192.168.139.184:8899/wsnail-harbor/jenkins-maven:jdk-17 .

#登录docker私服
docker login -uadmin 192.168.139.184:8899

#推送到仓库
docker push 192.168.139.184:8899/wsnail-harbor/jenkins-maven:jdk-17

 注意:1、该操作和docker私服在同一台服务器上

            2、请确认、etc/docker/damon.json文件配置了"insecure-registries": ["http://192.168.139.184:8899"] 

 

2、安装jenkins

2.1、创建Harbor secret


kubectl create secret docker-registry harbor-secret --docker-server=192.168.139.184:8899 --docker-username=admin --docker-password=Xiaojie12345 -n kube-devops

2.2、 jenkins-configmap.yaml

apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: mvn-settings
  namespace: kube-devops
  labels: 
    app: jenkins-server
data: 
  settings.xml: |- 
    <?xml version="1.0" encoding="UTF-8"?>
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
        <localRepository>/var/jenkins_home/repository</localRepository>
         <servers>
        <server>
            <!--此处id需要对应项目中pom.xml文件中的<distributionManagement> 标签下的id-->
            <id>release</id>
            <username>admin</username>
            <password>123456</password>
        </server>
        <server>
            <id>snapshots</id>
            <username>admin</username>
            <password>123456</password>
        </server>
    </servers>

        <mirrors>
                <mirror>
                     <id>releases</id>
                     <name>nexus maven</name>
                     <mirrorOf>*</mirrorOf>
                     <url>http://192.168.139.184:8081/repository/maven-public/</url>
                </mirror>
                <mirror>
                     <id>aliMaven</id>
                     <name>aliyun maven</name>	  	  
                     <url>	https://maven.aliyun.com/repository/public</url>
                     <mirrorOf>central</mirrorOf>
                </mirror>
        </mirrors>

        <pluginGroups>
                <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
        </pluginGroups>
        <profiles>
                <profile>
                        <id>releases</id>
                        <activation>
                                <activeByDefault>true</activeByDefault>
                                <jdk>1.8</jdk>
                        </activation>
                        <properties>
                                <sonar.host.url>http://sonarqube:9000</sonar.host.url>
                        </properties>

                        <repositories>
                                <repository>
                                        <id>repository</id>
                                        <name>Nexus Repository</name>
                                        <url>http://192.168.139.184:8081/repository/snail-group/</url>   
                                        <releases>
                                                <enable>true</enable>
                                        </releases>
                                        <snapshots>
                                                <enable>true</enable>
                                        </snapshots>
                                </repository>
                        </repositories>
                </profile>
        </profiles>
    </settings>

2.3、jenkins-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
  namespace: kube-devops
spec:
  storageClassName: manager-nfs-storage
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

2.4、jenkins-serviceAccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-admin
  namespace: kube-devops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: jenkins-admin
  namespace: kube-devops

2.5、jenkins-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: kube-devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins-server
  template:
    metadata:
      labels:
        app: jenkins-server
    spec:
      serviceAccountName: jenkins-admin
      #Default: 继承节点的DNS配置;ClusterFirst: 使用coredns作为DNS配置;
      #ClusterFirstWithHostNet:当Pod.spec.hostNetwork=true时,Pod的DNS策略被强制转换为Default,即继承节点的DNS配置;
      #  若Pod要使用coredns作为DNS配置,则需配置pod.spec.dnsPolicy=ClusterFirstWithHostNet;
      #   None: 没有DNS配置;
      dnsPolicy: Default  #解决pod内没有DNS解析不到插件地址
      imagePullSecrets:
        - name: harbor-secret # harbor 访问 secret
      containers:
        - name: jenkins
          image: 192.168.139.184:8899/wsnail-harbor/jenkins-maven:jdk-17   #这里是自己镜像的地址
          imagePullPolicy: IfNotPresent
          securityContext:
            privileged: true
            runAsUser: 0 # 使用 root 用户运行容器
          resources:
            limits:
              memory: "2Gi"
              cpu: "1000m"
            requests:
              memory: "500Mi"
              cpu: "500m"
          ports:
            - name: httpport
              containerPort: 8080
            - name: jnlpport
              containerPort: 50000
          livenessProbe:
            httpGet:
              path: "/login"
              port: 8080
            initialDelaySeconds: 90
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 5
          readinessProbe:
            httpGet:
              path: "/login"
              port: 8080
            initialDelaySeconds: 60
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3
          volumeMounts:
            - name: jenkins-data
              mountPath: /var/jenkins_home
            - name: docker
              mountPath: /run/docker.sock
            - name: docker-home
              mountPath: /usr/bin/docker
            - name: mvn-setting
              mountPath: /usr/local/apache-maven-3.9.9/conf/settings.xml
              subPath: settings.xml
            - name: daemon
              mountPath: /etc/docker/daemon.json
              subPath: daemon.json
            - name: kubectl
              mountPath: /usr/bin/kubectl
      volumes:
        - name: kubectl
          hostPath:
            path: /usr/bin/kubectl
        - name: jenkins-data
          persistentVolumeClaim:
              claimName: jenkins-pvc
        - name: docker
          hostPath:
            path: /run/docker.sock # 将主机的 docker 映射到容器中
        - name: docker-home
          hostPath:
            path: /usr/bin/docker
        - name: mvn-setting
          configMap:
            name: mvn-settings
            items:
            - key: settings.xml
              path: settings.xml
        - name: daemon
          hostPath: 
            path: /etc/docker/

2.6、jenkins-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: jenkins-service
  namespace: kube-devops
  annotations:
      prometheus.io/scrape: 'true'
      prometheus.io/path:   /
      prometheus.io/port:   '8080'
spec:
  selector:
    app: jenkins-server
  type: NodePort
  ports:
    - port: 8080
      targetPort: 8080

2.7、创建资源

#上面的配置文件均在manifests文件下
kubectl apply -f manifests/

#查看资源
kubectl get po,svc -n kube-devops

 3、配置

3.1 、获取初始密码

 kubectl logs jenkins-598b49d974-glv5x -n kube-devops

 3.2、安装插件

3.2.1、Build Authorization Token Root
3.2.2、Gitlab
3.2.3、SonarQube Scanner
3.2.4、Node and Label parameter
3.2.5、Kubernetes
3.2.6、Config File Provider
3.2.7、Git Parameter

3.3、插件配置

3.3.1、SonarQube Scanner配置

 注意:如果不是k8s部署可以使用外网访问,ip:port

在SonarQube创建token

在jenkins中添加sonarqube的token

3.3.2、kubernetes配置

 

 

3.3.3、创建gitlab凭证

五、构建项目

1、创建gitlab的secret

后面构建项目时候需要用到

#用户名
echo root > ./username

#密码
echo xiaojie123456 > password

#创建secret
kubectl create secret generic git-user-pwd --from-file=./username --from-file=./password -n kube-devops

#查看
kubectl get  secret -n kube-devops

2、配置jenkins任务

2.1、创建流水线Job

 2.2、配置流水线

2.3、配置gitlab的Webhooks

2.4、测试构建

 2.5、测试

3、构建SpringBoot项目 

3.1、配置项目流水线

 3.2、创建镜像私服全局凭证

 3.3、创建kubeconfig文件

cat ~/.kube/config

将文件内容复制

 3.4、创建sonarqube的webhook

3.5、 cicd-demo.yaml配置文件

---
#开发环境的deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: k8s-demo
    component: wssnail-devops
    tier: backend
  name: k8s-demo
  namespace: ks-k8s-demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: k8s-demo
      component: wssnail-devops
      tier: backend
  strategy:
    rollingUpdate:
      maxSurge: 100%
      maxUnavailable: 100%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: k8s-demo
        component: wssnail-devops
        tier: backend
    spec:
      imagePullSecrets:
        - name: harbor-secret #该secret必须和该项目在同一个namespace下
      containers:
        - name: k8s-demo
          image: REGISTRY/DOCKERHUB_NAMESPACE/APP_NAME:SNAPSHOT-BUILD_NUMBER   #该内容会在构建镜像时自动替换为实际内容
          readinessProbe:
            httpGet:
              path: /index
              port: 8080
            timeoutSeconds: 10
            failureThreshold: 30
            periodSeconds: 5
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
            requests:
              cpu: 100m
              memory: 100Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: k8s-demo
    component: wssnail-devops
  name: k8s-demo
  namespace: ks-k8s-demo
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: k8s-demo
    component: wssnail-devops
    tier: backend
  sessionAffinity: None
  type: NodePort

3.6、cicd-demo-dev.yaml

---
#开发环境的deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: k8s-demo
    component: wssnail-devops
    tier: backend
  name: k8s-demo
  namespace: ks-k8s-demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: k8s-demo
      component: wssnail-devops
      tier: backend
  strategy:
    rollingUpdate:
      maxSurge: 100%
      maxUnavailable: 100%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: k8s-demo
        component: wssnail-devops
        tier: backend
    spec:
      imagePullSecrets:
        - name: harbor-secret #该secret必须和该项目在同一个namespace下
      containers:
        - name: k8s-demo
          image: REGISTRY/DOCKERHUB_NAMESPACE/APP_NAME:SNAPSHOT-BUILD_NUMBER   #该内容会在构建镜像时自动替换为实际内容
          readinessProbe:
            httpGet:
              path: /index
              port: 8080
            timeoutSeconds: 10
            failureThreshold: 30
            periodSeconds: 5
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
            requests:
              cpu: 100m
              memory: 100Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: k8s-demo
    component: wssnail-devops
  name: k8s-demo
  namespace: ks-k8s-demo
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: k8s-demo
    component: wssnail-devops
    tier: backend
  sessionAffinity: None
  type: NodePort

 3.7、Dockerfile

## 基础镜像
FROM openjdk:17-slim

## 作者
LABEL org.opencontainers.image.authors="wssnail"

## 定义参数

## 创建并进入工作目录
RUN mkdir -p /wssnail
WORKDIR /wssnail

## maven 插件构建时得到 buildArgs 种的值
COPY target/*.jar app.jar

## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms256m -Xmx256m"

## 暴露端口
EXPOSE 8080

## 容器启动命令
## CMD 第一个参数之后的命令可以在运行时被替换
CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

3.8、Jenkinsfile

pipeline {

  agent {
    node {
      label 'maven'  // 这里配置的标签和jenkins中配置节点添加的标签一致
    }
  }

  environment {
    REGISTRY = '192.168.139.184:8899'   //harbor地址
    DOCKER_CREDENTIAL_ID = 'harbor-user-pwd' //harbor凭证,对应jenkins创建凭证的id
    GIT_REPO_URL = '192.168.139.184:9000'    //gitlab地址
    GIT_CREDENTIAL_ID = 'git-user-pwd'   //gitlab凭证,对应jenkins创建凭证的id
    KUBECONFIG_CREDENTIAL_ID = '30629742-ddae-4c80-a3ad-5807ffc6ff5a'  //对应jenkins创建kubeconfig文件时的id
    DOCKERHUB_NAMESPACE = 'wsnail-harbor' //镜像私服的命名空间
    GITHUB_ACCOUNT = 'root'  //git账号
    APP_NAME = 'demo-k8s'  //应用名称
    SONAR_SERVER_URL='http://192.168.139.208:32061'  //sonarqube地址
    SONAR_CREDENTIAL_ID='sonarqube-token'  //jenkins创建的凭证
  }

  //拉取代码
  stages {

    stage('clone code') {
      steps {
        //配置代码仓库地址 ,credentialsId和jenkins创建的凭证的id保持一致
          sh 'echo  start pull code  start'
          git(url: 'http://192.168.139.184:9000/gitlab-instance-e9e80190/demo-k8s.git', credentialsId: 'git-user-pwd', branch: 'master', changelog: true, poll: false)
          sh 'echo  start pull code end'
        }
    }

    //单元测试
    stage('unit test') {
      steps {
          sh 'mvn clean test'
      }
    }
    //代码质量分析,如果jenkins配置的service连接不上,使用外网地址访问
    stage('sonarqube analysis') {
      agent none
      //withSonarQubeEnv()的值和jenkins中配置的sonarqube的名字保持一致
      steps {
        withCredentials([string(credentialsId : 'sonarqube-token' ,variable : 'SONAR_TOKEN' ,)]) {
          withSonarQubeEnv('sonarqube') {
              sh '''mvn sonar:sonar -Dsonar.projectKey=$APP_NAME
              echo "mvn sonar:sonar -Dsonar.projectKey=$APP_NAME"'''
          }

            //代码质量扫描等待时间
          timeout(unit: 'MINUTES', activity: true, time: 10) {
            waitForQualityGate 'true'
          }
        }
      }
    }

    //打包构建镜像
    stage('build & push') {
      steps {
          sh 'mvn clean package -DskipTests'
          sh 'docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER .'
          withCredentials([usernamePassword(credentialsId : 'harbor-user-pwd' ,passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,)]) {
            sh '''echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin
            docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'''
          }
      }
    }

    stage('push latest') {
      //是master 分支时,构建镜像的tag为latest保证上线的代码是最新的
      when {
        branch 'master'
      }
      steps {
          sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest'
          sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest'
      }
    }

    stage('deploy to dev') {
    //开发分支时部署到开发分支,这里分支灵活配置,注意镜像地址要与主分支分开
      steps {
          input(id: 'deploy-to-dev', message: 'deploy to dev?')
            sh '''sed -i\'\' "s#REGISTRY#$REGISTRY#" deploy/cicd-demo-dev.yaml
            sed -i\'\' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" deploy/cicd-demo-dev.yaml
            sed -i\'\' "s#APP_NAME#$APP_NAME#" deploy/cicd-demo-dev.yaml
            sed -i\'\' "s#BUILD_NUMBER#$BUILD_NUMBER#" deploy/cicd-demo-dev.yaml
            kubectl apply -f deploy/cicd-demo-dev.yaml'''

      }
    }

    stage('push with tag') {
    //为gitlab打tag
      agent none
      when {
        expression {
        //当匹配tag 为v开头的分支时
          params.TAG_NAME =~ /v.*/
        }

      }
      steps {
        input(message: 'release image with tag?', submitter: '')
        withCredentials([usernamePassword(credentialsId : 'git-user-pwd' ,passwordVariable : 'GIT_PASSWORD' ,usernameVariable : 'GIT_USERNAME' ,)]) {
          sh 'git config --global user.email "whisper_snail@163.com" '
          sh 'git config --global user.name "wssnail" '
          sh 'git tag -a $TAG_NAME -m "$TAG_NAME" '
          sh 'git push http://$GIT_USERNAME:$GIT_PASSWORD@$GIT_REPO_URL/gitlab-instance-e9e80190/demo-k8s.git --tags --ipv4'
        }
          sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$TAG_NAME'
          sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$TAG_NAME'
      }
    }

//是否部署到生产环境
    stage('deploy to production') {
      agent none
      when {
        expression {
          params.TAG_NAME =~ /v.*/
        }

      }
      steps {
        input(message: 'deploy to production?', submitter: '')
          sh '''sed -i\'\' "s#REGISTRY#$REGISTRY#" deploy/cicd-demo.yaml
          sed -i\'\' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" deploy/cicd-demo.yaml
          sed -i\'\' "s#APP_NAME#$APP_NAME#" deploy/cicd-demo.yaml
          sed -i\'\' "s#TAG_NAME#$TAG_NAME#" deploy/cicd-demo.yaml
          kubectl apply -f deploy/cicd-demo.yaml'''
      }
    }
  }

//参数选择
  parameters {
    string(name: 'BRANCH_NAME', defaultValue: 'master', description: '请选择要发布的分支')
    choice(name: 'NAMESPACE',choices:['dev','test','master'],description: '命名空间')
    string(name: 'TAG_NAME', defaultValue: 'snapshot', description: '标签名称,必须以 v 开头,例如:v1、v1.0.0')
  }

}

3.9、完整代码见附录 

3.10、部署成功效果

 

 

 

六、附录

1、Gitlab安装包


链接: https://pan.baidu.com/s/1vUCRmxNzW0jO9mdZ79uYUQ?pwd=37s3 提取码: 37s3 

2、Harbor安装包


链接: https://pan.baidu.com/s/12bZcCA4C3RM89wf5K9_AqQ?pwd=4t49 提取码: 4t49 

3、带有Maven的Jenkins镜像


链接: https://pan.baidu.com/s/19luWsomE7Mktzp9UyAQ5VA?pwd=n7hp 提取码: n7hp 

4、源码地址

熟透的蜗牛/demo-k8s

5、参考

http://www.bilibili.com/video/BV1MT411x7GH/


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2228693.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【移动应用开发】访问网络

目录 一、运行截图 二、源代码 1. WebView的简单使用 ① activity_main.xml ② MainActivity.kt ③ AndroidManifest.xml 2. 使用OkHttp访问以下接口&#xff0c;获取Aspirin化合物的JSON格式数据 ① activity_okhttp.xml ② OKhttpActivity ③ 导入依赖 3. 使用GSO…

软件工程--需求分析与用例模型

面向对象分析(ObjectOrientedAnalysis&#xff0c;简称OOA) 分析和理解问题域&#xff0c;找出描述问题域所需的类和对象&#xff0c;分析它们的内部构成和外部关系&#xff0c;建立独立于实现的OOA模型&#xff0c;暂时忽略与系统实现有关的问题。 主要使用UML中的以下几种图…

Android中同步屏障(Sync Barrier)介绍

在 Android 中&#xff0c;“同步屏障”&#xff08;Sync Barrier&#xff09;是 MessageQueue 中的一种机制&#xff0c;允许系统临时忽略同步消息&#xff0c;以便优先处理异步消息。这在需要快速响应的任务&#xff08;如触摸事件和动画更新&#xff09;中尤为重要。 在 An…

MyBatis-Plus:简化 CRUD 操作的艺术

一、关于MyBatis-Plus 1.1 简介 MyBatis-Plus 是一个基于 MyBatis 的增强工具&#xff0c;它旨在简化 MyBatis 的使用&#xff0c;提高开发效率。 ​ ‍ ‍ ‍ ​ ‍ 关于Mybatis 简介 MyBatis 是一款流行的 Java 持久层框架&#xff0c;旨在简化 Java 应用程序与数…

ECharts饼图-圆角环形图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…

正则表达式匹配日期格式

前言 这里有sql文本&#xff0c;是从数据库中拷贝出来的&#xff0c;希望重新执行的时候createTime和updateTime都统一设置成当前日期。 利用正则表达式结合文本编辑器&#xff0c;就能全局替换了 (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) 替换结果如下

学习伊圣雨老师的 epoll 编程

&#xff08;1&#xff09;书里提出了疑问&#xff0c;epoll 函数的工作方式&#xff0c;区分为水平触发与边缘触发 &#xff1a; &#xff08;2&#xff09; 谢谢

3.2K+ Star!OpenLLMetry:一个开源的LLM应用可观测性工具

OpenLLMetry 简介 OpenLLMetry[1] 是一个基于OpenTelemetry的开源可观测性工具&#xff0c;专为LLM&#xff08;Large Language Models&#xff0c;大型语言模型&#xff09;应用设计。 它提供了一套扩展&#xff0c;可以帮助开发者全面监控和管理他们的LLM应用。 项目特点 主…

C# 编程语言学习教程

C# 编程语言学习教程 目录 C# 简介 1.1 什么是 C#1.2 C# 的特点1.3 C# 的应用领域 环境搭建 2.1 安装 Visual Studio2.2 创建第一个 C# 项目 基础语法 3.1 数据类型3.2 控制结构3.3 数组与字符串 面向对象编程 4.1 类与对象4.2 继承与多态4.3 接口与抽象类 常用库与框架 5.1 .…

分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB)

分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB) 目录 分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB)分类效果基本介绍程序设计参考资料分类效果 基本介绍 GCN图卷积神经网络多特征分类预测(MATLAB) 在图卷积神经网络(GCN)中,多特征分类

以AI赋能身份验证,Jumio助力中国企业出海

近年来&#xff0c;越来越多的中国企业开始扬帆出海积极拓展全球市场。而能够为企业出海提供各种助力的技术与解决方案&#xff0c;也成为了众多企业关注的焦点。 作为全球领先的在线身份验证和欺诈预防解决方案提供商&#xff0c;Jumio于近日在北京举办了中国媒体见面会&#…

中级 <HarmonyOS第一课>合理使用动画和转场的课后习题

天道无亲&#xff0c;常与善人。 天命人&#xff0c;战斗吧&#xff01;&#xff01;&#xff01; 来自 <HarmonyOS第一课>合理使用动画和转场的习题。 判断题 animateTo可以设置组件进行位移动画时的运动路径。❌ 单选题 模态转场不包括以下哪个类别&#xff1f; A. …

Python(包和模块)

包 定义 包是将模块以文件夹的组织形式进行分组管理的方法&#xff0c;以便更好地组织和管理相关模块。 包是一个包含一个特殊的__init__.py文件的目录&#xff0c;这个文件可以为空&#xff0c;但必须存在&#xff0c;以标识目录为Python包。 包可以包含子包&#xff08;子…

数据采集-Kepware OPCUA 服务器实现

KepserverEX OPC UA server设置 目录 KepserverEX OPC UA server设置一、OPC UA(OPC Unified Architecture)二、防火墙的配置三、配置KepserverEX的OPC UA3.1 启用远程连接3.2 启动OPCUA服务器接口 四、管理OPCUA的端口和证书4.1 添加端口4.2 证书申请 一、OPC UA(OPC Unified …

医学和生信web APP 平台- Appmatrix

医学&#xff08;和生信&#xff09;web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起&#xff0c;实现一站式访问&#xff0c;另外&#xff0c;使用了自己电脑内网穿透&#xff0c;一定程度上缓解了数据分析类APP消耗计算资源…

PyTorch nn.Conv2d 空洞卷积

torch.nn.Conv2d() 中 dilation 参数控制卷积核的间隔 dilation controls the spacing between the kernel points 当 dilation1 时, 表示卷积核没有额外的空白间距, 也就是标准卷积当 dilation>1 时, 表示空洞卷积(dilated convolution) 动画演示: 手动计算 以 2*2 的卷…

大模型,多模态大模型面试问题【计算图,LLama,交叉熵,SiLU,RLHF】

大模型&#xff0c;多模态大模型面试问题【计算图&#xff0c;LLama&#xff0c;交叉熵&#xff0c;SiLU&#xff0c;RLHF】 问题一&#xff1a;讲一讲计算图中pytorch是什么&#xff0c;TensorFlow是什么&#xff1f;1. PyTorch2. TensorFlow区别总结 问题二&#xff1a;Llama…

learnopencv系列一:使用神经网络进行特征匹配(LoFTR、XFeat、OmniGlue)、视频稳定化、构建Chrome Dino游戏机器人

文章目录 一、使用神经网络进行特征匹配1.1 什么是图像特征&#xff1f;1.2 特征匹配的应用场景——为什么在2024年还要进行特征匹配&#xff1f;1.3 特征匹配——经典方法与深度学习1.3.1 经典特征匹配1.3.2 深度学习特征匹配1.3.3 XFeat1.3.3.1 网络结构1.3.3.2 局部特征提取…

MySQL 数据出海之数据同步方案

优质博文&#xff1a;IT-BLOG-CN 数据库出海流程 【1】业务出海&#xff1a;1&#xff09;数据库出海&#xff1b;2&#xff09;应用出海&#xff1b;3&#xff09;流量分发&#xff1b; 【2】数据库出海&#xff1a;涉及业务方、信安、DBA和框架组。 数据库出海&#xff0c…

Elasticsearch 安装教程:驾驭数据海洋的星际导航仪

目录 一、准备工作1. ES的下载 二、安装步骤三、注意事项四、启动报错1. org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root2. max virtual memory areas vm.max_map_count [65530] is too low, increase to at l…