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
修改配置

10.2部署-整合阿里云镜像仓库
参考:https://www.cnblogs.com/makalochen/p/14240796.html

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

创建本地仓库

本地仓库创建完成

我们需要留意docker login 、docker pull、docker push 三条命令
需要留意自己的请求地址、命名空间、仓库名称、账号名称
10.3Jenkins修改阿里云镜像仓库
创建阿里云账号凭证,需要输入自己阿里云的账号密码

在环境变量添加自己阿里云的相关参数,分别是凭证(配置阿里云的账号密码)、请求地址、命名空间、仓库名称、账号名称
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'
}

创建阿里云的步骤,login和push地址拼对即可,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'
}
}
}
}
}

步骤都是成功状态

push完成

10.4流水线-部署gateway
创建流水线
peng-mall-jenkins-aliyun-cicd

选择git,输入项目gitee地址,选择gitee-id凭证(就是配置的gitee账号)

我的Jenkinsfile不在根目录,我这边指定了Jenkinsfile地址
选择是否开启浅克隆

选择运行,如果首次点击运行没有出现配置的项目参数(分支、PROJECT_VERSION、PROJECT_NAME),直接停止,获取不到参数流水线也会失败,运行停止1-2次参数的界面就应该就出来了,然后选择参数再运行

记得在这里删除运行失败的gulimall-gateway

服务部署成功

访问gulimall-gateway,出现SpringBoot的404代表部署成功

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

记得改一下版本就行了

10.5流水线-部署auth-server
部署gulimall-auth-service

成功后,我们去看pod

访问gulimall-auth-service,出现SpringBoot的404代表部署成功

10.6流水线-部署cart
部署gulimall-cart

部署成功后查看pod

访问gulimall-cart,出现SpringBoot的404代表部署成功

查看阿里云镜像

查看gulimall-cart的镜像

10.12最终部署-商城系统上线
10.12.1推送gulimall-nginx
把自己之前部署nginx挂载目录下的conf和html下载下来

查看gulimall-gateway网关地址

修改nginx的网关地址
gulimall-gateway-deploy.yaml配置的网关暴露接口为31000,所以nginx配置的上游地址是k8s节点ip:31000

以下是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;"]
把html、conf上传到k8s服务器
打包html目录,只用打包html下的所有文件,不需要html目录
tar -czvf html.tar.gz -C html .

打包conf目录,只用打包conf下的所有文件,不需要conf目录
tar -czvf conf.tar.gz -C conf .

然后可以删掉html、conf

在gulimall-nginx下进行打包
docker build -t gulimall-nginx:v1.0 -f Dockerfile .

登录阿里云,然后打上标签准备推送
# 登录
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

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

阿里云上传成功

10.12.2访问gulimall-nginx
创建gulimall-nginx见10.10.2
查看gulimall-nginx的静态资源和配置是否修改了

查看静态资源文件
cd /usr/share/nginx
cd html
ls

配置文件
cd /etc/nginx
cat nginx.conf

访问http://192.168.188.181:32419/static/search/img/01.png,静态资源正常访问接口

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

配置search.gulimall.com路由规则

配置完成所有服务的路由规则

10.7流水线-部署coupon
部署gulimall-coupon

Jenkinsfile发布版本的时候先推送到阿里云,然后gitee打标签时带上项目名称

每次推送镜像,版本会滚动升级

10.8流水线-部署完成&bug修改
检查我们部署的服务从31000端口开始(我没有全部部署,我的电脑已经支不住了)

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;
}

10.9流水线-修改为公有仓库

10.10最终部署-第一次部署前置nginx
10.10.1创建阿里云仓库
创建阿里云私有仓库
aliyun-repository

这里只需要输入域名即可,后面的命名仓库和镜像名称不需要
配置完成后,选择验证,验证通过即可

10.10.2创建gulimall-nginx
创建无状态服务
gulimall-nginx

选择自己刚创建的阿里云仓库地址,然后输入自己的ngxin版本
pengpeng-namespace/gulimall-nginx:v1.0

配置资源和端口
tcp-443 443 443
tcp-80 80 80

不需要挂载存储
选择外网访问,选择开启会话保持

创建完成后,进入查看gulimall-nginx映射的80端口
然后访问http://192.168.188.181:31868/,出现ngxin页面即可

10.11最终部署-创建网关与应用路由
10.11.1创建网关
进入项目中,选择高级设置,选择设置网关,选择LoadBalancer,删除下面掉2个插件,然后点击保存

10.11.2创建路由
选择应用负载,选择应用路由,点击创建

基本信息
gulimall-com

路由规则
选择指定域名,输入域名,选择http协议,选择gulimall-nginx,选择80
gulimall.com

选择下一步,然后创建

10.11.3访问gulimall-nginx
查看gulimall-nginx的静态资源和配置是否修改了

查看静态资源文件
cd /usr/share/nginx
cd html
ls

配置文件
cd /etc/nginx
cat nginx.conf

访问http://192.168.188.181:32419/static/search/img/01.png,静态资源正常访问接口

10.13最终部署-部署vue项目
10.13.1打包推送阿里云
配置static\config\index-prod.js的线上服务地址

前端打包
npm run build

打包完成后上传到服务进行压缩
tar -czvf dist.tar.gz -C dist .

以下是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

查看阿里云镜像,gulimall-admin-vue-app已推送上去

10.13.2部署gulimall-admin-vue-app
创建无状态服务
gulimall-admin-vue-app

选择阿里云镜像地址,输入镜像名称
命名空间/gulimall-admin-vue-app:v1.0

配置资源和端口
tcp-80 80 80

不需要挂载存储
高级设置
选择外网访问,选择NodePort,选择开启会话保持

在KubeSphere中访问gulimall-admin-vue-app查看服务端口,然后访问http://192.168.188.181:30712/#/login

10.13.3部署renren-fast
本来部署几个服务即可,我的电脑内存实在支不住了,想着还是把这个renren-fast部署了吧
修改renren-fast的application-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

修改redis配置

Jenkinsfile添加renren-fast项目
'renren-fast'

构建镜像的时候加上"$PROJECT_NAME" = "renren-fast" 的判断,我的renren-fast和gulimall-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
"""

部署到开发环境的时候也需要修改
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")
}
}

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"]

还有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选项,可以先运行,等一会再停止,然后在运行

运行成功

如果需要重新部署的话
在服务里选择renren-fast,然后选择工作负载下的renren-fast

选择更多操作,选择重新部署

10.13.4部署效果
10.13.5问题
10.13.5.1部署的pod一直重启
我的gulimall-gateway和nacos-v1-0每次启动的虚拟机的时候启动出错
原因是nacos需要初始化数据,所以没有找到nacos数据库,但是我的mysql8是正常的
gulimall-gateway因为没有找到服务注册中心nacos,也启动不起来
kubectl get pods -n peng-mall

解决:删掉这俩个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}"
}
}
}
}
}

10.13.5.3运行版本不能重复
运行版本不能重复

可以去阿里云镜像确认镜像版本

10.13.5.4i.r.common.exception.RRExceptionHandler : null
NullPointerException 和 FontConfiguration 相关的错误通常与 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"]

安装 fontconfig 和 ttf-dejavu
验证
apk add --no-cache fontconfig ttf-dejavu
fc-list

10.13.5.5Sonaqube中HttpUtils不通过
Sonaqube中HttpUtils不通过
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);
}
}

10.14最终部署-测试滚动更新部署admin-vue-app
在服务里选择gulimall-admin-vue-app,然后选择工作负载下的gulimall-admin-vue-app-v1

选择更多操作,选择编辑配置模版,选择容器组模版,选择编辑

选择容器组模版,修改你需要的镜像版本,点击确认即可

后台管理平台

前台界面

我就部署了这么多服务,保证基本功能正常就可以了,因为我的电脑内存马上又要满了

10.15线上预警与监控
admin登录,选择平台管理,选择平台设置,每个版本可能不一样,我的KubeSphere的版本v3.1.1

10.15.1配置qq邮箱
登录qq邮箱,选择设置,选择账号,让后向qq邮箱发送一个短信即可

配置邮箱
smtp.qq.com 465

开启服务成功后

我的KubeSphere的版本v3.1.1只需要设置完邮箱地址,添加告警策略会自动发送邮件

10.15.2添加告警策略
基本信息
gulimall-gateway-memory

gulimall-gateway运行内存肯定大于100Mi了,我们测试一下就行

添加标题和信息,点击创建

触发中

创作不易,感谢支持。

浙公网安备 33010602011771号