在Day2的文章中,筆者簡單的說明了kong
的service
與route
的關係,不過到目前為止的範例中,都僅用一個service
搭配一個route
的作法來示範。不過前面其實也同樣說到,其實一個優秀的API Gateway,應該要能夠協助開發人員降低重工的可能性。
前面非常多的示範,都圍繞在如何透過各種認證、授權或是可觀測性的三本柱,來協助開發人員可以降低其負荷。今天的個案則是準備要介紹,要如何透過不同的route
達到共用service
的觀念。
共用service
的優點是,可以降低開發人員要重複開發的重工事項,與先前不同的地方是,今天不只能讓開發人員每個系統不須重新刻劃認證、授權或是Log蒐集。而是直接透過共用API Service
的方式,卻可以滿足不同的需求。
這代表著,開發人員可以更專注在各種商業價值的開發上,而這些可以被API Gateway
完成的工作,就外包過來。進而達到開發人員的賦能,持續的讓他們交付具備商業價值的產出中。
另外,既然已經完成周遭可觀測性三本柱的建置,DevOps另外一個最重要的組成也應該要被完成,那就是 CI/CD的部分。CI/CD大多數起跑點都是以開發者所撰寫的程式到佈署維運作為重心,而從另一個視角則會從IaC(Infrastruct as Code)的持續佈署作為實踐。
筆者這次系列文之所以使用無資料庫(DB-Less)模式,使用declaretive yaml
實踐的目的,有很大一部分也是希望將這些設定檔,用code
的方式將其留下。過往的經驗中,非常常遇到今天連續調整了很多步驟之後,就忘了原本前次設定的組態。
變更管理的目的都是為了服務可以持續維運,而服務不會僅有運作中的API
,其實連路徑上其他的服務端點應該都要被包含進去,這都是為了能夠達到持續提供服務所做的一系列管理手段。今天開始的故事,將與團隊討論如何解決新的難題,另外也將帶入使用Azure DevOps Service
對整個環境希望可以做到的變更管理。
就在新服務case_ELK_JPG_AuthZN_weather
推出並提供試用後,終於開始收到新的業務合作對象的訂單了。但是這次是在嚴苛的金融相關行業的請求,團隊正在討論業務帶回來的規格,特別是對於更為嚴苛的認證授權規範這塊,讓大夥討論的更為熱烈。
Lala:你們看,給別人試用的API
服務,終於要出頭天了,因為終於有合作對象願意採買,雖說是按請求數計價的,但是至少是一個新業務的展開。
Aries:不過你們看這部分,[為確保本行資訊安全,所提供之服務須經安全性連線外,認證授權機制之機敏資訊需可供定期輪替,並確保逾時後授權失效之機制....]。不過我們目前好像都使用apikey
搭配ACL
作為主要的認證授權機制,這樣是不是不合規?
Sam:老實說,依照apikey
的方式,對於定期輪替的這個部分,還可以滿足,但逾時後授權失效的確就不行了。
Lala:以前在寫網頁時,通常會用session timeout
的方式來滿足這條。不過API與網頁不同,沒有瀏覽器的前提,我暫時無法想到要如何完成這個任務。而且還有個問題,同樣的程式我們是不是要複製一份丟到docker compose
去?不然現在的服務已經被trial
的這些試用者占去使用了,不可能有了業務合作對象,就把這條試用的路關掉吧?
Aries:你說的對,這樣感覺有點蠢,好重工的味道。
Sam:我喜歡這場討論,非常技術人。沒事的,我們有優秀的kong
可以協助我們完成這次的任務,而且可以不讓我們重複佈署同樣的程式碼到不同位置。要是到處都客製然後又佈署一份,這樣就不是在做產品了,讓我來跟你們說明要如何完成這次的任務。
Sam:再來就是,我們的產品既然已經進入到要提供外部客戶使用,這表示需要提供一定的服務等級保證(SLA),我提議先將kong
相關設定也列入我們變更管理的範疇,自動化套用與檢查一定可以協助我們團隊更快速與穩健的應對變化。
Lala:你是指將kong
也納入Azure DevOps Service
作為版本控管,然後用pipeline
來進行佈署嗎?這聽起來好像不錯,反正團隊已經使用的很習慣了。不過Pull Request
的時候,我可能對這段的設定不熟,沒辦法給太多建議喔。
Sam:這沒關係,團隊本來對於各自開發的項目就各有專長,不可能精通所有事情。只要大腦裡有個印象,我曾經看過某個工作項目被交付,事發當下有機會回頭去找出線索這就夠了。
Aries:聽起來挺酷的,那我們從哪裡開始?
Sam:變更管理好了,我們先來建立大家的工作環境,就跟那些可觀測的工具一樣。完成了這些建置,才能夠讓我們更無後顧之憂的努力開發。
筆者今天先跳出前面都以各式各樣程式碼與指令的主軸,要先來介紹與建置在Azure DevOps Service
那些關鍵要素,以及要如何思考IaC
的佈署與檢查這些事情。
圖 20-1 Azure Repos
既然是要將設定檔都變成Code,那就一定要先提到在Azure DevOps Service
存放程式碼的功能,就是Azure Repos
。Azure Repos
提供了兩種版本控管模式,包含主流的git
以及TFVC
,本系列文皆以git
作為版本控管的示範方式。
首先要讓讀者先考慮一件事情,請問你是否有曾經思考過,應用系統的程式碼要與IaC的code放在同一個repo嗎?。筆者對於這件事情思考過好一陣子,最終筆者認為不應該。
首先先看一下大多數筆者看到的團隊對於程式碼的協作與分支控管策略,可以參考到圖20-2。
圖20-2 常見程式碼分支控管策略
這是一種經典作法,特別是在傳統的vm可以看到的分支對應不同環境的CI/CD
行為。不過可以注意到的是,這種分支管理的做法,是為了讓開發人員可以根據不同的分支,在佈署階段可以進行各種開發與測試行為,而對照到常見的不同開發階段,例如 Dev/SIT/UAT/Prod。
開發人員對於那些環境,基本上是解耦合且抽象的概念,他們只需要知道例如,應用系統需要一個AD認證授權、需要資料庫進行存取就夠了。
但對於基礎設施而言,或許在企業所定義的環境中有被區分為Dev/SIT/UAT/Prod的這些環境,但實務上這些都是獨立存在不同環境的設施,而不是一一不同的階段。
就舉kong
設定中有一個plugin
叫做IP Restiction
,簡單列出設定如下就好:
plugins:
- config:
allow:
- 10.10.10.0/24
deny: null
message: null
status: null
enabled: true
name: ip-restriction
protocols:
... 以下省略 ...
這一段設定檔可以看到,這是一份白名單,代表在這個10.10.10.0/24
的網路區段中可以被許可存取。相信一般企業中,都會用不同的網路區段代表不同的zone,因此10.10.0.0/16
可能是測試環境,而正式環境可能就會是10.20.0.0/16
的區段。
如果是根據上面的常見的分支合併管理模式,勢必要在這份yaml中進行抽象化,例如把IP那段變成 #{Enterprise.Tpe.IPZone}#
,當整份yaml被過度抽象化之後,執行前的可讀性就會非常的低,進而開始容易犯錯。
因為基礎設施同仁無法在變更管理前進行直觀的審查,造成必須要佈署之後,根據錯誤訊息才能夠回頭去確認哪一段設定失敗了。這樣最終反而會增加認知負荷而造成更容易犯錯。
因此,筆者認為對於Infrasture as Code
的管理方式,除了要跟應用系統的程式碼切開以外,也應該要根據不同的環境進行實體的切分,並以各個實體以檔案描述,僅需將必須的secret
(看各公司政策)進行抽換即可。
例如下面資料夾結構,可以看出來各別不同環境被以資料夾的形式隔開,各不同的執行個體,都有其設定檔。
當然,這些都以預設分支(通常就是main
)作為主要變更管理協作分支。
.
├── pipelines/
│ ├─── Prod_kong.yaml
│ ├─── UAT_kong.yaml
│ ├─── SIT_kong.yaml
│ └─── ...其他pipeline yaml
├── Prod/ #同SIT 結構
├── UAT/ #同SIT 結構
├── SIT/
│ ├─── grafana/
│ ├─── Kong_declaretive/
│ ├─── prometheus/
│ ├─── docker-compose.yaml
│ └─── otel-collector-config.yaml
└── Readme.md #完整的結構說明文件
補充:其實各種論點都有,筆者在企業中也是有其他論點認為本來就要抽象化,這樣在不同環境才可以做到完整的驗證。筆者認為沒有所謂的絕對對的論點,但各種實作都應該要以降低認知負荷且減少
人犯錯的機會
為前提去設計為佳。對於筆者常接觸的
Infrastructure
人員來說,過度抽象一直都不是他們習慣的工作模式,因此筆者才以這種形式來建議變更管理與協作的模式。或許讀者會有不同見解,也歡迎分享與回饋。
圖20-3 Azure Repo:IaC_Demo
讀者可以使用示範專案路徑:ironman2025\case_ELK_JPG_Route_HMAC\Iac_Demo作為Azure Repos的範例匯入。
本次筆者匯入的repo name 為Iac_Demo
。
既然筆者已經決定要使用各別目錄區隔不同的環境,用檔案代表每一個環境的不同服務個體,那就可以在Azure Repos
將儲存庫建立起來,讀者可以參考圖20-3。
要注意的是,筆者通常在Repo
底下的Readme.md檔案,最少要有一些關於這個儲存庫主要存放內容的說明,通常會包含目錄結構,個檔案名稱代表的意義等。一個Repo代表的可能是企業中某個服務的儲存庫,可能是應用系統也可能是資源的描述,這些Readme.md是為了未來要閱讀的人而撰寫,包含未來的自己。
今天筆者也囉哩囉嗦寫了一大堆,明天將進入到佈署環境
以及自動化流水線
的設定,還敬請期待,明天見~