04-k8s專案部署

peng_boke發表於2024-10-14

前言

且停且忘且隨風,且行且看且從容

10部署

10.1Docker映象操作

Docker映象推送阿里雲

docker commit 命令用於建立一個新的映象,以當前容器的狀態為基礎。它可以將正在執行的容器的更改儲存為一個新的 Docker 映象。

docker commit說明:

  • -a "peng": 設定作者為 "peng"。
  • -m "nginx": 新增提交資訊為 "nginx"。
  • <容器ID>: 替換為你的 Nginx 容器的實際 ID 或名稱。
  • pengpeng-namespace/gulimall-nginx:v1.0: 指定新的映象名稱和標籤。
# 建立新的映象
docker commit -a "peng" -m "nginx" 容器id pengpeng-namespace/gulimall-nginx:v1.0

# 向阿里雲推送映象快照
docker push crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/pengpeng-registry:gulimall-nginx:v1.0

# 登入
docker login --username=pengpengservice crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com

# 建立新的標籤
docker tag crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/pengpeng-registry:gulimall-nginx:v1.0 crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/pengpeng-registry:latest

# 推送映象
docker push crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/pengpeng-registry:latest

修改配置

image-20241004043432914

10.2部署-整合阿里雲映象倉庫

參考:https://www.cnblogs.com/makalochen/p/14240796.html

image-20241002063458924

官方地址:https://cr.console.aliyun.com/cn-shanghai/instance/repositories

image-20241002053704838

建立本地倉庫

image-20241002053804868

本地倉庫建立完成

image-20241002064641285

我們需要留意docker login docker pulldocker push 三條命令

需要留意自己的請求地址、名稱空間、倉庫名稱、賬號名稱

10.3Jenkins修改阿里雲映象倉庫

建立阿里雲賬號憑證,需要輸入自己阿里雲的賬號密碼

image-20241002055409888

在環境變數新增自己阿里雲的相關引數,分別是憑證(配置阿里雲的賬號密碼)、請求地址、名稱空間、倉庫名稱、賬號名稱

  environment {
        DOCKER_CREDENTIAL_ID      = 'dockerhub-id'
        GITEE_CREDENTIAL_ID       = 'gitee-id'
        KUBECONFIG_CREDENTIAL_ID  = 'demo-kubeconfig'
        REGISTRY                  = 'docker.io'
        DOCKERHUB_NAMESPACE       = 'pengeng'
        GITEE_ACCOUNT             = '15549996135'
        SONAR_CREDENTIAL_ID       = 'sonar-token'
        BRANCH_NAME               = 'master'
		ALIYUN_CREDENTIAL_ID      = 'aliyun-id'
		ALIYUN_URL                = 'crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com' 
		ALIYUN_NAMESPACE          = 'pengpeng-namespace'
		ALIYUN_ACCOUNT            = 'pengpengservice'
    }

image-20241002080811694

建立阿里雲的步驟,loginpush地址拼對即可,tag版本號可以小點

 stage ('構建映象-推送阿里雲') {
            steps {
                dir('code/peng-mall-parent') {
                    container ('maven') {
                        sh 'cd service/$PROJECT_NAME && docker build -f Dockerfile -t $BRANCH_NAME-$BUILD_NUMBER .'
                        sh "echo 映象:$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER"
						sh 'docker images'
                        withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD', usernameVariable : 'DOCKER_USERNAME', credentialsId : "$ALIYUN_CREDENTIAL_ID")]) {                   
                            sh 'echo "$DOCKER_PASSWORD" | docker login --username="$ALIYUN_ACCOUNT" "$ALIYUN_URL" --password-stdin'
                            sh 'docker tag $BRANCH_NAME-$BUILD_NUMBER $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER'
                            sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER'
                        }
                    }
                }
            }
        }

image-20241002080904864

步驟都是成功狀態

image-20241002081112629

push完成

image-20241002081037969

10.4流水線-部署gateway

建立流水線

peng-mall-jenkins-aliyun-cicd

image-20241006032533809

選擇git,輸入專案gitee地址,選擇gitee-id憑證(就是配置的gitee賬號)

image-20241006032712576

我的Jenkinsfile不在根目錄,我這邊指定了Jenkinsfile地址

選擇是否開啟淺克隆

image-20241006032842856

選擇執行,如果首次點選執行沒有出現配置的專案引數(分支、PROJECT_VERSIONPROJECT_NAME),直接停止,獲取不到引數流水線也會失敗,執行停止1-2次引數的介面就應該就出來了,然後選擇引數再執行

image-20241006033304377

記得在這裡刪除執行失敗的gulimall-gateway

image-20241006033733676

服務部署成功

image-20241006050333670

訪問gulimall-gateway,出現SpringBoot的404代表部署成功

image-20241006060557295

fatal: tag 'gulimall-gateway-v1.0' already exists

+ git tag -a gulimall-gateway-v1.0 -m v1.0
fatal: tag 'gulimall-gateway-v1.0' already exists
script returned exit code 128

image-20241006045729391

記得改一下版本就行了

image-20241006050208366

10.5流水線-部署auth-server

部署gulimall-auth-service

image-20241006061514372

成功後,我們去看pod

image-20241006061541908

訪問gulimall-auth-service,出現SpringBoot的404代表部署成功

image-20241006061631697

10.6流水線-部署cart

部署gulimall-cart

image-20241006061815447

部署成功後檢視pod

image-20241006063450618

訪問gulimall-cart,出現SpringBoot的404代表部署成功

image-20241006063542352

檢視阿里雲映象

image-20241006063657616

檢視gulimall-cart的映象

image-20241006063721458

10.12最終部署-商城系統上線

10.12.1推送gulimall-nginx

把自己之前部署nginx掛載目錄下的confhtml下載下來

image-20241006073222388

檢視gulimall-gateway閘道器地址

image-20241007014612452

修改nginx的閘道器地址

gulimall-gateway-deploy.yaml配置的閘道器暴露介面為31000,所以nginx配置的上游地址是k8s節點ip:31000

image-20241006071450105

以下是Dockerfile內容

FROM nginx
MAINTAINER peng
ADD html.tar.gz /usr/share/nginx/html
ADD conf.tar.gz /etc/nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

htmlconf上傳到k8s伺服器

打包html目錄,只用打包html下的所有檔案,不需要html目錄

tar -czvf html.tar.gz -C html .

image-20241007022105599

打包conf目錄,只用打包conf下的所有檔案,不需要conf目錄

tar -czvf conf.tar.gz -C conf .

image-20241007022144718

然後可以刪掉htmlconf

image-20241007015252131

gulimall-nginx下進行打包

docker build -t gulimall-nginx:v1.0 -f Dockerfile .

image-20241006075941095

登入阿里雲,然後打上標籤準備推送

# 登入
docker login --username=pengpengservice crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com
# 標籤 0850795a13b6
docker tag [ImageId] crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/gulimall-nginx:v1.0

image-20241006080118679

推送到阿里雲

# 推送
docker push crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/gulimall-nginx:v1.0

image-20241006080215381

阿里雲上傳成功

image-20241006080400496

10.12.2訪問gulimall-nginx

建立gulimall-nginx見10.10.2

檢視gulimall-nginx的靜態資源和配置是否修改了

image-20241007023403438

檢視靜態資原始檔

 cd  /usr/share/nginx
 cd html
 ls

image-20241007023254856

配置檔案

cd /etc/nginx
cat nginx.conf

image-20241007023308539

訪問http://192.168.188.181:32419/static/search/img/01.png,靜態資源正常訪問介面

image-20241007023828317

10.12.3訪問所有服務

管理員執行SwitchHosts,配置k8s叢集的域名方案,我的都在一臺電腦上

192.168.188.181     gulimall.com
192.168.188.181     search.gulimall.com
192.168.188.181     item.gulimall.com
192.168.188.181     auth.gulimall.com
192.168.188.181     cart.gulimall.com
192.168.188.181     order.gulimall.com
192.168.188.181     member.gulimall.com
192.168.188.181     seckill.gulimall.com
192.168.188.181     admin.gulimall.com

image-20241007030220167

配置search.gulimall.com路由規則

image-20241007030750088

配置完成所有服務的路由規則

image-20241007030918222

10.7流水線-部署coupon

部署gulimall-coupon

image-20241006064721588

Jenkinsfile釋出版本的時候先推送到阿里雲,然後gitee打標籤時帶上專案名稱

image-20241006064554141

每次推送映象,版本會滾動升級

image-20241006065116481

10.8流水線-部署完成&bug修改

檢查我們部署的服務從31000埠開始(我沒有全部部署,我的電腦已經支不住了)

image-20241006065511311

gulimall-product商品服務和gulimall-seckill秒殺服務之前使用Redisson時地址固定了,這裡需要動態讀取

@Bean(destroyMethod="shutdown")
    public RedissonClient redissonClient(@Value("${spring.redis.host}")String host) throws IOException {
        //1、建立配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://" + host + ":6379");

        //2、根據Config建立出RedissonClient例項
        //Redis url should start with redis:// or rediss://
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

image-20241006070145598

10.9流水線-修改為公有倉庫

image-20241006070415850

10.10最終部署-第一次部署前置nginx

10.10.1建立阿里雲倉庫

建立阿里雲私有倉庫

aliyun-repository

image-20241007005658183

這裡只需要輸入域名即可,後面的命名倉庫和映象名稱不需要

配置完成後,選擇驗證,驗證透過即可

image-20241007011653941

10.10.2建立gulimall-nginx

建立無狀態服務

gulimall-nginx

image-20241007010732084

選擇自己剛建立的阿里雲倉庫地址,然後輸入自己的ngxin版本

pengpeng-namespace/gulimall-nginx:v1.0

image-20241007010953749

配置資源和埠

tcp-443   443   443
tcp-80    80    80

image-20241007011027072

不需要掛載儲存

選擇外網訪問,選擇開啟會話保持

image-20241007011122971

建立完成後,進入檢視gulimall-nginx對映的80埠

然後訪問http://192.168.188.181:31868/,出現ngxin頁面即可

image-20241007011247170

10.11最終部署-建立閘道器與應用路由

10.11.1建立閘道器

進入專案中,選擇高階設定,選擇設定閘道器,選擇LoadBalancer,刪除下面掉2個外掛,然後點選儲存

image-20241007012930648

10.11.2建立路由

選擇應用負載,選擇應用路由,點選建立

image-20241007013147331

基本資訊

gulimall-com

image-20241007013242916

路由規則

選擇指定域名,輸入域名,選擇http協議,選擇gulimall-nginx,選擇80

gulimall.com

image-20241007013345612

選擇下一步,然後建立

image-20241007013504323

10.11.3訪問gulimall-nginx

檢視gulimall-nginx的靜態資源和配置是否修改了

image-20241007023403438

檢視靜態資原始檔

 cd  /usr/share/nginx
 cd html
 ls

image-20241007023254856

配置檔案

cd /etc/nginx
cat nginx.conf

image-20241007023308539

訪問http://192.168.188.181:32419/static/search/img/01.png,靜態資源正常訪問介面

image-20241007023828317

10.13最終部署-部署vue專案

10.13.1打包推送阿里雲

配置static\config\index-prod.js的線上服務地址

image-20241008033436992

前端打包

npm run build

image-20241008003432017

打包完成後上傳到服務進行壓縮

tar -czvf dist.tar.gz -C dist .

image-20241008003544321

以下是Dockerfile內容

FROM nginx
MAINTAINER peng
ADD dist.tar.gz /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

打包映象

docker login --username=使用者名稱 阿里雲地址

docker build -t 阿里雲地址/名稱空間/gulimall-admin-vue-app:v1.0 -f Dockerfile .

docker push 阿里雲地址/名稱空間/gulimall-admin-vue-app:v1.0


docker login --username=pengpengservice crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com

docker build -t crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/gulimall-admin-vue-app:v1.0 -f Dockerfile .

docker push crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com/pengpeng-namespace/gulimall-admin-vue-app:v1.0

image-20241008003813464

檢視阿里雲映象,gulimall-admin-vue-app已推送上去

image-20241008003848052

10.13.2部署gulimall-admin-vue-app

建立無狀態服務

gulimall-admin-vue-app

image-20241008004251367

選擇阿里雲映象地址,輸入映象名稱

名稱空間/gulimall-admin-vue-app:v1.0

image-20241008004242144

配置資源和埠

tcp-80   80   80

image-20241008004418478

不需要掛載儲存

高階設定

選擇外網訪問,選擇NodePort,選擇開啟會話保持

image-20241008004500988

KubeSphere中訪問gulimall-admin-vue-app檢視服務埠,然後訪問http://192.168.188.181:30712/#/login

image-20241008005049640

10.13.3部署renren-fast

本來部署幾個服務即可,我的電腦記憶體實在支不住了,想著還是把這個renren-fast部署了吧

修改renren-fastapplication-prod.yml資料庫配置和新增nacos配置

spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://mysql8.peng-mall:3306/mall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
            username: root
            password: root
    cloud:
        nacos:
            discovery:
                server-addr: nacos.peng-mall:8848
    redis:
        open: false  # 是否開啟redis快取  true開啟   false關閉
        database: 0
        host: redis.peng-mall            

image-20241008025431363

修改redis配置

image-20241008013846636

Jenkinsfile新增renren-fast專案

'renren-fast'

image-20241008014009322

構建映象的時候加上"$PROJECT_NAME" = "renren-fast" 的判斷,我的renren-fastgulimall-gateway在同一個目錄,和其他service不在一起

						sh """
						if [ "$PROJECT_NAME" = "gulimall-gateway" ] || [ "$PROJECT_NAME" = "renren-fast" ]; then
							cd $PROJECT_NAME && docker build -f Dockerfile -t "$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER" .
						else
							cd service/$PROJECT_NAME && docker build -f Dockerfile -t "$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER" .
						fi
						"""	

image-20241008021012329

部署到開發環境的時候也需要修改

script {
					if (PROJECT_NAME == "gulimall-gateway" || PROJECT_NAME == "renren-fast") {
						kubernetesDeploy(configs: "$PROJECT_NAME/deploy/**", enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
					} else {
						kubernetesDeploy(configs: "service/$PROJECT_NAME/deploy/**", enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
					}
				}	

image-20241008021152811

Dockerfile之前也有修改

  • jdk版本
  • 使用RUN命令
  • 執行記憶體大小
FROM openjdk:8-jdk-alpine
EXPOSE 8080

VOLUME /tmp
ADD target/*.jar /app.jar
# RUN bash -c 'touch /app.jar'
# 使用 sh 替代 bash
RUN touch /app.jar
ENTRYPOINT ["java", "-jar", "-Xms128m", "-Xmx300m", "/app.jar", "--spring.profiles.active=prod"]

image-20241008021318735

還有renren-fast-deploy.yaml

  • 專案名稱都改為renren-fast
  • 映象地址image
  • 外界訪問埠nodePort
kind: Deployment
apiVersion: apps/v1
metadata:
  name: renren-fast
  namespace: peng-mall
  labels:
    app: renren-fast
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: renren-fast
      version: v1
  template:
    metadata:
      labels:
        app: renren-fast
        version: v1
    spec:
      containers:
        - name: renren-fast
          image: $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:latest
          ports:
            - containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 1000m
              memory: 500Mi
            requests:
              cpu: 10m
              memory: 10Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

---

kind: Service
apiVersion: v1
metadata:
  name: renren-fast
  namespace: peng-mall
  labels:
    app: renren-fast
    version: v1
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
      nodePort: 31021
  selector:
    app: renren-fast
  type: NodePort
  sessionAffinity: None

以上修改完成後記得提交

執行renren-fast,如果沒有出來renren-fast選項,可以先執行,等一會再停止,然後在執行

image-20241008013526086

執行成功

image-20241008023200073

如果需要重新部署的話

在服務裡選擇renren-fast,然後選擇工作負載下的renren-fast

image-20241008031819809

選擇更多操作,選擇重新部署

image-20241008031833595

10.13.4部署效果

10.13.5問題

10.13.5.1部署的pod一直重啟

我的gulimall-gatewaynacos-v1-0每次啟動的虛擬機器的時候啟動出錯

原因是nacos需要初始化資料,所以沒有找到nacos資料庫,但是我的mysql8是正常的

gulimall-gateway因為沒有找到服務註冊中心nacos,也啟動不起來

 kubectl get pods -n peng-mall

image-20241009221256736

解決:刪掉這倆個pod讓他重新部署(沒有找到根本原因,我的機器實在扛不住了)

先刪nacos,再刪gulimall-gateway,保證nacos正常執行,否則其他服務也找不到註冊中心

kubectl delete pod  nacos-v1-0  -n peng-mall
kubectl delete pod  gulimall-gateway-67cbfd4fdd-lwtc6  -n peng-mall
10.13.5.2本地執行成功,sonarqube一直不透過

首先確保你的程式碼本地執行沒有問題,這個只是臨時方案,不是根本解決,我的電腦不能同時支援我執行idea和`k8s叢集解決問題,所以才暫時這麼做

Jenkinsfile裡跳過sonarqube,不透過也繼續執行

stage('閾值判斷') {
            steps {
                script {
                    timeout(time: 1, unit: "HOURS") {
                        def qualityGate = waitForQualityGate()
                        if (qualityGate.status != 'OK') {
                            // error "SonarQube 檢測不透過: ${qualityGate.status}"
							echo "SonarQube 檢測不透過: ${qualityGate.status}" 
                        }
                    }
                }
            }
        }

image-20241009233433880

10.13.5.3執行版本不能重複

執行版本不能重複

image-20241009234053346

可以去阿里雲映象確認映象版本

image-20241009234118588

10.13.5.4i.r.common.exception.RRExceptionHandler : null

NullPointerExceptionFontConfiguration 相關的錯誤通常與 Java 環境中缺少字型檔案或配置檔案有關。這種情況在使用 Docker 容器時比較常見,因為預設的 Alpine 映象沒有安裝許多字型和圖形環境。

修改Dockerfile

FROM openjdk:8-jdk-alpine

# 安裝 fontconfig 和 DejaVu 字型
RUN apk add --no-cache fontconfig ttf-dejavu

EXPOSE 8080

VOLUME /tmp
ADD target/*.jar /app.jar
RUN touch /app.jar
ENTRYPOINT ["java", "-jar", "-Xms128m", "-Xmx300m", "/app.jar", "--spring.profiles.active=prod"]

image-20241010202556026

安裝 fontconfigttf-dejavu

驗證

apk add --no-cache fontconfig ttf-dejavu
fc-list

image-20241010215109530

10.13.5.5SonaqubeHttpUtils不透過

SonaqubeHttpUtils不透過

private static void sslClient(HttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");

            // 獲取系統預設的 TrustManager
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            // 初始化 SSLContext,使用預設的 TrustManager
            ctx.init(null, trustManagers, new SecureRandom());

            // 使用嚴格的主機名驗證
            SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);

            // 配置到 HttpClient
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException ex) {
            throw new RuntimeException(ex);
        }
    }

image-20241010223113131

10.14最終部署-測試滾動更新部署admin-vue-app

在服務裡選擇gulimall-admin-vue-app,然後選擇工作負載下的gulimall-admin-vue-app-v1

image-20241008034029172

選擇更多操作,選擇編輯配置模版,選擇容器組模版,選擇編輯

image-20241008034232185

選擇容器組模版,修改你需要的映象版本,點選確認即可

image-20241008034500732

後臺管理平臺

image-20241010235212379

前臺介面

image-20241010235347774

我就部署了這麼多服務,保證基本功能正常就可以了,因為我的電腦記憶體馬上又要滿了

image-20241010235249699

10.15線上預警與監控

admin登入,選擇平臺管理,選擇平臺設定,每個版本可能不一樣,我的KubeSphere的版本v3.1.1

image-20241008034903746

10.15.1配置qq郵箱

登入qq郵箱,選擇設定,選擇賬號,讓後向qq郵箱傳送一個簡訊即可

image-20241008040457622

配置郵箱

smtp.qq.com   465

image-20241008043700576

開啟服務成功後

image-20241008043241923

我的KubeSphere的版本v3.1.1只需要設定完郵箱地址,新增告警策略會自動傳送郵件

官方文件地址:https://v3-1.docs.kubesphere.io/zh/docs/cluster-administration/platform-settings/notification-management/configure-email/

image-20241008043517162

10.15.2新增告警策略

基本資訊

gulimall-gateway-memory

image-20241008044000799

gulimall-gateway執行記憶體肯定大於100Mi了,我們測試一下就行

image-20241008044019759

新增標題和資訊,點選建立

image-20241008044108006

觸發中

image-20241011002455461

創作不易,感謝支援。

wxzf

相關文章