在完成 k8s 上快速部署 go 服務後, 就可以假裝 devops 的能力已經有了(就是這麼膨脹), 接下來開始征戰微服務
服務小百科
- 從最簡單的開始
sequenceDiagram
client ->> server: Are you ok?
server ->> client: Fine, thx.
一起來看看, 會遇到哪些問題, 以及如何解決:
- 假設 client 數量爲 M, server 數量爲 N, 上面的問題規模爲 , 按照經典理論:
計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決
引入 服務註冊與發現
sequenceDiagram
server ->> serviceCenter: register(服務註冊)
client ->> serviceCenter: discovery(服務發現)
serviceCenter ->> client: server connect info
client ->> server: Are you ok?
- 高可用下, 服務要避免 單點 故障
server 可以起多個實例, 多個實例組成集羣, 集羣前置負載均衡(LB)
sequenceDiagram
client ->> LB: request
LB ->> serverA: request
serverA ->> LB: response
LB ->> client: response
還有這些問題:
- 熔斷: client 太熱情, server 扛不住, 需要對超出能力外的請求進行熔斷, 或者說限流
- 重試: client 沒有收到 server 的正常響應, 需要進行重試
- 鏈路監控: client / server 很多, 調用鏈複雜, 如何有效追蹤和監控
還有很多 非業務邏輯 的問題, 就不一一列舉了, 可以對照 微服務1.0 中的組件, 多問幾句:
這個組件是什麼(what)? 怎麼用的(how)? 爲什麼需要這個組件(why)?
微服務1.0: spring cloud 全家桶
爲了解決上面提到 共性 的問題, 先行者 遇山劈山, 遇水架橋, 提供 *類庫和框架 來解決, spring cloud 全家桶是裏面的佼佼者
spring cloud
- spring-cloud-commons: 框架公共類庫
- spring-cloud-netfix: netfix 提供的一整套解決方案
- spring-cloud-sleuth: 調用鏈
- spring-cloud-gateway: 網關
- spring-cloud-bus
- spring-cloud-consul
- spring-cloud-zookeeper
- spring-cloud-config
- spring-cloud-security
- spring-cloud-aws
- spring-cloud-cloudfoundry
netfix OSS
- eureka
- hystrix
- turbine
- archaius
- atlas
- feign
- ribbon
- zuul
除了 netfix, 還有其他產商也有對應的一整套解決方案, 比如 spring-cloud-alibaba
, 同樣是爲了解決 非業務邏輯 的共性問題
靈魂拷問來了: 既然是非業務的共性問題, 做成 基礎設施 豈不美哉?
微服務 2.0: service mesh 橫刀立馬
仔細一想, 這幾年在基礎設施領域, 可謂變革頗豐:
- 讓算力成爲基礎設施 -- 雲計算: 再也不用凌晨打電話給網管, 讓他手動重啓服務器了
- 讓應用成爲基礎設施 -- 容器: 應用 = 程序 + 程序運行所需的環境, 讓應用的交付更標準, 應用的迭代速度更快
- 讓應用編排部署成爲基礎設施 -- k8s: 業務 = 應用編排 + 硬件資源資源池
到現在, devops + k8s + 微服務
全套理念越發完備, 工具鏈越發完善的今天, 服務治理, 也可以成爲基礎設施
容器設計模式 sidecar: 將輔助功能同主業務解耦, 實現獨立發佈和能力重用
k8s 將 pod 作爲最小調度單位, pod = 一組容器組合 = 業務容器 + sidecar容器(非業務邏輯的輔助功能)
有了 sidecar, log proxy adapter
等功能都可以輕鬆實現, 而不影響業務
sequenceDiagram
client ->> clientSidecar: request
clientSidecar ->> serverSidecar: request
serverSidecar ->> server: request
server ->> serverSidecar: response
serverSidecar ->> clientSidecar: response
clientSidecar ->> client: response
sidercar容器是和業務容器部署在一起的, 最終:
sequenceDiagram
client(sidecar) ->> server(sidecar): Are you ok?
server(sidecar) ->> client(sidecar): Fine, thx.
有點 分久必合合久必分 的味道? 歷史並不是那頭拉磨的驢, 兜兜轉轉又回到了原點, 恰恰相反, 是走出了圍牆, 可以看到更大的世界
終於到我們的主角登場了: service mesh 今日之星 -- istio
istio 快速實踐
- 安裝
brew install istioctl
istioctl manifest apply # 安裝 istio 到 k8s
kubectl get svc -n istio-system # 校驗安裝是否成功
kubectl get pods -n istio-system
- 上手
bookinfo
demo
使用官方提供的 bookinfo
[圖片上傳失敗...(image-74749a-1600779417756)]
kubectl label namespace default istio-injection=enabled # default 命名空間下開啓 istio
kubectl apply -f bookinfo.yaml
kubectl get svc # 驗證 bookinfo 服務
➜ kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-558b8b4b76-5p84p 1/1 Running 0 14h
productpage-v1-6987489c74-n7q7f 1/1 Running 0 14h
ratings-v1-7dc98c7588-9jdsv 1/1 Running 0 14h
reviews-v1-7f99cc4496-fxmrq 1/1 Running 0 14h
reviews-v2-7d79d5bd5d-m2lvf 1/1 Running 0 14h
reviews-v3-7dbcdcbc56-qbmkz 1/1 Running 0 14h
# 查看 productpage 服務, 端口是 9080
➜ kubectl logs productpage-v1-6987489c74-n7q7f
INFO:root:start at port 9080
* Serving Flask app "productpage" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
INFO:werkzeug: * Running on http://0.0.0.0:9080/ (Press CTRL+C to quit)
INFO:werkzeug: * Restarting with stat
INFO:root:start at port 9080
WARNING:werkzeug: * Debugger is active!
INFO:werkzeug: * Debugger PIN: 808-256-567
# 進入一個容器, 測試一下 productpage 服務
kubectl exec -ti ratings-v1-7dc98c7588-9jdsv -- bash
root@ratings-v1-7dc98c7588-9jdsv:/opt/microservices# curl productpage:9080/productpage |grep -o '<title>.*</title>'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4183 100 4183 0 0 8081 0 --:--:-- --:--:-- --:--:-- 8090
<title>Simple Bookstore App</title>
開啓 istio, 會使用 sidecar
模式自動注入, 最終部署結果如下:
[圖片上傳失敗...(image-ef0c2e-1600779417756)]
PS: 圖中 Envoy
的 istio 的網絡功能組件
- 暴露 bookinfo 應用對外訪問
還是使用官方提供的 bookinfo-gateway
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl get gateway # 驗證網關
NAME AGE
bookinfo-gateway 31s
# 查看 istio-ingressgateway
➜ kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.111.92.66 localhost 15021:30534/TCP,80:31508/TCP,443:31743/TCP,15443:30249/TCP 21h
istiod ClusterIP 10.97.248.42 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP,53/UDP,853/TCP 21h
prometheus ClusterIP 10.97.136.9 <none> 9090/TCP 21h
已經可以從本地通過網關訪問到集羣了, docker desktop 下直接訪問 http://localhost/productpage
即可查看效果
寫在最後
技術在發展, 基礎設施在完善, 編程的世界一直在往前走, 一往無前.
我是 dayday, 讀書寫作敲代碼, 永遠在路上.