基本上,本文都是範例程式都是使用dotnet core作為範例,因此筆者會基於最簡單的API,開始透過Kong Gateway 進行進出口的各項示範設定。因此,接下來的範例提供,讀者如果希望可以跟著系列文走一回,那會需要準備一些環境,簡列如下:
其他有關於ELK與可觀測性的部分,筆者將透過docker compose 的各項yaml來示範,有興趣的讀者可以跟著筆者操作一回,這樣相信可以收穫滿滿。
範例程式都可以從 山姆大叔的Azure DevOps open source project 取得範例,請不要客氣。
接下來的示範將透過資料夾 ironman2025\case_1\2.api_provider\case_1_onlyapi 下的dotnet core project進行示範,請務必準備好dotnet core 8 sdk。
讀者可以透過右側連結下載 dotnet 8.0 請按我。
既然是API Gateway 的協作,一定要從API開始,首先先來準備這個系列文第一個範例程式,我們建立一個API服務。Open source 中示範的資料夾中是最簡單的API,透過dotnet core 的專案建立了一個基礎的API專案。
在讀者的Visual Studio Code下方的終端機中,切換到 case_1_onlyapi
資料夾。
執行以下指令來還原相依套件並啟動應用程式:
dotnet run
API 將會在本機的 http://localhost:5293
上執行。可以看到下圖執行的畫面:
圖2-1 dotnet run pic
開啟您的瀏覽器並前往 http://localhost:5293/swagger
。您可以直接在此頁面上與 API 進行互動並測試其功能。
圖2-2 Swagger 互動
是不是很簡單?這個專案還包含了使用Serilog 作為Log的留存,因此工程師是不是可以快樂的下班了?畢竟完成了需求單位的需求,提供了可以使用的API使用,而且運行順利,是時候該開香檳慶祝了!
企業中怎麼可能會有如此快樂的故事,當你把程式寫好並且佈署完成,準備要交卷快樂的下班時,就會遇到其他的困境。這個場景就是遇到了,公司要求不能夠直接將IIS 服務上面掛載的API直接暴露在Internet。
公司的理由是,如果今天直接暴露出去,如果遇到惡意攻擊時,公司的資安或是基礎設施團隊,不可能一一去調整每一個IIS服務器,來要求設定例如鎖定來源IP,集中匯出Log的需求。
過往筆者曾經接觸過Web Application Firewall(WAF),但大多數廠商與筆者討論後,都認為其實API類型的服務,無法完全針對API類型的風險進行全面緩解。
在這種情境下,API Gateway這種產品也就如同雨後春筍般的到處冒出來。如果在沒有資源的前提,又需要緩解公司指出的這種合理風險,這時候又是工程師們需要傷腦筋的議題了。
筆者雖說服務於大型金融業中,但其實身上流著的是客家人的血液。只要公司內部有任何建議或是想法,筆者都會希望先透過社群尋找答案。
因此早期在探索API Gateway 產品的時候,看過不少的產品,而且報價都不便宜。筆者都會需要耗費心思去思考要如何比較優劣並呈報高階主管,畢竟一個決定可能都是未來五到十年的巨額花費,不可不慎。
但在各家產品都僅留存在紙本與簡報上時,總是覺得不踏實。因此如果產品具備社群免費版,都會列為筆者第一考量的優先。原因是:
因此,筆者在五年前根據了各方比較之下,選擇了這個產品 Kong API Gateway。
既然上面的痛點是,不允許IIS服務器直接提供給Internet 做連線,因此首先要處理的事情就是,來將dotnet 所建立的API服務放到一個封閉的環境。且在封閉的環境中,透過中介角色 Kong API Gateway 來做為代理連線。
首先可以關注到ironman2025\case_1\2.api_provider\case_1_onlyapi\Dockerfile,筆者準備了dockerfile協助將dotnet api project 封裝到images。因此請執行下列指令:
docker build -t case_1_onlyapi:latest .
上面的指令代表你已經將dotnet core 專案的執行檔,封裝到docker image中。這代表著,服務器透過運行在container中,因此只要在啟動時,將本來要對外暴露的port位給關閉起來,並透過API Gateway 代理呼叫即可。
由於我們需要Kong 協助代理我們做Revert Proxy,因此筆者也設計了一個docker compose檔,請關注到下面檔案位置:
ironman2025\case_1\docker-compose.yaml
檔案簡列如下:
version: '3.8'
services:
kong-dbless:
image: 'kong/kong-gateway:3.11.0.2'
container_name: kong-dbless-readonly
read_only: true
restart: unless-stopped
networks:
- kong-net
volumes:
- ./1.Kong_declarative/declarative:/kong/declarative/
- ./1.Kong_declarative/tmp_volume:/tmp
- ./1.Kong_declarative/prefix_volume:/var/run/kong
environment:
KONG_PREFIX: /var/run/kong
KONG_DATABASE: off
KONG_DECLARATIVE_CONFIG: /kong/declarative/kong.yml
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: 0.0.0.0:8001
KONG_ADMIN_GUI_URL: http://localhost:8002
ports:
- "8000:8000"
- "8443:8443"
- "8001:8001"
- "8444:8444"
- "8002:8002"
- "8445:8445"
- "8003:8003"
- "8004:8004"
case_1_onlyapi:
image: case_1_onlyapi:latest
container_name: case_1_onlyapi
networks:
- kong-net
expose:
- "8080"
# 若有 volume/logs 需求可加下方設定
volumes:
- ./2.api_provider/case_1_onlyapi/logs:/app/logs
networks:
kong-net:
driver: bridge
會注意到這個docker compose 並沒有將dotnet core api 的服務port 透露到Internet,僅有Kong API Gateway 暴露在外,並透過設定的方式協助轉發。
接下來就要來介紹Kong 最簡易的設定。
圖2-3 Kong API Gateway
接下來,請關注到資料夾 ironman2025\case_1\1.Kong_declarative\
下,資料夾結構大概如下:
.
├── docker-compose.yml
├── declarative/
│ └── kong.yml
├── prefix_volume/
│ └── ... (Kong 的執行階段檔案)
└── tmp_volume/
└── kong-file.log
其中先關注到 declarative/kong.yml 這個檔案,簡列如下:
_format_version: "3.0"
services:
- name: example-service
url: http://case_1_onlyapi:8080
routes:
- name: example-route
paths:
- /my-service
plugins:
- name: file-log
config:
path: /tmp/kong-file.log
這段 kong.yml 檔案是用來設定 Kong API Gateway 的service、route與plugin。
在 services 區塊中,定義了一個名為 example-service 的服務,其後端目標 URL 為 http://case_1_onlyapi:8080。這代表當有請求導向這個服務時,Kong 會將流量轉發到這個指定的後端 API。
接著routes 區塊設定了這個服務的路由規則。這裡的 example-route 會攔截所有以 /my-service 開頭的路徑,並將這些請求導向 example-service。這讓你可以用自訂的 URL 路徑來代理後端服務。
plugins 區塊則是為這條route啟用了 file-log plugin。會將經過此路由的請求日誌寫入到 /tmp/kong-file.log 檔案中,有助於日誌記錄與後續的問題追蹤。
接下來,請在 ironman2025\case_1
目錄下,執行 `:
docker compose up -d
你應該會看到下面執行成功的畫面
圖2-4 執行成功
這時候,請勇敢的打開瀏覽器,並連線至 http://localhost:8000/my-service/weatherforecast
,你會發現到,已經成功的透過Kong API Gateway 轉發request 到後端的API了!
圖2-5 執行成功2
好吧~工程師終於可以回家休息一下惹~~