7 個 Diagrams as Code 的工具
https://medium.com/@icepanel/top-7-diagrams-as-code-tools-for-software-architecture-1a9dd0df1815


不論是微服務, Kubernetes 或是分散式架構的崛起,如今的軟體設計架構愈來愈追求各種高可用性與效能,整個系統架構設計上趨向複雜,已經不是過往單體式應用程式可以用一兩句話就描述清楚的架構,因此系統架構設計與 review 時如何能夠清楚地將架構展示出來讓眾人有一個共同的概念去檢視就是一個所有簡報者都必須要準備的素材。

文章列出七種不同可以讓你以程式碼的方式去描繪各式各樣 Diagrams 的工具,這些工具有的會使用自行撰寫的語言(DSL),有的則是基於 YAML 等各種格式,再搭配工具就可以將描述檔案給轉換為最後的架構圖,採用 As Code 的好處就是這些架構都可以透過 git 等版本控制的方式來控管,這樣工程師就可以用習慣的方式去保存這些版本的演進,而減少看到各種投影片的 v1, v2, v3 等,同時共同協作上也不會有各種一份檔案到處轉送,最後合併上又遇到各種版本不一致的問題。
從 DB Read 學習 Disk, FS 到 DB table 的互動流程

https://medium.com/@hnasr/following-a-database-read-to-the-metal-a187541333c2


本篇文章從 database read operation 出發,探討一個 DB read 實際上可能會發生的操作,包含
1. DB Table 的大小設計
2. DB Table 的 Cache 關係
3. DB Table 與 OS File System 的關係
4. OS File System 的 Page Cache
5. OS File System 與 Disk 的 Page 關係

這中間流程會有各種不同稱為 page 的術語,從 Disk, OS 到 Table 都有各自的 page,而其大小可能會有 4KB, 8KB, 32 KB 等都不同,所以這些不同大小的 Page 彼此之間是如何運作的,本文章就以比較淺白的方式去解釋流程,理解這些流程對於理解 DB 與儲存設備之間的參數調教會提供一些幫助,以至於不會亂槍打鳥
這兩日最大消息大概就是 nginx 的紛爭了,從這篇文章來看是一位自從 F5 收購後繼續無償幫 nginx 開源版本貢獻與維護的貢獻者因為與 F5 內部有些紛爭,最後這名貢獻者發起了 freenginx 的專案來繼續維持一個開源且免費的 nginx 版本

https://mailman.nginx.org/pipermail/nginx/2024-February/GPXQY27UA5SJJZ2Y6JWTRWJB2TKPTJR7.html
各種適用 Kubernetes 的 IDE


本篇文章列舉幾個對使用者相對友善的 Kubernetes IDE,這類型的工具目的都是提供一個好操作且視覺化的方式讓使用者可以去管理 Kubernetes 叢集。
相較於傳統使用 Kubectl 指令來管理,該指令需要使用者對指令有很好的熟悉程度,甚至很多時候還要使用各種指令組合才有辦法拼湊出 cluster 層級的資料,因此都會看到各種 -o json | jq, -o custom-colume 等各種輸出格式轉換並且搭配後續轉換。
而 dashboard 的目的就是簡化這些操作。

另外要特別注意的是,所有專案的使用是否都有 License(授權) 的條款,很多專案對個人免費,但是對於企業內的使用者都是要額外收費的,很多專案只是一開始沒有很嚴格的取締,但是並不代表往後不會突然收集資料直接索取應該有的授權費用,譬如 docker desktop 其實就是一個很常見的範例。

文內列舉的包含
1. Seabird
2. JET Pilot
3. Headlamp
4. OpenLens -> 大家比較熟悉的可能是 Lens 這個專案名稱,但是 Lens 本身使用上就有 License 的問題要注意,免費版本只有針對個人以及營收小於 10M 的企業而已,其餘情況理論上都是要購買 Lens Pro Enterprise 等相關授權。因此 OpenLens 這個選項才會出現在這邊,也許功能面上會比 Lens 少,但是授權問題會比較簡單。
5. Monokle
6. PyCharm K8s Plugin
7. K9s
8. Kubenav
9. Rancher -> 這個比較不能算單純 IDE,比較像是 K8s 管理工具並且附加的管理介面

https://medium.com/@seifeddinerajhi/explore-user-friendly-desktop-kubernetes-open-source-ides-5315516b0752
https://medium.com/@.anders/learnings-from-our-8-years-of-kubernetes-in-production-two-major-cluster-crashes-ditching-self-0257c09d36cd
本篇文章講述了將 Kubernetes 運行到正式環境 8 年來的心路歷程,最初使用時是於 AWS 上採取自建 Kubernetes 的環境,因為那時候根本沒有 AKS/EKS/GKE 等管理平台,所以可以說採用的時機點是非常早期,團隊於 2018 年開始將環境逐漸遷移到團隊比較熟悉的 Azure 上的 AKS。

這八年來不論是自己管理或是 AKS 的相關經驗學習如下

問題點: Cluster Crash
1. Root CA certificate, etcd/API server certificate 過期導致整個 Cluster 重建,雖然有各種 YAML/Helm 可以重組應用程式,但是卻沒有任何東西去紀錄 Cluster 建立的過程與設定檔案,這使得團隊花了幾天的時間才將整個環境重新打造並上線
2. 上述 Cluster 的重建過程中,使用了 kube-aws 這個專案來幫忙建置與管理,然而該專案那個時期有一個 bug 存在,沒有辦法正確的設定 etcd certificate 的有效期間,於是預設值又是一年,因此一年以後 cluster 又不能動了,不過這時因為有更多的經驗與知識,花了比較少的時間去修復問題,而且不需要整個 cluster 去重建。

上述經驗給團隊帶來的經驗有
1. Kubernetes 很複雜,沒有想像這麼簡單,不是隨時把一個人丟進去就可以學會使用 kubernetes,更別論 debugging 等需要更深入了解的操作
2. Certificate 很重要
3. 統一集中管理 Helm Chart
4. 要有 DR 計畫,更重要的是要測試過這些計畫,而且是時時刻刻都要測試,確保這些工具不會因為版本更新或是等相關架構改變而失效
5. Secret 等相關內容的備份
6. Vendor-Agnostic vs "Go All In": 最初搬移到 AKS 時,為了有招一日可能要搬移到其他的環境,所以很多服務組件都採取使用 open source 自架服務,譬如 container registry, security scanning, auth 等。 團隊最後還是全面切入到 Azure 的服務
,因為發現從開發體驗,維運複雜度,甚至成本來看,其實都更加划算與有感提升
7. 巔峰流量前就要先行 scaling,雖然有各種自動 scale 的機制來調整數量,但是團隊發現這速度太慢,無法應付瞬間高峰的流量。

文章後半部分還有關於 Observability, Security 等相關內容的
淺談 K8s 中那些完全感知不到的 OOM 事件
https://medium.com/itnext/kubernetes-silent-pod-killer-104e7c8054d9


Kubernetes 中的最小部署單元都是 Container,而 Container 大部分情況下都會只跑一隻主要 process 來處理相關請求,因此當該 Process 被 OOM Killed 後都可以於 Kubernetes 的相關 event 或是 metrics 中去觀察到這現象來除錯。

但是假如 Container 中有其他 process,也就是 pid 不是1 的那些 process 被 OOM Killed 的話會怎樣?
從 OS 的角度來說是可以從 kernel log 找到相關事件,但是對 Kubernetes 則是完全無感的,所以你單純從 Kubernetes 的角度出發就沒有辦法收集到任何相關資料,除錯上也就會比較沒有頭緒。

該問題直到 Kubernetes v1.28 並且啟用 cgroup v2 的 grouping 功能,當 container 內有任何 process 被 OOM Killed 後,就會誅九族連帶 main process 一起被砍掉,最後就可以從 Kubernetes 的角度去觀察到這些事件。

至於 Kubernetes v1.28 以前,基本上沒有任何方式可以去觀察與監控這類型事件,只能從
contianer 內自行去監控並且處理。
又一個基於 ebpf 的效能監測工具,這次是由 netflix 所推出的 bpftop,不過監測目標倒不是普通的應用程式,而是所有 ebpf 應用程式,所以才會看到第二欄的 Type 都是針對 ebpf 的各種類型

所者現在愈來愈多 ebpf 的應用程式被掛到環境,特別是 k8s 生態系中,也許這類型的工具可以用來幫助管理員釐清每個 ebpf 的效率問題

不過前提可能是管理員要先懂 ebpf 而不是單純 YAML engineer

https://github.com/Netflix/bpftop
10 個微服務架構下的 anti-pattern
https://medium.com/statuspal/6-best-open-source-status-page-alternatives-for-2024-b68e5a967cc1


微服務架構的構思非常好,希望透過解隅的方式將服務給拆解來達到更彈性且更容易擴充的架構,同時每個服務都可以採用不同的程式語言,中間透過定義好的介面溝通即可。

然而微服務架構下若服務本身的設計不適當,反而會適得其反,使得整個架構變得更難用,因此本篇文章就列舉十個微服務下要避免的架構模式。

1. Monolith in Microservices
2. Chatty Microservices
3. Distributed Monolith
4. Over-Microservices
5. Violating Single Responsibility
6. Spaghetti Architecture
7. Distributed Data Inconsistency
8. Tight Coupling
9. Lack of Observability
10. Ignoring Human Costs
如何於 Kubernetes 打造多階級的 namespace 來更好管理多用戶
https://medium.com/faun/hierarchical-namespaces-in-kubernetes-5b07ea2c3e65
Kubernetes 內建 namespace 的機制來提供輕量級虛擬化,雖然沒有辦法達到如 VM 架構下去隔絕網路流量與相關系統資源用量,但是目前能夠提供
1. 系統 Quota
2. Label/Annotation 供第三方服務使用(如 Istio...etc)
3. 獨立的 RBAC

妥善設計下,可以透過這些機制去管理不同使用者的使用情境,使用者可能是
1. 一個團隊
2. 一個產品
3. 一個部門
4. ...等

隨者使用者數量增大,不可避免的就是 namespace 相關的設定會愈來愈多,同時有很多設定可能本身其實邏輯上是有依賴性的,譬如某個部門底下的團隊的產品,其 Quota 設定上應該會有所規範。這一切的邏輯都可以透過妥善的設定與設計去處理,只是要花不少時間與心力去處理。

本篇文章介紹的 HNC(Hierarchical Namespaces Controller) 是一個第三方服務,能夠將這些 namespace 給串成一個 tree 的架構來達到多節層的管理,來達到
1. 更有邏輯的去管理不同 namespace
2. 自動傳遞相關設定 (parent to child)
3. 簡化 RBAC 的設定
以 Raft 而非 Zookeeper 來搭建的 Kafka Cluster

https://medium.com/itnext/kafka-cluster-without-zookeeper-ca40d5f22304

Kafka 過去安裝需要搭配 zookeepr 來處理
1. Service Discovery
2. Leader Election
3. Broker Discovery
4. Configuration Management
5. ...等

而 3.3 版本後已經內建使用 KRaft 演算法(基於 Raft 改善)來處理分散式的架構,這也意味整個安裝過程不再需要 zookpeer,因此本篇文章就是基於這個概念來分享其架構以及安裝使用過程。
如何使用 eBPF 來偵測到 Kafka 叢集的效能問題

https://blog.allegro.tech/2024/03/kafka-performance-analysis.html


文章探討團隊使用 Kafka 的效能問題,團隊的 Kafka 每秒大概會有 300k 的訊息產生,同時有 1M 訊息被處理。
大部分情況下,所有的 request 都可以 ms 等級內解決,但是系統卻有長尾效應,P99 的結果大概要 1 秒鐘,而 P999 則需要 3 秒鐘。

整篇文章則是探討整個除錯過程,包含從初期的 tcpdump 去分析,後期導入 eBPF 針對更細部的去分析,最終找到問題跟節點上的檔案系統 (ext4) 有關,特別是某些操作會花費過多的時間去等待 lock 導致整個時間被拉長。

文章內最直得學習的就是如何導入 eBPF 這類型的工具來幫忙偵測這類型問題,而不是像過往一樣不知道如何下手
不常見但是可以幫助開發效率的 Git 指令與功能
https://martinheinz.dev/blog/109


本篇文章介紹一些自從 2010 後所被開發出來的 Git 指令。
大部分開發者慣用的指令幾乎都是都是早期版本就有的指令,包含 chcckout, stash 等,而隨者 git 後期的開發,實際上有愈來愈多的指令與功能被開發出來改善效率,譬如文章中介紹的
1. switch
2. restore
3. sparse-checkout
4. worktree
5. bisect

這些指令都有適合的情境,譬如同時有多個 branch 需要開發,或是一個 monorepo 的檔案過大,每次 checkout 都要花費大量時間等,因此花一些時間研究一下這些新的指令說不定可以加速日常工作流程
大名鼎鼎的 Brendan Gregg 最近發佈了一篇文章提及系統上應該要有的除錯工具,從 CPU, Memory, Disk 到 Network 應有盡有

這些工具可以從下面的 package 安裝,文章內有更詳細每個 package 會提供哪些工具,以及大概可以處理什麼樣的資訊

procps, util-linux, sysstat, iproute2, numactl tcpdump, linux-tools-common, bpfcc-tools, bpftrace, trace-cmd, nicstat, ethtool, tiptop, cpuid, msr-tools


https://www.brendangregg.com/blog/2024-03-24/linux-crisis-tools.html
Kubernetes 內各種 GC 介紹

https://medium.com/overcast-blog/kubernetes-garbage-collection-a-practical-guide-22a5c7125257


寫應用程式的都聽過 Garbage Collection(GC) 的行為,而 Kubernetes 也是有類似這種行為的操作,目的都是清除用不到的資源,避免系統資源超載甚至影響整體效能。
文章提及三種相關的 GC,分別是
1. Container Image Garbage Collection (節點上的 Container Image 用量超過硬碟用量,需要 GC 移除以免之後踩到 Disk Pressue 導致 Node NotReady)
2. Evicted Pod Garbage Collection (觸發 Evicted 而被移動的 Pod 雖然會消失,但是對 etcd 來說還是會有一個狀態為 evicted 狀態的 Pod,可以從 etcd 中釋放用不到的資源)
3. Orphaned Resource Garbage Collection (Kubernetes 內的狀態很多有相關依賴性,有些會透過 owner reference 來連結這些物件,某些情況下可能資源刪除沒有完整,導致有一些資源其實已經用不到,但是當初其老爸被刪除的時候沒有把這些產物給一起刪除,最後就是 etcd 記錄了一些用不到的物件)

除了概念介紹外,也有分別介紹每個類別的實作方式。
Kubernetes 節點效能調校分享
https://medium.com/overcast-blog/kernel-tuning-and-optimization-for-kubernetes-a-guide-a3bdc8f7d255


本文章主要探討若要讓 Kubernetes 節點能夠有更好的效能,要如何從 Kernel 方面去針對 網路/檔案系統/記憶體/CPU/行程排程 等這些方面去設定 Kernel 參數,並且每個參數所帶來的效果有哪些,此外也有提到設定的前提是要先有足夠的指標監控系統,透過系統長期觀察每個參數帶來的效果才算是有效的調整,否則如無頭蒼蠅般的設定並不算是真正的瞭解系統。
文章內列舉的參數包含
1. net.core.somaxconn
2. net.ipv4.tcp_max_syn_backlog
3. net.ipv4.ip_loacl_port_range
4. vm.swappiness
5. vm.overcommit_memory
6. vm.dirty_background_ratio
7. vm.dirty_ratio
8. fs.file-max
9. fs.inotify.max_user_watches
10. kernel.sched_migration_cost_ns
11. kernel.sched_autogroup_enabled

此外 k8s 過往是不支援 swap 的,需要 1.22(alpha), 1.28(beta) 後的版本才可以開啟 SWAP,文章中提到的 CPU Affinity/Management 的 YAML 我自己看起來是完全達不到 CPU affinity 的用途,畢竟該功能需要仰賴 Guarantee QoS 的 Pod 且 CPU StaticManager 要有開啟才有辦法,否則預設情況下 Container 的 CPU 是無法由固定 CPU 處理的。
Title:
Netflix 分享跨地區的網路效能除錯經驗
Source:
https://medium.com/@netflixtechblog/investigation-of-a-cross-regional-network-performance-issue-422d6218fdf1


Netflix 團隊中遇到一個跨地區的網路問題,Client Application 團隊初期覺得是網路問題,因此請網路團隊幫忙除錯,網路團隊藉由錄製封包等行為觀察出下列現象
1. Client 已非常固定的時間,啟動 30 秒後就會自己發送 FIN 去關閉連線
2. 檢查 Client & Server 的封包,發現 Server 回傳的封包都有順利送到,沒有任何 Packet Loss 的現象

由上述觀察,網路團隊認為問題應該是 Client Application 本身,因為是 Client Application 自己關閉網路連線的,但是檢查了一下,發現
1. Client Version
2. Server Version
3. Network Infra
上述三個版本短期內都沒有變動,甚至 Server 還是一年多前的版本,然後有觀察到 Client 內有設定一個 Timeout 30 秒的時間,若時間內沒有辦法收完資料就會關閉連線。

最後團隊開始懷疑這個問題是由 Kernel 導致的,經過一連串的實驗與觀察,最後發現這個問題真的跟 Kernel 升級有關,使用舊版本 6.5.13 的時候, Client 只要 22 秒就可以送完資料,但是升級到 6.6.10 的時候則需要 39 秒,就會超過 timeout 導致斷線。

文章最後有詳細解釋原因,主要是跟 TCP Receive Windows 的計算方式改變有關,有興趣的可以閱讀全文
CNI 效能評比 2024 版本

https://medium.com/itnext/benchmark-results-of-kubernetes-network-plugins-cni-over-40gbit-s-network-2024-156f085a5e4e


作者先前於 2018,2019,2020 都有撰寫過相關的 CNI 分析,而這次 2024 也針對當前的 K8s 1.26(RKE2), Ubuntu 22.04 再次進行了效能分析。

首先要先針對 CNI 進行挑選,作者根據下列性質挑選出數個 CNI 解決方案
1. 12 個月內有 commit 更新
2. 跟廠商/硬體無關
3. 非 Meta CNI(Multus)
4. 最好支援 Network Policy
5. 好安裝於 K8s 上

因此選出來的評比對象分別是,其中每個又有特別強調使用的設定
1. Antrea 1.15.0
2. Calico 3.27.2
3. Canal 3.27.2
4. Cilium 1.15.2
5. Kube-OVN 1.12.8
6. Kube-Router .1.0

環境:
1. Supermicro 的機器
2. Supermicro 40Gbit switch
3. 以 DDAC SFP+ Cable 相連
4. 大家都同 VLAN,設定 MTU 9000

測試的面向非常多,包含
1. Pod to Pod
2. Pod to Service
3. TCP/UDP
4. Single Stream/Multi Stram
5. ...等
為什麼系統架構這麼難
https://medium.com/@ozanani/software-architecture-is-hard-71fe3ddafb60


作者敘述自己有一段時間一直被附近施工的聲音吵醒,因此起了搬家的念頭,為了確保搬家地點不會被施工聲音給干擾,於是作者去尋找該施工相關的文件報告,一看發現對方文件寫得非常清除,未來三年的施工計畫,每個地區估計的時間點都寫得非常明瞭,即使完全不懂都市工程的人都有辦法輕易閱讀。

作者就開始思考,那為什麼軟體架構方便則沒有辦法這麼清晰地去描述?
原因可能有
1. 團隊內負責架構設計的人能力不均
2. 大家對於架構的理解不同,撰寫出來的內容與抽象層度也不一定完全相同
3. 對於非功能面的理解,如 Reliability, Security. Privay, Scale 等不同,因此撰寫的東西也都不同

而過往很常見的作法則是採取 Top-Down 的架構,團隊內會有一個專職的架構師,由該架構師去進行統一的架構設計與規劃,底下的工程團隊根據敘述與藍圖進行施工,這種運行模式下,架構師基本上就負責整個架構權責,包含設計與文件等。
然而現在逐漸有另外一種 Bottom-Up 的運行模式,採取的是去中心化的架構設計分案,讓團隊內所有的工程師一起設計架構,一起完善整個系統,而並非由單一的架構師說了算。

這種流程下,團隊內不同經驗的工程師會負責的不同的領域,譬如比較資淺的可以負責較小的元件設計,而資深的工程師則會設計更大的範疇。該流程希望可以達到
1. 讓所有工程師一起學習成長
2. 提升每個工程師對該專案與的掌握度
3. 消除單點故障(架構師)的影響
4. 團隊內共享更多知識

然後說得好聽實作難,實作上可能會遇到
1. 經驗不一的人設計出來的架構品質不一致,團隊內可能最後會產生出四不像的架構
2. 設計流程過多,不同人的接受程度不同。譬如整個流程過於繁瑣且過大的負擔,可能會讓工程師花費更多時間在處理這些設計而非真正的實作,反過來則有可能根本沒有涉獵過多設計,所料想的優點一個都沒有,因此尺度拿捏上非常難。

作者最後介紹了 C4 Model 的實作範例,推薦所有團隊都先嘗試基於 C4 Model 來描述自己系統的架構,先熟悉這種描述的方式以及理解分四種模型對於整個文件與架構帶來的幫助,熟悉後對於後續的各種流程才會加速並且更游刃有餘。
Kubernetes 網路概論詳解

https://medium.com/devops-dev/networking-in-kubernetes-5bc2d574fd95


本篇文章巨細彌遺的解釋 CNI (Container Netwowrk Interface) 這個標準的用途,從最早期的 Docker 到後期 Kubernetes 這不同架構下是怎麼看待容器網路建置這件事情說起。
以 Kubernetes 來說,每個容器的網路基本需求就是
1. 一個不衝突的 IP
2. 能夠跟同節點上的 Pod 互相存取
3. 能夠跟不同節點上的 Pod 互相存取,且最好不需要經過 SNAT 與 DNAT

三個簡單的需求實作上有各種不同的可能性,因此 Kubernetes 則是專心使用介面,將所有的實作都下放給不同的專案,譬如 Cilium, Calico 等。
文章中以 Weave Network 為範例,以 weave network 的 CNI 探討上述流程的運作以及 Kubernetes 與 Kubelet 是如何設定 CNI 來幫容器設定所有網路功能的。
Kubernetes 1.0 發展之路回顧

https://itnext.io/kubernetes-the-road-to-1-0-525a9420fdf0


今年是 Kubernetes 發展十週年,世界各地都有相關的慶祝活動,本篇文章作者作為當初 Google 內部 Kuberetnes 開發人員之一,就以自己的記憶跟大家回顧 Kubernetes 誕生期間的種種發展。

1. 網路上最常見到的說法是 Google 內部 Borg 專案為 Kubernetes 的前身,但是作者認為更精準的說法應該是 Omega 才對, Omega 作為 Borg 的繼任者,改善更多使用上與操作上的問題,最後才順水推舟將一切好的設計保留到 Kubernetes 上。
2. Labels/Annotation 等概念設計都不是 Borg 一開始就有的,都是內部使用者回饋出來的機制,內部使用者希望透過一些方式以邏輯的方式分類物件,最終才產生這些設計
3. 最早期是採用 Task 來描述運算資源,後期才改為 Pod
4. 初期沒有 Kubelet 的設計,都是由 Kube-Proxy 直接跟 etcd 溝通取得相關計算
5. 節點最早期稱為 minion,後期才改名為 Node
6. ...等,文章內還有許多發展初期的討論