前言
且停且忘且隨風,且行且看且從容
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
只需要設定完郵箱地址,新增告警策略會自動傳送郵件
官方文件地址:https://v3-1.docs.kubesphere.io/zh/docs/cluster-administration/platform-settings/notification-management/configure-email/
10.15.2新增告警策略
基本資訊
gulimall-gateway-memory
gulimall-gateway
執行記憶體肯定大於100Mi
了,我們測試一下就行
新增標題和資訊,點選建立
觸發中
創作不易,感謝支援。