Kubernetes集群部署Springcloud微服務商務系統
文章目錄
- Kubernetes集群部署Springcloud微服務商務系統
- 1.微服務架構及理論概述
- 1.1.單體架構與微服務架構的區別
- 1.2.微服務組件架構圖
- 1.3.微服務注冊中心
- 1.4.不同的部署環境對于程式組態檔如何管理
- 2.微服務遷移至kubernetes平臺流程
- 2.1.專案遷移到K8S平臺流程
- 2.2.傳統部署與K8S部署的區別
- 3.微服務程式前期環境準備(配置、編譯、制作鏡像)
- 3.1.simple-microservice微服務專案介紹
- 3.2.simple微服務部署到K8S邏輯架構
- 3.3.準備微服務各程式的組態檔
- 3.3.1.創建微服務各個程式的prod組態檔
- 3.3.2.調整每個微服務的pom檔案增加prod環境
- 3.4.制作微服務程式所使用的的底層系統鏡像
- 3.4.1.為程式環境構建底層系統鏡像
- 3.4.2.為每個微服務程式撰寫Dockerfile
- 3.5.調整Protal微服務中連接Gateway網關的地址
- 3.6.部署Ingress用于將微服務程式發布到互聯網
- 4.在kubernetes集群部署simple微服務專案
- 4.1.部署simple微服務程式的mysql資料庫環境
- 4.2.部署eureka微服務注冊中心
- 4.2.1.修改Eureka組態檔增加各節點地址
- 4.2.2.調整Eureka的Dockerfile
- 4.2.3.構建Eureka服務的Docker鏡像
- 4.2.4.撰寫Eureka部署YAML資源檔案
- 4.2.5.在K8S集群中部署Eureka注冊中心
- 4.3.配置各個微服務程式連接Eureka集群的地址
- 4.4.將各個程式代碼編譯成可部署的程式
- 4.3.中部署Gateway網關服務
- 4.3.1.將Gateway程式打包成docker鏡像
- 4.3.2.在K8S集群中部署Gateway網關服務
- 4.3.3.在K8S集群中部署Gateway網關服務
- 4.4.撰寫快速部署微服務到K8S集群的腳本
- 4.5.使用腳本部署Order訂單服務
- 4.5.1.撰寫資源部署YAML檔案
- 4.5.2在K8S集群中部署Order訂單服務
- 4.6.使用腳本部署Product商品服務
- 4.6.1.撰寫資源部署YAML檔案
- 4.6.2.在K8S集群中熟不熟Product商品服務
- 4.7.使用腳本部署Stock庫存服務
- 4.7.1.撰寫資源部署YAML檔案
- 4.7.2.在K8S集群中部署Stock庫存服務
- 4.8.使用腳本部署Portal前端首頁
- 4.8.1.撰寫資源部署YAML檔案
- 4.8.2.在K8S集群中熟不熟Portal存服務
- 4.9.查看Eureka注冊中心中各個微服務的資訊
- 4.10.使用simple微服務電商平臺
- 5.基于K8S集群的微服務的擴容與升級
- 5.1.微服務的擴容
- 5.2.微服務的升級
- 5.2.1.微調Portal前端首頁的代碼
- 5.2.2.編譯最新代碼
- 5.2.3.通過腳本將Protal最新代碼打包成鏡像
- 5.2.4.升級K8S集群中的Protal微服務
1.微服務架構及理論概述
? 程式架構一共經歷了3個階段:單體架構、SOA架構、微服務架構,
? 微服務系統應用由原來的單體變成幾十到幾百個不同的工程,會產生例如包括服務間的依賴,服務如何拆封,內部介面規范,資料傳遞等等問題,尤其是服務拆分,需要團隊熟悉業務流程,懂得取舍,要保證拆分的粒度服務既符合“高內聚,低耦合”的基本原則,還要兼顧業務的發展以及公司的愿景,要還要說服團隊成員為之努力,并且積極投入,在多方中間取得平衡,
? 微服務從概念上講就是將一個大的平臺拆分成幾個獨立的小模塊,這些模塊有自己專門的資料庫服務,即使這個單獨模塊出現了故障,也不會影響整個平臺的使用,例如一個平臺中有訂單模塊、新聞模塊、咨詢模塊,即使新聞模塊宕機了,訂單模塊、新聞模塊依然作業正常,也不會造成整個網站的癱瘓,
? 對于微服務版本迭代而言,只需要針對特定功能所在的子專案上線即可,版本迭代更加靈活,而單體程式版本迭代,哪怕只是一個小小的功能也需要對整個系統進行更新,
? 目前主流的程式架構就是微服務系統,運用的技術堆疊更加豐富,例如kubernetes、CI/CD、Devops等等,
? 微服務專案在kubernetes環境部署主要有兩種實作方式:無狀態的部署、istio微服務網格部署,
? 可以把微服務理解為是一個大的框架,在這個框架里面內嵌各個子系統,
1.1.單體架構與微服務架構的區別
微服務的特點:
- 系統服務獨立化
- 每個子專案系統都會獨立開發、部署,有效的避免一個服務的bug影響整個系統的使用
- 技術堆疊靈活
- 每個子系統之間約定一個通信方式,例如MQ、API等,不再像單體服務那么的局限性
- 獨立部署
- 每個微服務系統都獨立部署,都有單獨的war包,即使其中一個服務例外宕機,也不會對整個平臺產生影響
- 擴展性強
- 每個微服務都可以部署多套,配合注冊中心實作負載均衡能力
- 獨立資料
- 每個微服務都有獨立的存盤組件,比如資料庫、快取等,互不影響
單體服務的特點
- 易于部署
- 單體服務只有一個程式包,只需要部署一個服務即可完成整個系統的建設
- 易于測驗
- 測驗用例也只需要設計一個即可
單體服務的不足
- 代碼量級巨大,難以維護,如果系統中存在bug,修復起來牽扯功能太多,故障百出
- 構建、部署的成本巨大,服務都集成在一起,啟動的時間也會非常緩慢
- 新人上手較難,如果整個服務也沒有注釋的情況下,新的開發人員上手會非常難
微服務與單體服務架構上的不同
單體服務:程式包只有一個,開發團隊可能有一群人,用戶之間訪問程式包即可獲取系統資訊,后端對應一個資料庫
微服務:程式包有多個,每個程式包都是不同的功能結合,且每個微服務程式都有自己的單獨資料庫存盤資料,所有的微服務資訊都會存盤到注冊中心,網關程式在最前面,當用戶有請求進來后,首先發送給網關服務,然后網關根據注冊中心的資料,將不同功能的請求轉發給不同的微服務程式

1.2.微服務組件架構圖
以電商平臺為例,描述一個購買商品的微服務之間呼叫流程
? 用戶首先訪問到平臺的靜態首頁,發送一個搜索請求從前端頁面提交給微服務的網關服務,網關服務是對外的,也就是不管用戶要操作什么請求,都需要由網關服務轉發給具體的微服務,因為網關服務是入口,因此網關服務一般都是多臺做成的負載均衡,搜索請求到達網關服務后,網關服務會根據請求的功能轉發到搜索服務的程式上,搜索出來商品后,會呼叫商品服務程式,查看商品的詳細情況,用戶選擇完商品后,商品服務再呼叫訂單服務,完成訂單的創建,再由訂單服務呼叫支付服務,完成商品的購買,
? 所有的微服務介面資訊都會注冊到注冊中心,當程式啟動成功就會自動注冊到注冊中心,注冊中心也會起到一個負載均衡的作用,根據網關的API請求,在注冊中心上找到特定的微服務程式進行轉發,
? 微服務程式還有自己的一套配置中心,保存著各個微服務的組態檔,所有的微服務程式可能都有自己獨立的后端組件,比如MySQL、Redis、MQ、分布式存盤,
微服務之間的通信可以采用介面API、MQ、RPAC等機制
微服務在kubernetes集群中部署時可以采用無狀態服務的部署,對于資料庫、Redis、MQ、存盤還是建議部署在k8s集群之外,
注冊中心與微服務之間的聯系:發現微服務—>微服務注冊到注冊中心—>進行心跳監測,例外的節點會踢出
微服務程式的門戶網站會配置Gateway網關服務的地址,由門戶網站用戶請求的微服務資訊,轉發給Gateway網關程式,所有的微服務都會注冊在Eureka注冊中心中,Gateway網關會將請求通過注冊中心轉發給對應的微服務程式,

1.3.微服務注冊中心
微服務面對著很多問題:
- 如何記錄一個微服務副本的介面地址,如何對多個微服務節點組成的集群做負載均衡
- 符合判斷集群中某一個微服務是否可用
微服務面臨的這些問題都可以通過注冊中心去解決,在注冊中心中可用記錄某一個微服務的所有副本節點,當一個副本節點掛掉了,注冊中心也會將其踢出集群,注冊中心會將一個微服務的所有副本節點自動形成一個負載均衡
在微服務中配合注冊中心地址之后,程式一旦啟動,無需配置注冊中心,且能夠自動注冊到注冊中心
微服務接入注冊中心流程:微服務程式---->注冊---->注冊中心服務器
注冊中心呼叫微服務流程:微服務網關程式---->注冊/查詢微服務(呼叫微服務)---->注冊中心---->微服務程式
當然也可以不適用注冊中心,k8s自身的功能就有服務發現自動形成負載均衡,也可以用健康檢查監控服務的運行狀況
目前主流的注冊中心:Eureka、Nacos
1.4.不同的部署環境對于程式組態檔如何管理
可以通過以下四種方式來管理不同環境使用不同的組態檔
- kubernetes configmap資源
- 可以根據線上、預發布、測驗環境撰寫不同的configmap資源,然后將其掛載到對應的deployment資源上
- docker 容器啟動腳本entrypoint.sh
- 根據環境的不同在entrypoint.sh宣告環境變數,運行特定的組態檔
- java啟動命令控制
- java程式可以同時存在多個程式組態檔,可以在組態檔中宣告各自的變數,然后使用
java --spring.profiles.active=xxx xxx.jar的方式來指定不同環境的組態檔
- java程式可以同時存在多個程式組態檔,可以在組態檔中宣告各自的變數,然后使用
- 使用開源的統一配置中心程式,比如市面上主流的Apollo以及Disconf,這兩款程式都有自己的圖形化管理系統,配置可視化
2.微服務遷移至kubernetes平臺流程
2.1.專案遷移到K8S平臺流程

專案遷移到K8S平臺大致流程分為以下幾個階段:
-
制作程式鏡像
- 在K8s環境,所有的程式都是以Docker鏡像來運行的,一個鏡像包含了檔案系統、程式的運行環境、程式本身,可以通過Dockerfile的形式制作鏡像
-
使用資源控制器管理Pod資源
- 程式鏡像運行需要依靠Pod資源,需要有Pod控制器去管理Pod資源
- 常見的Pod控制器:Deployment(無狀態程式部署)、Statefulset(有狀態程式部署)、Job/CronJob(批量處理)
-
將Pod資源使用服務發現對外進行暴露
- Services資源注意通過label標簽與Pod進行關聯,實作對一組Pod的自動負載均衡以及服務發現
- Services資源支持Cluster、Nodeport、LoadBalancer三種型別
-
對外發布應用程式
- 可以使用單獨的nginx容器去反向代理Cordns決議的services名稱將Pod應用對外發布
- 也可以使用ingress+services的方式將應用程式對外發布,使用ingress的前提是必須可以通過域名訪問應用
- 架構圖如下

-
后期的日志收集與監控
- 當應用在K8s程式運行后,對于程式的日志比如nginx、tomcat這些日志檔案都不會做持久化,因此就需要考慮對日志進行收集,可以采用Filebeat+ELK方式對程式日志進行收集
- 使用Prometheus+Grafana對整個K8s平臺進行全方面監控
2.2.傳統部署與K8S部署的區別
傳統方式部署專案方式:
首先由開發人員提交代碼到Gitlab代碼倉庫,Jenkins觸發更新從Gitlab上獲取最新代碼,通過maven將代碼編譯成war包或者jar包,再由Jenkins通過寫好的自動化部署腳本或者Ansible自動化程式將war包部署到程式所在的云主機,云主機一定會是多臺組成的負載均衡集群,將負載均衡VIP與域名進行系結,用戶通過訪問域名由負載均衡轉發至對應的后臺主機,
傳統架構運維環境一般由zabbix監控系統進行監控,日志采集會使用ELK平臺,

Kubernetes平臺部署專案方式:
首先由開發人員提交代碼到Gitlab代碼倉庫,Jenkins觸發更新從Gitlab上獲取最新代碼,通過寫好流水線將程式打包成Docker鏡像并推送至Harbor倉庫,再由Jenkins呼叫K8s的Master Api將程式的鏡像采用Deployment控制器部署到K8s集群,再由service資源暴露pod資源,最后由ingress或者nginx資源將程式發布到互聯網,

3.微服務程式前期環境準備(配置、編譯、制作鏡像)
3.1.simple-microservice微服務專案介紹
本次使用的微服務為spring cloud的電商平臺專案
專案名稱:simple-microservice
simple-microservice微服務的各個程式:
- eureka-service(注冊中心)
- gateway-service(網管服務)
- order-service(訂單服務)
- product-service(商品服務)
- portal-service(門戶網站)
- stock-service(庫存服務)
用戶請求首先到Protal前端頁面,也就是程式的首頁,在首頁的各項功能操作都會由Gateway網關服務轉發到各自的微服務程式上,比如請求一個訂單服務,訂單服務會事先注冊到Eureka中,由Gateway將請求發送給Eureka,再由Eureka轉發給具體的微服務程式,這些微服務程式都有自己單獨的資料庫服務,
微服務程式的門戶網站會配置Gateway網關服務的地址,由門戶網站用戶請求的微服務資訊,轉發給Gateway網關程式,所有的微服務都會注冊在Eureka注冊中心中,Gateway網關會將請求通過注冊中心轉發給對應的微服務程式,

該微服務程式代碼可以托管在gitlab代碼倉庫中,我們可以建立多個分支模擬從開發到上線的流程,理念:分別創建5個分支,在每個分支中增加對應的代碼,最后合并到master分支,也可以直接就在master分支上新增組態檔,我是直接拉取dev1分支,只有程式代碼的分支,然后新增一系列配置,最后上線,
拉取dev1分支,進行一系列配置的話,首先要把master分支里的protal程式代碼同步到dev1分支里,因為dev1的protal程式代碼有點bug,整個微服務運行完畢后,order訂單服務會報錯,
分別有五個分支:
- dev1:交付代碼
- dev2:新增程式打包的Dockerfile檔案
- dev3:新增K8s資源編排Yaml檔案
- dev4:微服務鏈路監控
- dev5:新功能代碼更新上線
- master:上線版本

3.2.simple微服務部署到K8S邏輯架構
simple-microservice微服務部署到k8s平臺主要分為如下幾個步驟:
- 修改程式組態檔,將資料庫等各組件地址修改為當前環境
- 將各個微服務程式使用Maven編譯成可部署的jar包
- 撰寫Dockerfile將程式做成docker鏡像
對K8S環境的要求:
一套完整的K8S集群、有cordns可以決議Service地址、Harbor鏡像倉庫、Nginx容器將專案發布到互聯網或者INgress資源將專案發布到互聯網,
微服務部署到K8S環境之后架構是怎樣的
首先用戶訪問網站的域名,請求達到前端頁面,點擊前端頁面中的功能跳轉到不同的微服務,比如商品服務,將商品服務的請求交個Gateway網關服務,由網關服務轉發給商品的微服務程式Product,各個微服務之間的呼叫,都從Eureka注冊中心讀取各個微服務的資訊完成調度,Product(商品)、Order(訂單)、Stock(庫存)都有單獨的資料庫,MySQL資料部署在K8S集群之外,
服務發布到互聯網采用Nginx而不采用Ingress,Nginx可以配置更多的引數,將Nginx容器運行在每一個Node主機上,映射Node主機的80/443埠,通過在hosts檔案里系結node主機ip+程式域名的方式訪問微服務,

3.3.準備微服務各程式的組態檔
在使用Maven之前,首先將程式的組態檔進行修改,編譯成功之后再想修改組態檔內容,就需要重新編譯了,將每個微服務的環境地址都修改成自己環境的地址,
拉取dev1分支展開全新配置
3.3.1.創建微服務各個程式的prod組態檔
eureka(注冊中心)、gateway(網關)、order(訂單)、portal(首頁)、product(商品)、stock(庫存)這幾個微服務程式都需要配置,新建一個prod的組態檔,用于線上生產環境
order(訂單)、product(商品)、stock(庫存)這些微服務有兩個包,分別是xxx-biz和xxx-api,只需要部署biz目錄下的jar包即可,api的目錄只是存在一些依賴
order(訂單)、product(商品)、stock(庫存)這些微服務都有自己單獨的資料庫
先將prod的組態檔創建出來,待eureka專案部署完成后,再進行進一步的修改,最后將程式編譯
1.eureka-service組態檔
1.創建一個prod的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# cd eureka-service/src/main/resources/
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/eureka-service/src/main/resources]# cp application-fat.yml application-prod.yml
2.程式使用prod的組態檔運行
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/eureka-service/src/main/resources]# vim application.yml
server:
port: 8080 #eureka的埠號
spring:
application:
name: legendshop-basic-eureka
profiles:
active: prod #將這里修改為prod就會呼叫prod組態檔
3.配置eureka服務的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/eureka-service/src/main/resources]# vim application-prod.yml
eureka:
server:
renewal-percent-threshold: 0.9
enable-self-preservation: false
eviction-interval-timer-in-ms: 40000
instance:
hostname: 127.0.0.1
prefer-ip-address: true
client:
register-with-eureka: false
serviceUrl:
defaultZone: http://127.0.0.1:${server.port}/eureka/
fetch-registry: false
2.gateway-service組態檔
1.創建一個prod的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# cd gateway-service/src/main/resources/
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/gateway-service/src/main/resources]# cp application-fat.yml application-prod.yml
2.程式使用prod的組態檔運行
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/gateway-service/src/main/resources]# cat application.yml
server:
port: 8080
spring:
profiles:
active: prod
application:
name: @artifactId@
3.配置程式組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/gateway-service/src/main/resources]# vim application-prod.yml
······
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka-service:8080/eureka/ #修改eureka地址
3.order-service組態檔
1.創建一個prod的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# cd order-service/order-service-biz/src/main/resources/
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/order-service/order-service-biz/src/main/resources]# cp application-fat.yml application-prod.yml
2.程式使用prod的組態檔運行
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/order-service/order-service-biz/src/main/resources]# vim application.yml
server:
port: 8080
spring:
profiles:
active: prod
application:
name: order-service
3.配置程式組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/order-service/order-service-biz/src/main/resources]# vim application-prod.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.11:3306/tb_order?characterEncoding=utf-8 #mysql資料庫地址
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka-service:8080/eureka/ #eureka地址
5.product-service組態檔
1.創建一個prod的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# cd product-service/product-service-biz/src/main/resources/
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/product-service/product-service-biz/src/main/resources]# cp application-fat.yml application-prod.yml
2.程式使用prod的組態檔運行
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/product-service/product-service-biz/src/main/resources]# vim application.yml
server:
port: 8080
spring:
profiles:
active: prod
application:
name: product-service
3.配置程式組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/product-service/product-service-biz/src/main/resources]# vim application-prod.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.11:3306/tb_product?characterEncoding=utf-8 #資料庫地址
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka-service:8080/eureka/ #eureka地址
6.stock-service組態檔
1.創建一個prod的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# cd stock-service/stock-service-biz/src/main/resources/
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/stock-service/stock-service-biz/src/main/resources]# cp application-fat.yml application-prod.yml
2.程式使用prod的組態檔運行
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/stock-service/stock-service-biz/src/main/resources]# vim application.yml
server:
port: 8080
spring:
profiles:
active: prod
application:
name: stock-service
3.配置程式組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/stock-service/stock-service-biz/src/main/resources]# vim application-prod.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.11:3306/tb_stock?characterEncoding=utf-8 #資料庫地址
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-service.eureka:8080/eureka/ #eureka地址
4.portal-service組態檔
1.創建一個prod的組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# cd portal-service/src/main/resources/
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/portal-service/src/main/resources]# cp application-fat.yml application-prod.yml
2.程式使用prod的組態檔運行
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/portal-service/src/main/resources]# vim application.yml
server:
port: 8080
undertow:
io-threads: 16
worker-threads: 256
buffer-size: 1024
direct-buffers: true
spring:
application:
name: portal-service
profiles:
active: prod
3.配置程式組態檔
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/portal-service/src/main/resources]# vim application-prod.yml
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka-0.eureka-service:8080/eureka/ #指定eureka地址
register-with-eureka: true
fetch-registry: true
······
3.3.2.調整每個微服務的pom檔案增加prod環境
由于我們新加了一個prod線上環境的組態檔,因此也需要在pom.xml中配置,配置完成后可以編譯一下,看看是否可以做成可部署的程式包
1.安裝maven
[root@binary-k8s-master1 ~]# yum -y install java-1.8.0-openjdk maven
2.調整pom.xml增加prod環境配置
[root@binary-k8s-master1 simple-microservice-dev1]# vim pom.xml
······ #65行左右
<profile>
<id>prod</id>
<properties>
<profileActive>prod</profileActive>
</properties>
</profile>
</profiles>
······
2.編譯程式
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# mvn clean package -D maven.test.skip=true -P prod
3.查看編譯成功的war包
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1]# find . -name "*.jar"
./basic-common/basic-common-core/target/basic-common-core.jar
./eureka-service/target/eureka-service.jar
./gateway-service/target/gateway-service.jar
./order-service/order-service-api/target/order-service-api.jar
./order-service/order-service-biz/target/order-service-biz.jar
./portal-service/target/portal-service.jar
./product-service/product-service-api/target/product-service-api.jar
./product-service/product-service-biz/target/product-service-biz.jar
./stock-service/stock-service-api/target/stock-service-api.jar
./stock-service/stock-service-biz/target/stock-service-biz.jar
3.4.制作微服務程式所使用的的底層系統鏡像
3.4.1.為程式環境構建底層系統鏡像
由于是SpringCloud微服務系統,SpringCloud屬于JAVA語言開發的專案,因此要有JAVA啟動環境,
1.拉取centos7.5作為底層容器
[root@binary-k8s-master1 ~]# docker pull centos:7.5.1804
2.啟動容器
[root@binary-k8s-master1 ~]# docker run -itd centos:7.5.1804
3.進入系統容器進行環境配置
[root@binary-k8s-master1 ~]# docker exec -it 462237f9a0a bash
#安裝java環境
[root@2fcfb51f04e0 /]# yum -y install java-1.8.0-openjdk net-tools
[root@2fcfb51f04e0 /]# java -version
openjdk version "1.8.0_302"
OpenJDK Runtime Environment (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM (build 25.302-b08, mixed mode)
[root@2fcfb51f04e0 /]# mkdir /data/simple-microservice -p
#調整系統時區
[root@2fcfb51f04e0 /]# yum -y intall tzdata
[root@2fcfb51f04e0 /]# ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
4.將容器提交為鏡像
[root@binary-k8s-master1 ~]# docker commit 2fcfb51f04e0 centos-java:v1
5.配置Harbor鏡像倉庫
[root@binary-k8s-master1 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://9wn5tbfh.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.20.10"]
}
[root@binary-k8s-master1 ~]# systemctl restart docker
6.提交鏡像到Harbor倉庫
[root@binary-k8s-master1 ~]# docker login -u admin -p Harbor12345 192.168.20.10
[root@binary-k8s-master1 ~]# docker tag centos-java:v1 192.168.20.11/base/centos-java:v1
[root@binary-k8s-master1 ~]# docker push 192.168.20.11/base/centos-java:v1
3.4.2.為每個微服務程式撰寫Dockerfile
設計概念:
采用3.3.1中制作的底層鏡像
第一步:在鏡像里面創建/data/simple-microservice/微服務名稱這樣的目錄用于存放程式的jar包
第二步:將程式的jar包拷貝至鏡像中
第三步:生成一個啟動腳本,由于服務名稱都不一樣也就是每個程式的路徑都不同,想要做到一個底層鏡像多個程式復用,那么就需要在啟動腳本里手動指定程式的路徑,在腳本中指定程式的部署路徑以及日志路徑
第四步:暴露8080埠
將Dockerfile放到程式編譯的目錄也就是與src在同一目錄
1.eureka-service服務
在4.2.2.會寫
2.gateway-service服務
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/gateway-service]# vim Dockerfile
FROM 192.168.20.11/base/centos-java:v1
RUN mkdir /data/simple-microservice/gateway-service -p
COPY ./target/gateway-service.jar /data/simple-microservice/gateway-service/
RUN echo -e "#!/bin/bash \njava -jar /data/simple-microservice/gateway-service/gateway-service.jar > /data/simple-microservice/gateway-service/gateway-service.log & \ntail -f /data/simple-microservice/gateway-service/gateway-service.log" > /data/entrypoint.sh && chmod a+x /data/entrypoint.sh
EXPOSE 8080
ENTRYPOINT /data/entrypoint.sh
3.order-service服務
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/order-service/order-service-biz]# vim Dockerfile
FROM 192.168.20.11/base/centos-java:v1
RUN mkdir /data/simple-microservice/order-service -p
COPY ./target/order-service-biz.jar /data/simple-microservice/order-service/
RUN echo -e "#!/bin/bash \njava -jar /data/simple-microservice/order-service/order-service-biz.jar > /data/simple-microservice/order-service/order-service-biz.log & \ntail -f /data/simple-microservice/order-service/order-service-biz.log" > /data/entrypoint.sh && chmod a+x /data/entrypoint.sh
EXPOSE 8080
ENTRYPOINT /data/entrypoint.sh
4.portal-service服務
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/portal-service]# vim Dockerfile
FROM 192.168.20.11/base/centos-java:v1
RUN mkdir /data/simple-microservice/portal-service -p
COPY ./target/portal-service.jar /data/simple-microservice/portal-service/
RUN echo -e "#!/bin/bash \njava -jar /data/simple-microservice/portal-service/portal-service.jar > /data/simple-microservice/portal-service/portal-service.log & \ntail -f /data/simple-microservice/portal-service/portal-service.log" > /data/entrypoint.sh && chmod a+x /data/entrypoint.sh
EXPOSE 8080
ENTRYPOINT /data/entrypoint.sh
5.product-service服務
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/product-service/product-service-biz]# vim Dockerfile
FROM 192.168.20.11/base/centos-java:v1
RUN mkdir /data/simple-microservice/product-service -p
COPY ./target/product-service-biz.jar /data/simple-microservice/product-service/
RUN echo -e "#!/bin/bash \njava -jar /data/simple-microservice/product-service/product-service-biz.jar > /data/simple-microservice/product-service/product-service-biz.log & \ntail -f /data/simple-microservice/product-service/product-service-biz.log" > /data/entrypoint.sh && chmod a+x /data/entrypoint.sh
EXPOSE 8080
ENTRYPOINT /data/entrypoint.sh
6.stock-service服務
[root@binary-k8s-master1 ~/springcloud/simple-microservice-dev1/stock-service/stock-service-biz]# cat Dockerfile
FROM 192.168.20.11/base/centos-java:v1
RUN mkdir /data/simple-microservice/stock-service -p
COPY ./target/stock-service-biz.jar /data/simple-microservice/stock-service/
RUN echo -e "#!/bin/bash \njava -jar /data/simple-microservice/stock-service/stock-service-biz.jar > /data/simple-microservice/stock-service/stock-service-biz.log & \ntail -f /data/simple-microservice/stock-service/stock-service-biz.log" > /data/entrypoint.sh && chmod a+x /data/entrypoint.sh
EXPOSE 8080
ENTRYPOINT /data/entrypoint.sh
3.5.調整Protal微服務中連接Gateway網關的地址
Protal是我們電商平臺的門戶網站,也就是前端首頁,在Protal微服務中會填寫好其他微服務程式的地址,Gateway網關程式的地址就是寫死在Protal專案的js里,在我們定義好Gateway網關服務的域名后,就要將域名寫入到對應的js檔案里,否則當專案啟動之后是無法調通的,
需要修改下列這四個檔案
portal-service/src/main/resources/static/js/orderList.js
portal-service/src/main/resources/static/js/productList.js

打開這四個檔案,將里面的gateway.ctnrs.com域名修改為gateway.jiangxl.com域名
vim修改命令:%s/gateway.ctnrs.com/gateway.jiangxl.com/g
3.6.部署Ingress用于將微服務程式發布到互聯網
1.下載ingress部署的yaml檔案
[root@binary-k8s-master1 ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
[root@binary-k8s-master1 ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
2.調整ingress nodeport埠
[root@binary-k8s-master1 ~/springcloud/ingress]# vim service-nodeport.yaml
······
ports:
- name: http
port: 80
targetPort: 80
nodePort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
nodePort: 443
protocol: TCP
······
3.部署ingress
[root@binary-k8s-master1 ~/springcloud/ingress]# kubectl apply -f mandatory.yaml
4.查看ingress部署的結果
[root@binary-k8s-master1 ~]# kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-ingress-controller-766867958b-n7dwj 1/1 Running 0 49m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx NodePort 10.0.0.107 <none> 80:80/TCP,443:443/TCP 49m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-ingress-controller 1/1 1 1 49m
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-ingress-controller-766867958b 1 1 1 49m
4.在kubernetes集群部署simple微服務專案
simple微服務專案在K8S集群中部署,只有eureka服務采用statefulset控制器部署,其余所有微服務均采用deployment控制器部署,所有的微服務通過ingress發布在互聯網,
simple微服務電商專案在K8S集群部署流程
1)部署simple電商微服務專案的資料庫環境
2)在K8S中部署Eureka注冊中心
3)修改每個微服務的組態檔,指定eureka注冊中心集群的地址
4)使用maven將每個微服務構建成可部署的jar包
5)部署Gateway關服務
6)部署protal、order、product、stock服務
4.1.部署simple微服務程式的mysql資料庫環境
1.安裝MySQL資料庫
[root@harbor-mysql ~]# rpm -ivh http://repo.mysql.com/yum/mysql-5.6-community/el/7/x86_64/mysql-community-release-el7-5.noarch.rpm
[root@harbor-mysql ~]# yum install mysql-community-server
2.啟動MySQL
[root@harbor-mysql ~]# systemctl start mysqld
[root@harbor-mysql ~]# systemctl enable mysqld
3.設定資料庫密碼
[root@harbor-mysql ~]# mysqladmin -u root password '123456'
4.創建order(訂單)、product(商品)、stock(庫存)微服務的資料庫
[root@harbor-mysql ~]# mysql -uroot -p123456
mysql> create database tb_order;
Query OK, 1 row affected (0.00 sec)
mysql> create database tb_product;
Query OK, 1 row affected (0.01 sec)
mysql> create database tb_stock;
Query OK, 1 row affected (0.00 sec)
5.匯入資料庫資料
#將資料庫檔案傳到資料庫服務器
[root@binary-k8s-master1 simple-microservice-dev1]# scp -r db root@192.168.20.11:/root
#匯入order資料庫的資料
mysql> use tb_order
mysql> source /root/db/order.sql
#匯入product資料庫的資料
mysql> use tb_product
mysql> source /root/db/product.sql
#匯入stock資料庫的資料
mysql> use tb_stock;
mysql> source /root/db/stock.sql
6.允許資料庫遠程訪問
mysql> grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
Query OK, 0 rows affected (0.00 sec)
4.2.部署eureka微服務注冊中心
Eureka在整個微服務架構中起到至關重要的的作用,必須保證Eureka服務高可用,
Eureka服務采用statefulset有狀態應用部署方式再K8S集群中進行部署,
Eureka本身就可以利用自身的服務發現來實作集群的高可用,只需要在Eureka組態檔中指定各個Eureka節點的地址就可以實作,
將程式部署在K8S之后,如何能夠保證每個Eureka Pod的地址唯一不變,就需要用到Statefulset控制器采用有狀態的應用部署,使用Statefulset控制器之后,每個Pod的名稱都是唯一不變的,并且每個Pod都有一個DNS服務發現地址,通過這個DNS地址就可以請求到Pod中的服務,主要是coredns組件來實作的,因此集群還需要安裝有coredns服務,我們可以將每一個Eureka Pod的DNS服務發現地址寫入到Eureka的組態檔中,每個Eureka節點相互注冊,最終形成高可用集群,
Statefulset+Headless部署的程式DNS名格式:<statefulsetName-index>.<service-name>.<namespace-name>.svc.cluster.local后面的.svc.cluster.local可以去掉,K8S默認就是.svc.cluster.local,
<statefulsetName-index>就是Pod的名稱,-index是每一個Pod名稱后面的數字編號,Statefulset控制器部署好的Pod,會在每一個Pod名稱后面加上一個數字編號,從0開始,一次累加,保證所有的Pod都有一個獨立的訪問入口
<service-name>是程式的service資源的名稱
<namespace-name>是程式所在的namespace名稱
我們的Eureka規定的節點數為3個,也就是最終statefulset會啟動3個Pod副本組成Eureka集群,
4.2.1.修改Eureka組態檔增加各節點地址
Eureka集群節點每個Pod副本服務發現地址如下,需要將其配置在eureka中
http://eureka-0.eureka-service.simple-ms
http://eureka-0.eureka-service.simple-ms
http://eureka-0.eureka-service.simple-ms
修改Eureka的組態檔,采用Dns服務發現地址的形式將每個節點的地址都寫在組態檔中,當Eureka啟動之后,每個節點都會相互發現最終形成高可用集群,
1.修改Eureka組態檔中的節點地址
[root@binary-k8s-master1 eureka-service]# vim src/main/resources/application-prod.yml
eureka:
server:
renewal-percent-threshold: 0.9
enable-self-preservation: false
eviction-interval-timer-in-simple-ms: 40000
instance:
hostname: 127.0.0.1
prefer-ip-address: false
client:
register-with-eureka: true
serviceUrl:
defaultZone: http://eureka-0.eureka.simple-ms:${server.port}/eureka/,http://eureka-1.eureka.simple-ms:${server.port}/eureka/,http://eureka-2.eureka.simple-ms:${server.port}/eureka/
fetch-registry: true
2.使用maven將最新的Eureka編譯
[root@binary-k8s-master1 simple-microservice-dev1]# mvn clean package -D maven.test.skip=true -P prod
注意:只能在專案最外層的目錄中執行mvn clean package
4.2.2.調整Eureka的Dockerfile
由于我們在Eureka組態檔中配置的是以dns名稱來互相發現對方,并不是以IP地址形式發現,因此我們需要配置Dockerfile,在啟動程式時將組態檔中的hostname欄位值修改為當前Pod的dns名稱,
因為我們的Eureka是多Pod組成的高可用集群,因此不能將dns名稱寫死在組態檔中,不然每個Pod都是同樣的地址,集群是組件不成功的,所以就需要在Dockerfile中定義程式啟動命令時,將dns名稱地址設定成變數,由Pod資源將變數值傳入到啟動命令中,程式啟動時就會用Pod的dns名稱地址替換掉組態檔中的IP地址,
1.修改DOckerfile檔案內容
[root@binary-k8s-master1 eureka-service]# vim Dockerfile
FROM 192.168.20.11/base/centos-java:v1
RUN mkdir /data/simple-microservice/eureka-service -p
COPY ./target/eureka-service.jar /data/simple-microservice/eureka-service/
RUN echo -e "#!/bin/bash \njava -jar -Deureka.instance.hostname=${MY_POD_NAME}.eureka.simple-ms /data/simple-microservice/eureka-service/eureka-service.jar > /data/simple-microservice/eureka-service/eureka-service.log & \ntail -f /data/simple-microservice/eureka-service/eureka-service.log" > /data/entrypoint.sh && chmod a+x /data/entrypoint.sh
EXPOSE 8080
ENTRYPOINT /data/entrypoint.sh
啟動命令單獨拉出來看一下,-Deureka.instance.hostname這個引數表示修改組態檔中hostname引數的值,${MY_POD_NAME}這個變數使從deployment資源檔案中定義的env變數,將Pod的名稱賦給MY_POD_NAME變數,最后引入到啟動命令中,最后在組態檔中hostname欄位的值應該是eureka-0.eureka-service.simple-ms
java -jar -Deureka.instance.hostname=${MY_POD_NAME}.eureka-service.simple-ms /data/simple-microservice/eureka-service/eureka-service.jar
4.2.3.構建Eureka服務的Docker鏡像
[root@binary-k8s-master1 eureka-service]# docker build -t 192.168.20.11/simple-microservice/eureka-service:v1 .
[root@binary-k8s-master1 eureka-service]# docker images | grep eureka
192.168.20.11/simp-microservice/eureka-service v1 1dc64fc9ba09 About a minute ago 800MB
[root@binary-k8s-master1 eureka-service]# docker push 192.168.20.11/simple-microservice/eureka-service:v1
4.2.4.撰寫Eureka部署YAML資源檔案
1)創建命名空間
1.創建命名空間
# kubectl create ns simple-ms
namespace/simple-ms created
2.創建資源編排YAML檔案存放路徑
[root@binary-k8s-master1 ~]# mkdir springcloud/simple-microservice-dev1/k8s/
2)登錄Harbor
可以不在每一個Node節點使用docker login登陸Harbor倉庫,可以將Harbor倉庫的認證資訊做成secret,通過使用secret的方式連接Harbor,
[root@binary-k8s-master1 ~]# kubectl create secret docker-registry registry-pull-secret --docker-server=192.168.20.11 --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@ctnrs.com -n simple-ms
3)撰寫資源YAML檔案
eureka要做成集群式的服務,所以要采用statefulset控制器部署,并采用headless service保證statefulset創建的pod名稱唯一性,最后通過ingress將eureka服務發布在互聯網環境,
[root@binary-k8s-master1 k8s]# vim eureka-deploy.yaml
---
#ingress資源
apiVersion: extensions/v1beta1
kind: Ingress #型別為ingress
metadata: #定義元資料資訊:資源名稱、資源所在的命名空間
name: eureka
namespace: simple-ms
spec:
rules: #定義ingress規則
- host: eureka.jiangxl.com #定義eureka使用的域名
http: #采用http型別的訪問方式
paths: #定義程式的url路徑
- path: /
backend: #針對定義的程式路徑關于對應的后端service資源
serviceName: eureka
servicePort: 8080
---
#headless service資源
apiVersion: v1
kind: Service
metadata:
name: eureka
namespace: simple-ms
spec:
clusterIP: None #ClusterIP資源設定為Node就代表headless型別的service
ports: #定義暴露的eureka埠號
- port: 8080
name: eureka
selector: #標簽選擇器,關聯后端pod
project: simple
app: eureka
---
#statefulset資源
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eureka
namespace: simple-ms
spec:
replicas: 3 #副本數
selector: #標簽選擇器
matchLabels:
project: simple
app: eureka
serviceName: "eureka" #service的名稱,也就是將來的pod名稱
template:
metadata:
labels:
project: simple
app: eureka
spec:
imagePullSecrets: #harbor鏡像倉庫的憑據資訊
- name: registry-pull-secret
containers:
- name: eureka
image: 192.168.20.11/simple-microservice/eureka-service:v1
ports:
- protocol: TCP
containerPort: 8080
env: #增加一個環境變數,變數名為MY_POD_NAME,值為pod的名稱,這個變數資訊會傳入dockerfile中
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
resources: #資源配額
requests: #最小資源限制,cpu為0.5,記憶體為256M
cpu: 0.5
memory: 256Mi
limits: #最大資源限制,cpu為1,記憶體為1G
cpu: 1
memory: 1Gi
readinessProbe: #就緒性健康檢查
tcpSocket: #以tcp 8080埠作為健康檢查的機制
port: 8080
initialDelaySeconds: 60 #容器啟動60秒后進行檢測
periodSeconds: 10 #探測的頻率
livenessProbe: #存活性健康檢查
tcpSocket: #以tcp 8080埠作為健康檢查的機制
port: 8080
initialDelaySeconds: 60 #容器啟動60秒后進行檢查
periodSeconds: 10 #探測的頻率為10秒一次
4.2.5.在K8S集群中部署Eureka注冊中心
1.部署eureka服務
[root@binary-k8s-master1 k8s]# kubectl apply -f eureka-deploy.yaml
2.查看部署的資源狀態
[root@binary-k8s-master1 k8s]# kubectl get all -n simple-ms
NAME READY STATUS RESTARTS AGE
pod/eureka-0 1/1 Running 1 12h
pod/eureka-1 1/1 Running 0 12h
pod/eureka-2 1/1 Running 0 12h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/eureka ClusterIP None <none> 8080/TCP 13h
NAME READY AGE
statefulset.apps/eureka 3/3 13h
3.查看eureka的ingress狀態
[root@binary-k8s-master1 k8s]# kubectl get ingress -n simple-ms
NAME CLASS HOSTS ADDRESS PORTS AGE
eureka <none> eureka.jiangxl.com 10.0.0.107 80 13h
首先在本地hosts檔案中系結eureka域名決議,然后在瀏覽器中輸入eureka.jiangxl.com訪問eureka服務,

4.3.配置各個微服務程式連接Eureka集群的地址
在程式的組態檔中填寫eureka集群所有節點的服務發現地址
1.gateway-service組態檔
# vim gateway-service/src/main/resources/application-prod.yml
······
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.simple-ms:8080/eureka,http://eureka-1.eureka.simple-ms:8080/eureka,http://eureka-2.eureka.simple-ms:8080/eureka
2.order-service組態檔
# vim order-service/order-service-biz/src/main/resources/application-prod.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.11:3306/tb_order?characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.simple-ms:8080/eureka,http://eureka-1.eureka.simple-ms:8080/eureka,http://eureka-2.eureka.simple-ms:8080/eureka
3.product-service組態檔
# vim product-service/product-service-biz/src/main/resources/application-prod.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.11:3306/tb_product?characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.simple-ms:8080/eureka,http://eureka-1.eureka.simple-ms:8080/eureka,http://eureka-2.eureka.simple-ms:8080/eureka
4.stock-service組態檔
# vim stock-service/stock-service-biz/src/main/resources/application-prod.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.11:3306/tb_stock?characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.simple-ms:8080/eureka,http://eureka-1.eureka.simple-ms:8080/eureka,http://eureka-2.eureka.simple-ms:8080/eureka
5.portal-service組態檔
# vim portal-service/src/main/resources/application-prod.yml
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka-0.eureka.simple-ms:8080/eureka,http://eureka-1.eureka.simple-ms:8080/eureka,http://eureka-2.eureka.simple-ms:8080/eureka
register-with-eureka: true
fetch-registry: true
······
4.4.將各個程式代碼編譯成可部署的程式
[root@binary-k8s-master1 simple-microservice-dev1]# mvn clean package -D maven.test.skip=true -P prod
4.3.中部署Gateway網關服務
4.3.1.將Gateway程式打包成docker鏡像
[root@binary-k8s-master1 gateway-service]# docker build -t 192.168.20.11/simple-microservice/gateway-service:v1 .
4.3.2.在K8S集群中部署Gateway網關服務
所有程式的資源YAML檔案都存放在/root/springcloud/simple-microservice-dev1/k8s路徑,
微服務程式的話就不需要有狀態應用部署了,直接采用deployment無狀態應用部署的控制器,欄位配置和eureka服務的statefulset配置引數幾乎是一樣的,微服務的各個程式也都采用有deployment控制器去部署,每個程式的yaml檔案也只有名字、使用的鏡像不同,其余所有引數均一致,
gateway是網關服務,需要配置一個ingress和service資源,將其發布在集群之外,
欄位配置和statefulset的一致,不再做注釋資訊
# vim gateway-deploy.yaml
---
#ingress資源YAML
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gateway
namespace: simple-ms
spec:
rules:
- host: gateway.jiangxl.com
http:
paths:
- path: /
backend:
serviceName: gateway
servicePort: 8080
---
#service資源YAML
apiVersion: v1
kind: Service
metadata:
name: gateway
namespace: simple-ms
spec:
ports:
- port: 8080
name: gateway
selector:
project: simple
app: gateway
---
#deployment資源YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
namespace: simple-ms
spec:
replicas: 1 #副本數設定1個,后續再加
selector:
matchLabels:
project: simple
app: gateway
template:
metadata:
labels:
project: simple
app: gateway
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: gateway
image: 192.168.20.11/simple-microservice/gateway-service:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
4.3.3.在K8S集群中部署Gateway網關服務
1.部署網關服務
[root@binary-k8s-master1 k8s]# kubectl apply -f gateway-deploy.yaml
2.查看gateway pod資源的狀態
[root@binary-k8s-master1 k8s]# kubectl get pod -n simple-ms
NAME READY STATUS RESTARTS AGE
eureka-0 1/1 Running 1 2d12h
eureka-1 1/1 Running 0 2d12h
eureka-2 1/1 Running 0 2d12h
gateway-7c687f6c45-mcwpf 1/1 Running 0 2m2s
3.查看deployment和svc的資源狀態
[root@binary-k8s-master1 k8s]# kubectl get deploy,svc -n simple-ms
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/gateway 1/1 1 1 17h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/eureka ClusterIP None <none> 8080/TCP 2d13h
service/gateway ClusterIP 10.0.0.188 <none> 8080/TCP 17h
4.查看gateway ingress資源狀態
[root@binary-k8s-master1 k8s]# kubectl get ingress -n simple-ms
NAME CLASS HOSTS ADDRESS PORTS AGE
eureka <none> eureka.jiangxl.com 10.0.0.107 80 2d13h
gateway <none> gateway.jiangxl.com 10.0.0.107 80 17h
4.4.撰寫快速部署微服務到K8S集群的腳本
由于微服務程式眾多,并且每個程式在K8S集群部署的流程也基本一樣,因此我們撰寫一個部署腳本,只要準備好程式的jar包以及資源YAML檔案就可以將其一鍵部署到K8S集群,當前也可以通過Helm來實作,
1.腳本內容
實作邏輯:
1.將harbor倉庫的地址、所有微服務的名稱、k8s yaml檔案的路徑、微服務代碼所在的路徑都定義成環境變數,
2.如果只想部署其中一個微服務的話,通過位置傳參的方式來實作,也就是再定義一個微服務名稱的變數,變數值為KaTeX parse error: Expected '}', got 'EOF' at end of input: {1:-{service_list}},將要部署的微服務名稱通過位置傳參的方式,將值傳入到service_list變數名里,覆寫原service_list變數值,實作單個微服務的部署,如果沒有使用位置引數,那么默認部署全部的微服務,
3.進入微服務代碼所在的路徑,然后通過for回圈的方式,遍歷service_list變數中的各個微服務,然后本次回圈的微服務代碼路徑,判斷是否有包含biz的目錄,如果有biz目錄則切入到biz目錄,然后通過變數的形式定義鏡像名稱,構建鏡像、推送至鏡像倉庫,
4.將最新打包好的docker進在yaml檔案中通過sed命令替換,最后在k8s集群中部署這個微服務,
${1:-${service_list}}:這個的意思就是如果$1位置引數沒有傳入值,那么service_list變數的值就是$service_list變數的值,相當于一個判斷,
本腳本可以自動化完成微服務到K8S集群的一個部署,包括程式的編譯、打包成docker鏡像、推薦鏡像到Harbor倉庫,最后將程式部署到K8S集群
#!/bin/bash
registry_addr=192.168.20.11
service_list="eureka-service gateway-service order-service product-service stock-service portal-service"
service_list=${1:-${service_list}}
current_dir=/root/springcloud/simple-microservice-dev1/k8s
service_dir=$(dirname $current_dir)
cd $service_dir
#mvn clean package -Dmaven.test.skip=true
for service in $service_list; do
cd $service_dir/$service
biz_count=`ls | grep biz | wc -l`
if [ $biz_count -eq 1 ];then
cd ${service}-biz
fi
service_name=`echo $service | awk -F- '{print $1}'`
image_name=${registry_addr}/simple-microservice/${service}:v1
yaml_name=${service_name}-deploy.yaml
docker build -t ${image_name} .
docker push ${image_name}
sed -i -r "s#(image: )(.*)#\1$image_name#" ${current_dir}/${yaml_name}
kubectl apply -f ${current_dir}/${yaml_name}
done
2.腳本使用方式
執行本腳本前提是必須先將程式部署的YAML檔案準備好,放在/root/springcloud/simple-microservice-dev1/k8s路徑
腳本的用法:
sh deploy_k8s.sh 微服務名稱
4.5.使用腳本部署Order訂單服務
4.5.1.撰寫資源部署YAML檔案
# vim order-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order
namespace: simple-ms
spec:
replicas: 1
selector:
matchLabels:
project: simple
app: order
template:
metadata:
labels:
project: simple
app: order
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: order
image: 192.168.20.11/simple-microservice/order-service:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
4.5.2在K8S集群中部署Order訂單服務
1.使用腳本將Order服務部署到K8S集群
[root@binary-k8s-master1 k8s]# sh deploy_k8s.sh order-service
執行完腳本,order程式的docker鏡像已經制作好并且推送到了harbor倉庫,已經使用sed命令將鏡像的名稱在yaml中替換成了最新的鏡像,部署到了K8S集群

2.查看程式資源的狀態
1.查看pod的狀態
[root@binary-k8s-master1 k8s]# kubectl get all -n simple-ms
NAME READY STATUS RESTARTS AGE
pod/eureka-0 1/1 Running 1 2d15h
pod/eureka-1 1/1 Running 0 2d15h
pod/eureka-2 1/1 Running 0 2d15h
pod/gateway-8665d5d56-tx2m8 1/1 Running 0 39m
pod/order-6694f4c474-cp5d6 1/1 Running 0 35m
2.查看deployment資源的狀態
[root@binary-k8s-master1 k8s]# kubectl get deploy -n simple-ms
NAME READY UP-TO-DATE AVAILABLE AGE
gateway 1/1 1 1 21h
order 1/1 1 1 36m
4.6.使用腳本部署Product商品服務
4.6.1.撰寫資源部署YAML檔案
# vim product-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: product
namespace: simple-ms
spec:
replicas: 1
selector:
matchLabels:
project: simple
app: product
template:
metadata:
labels:
project: simple
app: product
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: product
image: 192.168.20.11/simple-microservice/product-service:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
4.6.2.在K8S集群中熟不熟Product商品服務
1.使用腳本在K8S集群中部署product服務
[root@binary-k8s-master1 k8s]# sh deploy_k8s.sh product-service

2.查看程式資源的狀態
1.查看pod的狀態
[root@binary-k8s-master1 k8s]# kubectl get pod -n simple-ms
NAME READY STATUS RESTARTS AGE
eureka-1 1/1 Running 3 2d16h
eureka-2 1/1 Running 2 2d16h
gateway-8665d5d56-tx2m8 1/1 Running 2 74m
order-6694f4c474-cp5d6 1/1 Running 4 69m
product-77c8bb6847-vbxnr 1/1 Running 2 21m
2.查看deployment資源的狀態
[root@binary-k8s-master1 k8s]# kubectl get deploy -n simple-ms
NAME READY UP-TO-DATE AVAILABLE AGE
gateway 1/1 1 1 21h
order 1/1 1 1 72m
product 1/1 1 1 24m
4.7.使用腳本部署Stock庫存服務
4.7.1.撰寫資源部署YAML檔案
# vim product-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: product
namespace: simple-ms
spec:
replicas: 1
selector:
matchLabels:
project: simple
app: product
template:
metadata:
labels:
project: simple
app: product
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: product
image: 192.168.20.11/simple-microservice/product-service:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
4.7.2.在K8S集群中部署Stock庫存服務
1.使用腳本在K8S集群中部署stock服務
[root@binary-k8s-master1 k8s]# sh deploy_k8s.sh stock-service

2.查看程式資源的狀態
1.查看pod的狀態
[root@binary-k8s-master1 ~]# kubectl get pod -n simple-ms
NAME READY STATUS RESTARTS AGE
eureka-0 1/1 Running 5 2d16h
eureka-1 1/1 Running 3 2d16h
eureka-2 1/1 Running 2 2d16h
gateway-8665d5d56-tx2m8 1/1 Running 2 112m
order-6694f4c474-cp5d6 1/1 Running 4 107m
product-77c8bb6847-vbxnr 1/1 Running 2 59m
stock-6cf98bb445-mxf7b 1/1 Running 0 30m
2.查看deployment資源的狀態
[root@binary-k8s-master1 ~]# kubectl get deploy -n simple-ms
NAME READY UP-TO-DATE AVAILABLE AGE
gateway 1/1 1 1 22h
order 1/1 1 1 108m
product 1/1 1 1 60m
stock 2/2 2 2 31m
4.8.使用腳本部署Portal前端首頁
4.8.1.撰寫資源部署YAML檔案
# vim portal-deploy.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: portal
namespace: simple-ms
spec:
rules:
- host: portal.jiangxl.com
http:
paths:
- path: /
backend:
serviceName: portal
servicePort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: portal
namespace: simple-ms
spec:
ports:
- port: 8080
name: portal
selector:
project: simple
app: portal
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: simple-ms
spec:
replicas: 1
selector:
matchLabels:
project: simple
app: portal
template:
metadata:
labels:
project: simple
app: portal
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: portal
image: 192.168.20.11/simple-microservice/portal-service:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
4.8.2.在K8S集群中熟不熟Portal存服務
1.使用腳本在K8S集群中部署portal服務
[root@binary-k8s-master1 k8s]# sh deploy_k8s.sh portal-service

2.查看程式資源的狀態
到此為止,所有的simple電商平臺的微服務程式以及全部部署完畢,
1.查看所有微服務的程式
[root@binary-k8s-master1 k8s]# kubectl get all -n simple-ms
NAME READY STATUS RESTARTS AGE
pod/eureka-0 1/1 Running 5 2d16h
pod/eureka-1 1/1 Running 3 2d16h
pod/eureka-2 1/1 Running 2 2d16h
pod/gateway-8665d5d56-tx2m8 1/1 Running 2 117m
pod/order-6694f4c474-cp5d6 1/1 Running 4 112m
pod/portal-d5d55b784-7kntp 1/1 Running 0 2m53s
pod/product-77c8bb6847-vbxnr 1/1 Running 2 64m
pod/stock-6cf98bb445-mxf7b 1/1 Running 0 35m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/eureka ClusterIP None <none> 8080/TCP 2d18h
service/gateway ClusterIP 10.0.0.188 <none> 8080/TCP 22h
service/portal ClusterIP 10.0.0.190 <none> 8080/TCP 2m53s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/gateway 1/1 1 1 22h
deployment.apps/order 1/1 1 1 112m
deployment.apps/portal 1/1 1 1 2m53s
deployment.apps/product 1/1 1 1 65m
deployment.apps/stock 1/1 1 1 35m
NAME DESIRED CURRENT READY AGE
replicaset.apps/gateway-8665d5d56 1 1 1 117m
replicaset.apps/order-6694f4c474 1 1 1 112m
replicaset.apps/portal-d5d55b784 1 1 1 2m53s
replicaset.apps/product-77c8bb6847 1 1 1 64m
replicaset.apps/stock-6cf98bb445 1 1 1 35m
NAME READY AGE
statefulset.apps/eureka 3/3 2d18h
2.查看所有微服務的ingress資源
[root@binary-k8s-master1 k8s]# kubectl get ingress -n simple-ms
NAME CLASS HOSTS ADDRESS PORTS AGE
eureka <none> eureka.jiangxl.com 10.0.0.107 80 2d18h
gateway <none> gateway.jiangxl.com 10.0.0.107 80 22h
portal <none> portal.jiangxl.com 10.0.0.107 80 3m16s
4.9.查看Eureka注冊中心中各個微服務的資訊
每個微服務程式均在Eureka注冊中心中注冊完成,

4.10.使用simple微服務電商平臺
到4.8步驟之后,我們的simple微服務電商平臺已經全部部署在K8S集群了,可以在本機hosts里系結simple微服務的域名,操作電商平臺,

這個微服務平臺的背景圖其實是京東的一張圖而已,是不可以點的,

只能在商品服務中查詢能購買的商品,然后進行購買,最后在訂單服務中查詢,
搜索商品時會呼叫product商品微服務,下單后,查詢訂單服務時會呼叫order訂單服務,
點擊查詢商品服務,我們來下單一個美女觀察一下效果,下單后會提示下單成功,

點擊查詢訂單服務就可以看到我嗎下的訂單了

5.基于K8S集群的微服務的擴容與升級
5.1.微服務的擴容
微服務在物理機環境運行時,網站并發量高的情況下,擴容只能去購買云服務器,然后搭建一套一模一樣的服務,手動組成負載均衡集群,增加一臺其實還好,如果要增加幾十臺,太費人工成本了,
當微服務遷移到K8S集群之后,擴容其實變得非常簡單,只需要增加程式Pod的副本數就可以完成程式的擴容,
命令如下,以擴展order商品微服務為例,
將order商品服務的副本數調整為3個,原本是1個,現在擴容到3個
[root@binary-k8s-master1 k8s]# kubectl scale deploy order --replicas=3 -n simple-ms
deployment.apps/order scaled
可以看到order訂單服務目前已經有3個pod副本了
[root@binary-k8s-master1 ~]# kubectl get pod -n simple-ms
NAME READY STATUS RESTARTS AGE
eureka-0 1/1 Running 1 6m15s
eureka-1 1/1 Running 0 7m59s
eureka-2 1/1 Running 1 9m40s
gateway-848874fc9d-pwp9w 1/1 Running 0 48m
order-6694f4c474-cp5d6 1/1 Running 4 3h29m
order-6694f4c474-kh8hm 1/1 Running 0 96s
order-6694f4c474-rg7kw 1/1 Running 0 96s
portal-6fdcd765bd-mtq68 1/1 Running 1 24m
product-784d9f77b5-rxsf2 1/1 Running 0 64m
stock-6cf98bb445-l8gxb 1/1 Running 0 133m
縮容也很簡單,將order的副本數縮減成1個
[root@binary-k8s-master1 k8s]# kubectl scale deploy order --replicas=1 -n simple-ms
deployment.apps/order scaled
成功縮減到1個副本
[root@binary-k8s-master1 ~]# kubectl get pod -n simple-ms
NAME READY STATUS RESTARTS AGE
eureka-0 1/1 Running 1 9m24s
eureka-1 1/1 Running 0 11m
eureka-2 1/1 Running 1 12m
gateway-848874fc9d-pwp9w 1/1 Running 0 51m
order-6694f4c474-rg7kw 1/1 Running 0 4m45s
portal-6fdcd765bd-mtq68 1/1 Running 1 27m
product-784d9f77b5-rxsf2 1/1 Running 0 67m
stock-6cf98bb445-l8gxb 1/1 Running 0 136m
5.2.微服務的升級
微服務在物理機環境更新時只需要拉取最新的代碼,編譯成jar包,在服務器上部署就可以了,但是微服務遷移到K8S集群之后,更新程序就變得比較復雜了,首先更新的代碼,然后編譯成jar包,再通過Dockerfile將jar包做成docker鏡像,然后在k8s集群中部署,當然這些流程可以通過Jenkins實作自動化上線,
5.2.1.微調Portal前端首頁的代碼
將平臺的這些檔案修改成jiangxl.com的內容完成一次portal前端首頁的升級

首先找到記錄這些文字的檔案

# vim templates/index.ftl
# vim templates/orderList.ftl
# vim templates/productList.ftl
進入檔案后在末行模式輸入:
%s/容器學院 www.ctnrs.com/jiangxl.com/g
%s/www.ctnrs.com/jiangxl.com/g
然后將所有的容器學院的文字洗掉
5.2.2.編譯最新代碼
[root@binary-k8s-master1 simple-microservice-dev1]# mvn clean package -D maven.test.skip=true -P prod
5.2.3.通過腳本將Protal最新代碼打包成鏡像
直接使用前面部署程式的腳本即可
[root@binary-k8s-master1 k8s]# sh deploy_k8s.sh portal-service
5.2.4.升級K8S集群中的Protal微服務
[root@binary-k8s-master1 k8s]# kubectl -n simple-ms set image deployment portal portal=192.168.20.11/simple-microservice/portal-service:v1 --record
程式更新完成后重繪頁面就可以看到我們更新的頁面內容

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/374749.html
標籤:java
