04-k8s项目部署

前言

且停且忘且随风,且行且看且从容

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
posted @ 2024-10-14 01:00  peng_boke  阅读(26)  评论(0编辑  收藏  举报