寫在前面
很多neter都有在用Ocelot做Api閘道器,但是Ocelot又不像kong或者其他閘道器一樣,開箱即用。它需要你單獨開一個web專案來部署,這樣很多同學都在做重複的事了。
這裡[Hei.Ocelot.ApiGateway] 就把這件事給做了,以後有同學要用的話可以單獨拉下程式碼來部署,或者docker/k8s直接部署就好了(這是我的計劃,後續怎麼做可能要看我自己的需求,我們公司內部部分專案也用);
--大家也可以當成一個ocelot的demo哈,畢竟沒什麼程式碼量。
基於此,本文目標讀者是對Ocelot有初步瞭解的同學。
專案地址:https://github.com/gebiWangshushu/Hei.Ocelot.ApiGateway
怎樣跑起來
專案結構很簡單:
Hei.Ocelot.ApiGateway 是主角,是我配置好的Ocelot閘道器;
Hei.Api 是閘道器測試用的Api;
Hei.IdentityServer 是測試用的IdentityServer,給部分自己沒準備好IdentityServer的同學體驗的;
裸機(Host)直接部署
直接clone專案下來,按需分別跑起來就行;
docker、docker-compose部署
1、clone專案下來,配置好 /Hei.Ocelot.ApiGateway/config 下的appsettings.yml;
2、把這個整個config目錄拷貝到 /home/heidemo/config (因為我demo裡面掛載在這個目錄);
3、去專案根目錄執行docker-compose up
(docker-compose.yml就在根目錄,你可以註釋掉你不想啟用的service)
k8s部署
1、deploy.yml下載到本地,修改檔案後面的ConfigMap節點,這部分是配置,含義跟其他部署方式一樣;
2、執行kubectl apply -f deploy.yml
;
我自己部署的
Hei.Ocelot.ApiGateway 閘道器地址:http://172.16.3.117:5000
Hei.Api地址:http://172.16.3.117:5003
Hei.IdentityServer地址:http://172.16.3.117:5100
通過閘道器訪問下我的HeiApi:
http://172.16.3.117:5000/user、http://172.16.3.117:5000/WeatherForecast
OK,美
我們講下各個功能怎麼開啟,隨便簡單聊聊怎麼用。
啟用Admin Api 管理配置
Ocelot 有一堆的配置https://ocelot.readthedocs.io/en/latest/features/configuration.html,Ocelot 支援在執行時動態改配置,Ocelot 提供了對應的Rest Api 修改即時生效。不然每次改一點點配置都要找運維挺麻煩的;
對應的Rest Api是用IdentityServer保護的,可以直接配置用已搭建好的IdentityServer或者用Ocelot內建的IdentityServer,用來做這個Api的授權。我們實現的是前者;
開啟配置
appsetting.yml加上以下配置即可啟用:
Administration:
Path: /administration #這裡是admin api的目錄
IdentityServer:
Authority: http://172.16.3.117:5100 #IdentityServer地址
ApiName: ocelot #這些是我配置好在IdentityServer裡的
RequireHttpsMetadata: false
ApiSecret: secret #這些是我配置好在IdentityServer裡的
使用
1、先去IdentityServer申請token
POST http://172.16.3.117:5100/connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
2、去Hei-Ocelot-Gateway 查詢配置
GET http://172.16.3.117:5100/administration/configuration HTTP/1.1
Authorization: Bearer token
紅框中的就是步驟1申請的token。
3、更新Hei-Ocelot-Gateway 更新配置
POST http://172.16.3.117:5100/administration/configuration HTTP/1.1
Authorization: Bearer token
我發現這個admin Api配置好的配置,重啟後又會復原為初始化狀態,不知道是不是Bug。生產謹慎使用或有管理工具每次更新備份好再用。
整合IdentityServer做服務授權
你的閘道器後面有很多服務,某些服務安全性較高的話可接入IdentityServer做服務授權。
開啟配置
appsetting.yml
IdentityProvider:
- Authority: http://172.16.3.117:5100
ApiName: ocelot
ApiSecret: secret
RequireHttpsMetadata: false
2、ocelot路由配置
然後使用前面搭建好的Admin Api,或者你用的是配置檔案,加上以下Routes:
{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [{
"Host": "172.16.3.117",
"Port": 5003
}],
"UpstreamPathTemplate": "/protect/{url}",
"UpstreamHttpMethod": ["Get", "Post", "Put"],
"AuthenticationOptions": {
"AuthenticationProviderKey": "ocelot",
"AllowedScopes": []
},
"RouteClaimsRequirement": {}
}
3、測試
我們再次訪問,http://172.16.3.117:5000/user 的受保護路由 http://172.16.3.117:5000/protect/user
申請token
再次訪問
服務發現
Ocelot 支援Consul和Eureka做服務發現,基本能滿足我們日常需求;
Consul
開啟配置
1、appsetting.yml
GlobalConfiguration:
ServiceDiscoveryProvider:
Host: 172.16.3.119 #這是我配置在其他機器的consul agent,生產用的一般會在本機配個agent
Port: 8500
Type: Consul
2、ocelot路由配置
首先要求你們的服務要註冊到Consul,這裡我自己註冊了一個叫MessageApi
的服務;
加上以下Routes:
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/consul/{url}",
"UpstreamHttpMethod": [ "Get", "Post", "Put" ],
"ServiceName": "MessageApi",
"LoadBalancerOptions": {
"Type": "LeastConnection"
}
}
這樣你訪問閘道器 http://172.16.3.117:5000/consul/ 就能訪問到對應服務了;
Eureka
開啟配置
1、appsetting.yml
Eureka:
Client:
ServiceUrl: http://localhost:8761/eureka/ #你的eureka
ShouldRegisterWithEureka: false
ShouldFetchRegistry: true
2、ocelot配置
GlobalConfiguration:
ServiceDiscoveryProvider:
Type: Eureka
3、測試
略,eureka環境給我刪了,今天懶得搭了,如果需求強烈,我加上。
K8s支援
ocelot是支援k8s的,如果你啟用k8s,那它在k8s叢集裡的角色比較接近於“ocelot-ingress”吧;然後我用的是
<PackageReference Include="Ocelot.Provider.Kubernetes" Version="16.0.1" />
16.0.0 有點問題,直接用
AddKubernetes()
訪問總會報錯,我換了種方式實現;
開啟配置
開啟前你肯定要搭建好k8s叢集了;
1、ocelot配置
GlobalConfiguration:
ServiceDiscoveryProvider:
Type: Kube
NameSpace: dotnetcore #這是我自己部署的HeiApi的名稱空間,你的如果你的api有多個名稱空間可以在路由裡配置
2、ocelot新增路由
{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/kube/{url}",
"ServiceName": "hei-ocelot-api",
#"Namespace": "dev", #比如這裡你的這個路由對應的serverName不是dotnetcore,你可以這樣配置
"UpstreamHttpMethod": [ "Get" ]
}
3、測試
我們來訪問我們剛剛新增的路由對應地址: http://172.16.1.30:31500/kube/user (之所以換了地址是因為我剛剛172。16.3.117那臺機沒搭k8s環境)
大家也看到服務發現和k8s(在ocelot這裡也是一種新式的服務發現)都在配置GlobalConfiguration:ServiceDiscoveryProvider: 下面,那Consul和eureka和k8s是互斥的,都有配置的話優先順序consul>eureka>k8s
總結
我大概看著自己的需求實現了部分需要單獨引用擴充包才能啟用的功能,但是還有部分功能未有實現,比如Caching、Tracing這些(大家可以修改測好後直接提pr,我不是懶得寫而是測試麻煩,懶哈哈)
同樣,不需要引用包,單獨配置就可以啟用的功能,都一一保留著,比如
- 限流
- 服務熔斷降級
- 求求合併
- 請求頭轉換等等
參考
https://ocelot.readthedocs.io/en/latest/
專案地址
https://github.com/gebiWangshushu/Hei.Ocelot.ApiGateway (喜歡的話給我點個星~~)