iT邦幫忙

2025 iThome 鐵人賽

DAY 2
0

從程式碼開始

準備事項

基本上,本文都是範例程式都是使用dotnet core作為範例,因此筆者會基於最簡單的API,開始透過Kong Gateway 進行進出口的各項示範設定。因此,接下來的範例提供,讀者如果希望可以跟著系列文走一回,那會需要準備一些環境,簡列如下:

  • 環境準備
    • dotnet core 8 sdk
    • Visual Studo Code
    • Docker Desktop
    • Azure EntraID (JWT 一節將會使用到)

其他有關於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專案。

  1. 在讀者的Visual Studio Code下方的終端機中,切換到 case_1_onlyapi 資料夾。

  2. 執行以下指令來還原相依套件並啟動應用程式:

    dotnet run
    
  3. API 將會在本機的 http://localhost:5293 上執行。可以看到下圖執行的畫面:
    https://ithelp.ithome.com.tw/upload/images/20250914/201628005R5c6r1uHV.png
    圖2-1 dotnet run pic

  4. 開啟您的瀏覽器並前往 http://localhost:5293/swagger。您可以直接在此頁面上與 API 進行互動並測試其功能。
    https://ithelp.ithome.com.tw/upload/images/20250914/20162800NU7Ii2iZZg.png
    圖2-2 Swagger 互動

是不是很簡單?這個專案還包含了使用Serilog 作為Log的留存,因此工程師是不是可以快樂的下班了?畢竟完成了需求單位的需求,提供了可以使用的API使用,而且運行順利,是時候該開香檳慶祝了!

安全性議題:不能透過Internet 直接連線

企業中怎麼可能會有如此快樂的故事,當你把程式寫好並且佈署完成,準備要交卷快樂的下班時,就會遇到其他的困境。這個場景就是遇到了,公司要求不能夠直接將IIS 服務上面掛載的API直接暴露在Internet。

公司的理由是,如果今天直接暴露出去,如果遇到惡意攻擊時,公司的資安或是基礎設施團隊,不可能一一去調整每一個IIS服務器,來要求設定例如鎖定來源IP,集中匯出Log的需求。

過往筆者曾經接觸過Web Application Firewall(WAF),但大多數廠商與筆者討論後,都認為其實API類型的服務,無法完全針對API類型的風險進行全面緩解。

在這種情境下,API Gateway這種產品也就如同雨後春筍般的到處冒出來。如果在沒有資源的前提,又需要緩解公司指出的這種合理風險,這時候又是工程師們需要傷腦筋的議題了。

API Gateway

筆者雖說服務於大型金融業中,但其實身上流著的是客家人的血液。只要公司內部有任何建議或是想法,筆者都會希望先透過社群尋找答案。

因此早期在探索API Gateway 產品的時候,看過不少的產品,而且報價都不便宜。筆者都會需要耗費心思去思考要如何比較優劣並呈報高階主管,畢竟一個決定可能都是未來五到十年的巨額花費,不可不慎。

但在各家產品都僅留存在紙本與簡報上時,總是覺得不踏實。因此如果產品具備社群免費版,都會列為筆者第一考量的優先。原因是:

  • 可以先玩玩看: 筆者是觸感生物:可以先透過有限甚至免費的資源先接觸,感受很重要。
  • 蒐集社群回饋: 如果具備免費版,表示社群中可以看見相當程度的回饋,也可以透過社群知道產品是否成熟。

因此,筆者在五年前根據了各方比較之下,選擇了這個產品 Kong API Gateway

先將API 根據痛點放到封閉環境

既然上面的痛點是,不允許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 最簡易的設定。

Kong API Gateway

https://ithelp.ithome.com.tw/upload/images/20250914/20162800Cnb8lr6C89.png
圖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

你應該會看到下面執行成功的畫面

https://ithelp.ithome.com.tw/upload/images/20250914/20162800uz2ZyZP9Pt.png
圖2-4 執行成功

這時候,請勇敢的打開瀏覽器,並連線至 http://localhost:8000/my-service/weatherforecast,你會發現到,已經成功的透過Kong API Gateway 轉發request 到後端的API了!

https://ithelp.ithome.com.tw/upload/images/20250914/20162800DTNAiBGuTB.png
圖2-5 執行成功2

好吧~工程師終於可以回家休息一下惹~~


上一篇
Day 1:從Kong進入可觀測性世界的緣起
下一篇
Day 3:Kong的基礎
系列文
解鎖API超能力:我的30天Kong可觀測性與管理實戰之旅9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言