推送到 Nexus 仓库->部署为 k8s 服务实践">构建 dotnet&vue 应用镜像->推送到 Nexus 仓库->部署为 k8s 服务实践
前言
前面分享了 k8s 的部署安裝,本篇來點實操,將會把一個 .net core + vue 的項目(zhontai),打包構建成 docker 鏡像,推送到 nexus 鏡像倉庫,并部署到 k8s 中
準備
要實現項目的部署,除了準備要部署的環境(k8s),還需要準備項目所用到的各中間件,本文旨在分享部署的一個整體流程,對項目中所使用到的各中間件(mysql,redis 等)的安裝使用可自行在本 DevOps 系列文章中找到
-
一個 .net core+vue 的項目
- 使用 zhontai 項目,之前也有做分享,文章介紹
- 后端 Admin.Core v3.7.1
- 前端 admin.ui.plus v2.2.0
-
Nexus 的安裝部署,文章介紹
- 做為鏡像倉庫使用,將項目打包鏡像及項目鏡像推送到倉庫,k8s 也從此倉庫拉取鏡像
- 版本為 v3.61 ,安裝地址為 192.168.0.214:8081,并使用局域網域名解析,
- 在目標機器先登錄能夠拉取推送鏡像,參考
- 拉取鏡像地址:https://nexus.devops.test.com
- 推送鏡像地址:https://push.nexus.devops.test.com
-
Docker 的安裝部署,文章介紹
- 使用 doker 拉取 sdk、nodejs 鏡像進行打包,構建 k8s 所需要的項目鏡像
- 版本:v24.0.6
-
K8S 的安裝與部署,文章介紹
- 部署項目服務
- 使用 ingress 解析域名到服務
-
部署前后端項目到 K8S,本文介紹
使用 Docker 打包應用鏡像
不管什么語言,基本都可以使用這個打包流程,將官方鏡像打包推送到私有鏡像倉庫個人認為是必要的,不然如果一旦遠端的鏡像失效,又需要重新拉取鏡像時就會很尬尷。
-
準備打包所需鏡像
- 獲取基礎打包鏡像(dotnet 獲取 sdk 鏡像,vue 獲取 node 鏡像)
- 基于基礎鏡像,安裝所需軟件,設置默認配置,復制默認文件,封裝項目的打包鏡像
- 掛載項目到 sdk 鏡像進行打包,打包后獲取構建完成的產物
-
準備運行所需的基礎鏡像
- 獲取運行時鏡像(.net core 獲取 runtime 鏡像,vue 獲取 nginx 鏡像)
- 基于運行時鏡像,將打包構建完從的產物添加到鏡像,構建項目鏡像
- 推送項目鏡像到倉庫
.Net Core 7.0 項目鏡像
構建所需一個 sdk 鏡像用于打包編譯項目,一個 runtime 鏡像運行 .net core 項目,版本選擇對應的 7.0 即可
- dotnet sdk 鏡像地址:https://hub.docker.com/_/microsoft-dotnet-sdk/
- dotnet runtime 鏡像地址: https://hub.docker.com/_/microsoft-dotnet-runtime/
構建 dotnet sdk 7.0 打包鏡像
-
拉取 dotnet sdk 鏡像:
docker pull mcr.microsoft.com/dotnet/sdk:7.0- 目前可以直接拉取,若無法拉取則配置國內鏡像源
- 臨時運行容器進行測試:
docker run -it --rm mcr.microsoft.com/dotnet/sdk:7.0,可以將需要的東西進行安裝測試再編寫 dockerfile
-
使用 Dockerfile 構建打包鏡像 dotnet-sdk-7.0
- 為了便于后期維護,使用 Dockerfile 來構建
- 目錄文件:dotnet-sdk-7.0/Dockerfile
- 基于 sdk 安裝 dotnet-monitor v7.3.2, 文檔 這里只做演示,暫時沒用上,后續使用多階段構建的時候可以將其復制到運行時鏡像中
-
# 基礎sdk鏡像 v7.0 FROM mcr.microsoft.com/dotnet/sdk:7.0 # 將tools目錄加入環境變量 ENV PATH="$PATH:/root/.dotnet/tools" # 安裝 dotnet-monitor RUN dotnet tool install -g dotnet-monitor --version 7.3.2 - 執行構建:
docker build -t dotnet-sdk-7.0 -f ./Dockerfile .
-
推送鏡像到 Nexus 倉庫
- 鏡像登錄認證:
docker login push.nexus.devops.test.com -u pusher -p devops666 - 打標簽:
docker tag dotnet-sdk-7.0 push.nexus.devops.test.com/projectbuild/dotnet-sdk-7.0 - 推送鏡像:
docker push push.nexus.devops.test.com/projectbuild/dotnet-sdk-7.0 - 記得清理本地緩存鏡像:
docker rmi dotnet-sdk-7.0 && docker rmi push.nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
- 鏡像登錄認證:
-
使用鏡像
- 后續使用 dotnet sdk 7.0 就可以直接使用
nexus.devops.test.com/projectbuild/dotnet-sdk-7.0即可 - 直接拉?。?code> docker pull nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
- 后續使用 dotnet sdk 7.0 就可以直接使用
構建 dotnet runtime 7.0 運行時鏡像
-
拉取 dotnet runtime 鏡像:
docker pull mcr.microsoft.com/dotnet/runtime:7.0- 臨時運行容器進行測試:
docker run -it --rm mcr.microsoft.com/dotnet/runtime:7.0
- 臨時運行容器進行測試:
-
使用 Dockerfile 構建運行時鏡像
- 為了便于后期維護,使用 Dockerfile 來構建
- 目錄文件:dotnet-runtime-7.0/Dockerfile
- 若非需要,可以不安裝軟件,安裝軟件后鏡像會多個 100M
-
# 基礎runtime鏡像 v7.0 FROM mcr.microsoft.com/dotnet/aspnet:7.0 # 寫入阿里云鏡像源 RUN echo " \ deb http://mirrors.aliyun.com/debian/ bullseye main contrib non-free\n \ deb-src http://mirrors.aliyun.com/debian/ bullseye main contrib non-free\n \ \n \ deb http://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free\n \ deb-src http://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free\n \ \n \ deb http://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free\n \ deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free\n \ \n \ deb http://mirrors.aliyun.com/debian/ bullseye-backports main contrib non-free\n \ deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main contrib non-free\n \ " | tee /etc/apt/sources.list # 安裝 curl&&vim RUN apt-get update -y && apt-get install -y curl && apt-get install -y vim - 執行構建:
docker build -t dotnet-runtime-7.0 -f ./Dockerfile .
-
推送鏡像到 Nexus 倉庫
- 鏡像登錄認證:
docker login push.nexus.devops.test.com -u pusher -p devops666 - 打標簽:
docker tag dotnet-runtime -7.0 push.nexus.devops.test.com/projectbuild/dotnet-runtime-7.0 - 推送鏡像:
docker push push.nexus.devops.test.com/projectbuild/dotnet-runtime-7.0 - 記得清理本地緩存鏡像:
docker rmi dotnet-runtime-7.0 && docker rmi push.nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
- 鏡像登錄認證:
-
使用鏡像
- 后續使用 dotnet runtime 7.0 就可以直接使用
nexus.devops.test.com/projectbuild/dotnet-runtime-7.0即可 - 直接拉?。?code> docker pull nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
- 后續使用 dotnet runtime 7.0 就可以直接使用
構建 zhontai 后端項目的應用鏡像
制作完鏡像,下面將使用 sdk 鏡像打包項目生成部署文件,再使用 runtime 鏡像部署運行。
-
下載/克隆項目 admin.core 到服務器,進入項目目錄開始執行
-
# 克隆項目 git clone https://github.com/zhontai/Admin.Core.git -b v3.7.0 # 進入項目 cd Admin.Core cd Admin.Core - src 為.net core 項目代碼
-
-
使用 sdk 鏡像進行打包,生成部署文件到 publish_output
-
docker run -i --rm創建一個臨時容器,容器退出后自動刪除容器 -
-v ./build:/build掛載 MSBuild 屬性文件目錄(./src/Directory.Build.props 中使用) -
-v ./src:/src掛載源碼到容器中 -
-v ./publish_output:/publish_output掛載構建物輸出目錄 -
--name build_zhontai_api指定運行的容器名稱 -
nexus.devops.test.com/projectbuild/dotnet-sdk-7.0sdk 鏡像 -
/bin/bash -c "xxx"以交互模式運行容器,運行時執行命令 - 若有自定義 nuget 倉庫的包還需掛載
/root/.nuget目錄,或直接制作在鏡像中 - 記得掛載 build 目錄,否則會提示:Invalid framework identifier
-
docker run -i --rm \ -v ./build:/build \ -v ./src:/src \ -v ./publish_output:/publish_output \ --name build_zhontai_api \ nexus.devops.test.com/projectbuild/dotnet-sdk-7.0 \ /bin/bash -c 'dotnet publish /src/hosts/ZhonTai.Host -c Release -o /publish_output --runtime linux-x64 --framework net7.0' - 執行成功后程序包就生成到 publish_output 中了
-
-
使用 runtime 鏡像制作應用鏡像
- 將上一步的構建物 Admin.Core/publish_output 添加到運行時鏡像中
- 使用 echo 創建一個 Dockerfile
-
#創建Dockerfile echo 'FROM nexus.devops.test.com/projectbuild/dotnet-runtime-7.0 AS runtime WORKDIR /app COPY ./publish_output /app ENV ASPNETCORE_URLS=http://+:8000 ENTRYPOINT ["dotnet", "ZhonTai.Host.dll"]' > Dockerfile - 執行構建:
docker build -t zhontai_api . - 運行測試,成功
-
推送鏡像到倉庫
-
#打標簽 docker tag zhontai_api push.nexus.devops.test.com/projectapp/zhontai_api #推送 docker push push.nexus.devops.test.com/projectapp/zhontai_api - 推送成功,這里手動只構建的 latest 版本,若使用自動化構建,還需構建對應版本的鏡像,以支持快速回滾
-
Vue 3 項目打包
構建所需一個 node 鏡像用于 vue 項目打包,nginx 用于部署前臺項目
- node 鏡像地址:https://hub.docker.com/r/library/node ,選擇版本:node:18.17.1
- nginx 鏡像地址:https://hub.docker.com/_/nginx ,選擇版本:nginx:1.24.0
構建 nodejs 18.17.1 打包鏡像
-
拉取 nodejs 鏡像:
docker pull node:18.17.1 -
將 node 鏡像 vue-node-18 打上標簽推送到倉庫
-
#拉取倉庫 docker pull node:18.17.1 # 打標簽 docker tag node:18.17.1 push.nexus.devops.test.com/projectbuild/vue-node-18.17 #推送 docker push push.nexus.devops.test.com/projectbuild/vue-node-18.17 - 測試使用:
docker run -it --rm nexus.devops.test.com/projectbuild/vue-node-18.17 /bin/bash -c "node -v"
-
構建 nginx 1.24 運行時鏡像
-
拉取 nginx 鏡像:
docker pull nginx:1.24 -
將 nginx 鏡像 vue-nginx-1.24 打上標簽推送到倉庫
-
#拉取倉庫 docker pull nginx:1.24 # 打標簽 docker tag nginx:1.24 push.nexus.devops.test.com/projectbuild/vue-nginx-1.24 #推送 docker push push.nexus.devops.test.com/projectbuild/vue-nginx-1.24 - 測試使用:
docker run -it --rm nexus.devops.test.com/projectbuild/vue-nginx-1.24 /bin/bash進入容器后啟用 nginx,并使用 curl http://localhost 測試 nginx 可用
-
構建 zhontai 前端項目的應用鏡像
-
下載/克隆項目 admin.ui.plus 到文件夾
-
# 克隆項目 git clone https://github.com/zhontai/admin.ui.plus.git -b v2.2.0 # 進入項目cd admin.ui.plus cd admin.ui.plus # 修改接口地址 # 編輯.env.production 中的 VITE_API_URL 配置為接口地址
-
-
使用 node 鏡像進行打包,生成文件到 dist
-
docker run -i --rm \ -v ./:/app \ --name build_zhontai_webui \ nexus.devops.test.com/projectbuild/vue-node-18.17 \ /bin/bash -c 'cd /app npm config set registry https://registry.npmmirror.com npm install npm run build' - 執行成功,構建輸出到 dist 中
-
-
使用 nginx 鏡像制作應用鏡像
-
# 創建nginx.conf echo ' server { listen 80; server_name localhost; charset utf-8; location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; index index.html index.htm; } #error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } '> vue-nginx.conf #創建Dockerfile echo ' FROM nexus.devops.test.com/projectbuild/vue-nginx-1.24 EXPOSE 80 COPY ./dist /usr/share/nginx/html COPY ./vue-nginx.conf /etc/nginx/conf.d/default.conf' > Dockerfile - 執行構建:
docker build -t zhontai_webui . - 測試訪問成功
-
-
推送鏡像到倉庫
#打標簽
docker tag zhontai_webui push.nexus.devops.test.com/projectapp/zhontai_webui
#推送
docker push push.nexus.devops.test.com/projectapp/zhontai_webui
將 Docker 應用鏡像部署到 K8S
應用鏡像打包成功,現在需要將兩個應用精選鏡像部署到 k8s 中
應用鏡像的拉取憑證設置
因為 nexus 部署在局域網,并且配置的域名是局域網域名,所以面臨著如何在 k8s 中訪問 https://nexus.devops.test.com 獲取鏡像的問題,目前我的解決方法時每個節點機器都配置好對應 dns
要想訪問到 nexus 倉庫,需要滿足兩個條件,一個是訪問到倉庫,一個是倉庫的認證
-
給 k8s 所有節點添加 dns 設置
nameserver 192.168.123.214- 使用
docker login nexus.devops.test.com -u puller -p devops666在宿主機中登錄倉庫確保可以在節點拉取鏡像
- 使用
-
創建 nexus 登錄憑證
-
kubectl create secret \ docker-registry \ nexus-login-registry \ --docker-server=nexus.devops.test.com \ --docker-username=puller \ --docker-password=devops666 \ -n default
-
使用 Deployment 部署應用
配置僅供參考,關于數據庫,配置文件,日志,上傳文件等未處理
-
創建后端部署配置:zhontai_api.yaml
-
--- ## 配置服務 kind: Service apiVersion: v1 metadata: name: app-zhontai-api namespace: default labels: app: app-zhontai-api spec: selector: app: app-zhontai-api type: ClusterIP ports: - name: p80 port: 80 targetPort: 8000 --- kind: Deployment # 指定創建資源的角色/類型 apiVersion: apps/v1 # 指定api版本,此值必須在kubectl api-versions中 metadata: # 資源的元數據/屬性 name: app-zhontai-api # 資源的名字,在同一個namespace中必須唯一 namespace: default # 部署在哪個namespace中 labels: # 設定資源的標簽 app: app-zhontai-api spec: # 資源規范字段 selector: matchLabels: app: app-zhontai-api replicas: 2 # 聲明副本數目 revisionHistoryLimit: 2 # 保留歷史版本 strategy: # 策略 rollingUpdate: # 滾動更新 maxSurge: 1 # 最大額外可以存在的副本數,可以為百分比,也可以為整數 maxUnavailable: 1 # 示在更新過程中能夠進入不可用狀態的 Pod 的最大值,可以為百分比,也可以為整數 type: RollingUpdate # 滾動更新策略 template: # 模版 metadata: # 資源的元數據/屬性 labels: # 設定資源的標簽 app: app-zhontai-api spec: # 資源規范字段 containers: - image: nexus.devops.test.com/projectapp/zhontai_api:latest # 容器使用的鏡像地址 name: app-zhontai-api # 容器的名字 # 每次Pod啟動拉取鏡像策略,三個選擇 Always、Never、IfNotPresent # Always,每次都檢查;Never,每次都不檢查(不管本地是否有);IfNotPresent,如果本地有就不檢查,如果沒有就拉取 imagePullPolicy: Always resources: # 資源管理 # limits: # 最大使用 # cpu: 300m # CPU,1核心 = 1000m # memory: 500Mi # 內存,1G = 1024Mi # requests: # 容器運行時,最低資源需求,也就是說最少需要多少資源容器才能正常運行 # cpu: 100m # memory: 100Mi livenessProbe: # pod 內部健康檢查的設置 httpGet: # 通過httpget檢查健康,返回200-399之間,則認為容器正常 path: /admin/health # URI地址 port: 8000 # 端口 scheme: HTTP # 協議 initialDelaySeconds: 10 # 表明第一次檢測在容器啟動后多長時間后開始 timeoutSeconds: 5 # 檢測的超時時間 periodSeconds: 30 # 檢查間隔時間 successThreshold: 1 # 成功門檻 failureThreshold: 5 # 失敗門檻,連接失敗5次,pod殺掉,重啟一個新的pod ports: - name: http # 名稱 containerPort: 80 # 容器開發對外的端口 protocol: TCP # 協議 env: # 時區 - name: TZ value: Asia/Shanghai # app name - name: APP_NAME value: app.zhontai.api # 掛載 volumeMounts: - name: app-logs mountPath: /logs #容器中的路徑 # 卷軸 volumes: - name: app-logs hostPath: path: /app/logs #將日志存放在宿主機的路徑,需要在宿主機創建目錄 type: Directory #重啟策略 restartPolicy: Always imagePullSecrets: # 鏡像倉庫拉取密鑰 - name: nexus-login-registry
-
-
執行部署:
kubectl apply -f zhontai_api.yaml -
創建前端部署配置:zhontai_webui.yaml
-
--- ## 配置服務 kind: Service apiVersion: v1 metadata: name: app-zhontai-webui namespace: default labels: app: app-zhontai-webui spec: selector: app: app-zhontai-webui type: ClusterIP ports: - name: p80 port: 80 targetPort: 80 --- kind: Deployment # 指定創建資源的角色/類型 apiVersion: apps/v1 # 指定api版本,此值必須在kubectl api-versions中 metadata: # 資源的元數據/屬性 name: app-zhontai-webui # 資源的名字,在同一個namespace中必須唯一 namespace: default # 部署在哪個namespace中 labels: # 設定資源的標簽 app: app-zhontai-webui spec: # 資源規范字段 selector: matchLabels: app: app-zhontai-webui replicas: 2 # 聲明副本數目 revisionHistoryLimit: 2 # 保留歷史版本 strategy: # 策略 rollingUpdate: # 滾動更新 maxSurge: 1 # 最大額外可以存在的副本數,可以為百分比,也可以為整數 maxUnavailable: 1 # 示在更新過程中能夠進入不可用狀態的 Pod 的最大值,可以為百分比,也可以為整數 type: RollingUpdate # 滾動更新策略 template: # 模版 metadata: # 資源的元數據/屬性 labels: # 設定資源的標簽 app: app-zhontai-webui spec: # 資源規范字段 containers: - image: nexus.devops.test.com/projectapp/zhontai_webui:latest # 容器使用的鏡像地址 name: app-zhontai-webui # 容器的名字 # 每次Pod啟動拉取鏡像策略,三個選擇 Always、Never、IfNotPresent # Always,每次都檢查;Never,每次都不檢查(不管本地是否有);IfNotPresent,如果本地有就不檢查,如果沒有就拉取 imagePullPolicy: Always resources: # 資源管理 # limits: # 最大使用 # cpu: 300m # CPU,1核心 = 1000m # memory: 500Mi # 內存,1G = 1024Mi # requests: # 容器運行時,最低資源需求,也就是說最少需要多少資源容器才能正常運行 # cpu: 100m # memory: 100Mi livenessProbe: # pod 內部健康檢查的設置 httpGet: # 通過httpget檢查健康,返回200-399之間,則認為容器正常 path: / # URI地址 port: 80 # 端口 scheme: HTTP # 協議 initialDelaySeconds: 10 # 表明第一次檢測在容器啟動后多長時間后開始 timeoutSeconds: 5 # 檢測的超時時間 periodSeconds: 30 # 檢查間隔時間 successThreshold: 1 # 成功門檻 failureThreshold: 5 # 失敗門檻,連接失敗5次,pod殺掉,重啟一個新的pod ports: - name: http # 名稱 containerPort: 80 # 容器開發對外的端口 protocol: TCP # 協議 env: # 時區 - name: TZ value: Asia/Shanghai # app name - name: APP_NAME value: app.zhontai.webui #重啟策略 restartPolicy: Always imagePullSecrets: # 鏡像倉庫拉取密鑰 - name: nexus-login-registry
-
-
執行部署:
kubectl apply -f zhontai_webui.yaml
配置 Ingress 使用域名訪問
- 部署成功后添加對應 ingress 配置,即可使用域名訪問
前端項目需要修改為對應的接口地址
確保綁定的域名正常解析到 k8s 節點,即可使用域名訪問了,我這里使用的 DnsServer 泛解析,故可以直接訪問,
至此,一步步將一個單體項目部署到了 k8s 中,僅供參考,實際如果時微服務,還設計到一些通用和環境的配置,后面再慢慢分享。
根據上面的步驟,后面分享將其整理成腳本,以便后續可以直接使用。
相關文檔
-
相關文章
- 一篇適合躺收藏夾的 Nexus3 搭建 NuGet&Docker 私有庫的安裝使用總結
- 一篇可供參考的 K8S 落地實踐經驗
- 前后端都用得上的 Nginx 日常使用經驗
-
參考文章
- 如何創建一個帶診斷工具的.net 鏡像
后語
本文始于2023末,結束于2024始。
2023的最后兩個月,是這幾年以來,學習,產出最高的的兩個月。
始于國慶,不止步于元旦。
新年快樂!
總結
以上是生活随笔為你收集整理的推送到 Nexus 仓库->部署为 k8s 服务实践">构建 dotnet&vue 应用镜像->推送到 Nexus 仓库->部署为 k8s 服务实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2023年总结
- 下一篇: 5 款开源热搜项目「GitHub 热点速