仔細一看是打算採用藍綠部署來解決兩個版本之間升級的過渡期
以 Kubernetes 來說,原生沒有支援藍綠部署的機制,所以原生做法大抵上都會跟文章內一致,部署兩個版本並且透過 Ingress/Service 等機制來切換流量,粗暴但可行
如果採用 Argo Rollout 的話可以把這些步驟給簡化並且透過 Portal 的方式一目瞭然目前的更新版本狀況。
若要採用原本 Rolling Upgrade 升級的話,其實也有很多參數需要調整,包含
1. Strategy 裡面的 MaxUnavailable /MaxSurge-> 每次升級同時間可以減少/新增的 Pod
2. TerminationPeriod -> 有些應用程式預設30秒停不住,需要提升以確保關機前已經釋放所有資源
3. PDB -> 平常用不到,但是遇到 Node Drain 機制時也要能夠確保 Pod 不會一口氣被踢掉太多
4. 考慮到多節點跨多區域的情況下,適當的 Pod Affinity 或是 PodSpreadConstraint 可能都需要導入來確保 Pod 的分配是均勻或是如預期的
https://medium.com/@a.j.abbott24/kubernetes-zero-downtime-release-pattern-942223d6bad3
根據華爾街日報 (WSJ) 的報導顯示, GitHub Copilot 努力虧損中,目前使用者付費是每個月$10美金,但是實際上對微軟來說卻是虧損$20左右

Copilot 目前約有 150 萬使用者,所以每個月粗估虧損 3000萬美金

推測也許未來會有 MS 365 Copilot 大概要花 $30 來提供服務以彌補虧損

另外跟文章中想到的 Bing Chat, Bing Image Creator 目前也都是免費的服務,這樣下去應該不久就要全面邁入使用者付費的行列的?

https://www.thurrott.com/cloud/290661/report-github-copilot-loses-an-average-of-20-per-user-per-month
有趣的小專案,幫你掃出所有孤兒資源,特別是那些根本沒有被人用的 configmap, RBAC, PVC, HPA ... 等,不確定目前還有沒有其他的好工具可以瞬間掃出這些孤兒
https://github.com/yonahd/kor
這篇文章是來自 Medium 的官方技術文章,稍微探討了一下其內部如何使用 Kubernetes 的,整體是偏向 high level 的角度,因此不會有太多細節

1. Production 環境是建立於 4 個 AZ 上
2. 使用 Terraform 以及其他內部自行搭建的軟體來管理
3. 使用 cluster-overprovisioner 來提早部署節點以因應服務資源的變動需求
4. 其他細節可以看文章內容

https://medium.engineering/kubernetes-infrastructure-at-medium-d9e2444932ef?gi=531e0733b35c
來自 Cloudflare 的技術文章,非常特別是文章進去有繁簡版本可以直接閱讀

文章摘要為
1. Cloudflare 以 Rust 重新打造名為 Pingora 的 HTTP Proxy
2. 效能比 Nginx 更好
3. 探討 Nginx 原生 worker(process) 運作模式的缺點以及為什麼「重複連線使用」的表現會非常差
4. Nginx 原生的模型不容易客製化功能,採用 Lua 效能不好且非靜態語言
5. 多方考量後決定自行打造一個屬於自己的 HTTP Proxy,採用 Thread 為基礎已達到共有效的共用資源。
6. 結果論: CPU 減少70%, 記憶體減少 67%




Ref: https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/
過往本地開發家打包 Container Image 普遍採用 docker 的方式來打包,而本篇文章則是要介紹一個發展也很久的工具 Buildpacks,比較一下兩者的優缺點以及什麼情況下適合使用 Buildpacks


https://medium.com/itnext/replace-dockerfile-with-buildpacks-f7e435ad2bfc
隨者 Kubeval 本底開發效率降低後而生的新專案 Kubeconform,很多概念都源自於 Kubeval 但是解決諸如 CRD, wirldcard 資料夾等各種問題。


這年代專案來得快也去得也快...今天可以用的東西也許兩三年後就沒人維護了,沒有持續更新很容易就會握者一大堆死去專案, sad

https://github.com/yannh/kubeconform
Google SRE 團隊分享運行 SRE 20 年的 11 條經驗

對 Google 來說,20 年的時間有非常多的架構改變,最初每個 datacenter 大約只有數千台伺服器,其中透過 2.4G 頻寬的網路連結串連彼此。
如今資料中心的規模是過往的一千倍,網路的規模更是一萬倍。

因此該篇文章就細數這段改變以來所學到的經驗

節錄幾個有趣且常被忽略的點
1. Recovery mechanisms should be fully tested before an emergency

備援方案不是紙上談兵,沒有定期維護驗證過的備援方案跟我出嘴喊喊其實差不多


2. COMMUNICATION CHANNELS! AND BACKUP CHANNELS!! AND BACKUPS FOR THOSE BACKUP CHANNELS!!!

溝通設備需要有備案,但是這些備案基本也與上述環環相扣,需要測試才算是真正的備案

3. A single global hardware version is a single point of failure

單一型號的硬體簡化了維運與操作,但是一旦該型號出現大問題,你就慘了
文章舉出 2020 內某網路裝置就出現這種問題

剩下的八個經驗就請自行閱讀囉

https://sre.google/resources/practices-and-processes/twenty-years-of-sre-lessons-learned/
Java 應用程式於 Kubernetes 內的效能問題

眾所皆知,於 Kubernetes 內部署 Java 應用程式很容易遇到關於 startup 階段資源調整的挑戰,應用程式起來時需要一些時間進行暖機來初始化所有資源,這其中應用程式就會落入容器已經部署但是容器還沒有準備好的階段。

Kubernetes 內提供 Startup/Readness 等相關 Probe 來處理不同階段的狀態處理,但是當應用程式配上 HPA 等機制來動態調整 Pod 數量時就可能會遇到「即時新增 Pod 來處理流量,結果新的 Pod 要花久時間才可以處理流量」的情況。

本篇文章作者提及數個關於 JVM 參數來最佳化啟動的時間,同時也提及 ReadyNow Profile log 如何一同協作處理。
以結果來說,整個暖機時間從 1000s 降到 180s,高達 81% 的降幅


Ref: https://medium.com/walmartglobaltech/pod-startup-time-improvements-e2f3fb79751d
這一兩年於 CNCF 領域中看到 Wasm(WebAssembly) 的消息愈來愈多,甚至於 CNCF landscape 中也有一頁介紹 Wasm 生態系的開源專案們(Languages, Runtimes, AI, Tooling, O11y, App framework...etc).

文章從最基礎先探討何謂 Wasm,最後也有介紹如果要於 k8s 生態系中去運行 Wasm 的話要怎麼去調整 CRI 那層的設定,內容雖然很長,但是閱讀完畢會對 Wasm 有更深一層的理解。

Ref: https://medium.com/@seifeddinerajhi/wasm-and-kubernetes-a-new-era-of-cloud-native-application-deployment-b3c59b39f640
Leveraging Cluster API for Production-Ready Multi-Regional Infrastructures

LINE (LY) 於 KubeCon/CloudNativeCon 2023 上的分享,算是基於 ClusterAPI 為基礎介紹內部如何達成控管 K8s Cluster 的生命週期,其中是以 CAPO, CABPK. CACPK 等不同 Cluster API Provider 來處理,分別呼叫 Openstack 以及透過 kubeadm 等工具來快速搭建一套 Cluster,整個邏輯與流程滿適合研究學習的,畢竟整體規模超過 1k cluster


https://static.sched.com/hosted_files/kccncna2023/18/leveraging_cluster_api_for_production_ready_multi_regional_infrastructure.pdf
Code-first vs. Product-first
雖說是多年之前的文章,但是不管什麼時候來看都覺得非常貼切,似乎是這個行業永遠不會消失的討論

文章中闡述目前開發者大抵制上可以分成兩種
1 程式品質優先
2 產品優先

程式品質優先主要著重於程式碼如何架構,採用何種工具框架與程式語言...等各種程式語言相關的考量,而產品優先者來說,也會在意這些程式碼等工具,但是這只是手段,最終還是產品本身能否解決問題,更喜歡看到產品上線後使用者的回饋與反應

作者自身的觀點則是偏向撰寫程式的目的不是為了寫出多漂亮多炫酷的程式碼,反而是解決問題才是重點,但是這並不代表為了解決問題就可以完全不考慮程式碼本身的品質與架構,而是取捨之間都要考慮「一個不能解決問題的產品,其程式本身鐵定不好」

以目前的 Cloud Native 生態來說似乎也會看到類似的概念,基底還沒有完成就著急的將所有各種新知都一路疊加上來,卻忽略自己當初到底想要解決什麼問題,譬如連一個 cluster 都還沒有,就開始考量如果有一百萬個 cluster 時要如何處理各種問題

https://thezbook.com/code-first-vs-product-first
Like LeetCode for Linux

一個適合系統管理員的練習網站,問題分成三個難度並且讓你去挑戰嘗試修復問題,拿來練習訓練彼此對系統熟練度似乎是個不錯的契機?
https://niravshah2705.medium.com/kubernetes-image-pull-optimisation-part-i-exploring-options-f79d79c3fe45

本篇文章探討 Kubernetes 目前內部是如何抓取 Container Image 以及實務上如果想要加速可以有哪些策略去執行。

根據作者團隊的統計結果,以 20 不同應用程式去計算,從 Pod 部署到容器正式提供服務,大概有 57% 的時間卡在抓取 Image,剩下的時間則是給 Probe, Mount Volume, Node Provisioing 等狀態去處理。

因此如果可以改善 Pulling Image 所需要的時間,就可以更有效去產生新的 Pod ,特別是當遇到 HPA 這種需要及時雨的情況。

雖說我們可以透過 ImagePullPolicy:IfNotPresent 來達到使用 local cache 的機制,但是作者提到很多時候新產生的 Pod 要跟舊 Pod 落在同一節點並不是可以保證的情況,因此如何提供更有效的 Image Cache 解決方式也是一個改善整體服務效率的環節。

文內提出不同種方式

1. 平行下載 Image: Kubernetes/Kubelet 預設是採取 Sequencial 的方式去下載 Image,因此新節點上線然後瞬間大量不同 image 服務部署上去時,大家就會輪番排隊,這部分可以透過 kubelet 的設定調整成支援平行處理。此外 kubernetes 1.27 後則支援可以調整最大平行數量來控制平行的行為
2. 透過 Lazy-Loading 的方式,一邊執行容器一邊下載容器: 這部分需要仰賴特別的 OCI 實作,文章提到 AWS 有開源 Seekable OCI 來支援此種操作,而 GKE 也有 GKE image straming 的技術可以達到一邊下載一邊執行
3. Pre-fetch images: 事先抓取好所有會用到的 Image,文章提到可以透過 kube-fledged 開源專案來動態執行,將所有可能會用到的 image 提早先抓到相關節點上
4. 透過 pull through cache 機制來避免每次抓取 Image 都要到外部服務(Quay, Dockerhub)。
Title: 調整資源需求卻不用重啟容器?
Source: https://medium.com/@seifeddinerajhi/the-new-in-place-kubernetes-pod-resource-resizing-feature-a-deep-dive-11b0ece334ef


Kubernetes 內的容器都可以透過 resource.request 以及 resource.limit 來調整 CPU,Memory 等資源設定的需求,而 Kubernetes 1.27 後則正式支援動態調整資源用量的機制,該機制狀態為 Alpha,因此 1.27 的使用者必須要修改 feature gate 來開啟該功能 InPlacePodVerticalScaling 。

該功能允許 Pod 的使用者去調整資源垂直用量調整的行為,目前允許兩種行為, “NotRequired” 以及 “RestartContainer”。 RestartContainer 的行為就是過往的行為,意味當修改 resource.request 或是 resource.limit 資源時會將 Container 重啟以套用新的設定,而 NotRequired 則是不會重啟 Container,能夠動態的修改需求而不影響容器,也就不會造成服務 downtime.

本功能的出現能夠對服務提供更好的資源控管,該功能從設定到啟動大概會需要幾十秒到一分鐘左右的設定時間,對於應用程式來說能夠更有效地去利用資源用量而非寫死一個固定值。此外若此功能逐漸穩定,似乎可以與 VPA 搭配來更有效的縮放資源讓應用程式適應情境並且控管資源成本。
Title: 如何透過兩個簡單步驟減少 Docker build 40% 所需時間
Source: https://medium.com/datamindedbe/how-we-reduced-our-docker-build-times-by-40-afea7b7f5fe7
容器化導入對開發團隊來說一個非常顯著的困境大概就是應用程式部署到環境的流程,為了讓開發者有更好的開發體驗以及減少不同工具帶來的問題,通常都會透過設定好的 CI/CD pipeline 來達到統一的方式,然而這個過程消耗的時間則取決於整個 pipeline 的設計。
對於開發者來說,若是每次測試都要等待數十分鐘,則會覺得浪費時間,有可能乾等或是切換到其他工作,前者虛度光陰後者則有可能會因為大量的 context switch 而導致疲累與無法專注。

因此如何有效改善 CI/CD pipeline 避免開發者等待太久進而降低開發者生產力則是一個不可避免的議題。

本篇文章主要探討如何用兩個概念來提昇 Docker build 的所需時間,其中第一個是牽扯到 buildkit 的用法,透過 buildx plugin 的導入來利用 buildkit 所帶來的各種功能,並且透過 remote cache 的方式來提升整個效率。第二個範例則是藉由新版 Dockerfile 所提供的新語法,改善 COPY 指令所帶來的消耗,過往 COPY 指令會基於前述 Layer 產生一個全新的 Layer,並且最後透過 DIFF 的方式來產生最終 image,而新版則提供 “–link” 的方式來改善實作,透過 link 的概念來實作 COPY 的行為,不需要維護不必要的 layer 進而提升整體建制時間,特別是當使用 multistage 為基礎去建制時會因為大量 COPY 而更有感。
Title: Kubernetes 1.27 引入 Memory Throttling 機制來減少應用程式 OOM 的次數
Source: https://kubernetes.io/blog/2023/05/05/qos-memory-resources/

Kubernetes 過往透過 resource.limit 來控管當 CPU 與 Memory 踩到上限時的保護,而兩者的差異在於 CPU 會被限速(Throttling) 而 Memory 則是會直接觸發 OOM(Out Of Memory) Killer 將應用程式直接砍掉。

而 Kubernetes v1.27 則正式引入全新的功能,該功能為 Alpha 階段,需要於 Kubelet 開啟 MemoryQoS 來使用。
MemoryQoS 的目的是基於 Cgroups v2 的功能提供一層全新的 QoS 保護,該保護會提供類似於 CPU Throttling 的效果,當 Memory 用量超過門檻後,kernel 會開始更積極的回收相關記憶體並且降低應用程式的使用速度避免該應用程式用到滿最後被 OOM 移除。

該功能的使用情境是譬如應用程式可能短時間內會大量使用 memory 且用量很有可能觸發到 OOM,當 OOM 發生時就會造成服務 downtime,而該功能希望能夠減緩消耗量來確保應用程式依然可以服務,並且待時間過後恢復到正常的 memory 使用量。

該門檻的計算方式相對複雜,同時不同 Pod QoS 會有不同設定,若 Pod 本身是 Guarantee 類別,其本身則不會有該門檻的設定,盡量讓應用程式能夠全速運轉。若為 Burstable 或是 BestEffort 兩種類型的 Pod,則會有不同的計算方式來計算該門檻。

官方文章有介紹更為詳細的計算方式以及原理介紹。
Title: Java 應用程式於 Kubernetes 內的 Memory 不如預期
Source: https://medium.com/nerds-malt/java-in-k8s-how-weve-reduced-memory-usage-without-changing-any-code-cbef5d740ad

本篇文章探討的是作者團隊將應用程式轉移到 Google Kubernetes Engine 上後開始遇到一些不好解釋的 memory 使用現象,舉例來說就是不同類型角度的記憶體曲線難以解釋成長
文章的圖表呈現三種曲線,分別是

Pod resource.limit: 也就是上限,只要踩到這個點就會觸發 OOM
Resident Set Size(RSS): 從 OS 角度觀看所使用的記憶體用量
JVM: 從 JVM 角度觀察到的記憶體使用量,包含 Heap, Metaspace 等
(1) 是用來避免記憶體使用過度的保護機制,而 (2)/(3) 則是應用程式運行期間產生的數值,令團隊感到難以解釋的就是 (2)/(3) 的使用量差距很大,幾乎快要到兩倍的差距,應用程式運行久了後 (2) 的數值會逐漸提高最後觸發 OOM,但是 (3) 的使用量一直都很低。

一種解法就是不停的加大 (1) 讓 OOM 的門檻更高,但是這樣的做法就是浪費系統資源,因為 JVM(3) 實際用的量就是不高,無限疊高門檻只是把問題轉移到成本上而已。
為了解決這個問題,作者團隊先重新檢視目前 JVM 的設定,包含

Heap Size (-Xmx)
Metaspace (-XX:MaxMetaspaceSize)
Thread Stackcs (-Xss)
DirectMemory (-XX:MaxDirectMemorySize)
CodeCache: (-XX:ReservedCodeCacheSize)
不同 GC 策略(G1/GC, Shenandoah …etc)
然而各種組合都沒有辦法解決 RSS 的記憶體逐漸提升且是 JVM 角度兩倍的問題,因此團隊花費數個月研究後決定轉往到另一個方向觀察,也就是記憶體配置。
從根本問題來看,OS 覺得 RSS 記憶體就是吃這麼大,而 JVM 覺得吃的不大,如果兩個系統都沒有出錯,說的也都是事實的話,那問題可能就會是記憶體配置的回收問題,因此
開始使用 jemalloc 來試試看。

有趣的是一但使用 jemalloc,上述的問題幾乎就不見了, RSS 的使用量大幅度下降,與 JVM 的用量更為貼近,似乎代表 jemalloc 更能有辦法將記憶體回收給 OS,有了這個發現
開始研究 jemalloc 與預設 glibc 實作的差異,想透過實作差異來理解整個問題的本質

jemalloc 相對於原始的malloc 來說更加強調破碎化的處理,所以作者團隊就從這邊出發開始理解底層是如何去要記憶體空間,以及釋放的邏輯,最後也找到一個有趣的參數去控管 Arena(一個底層內部控管記憶體分享的資料結構)的大小,根據該參數調整後就算是原先版本也可以得到較好的記憶體使用分配。
文章最後也有嘗試使用 TCMalloc 去進行分配,得到的結果與 jemalloc 近乎相同,都比預設的好上不少

全文內容頗長,對 java memory 有瞭解需求的也許可以參考看看
Title: 什麼是 Micro Frontend? 是一種解藥還是又一種 buzzword?
Source: https://newsletter.systemdesign.one/p/micro-frontends

近年微服務(Microservices)隨者容器化的發展幾乎已經變成軟體開發的一種常見模式,然而大部分的微服務都是聚焦於後端伺服器的開發,那前端的部分是否也會有類似的概念?
Mirco Frontend 一詞出現於 2016 年,主要目的是想要探討微服務的架構精神是否也可以運用於前端的架構中?
一個簡單的就是有無辦法講前端頁面中的元件依據功能,或是依據商業需求 (business domain) 拆分成不同的模組,而每個模組都可以有專門的團隊去進行開發與維護,最後的前端頁面則動態的將這些模組載入,因此實務上開發就不需要一組人馬一次搞定全部,而是可以達成像微服務精神一樣各自開發與部署,最後組合出完整的頁面。

然而只要是微服務就會有元件溝通問題,而前端架構中要動態載入這些不同模組大抵上就是 iframe, js, web component 等相關方式,因此文章中也有介紹不同方式的優缺點以及目前相關的框架。

然而微服務帶來的問題勢必也會於 Micro Frontend 身上看到,隨者元件拆分,整個專案變得更為複雜,同時同時載入這些是否會有效能上的問題? 以及所有的 CSS 等相關風格是否一制可能都會導致實作上的困擾。

如同微服務一樣,這類型的架構都需要仔細專研並且確保有益處才需要真的導入,否則只會導入各種缺點卻又享受不到優點,最後就是拿磚砸自己的腳。

註: 下列文章列出近年來有公開宣稱使用 micro frontend 的公司
https://entando.com/page/en/7_successful_companies_using_micro_frontends_en_1