ref: https://blog.mozilla.org/en/internet-culture/deep-dives/why-are-hyperlinks-blue/
本篇是一個歷史科普文,幫大家介紹為什麼瀏覽網頁內的超連結會是藍色的?
千萬不要想到超連結就覺得一定是 Netscape,從本文的歷史角度來看 Netscape 連前五都不算呢

作者從 2001 年就開始撰寫網頁,一直以來都沒有去思考為什麼超連結是藍色的,直到朋友某天的詢問才讓頓時傻住
這個自己視為理所當然的東西實際上必定也是某個發明,是什麼時候被決定的?誰決定的?為什麼決定是藍色的?

與同事一起找尋的結果是 Marc Andreessen and Eric Bina 於 01/23/1993
所發佈的 Mosaic(馬賽克) 瀏覽器是第一套提供藍色超連結功能的瀏覽器。

時間點來看的話
1. 1964 Project Xanadu 是第一個嘗試透過實體連結將兩個頁面的系統
2. 1987 第一套瀏覽器 WWW 誕生
3. 1993 第一個使用基於藍色的超連結瀏覽器出現
4. 2016 Google 開始嘗試將超連結顏色改到黑色

研究出這些歷史痕跡後,作者依然對於為什麼是藍色這件事情沒有著落
很多人都說因為對比色的緣故,所以超連結選則藍色。
作者認為 W3C 直到 1994 才出現,所以那之前所謂的標準都還沒有被定義,此外從對比的角度來看,藍色與黑色的對比程度是2.3:1,實際上也不是說多好。

作者後面從不同角度去思考出一個結論
1. Cello/Mosaic 假設它們的設計都受到該年代 UI 設計潮流的影響
2. 該年代是 Windows 3.1 崛起的日子,而 Windows 3.1 也是第一個重度使用藍色作為選擇色的系統(網頁中有展示 windows 3.1 中很多選擇都會呈現藍色)
3. 隨者支援色彩的電腦螢幕普及,Mosaic 也一起受歡迎,使用藍色的超連結逐漸變成一個習慣,因此此後的 IE/Netscape 等也就沿用這個藍色的設計。

對於歷史考古文有興趣的可以詳細閱讀全文
ref: https://lwn.net/Articles/853637/

如果對 SO_REUSEPORT 這個能夠提供網路服務吞吐量的 socket options 不陌生的話,那這篇文章強烈推薦看看。
本篇文章是從討論開啟 SO_REUSEPORT 這個選項會出現的一些行為以及可能可以怎麼做

最直得看的應該是留言區本身,有很多不同層級的討論,大家最愛講的 Google SRE 人也都出來分享自己的經驗了。


正常情況下,每個 TCP Port 只能被一個 process 給使用來聽取封包,但是對於一些網路重度使用的系統來說,就算讓該 process 將連線給分散到其他的 process 去處理,該 process 依然可能是系統的效能瓶頸。
Linux Kernel 3.9 後引入的 SO_REUSEPORT 參數就是為了解決這個效能問題而來的,這個參數允許多個 Process 同時使用一個 TCP Port,每當底層有一條新的連線請求時, Kernel 會從眾多的候選人之一中挑選一個可用來處理。
這種情況下,網路應用程式就可以專心處理連線工作,然後實務上同時執行多個 Process 即可。底層的 Kernel 會幫忙做連線的負載分配。

當眾多候選 process 其中之一掛掉了(可能是 crash,也有可能是有意的重啟), kernel 會注意到這個候選人要說掰掰,這候選人處理的所有 connection 都會被移除,比較糟糕的是其他待在 Accept-Queue 那些還沒被建立連線的連線請求也會一併被移除。
作者認為 Kernel 應該要有能力可以轉移那些 Accept-queue 中的連線到其他還工作的候選 process 下去處理,這樣使用者/Client 的連線就不會需要處理太多重連的問題。

文章後面都在探討可行的做法以及這個問題可能會導致什麼問題。

留言區滿熱鬧的,譬如說
1. 有人認為 server 重啟的情況實在太少見,有需要為這麽少見的情況導入這麼複雜的修改到 Kernel 中?
a. 有人回答使用 Let's Encrypt 你可能每幾週就要重啟一次。
b. Google SRE 回答其內部因為調整設定的緣由,幾乎無時無刻都需要重啟服務,不過這問題已經從別的層級去處理掉,所以修改 Kernel 對他們的用途不太大。
2. 有人提出 Nginx 本身有 live migration 的功能,可以將 fd 給轉移到其他的 process 去處理。
a. 有人提出這邊談的是 socket/connection 的層級,這些東西都還沒發生到 userspace process 同時也不是 userspace 應用程式可以接觸處理的。
b. 本文探討的是 bind(), accept(), listen() 這類型 function call 之間 kernel 會幫忙做的事情。

有興趣的別忘了閱讀留言區
ref: https://wiki.bash-hackers.org/howto/redirection_tutorial
本篇是個 Linux 相關的教學文,專注於透過視覺化的方式來教學到底 shell 上常常使用的 >, 2>&1 等差異是什麼。
舉例來說,你能不能清楚的說出下列兩種用法的差異,實際上 fd 到底會怎麼運作?
1. > file 2>&1
2. 2>&1 > file

亦或是某些 shell script 常看到 exec 2>log 到底是什麼意思?

本篇文章解釋得非常清除,透過 /dev/pts 這種 pseudo terminal 為起點,將 0(stdin), 1(stdout), 2(stderr) 三個 fd 給視覺化呈現。
基於這個概念開始探討下列不同指令實際上 fd 會有什麼變化

# Simple Redirections
">" 應該是最為簡單也最廣為人知的用法,command > file 的方式將輸入(stdout)給導入檔案(file)。
那加上數字後會有什麼變化呢? 譬如 command 1>file, command 3>file ?

下一個不能不知的就是 pipe 的概念,透過 pipe 能夠組合出各種指令來解決問題,到底 pipe(|) 的過程中這些 fd 是什麼變化?

# More On File Descriptors
另外一個很常被問到的用法就是,有沒有辦法將 stderr 跟 stdout 一起 輸出?
這時候可能就會看到 1>&2 2>&1 等各種答案,那到底這些語法的背後是什麼意思?

非常推薦所有人都仔細閱讀這篇文章重新複習/學習這類型操作的底層變化。
ref: https://medium.com/sailpointtechblog/improving-on-call-engineering-at-sailpoint-35213090c35c

本篇是一個經驗分享文,Sailpoint 想要探討疫情後整個團隊是如何重建並且改善 On-Call 的整個運作模式。
因應 COVID 帶來的職缺變化,愈來愈多的遠端工作者加入到 SailPoint 的團隊中,整個 DevOps Team 的人數也因此整整翻了一倍。

過往的 on-call 流程基本上沒有什麼受到太多重視與關注,並且一直以來都運作的很好,但是隨者團隊人數與專案數量的提升,當前的運作方式只能用堪用來說
因此需要重新審思如何改善,加強整體效率。

SailPoint 之前的 On-Call 是使用 PageDuty 這套服務來處理的,因此團隊想要看看是否這中間還可以有改善的空間
不論是新的流程或是 PageDuty 有什麼功能是團隊還沒有妥善使用的。

Baby Steps with PagerDuty
PageDuty 有個名為 PagerDuty Virtual Summit 的年度盛會,作者團隊決定參加盛會來聽看看有什麼功能是目前沒有好好使用的。
除了 Digital Operations Tier 這個更加智慧甚至提供基於 machine learning 的相關控制功能外,作者團隊還學到了關於 Slack
的新整合功能,有鑒於整個團隊愈來愈趨向遠端協作, Slack 的使用也就變得愈加重要,因此團隊優先的將 Slack 整合該新功能。


Feature Rich Proof of Concept, A Short Story
1. 作者團隊於會後積極的聯繫 PageDuty 的團隊,想要針對各項新功能進行更多的探討與使用,這方面 PageDuty 也很積極的幫忙建立 PoC 環境與回答各種問題,讓團隊可以試用這些新功能
2. 第一個嘗試的功能是針對團隊的 RDS Alert 的智慧處理功能。過往當 DB 出現問題時 Cloud Watch 就會出現高達 60 多個相關 Alert,透過新的智慧功能這些 alerts 會被辨識為一個單一意外,就不會遇到 Alert 洗版的現象
3. 過往 RDS Alert 出現時,每次都要針對那些 Alert 一個一個的去 acknowledge,現在因為全部都統一辨識為單一 Alert,因此 acknowledge 也只需要執行一次,整個效率大幅度上升, on-call 的工程師可以花更多時間去專注解決問題。
4. 下一個嘗試的功能就是全新的儀表板,該儀表板顯示了 alerts 的趨勢變化與相關參數,這些資料讓該團隊每週的 on-call 會議有更多的資料去檢視過去一週的情況,藉此可以找到團隊中比較脆弱容易出事情的服務。

文章中還有兩個章節探討剩下的改善,對於 On-Call 有經驗也有興趣的人別錯過全文。
ref: https://www.infoworld.com/article/3632142/how-docker-broke-in-half.html

這篇文章是作者訪談多位前任/現任的 Docker 員工,Docker 社群貢獻者, Docker 消費者以及市場分析師的相關心得文,目的是想要探討 Docker 商業模式的成功與失敗,到底目前 Docker 商業模式的進展是否有跡可循,以及我們可以從這些歷史決策中學到什麼?

Docker 不是輕量級虛擬化技術的開創者,但是卻是個將 Container 這個技術給推向所有開發者的重要推手,Docker 簡化的整體的操作使得每個開發者都可以輕鬆的享受到 Container 的好處,但是從結果論來說, Docker 還是於 2019 年 11 月給 Mirantis 給收購了
到底 Docker 的商業模式哪一步走錯了,接下來就跟者作者一起去訪談與思考。

[Docker 的誕生之路]
Solomon Hykes(文章很多該人看法) 於 2008 年創辦一間專注提供 Platform as a Serivce 的公司, DotCloud,該公司希望讓開發者可以更簡易的去建置與部署開發的應用程式,該公司的底層技術後來也由 Docker 繼續沿用,當然創辦 Docker 的依然是 Solomon Hykes。
Docker 開源專案誕生之後吸引了全球目光,除了來自各地的使用與開發者外,大型公司如 Microsfot,AWS,IBM 等都也加入,但是就跟其他基於開源專案的軟體公司一樣, Docker 也面臨的商業模式的問題,這種類型的軟體公司到底要如何穩定獲利?
從 2021 往回看,一個很簡短的說法可以說是 Docker 的企業化管理工具 Docker Swarm 還沒有站穩腳步之時就遇到 Kubernetes 這個龐然怪獸,然後 Kubernetes 橫掃時間把所有 Docker Swarm 的市場全面清空,
當然真實版本一定更加複雜得多,絕對不是一句 Kubernetes 就可以概括的

[開源專案的商業化之路總是困難]
Docker 於 2014 年開始認真探討其商業策略,如何將其作為 Container 領頭羊的角色轉變成為一個可以帶來收入的策略,VC 創投的資金讓其有能力收購 Koality 與 Tutum,同年 Docker 也正式宣布第一個商業版本的支援計劃。
這一連串的計算誕生出了許多產品,譬如 Docker Hub 及 Docker Enterprise.
不過可惜的是上述的產品並沒有辦法從企業用戶手中帶來穩定的獲利,大部分的客戶相對於直接購買 Docker 解決方案,更傾向跟已經合作的系統整合商一起合作。

Solomon Hykes 今天夏天跟 infoworld 的一次訪談中提到,Docker 從來沒有推出一套真正的好的商業產品,原因是因為 Docker 並沒有很專注地去處理這塊需求。
Docker 嘗試每個領域都碰一小塊,但是卻發現想要同時維護一個開發者社群又要同時打造一個良好的商業產品是極度困難的, Dockre 花費大量的時間與金錢想要魚與熊掌兼得,但是最後才體會到這件事情幾乎不太可行,Hykes 也認為 Docker 應該要花更多時間去聆聽用戶的需求,而不是自己埋頭苦幹的去打造一個沒有滿足使用者需求的企業產品。

來自 Google 的開發推廣大使 Kelsev Hightower 於今年的訪談中提到,Docker 成功地解決問題,但是卻遇到了瓶頸,舉例來說,Docker 提供工具讓開發者可以 產生 Image, 提供地方儲存 Image,運行 Image 除了這些之外, Docker 還有可以發展的空間嗎?
Hykes 不贊同這個說法,譬如 RedHat 與 Pivotal 都很成功的將 Docker 整合到彼此的 PaaS 產品(OpenShift, Cloud Foundry),也成功從中獲利,所以 Docker 實際上有很多方式可以去獲利的,只是沒有成功而已。

從結果論來看, Docker 早期的商業夥伴,一家專注於 Travel 的科技公司, Amadeus 於 2015 年正式跟 Docker 分手改而投向 RedHat 的懷抱。
畢竟 RedHat 有提供更多關於 Container 相關的技術支援,畢竟對於一個想要踏入 Container 世界的企業,如何將應用程式容器化是第一步,而接下來則是更為重要的 Container Orchestration 解決方案,很明顯的 Docker 這個戰場上是完全被 Kubernetes 打趴的。

[Kubernetes 的決策]
從結果來看,Docker 拒絕擁抱 Kubernetes 是一個致命的錯誤,Jérôme Petazzoni, Docker 第一位也是目前在位最久的員工分享到, Docker 內部曾經針對 Kubernetes 去探討,認為 Kubernetes 架構過於複雜,而 Docker Swarm 的架構應該使得 Docker Swarm 更為成功。
事實上, Docker 曾經是有機會可以跟 Google 內的 Kubernetes 團隊一起合作發展的,並且有機會去掌握整個 Container 生態系的發展,如果那時候同意這些發展,那 Docker GitHub 底下的第一個專案可能就會是 Kubernetes。

Hykes 承認的說,那個時空背景(2014,2015)下, Docker 公司很難找到一個很好的 Container Orchestration 解決方案來滿足各種各戶的需求,而那時候的 Kubernetes 也很難斬釘截鐵的說就是那個解決方案, 畢竟那時候 Kubernetes 還非常早期,同時期還有很多開源專案,很難料想到
Kubernetes 最後會主宰整個 Container Orchestration 世界。

文章後半段還有非常多的討論,非常推薦大家去看全文,雖然沒有辦法改變歷史,但是從歷史中可以學到非常有趣的東西,特別是當被客戶問到 Docker/Kubernetes 的一些生態問題時,有這些歷史資料的可以讓你講起來更有迷之自信
ref: https://blog.kubecost.com/blog/kubernetes-labels/

本篇文章是一個 Kubernetes Label 介紹文, Kubernetes 的使用者一定都知道 Kubernetes 內的物件很大量依賴 Label 的使用,最基本的用法就是
Deployment 與 Pod 之間是透過 Label 與 LabelSelector 互相溝通的。

Kubernetes 提供兩種不同的方式來為資源打上標記,分別是
1. labels
2. annotations

兩者都是基於 key/value 的方式來設定,不過用途是完全不同。 Label 主要是用來提供辨識的功能,讓使用者可以透過 key/value 的方式來辨識當前的資源,就如同前述提到的 Deployment 與 Pod 的關係。
透過 Label 來標示 Pod,而 Deployment 則透過 LabelSelector 來選擇符合標準的 Pod。

Label 主要有兩大用法
1. Grouping Resource for Queries
2. Bulk Operations.

第一種用法就是前述提到的,將一群資源透過 Label 給標記起來,另外一個則是透過 kubectl 等指令操作時,可以一口氣操作多個資源,譬如
kubectl delete deployment -l environment in (dev,sit)
上述資源可以一口氣將符合 environmnet=dev 以及 environmnet=sit 的 deployment 給一次刪除。

文章中還列舉了其他介紹與學習 Labeling 概念的網站,最後還提到一個使用 Label 上要注意的相關事項
1. 不要將一些會一直改變的資料放到 Label 中
2. 沒有任何理由的話,不要輕易去修改運行資源的 Label 內容
3. Label 本身的設計不是一個 data store,所以不要將一些 Application 的重要資料給存放到 Label 上

對於 Label 這概念想要更深理解的可以參閱全文
ref: https://www.cncf.io/blog/2021/09/01/chaos-mesh-2-0-ga-to-a-chaos-engineering-ecology/

Chaos Mesh 2.0 於 07/23/2021 正式 GA 了,團隊期盼透過這次 2.0 的釋出能夠讓整個 Chaos Engineering 的生態性更加茁壯與蓬勃發展。

Chaos Mesh 一直以來的目標就是讓 Chaos Engineering 能夠更輕易地進入到每個管理者的 Kubernetes 叢集, 2.0 則是這個目標路上的一個重大里程碑,
歷經一年左右的開發與努力, 2.0 主要有三大改進
1. 簡化使用的困難性
Chaos Mesh 透過一套基於 Web 的管理介面 Chaos Dashboard 讓使用者可以輕易地去檢視目前所有的實驗與內容,而 2.0 更是簡化整體操作,
界面更加簡潔同時也可以觀看每個實驗的詳細資訊。
針對不同的雲端業者環境,也支援 AWSChaos/GCPChaos 等不同的環境設定,確保所有的 Kubernetes 測試都能夠更加一致。

2. 強化 Chaos 實驗的自動調度功能
實務上來說,一個單一的實驗沒辦法有效的模擬各種測試環境,因此很多時候都需要人為操作的介入,為了讓這一切更加流暢與自動,Chaos Mesh 過往整合了 Argo Workflow 來協助調度各種實驗。
不過後來團隊發現 Argo Workflow 並不是一個非常適合描述 Chaos 實驗的工具,因此 2.0 版本重新實作了 workflow 的機制,這次的機制是原生支援而不需要仰賴任何第三方解決方案。


3. 支援更多 Injection 的類型
從 2.0 開始, Chaos Mesh 開始支援如 JVMChaos, HTTPChaos 等不同的測試目標。
JVMChaos 用來針對 Java/Kotlin 等使用程式語言撰寫的應用程式,而 HTTPChaos 可以攔截 HTTP 的封包並且竄改內容

此外針對實體機器部分,Chaos Mesh 則是開發了一個名為 Chaosd 的來模擬各種環境問題,譬如砍掉 process, 模擬網路問題,模擬 Disk 問題等

對 Chaos Engineering 有興趣的可以試試看
ref: https://kubernetes.io/blog/2021/09/03/api-server-tracing/
該文章介紹的是 Kubernetes v1.22 所推出的新功能,該功能目前還是屬於 Alpha 階段,這意味要打開該功能則必須要從 Feature flag 下手打開

該功能非常簡單,就是讓 Kubernetes API Server 支援 Tracing 的功能,讓管理者可以透過 Tracing 的工具去檢視 API Server 之間的 Tracing 資料。

分散式系統的環境使得除錯非常困難,每次問題發生時都要針對一個又一個的元件去檢查,找看看每個元件的 log,甚至可能還需要開啟 debug log 的選項才可以
看到更仔細與直接的內容。而 Distributed tracing 就是用來解決這種情境的,而 Kubernetes API Server 又是 Kubernetes 叢集內最重要的核心元件,
因此 Kubernetes 的 SIG Instrumentation 群組目標就是讓各位管理員能夠更輕易地透過 Tracing 去理解當前 API Server 的狀態。

這次的解決方案是基於 OpenTelemetry 的框架去使用的,文章範例中使用 Jaeger 作為 Backend 的 UI 來顯示 API Server 間的 tracing 資料。

從 Observability 的角度來看,能夠透過 Tracing 觀察與監控 Kubernetes 叢集本身的狀況對維運人員來說是一個滿好的工具,不過該功能目前於 v1.22 都還是 Alpha 的版本。
因此對於大部分的使用者來說應該都還是沒有辦法測試該功能,特別是使用 Kubernetes Managed Service 的使用者來說,估計可能還要再等上一段時間才會變得內建支援。
ref: https://medium.com/srivatsan-sridharan/cracking-the-engineering-manager-interview-faqs-94dcfdf38ef

這篇文章是作者分享關於 EM(Engineering Manager) 面試相關的討論文,作者先前已經分享過一系列關於 Engineering Manager 面試的一些經驗
有滿多網友表示之前系列文的分享讓他們有一個方向去準備這類型的面試,而成果也是非常的好。
因此作者寫了最後一篇來分享面試的一些心得與想法

包含下列主題,本文就針對幾個主題進行介紹,對於有興趣的讀者別忘了參閱全文
How important are the technical interviews in the EM interview loop?
Do I need to practice Leetcode to crack the coding rounds?
What if I don’t have relevant experiences to answer situational or experience based questions?
What if I’ve never had to let go of someone from my team?
How much detail should I go into when talking about a situation?
When asked about my weaknesses as a manager, what should I say?
How do I answer the question — what is your management philosophy?
What are some failure modes or traps to watch out for?

How important are the technical interviews in the EM interview loop?
1. 非常重要,雖然大部分情況下 EM 可能沒有太多寫程式的機會,但是沒有技術背景的人是要如何管理一群技術人?
2. 相對於單純寫 Code,技術架構的瞭解更為重要
3. 技術能力與領導經驗哪個更為重要還是要看公司,沒有一定答案,找工作的時後請先好好問一下 recruiter 這些小細節

Do I need to practice Leetcode to crack the coding rounds?
1. 具備 Leetcode medium 等級的能力即可,除非該公司期望 EC 職位的人也必須要從事 IC(Individual Contributor) 或是非常小心創的 Tech Head。不然大部分情況不會遇到太複雜的演算法題目
2. 更多的情況會是詢問如何使用一些基本的資料結構或是解決簡單的演算法問題
3. 主要是判斷你是否有能力將實際的問題轉換為程式碼,是否能夠讀懂,理解與除錯程式碼
4. 忘記 function/語法沒關係,畢竟會面是這個職位的近期程式寫的比較少是可預期的。最重要的還是思路,如何將問題的解法給描述出來

What if I don’t have relevant experiences to answer situational or experience based questions?
1. 這個是非常常見的問題,特別是剛踏入 EM 生涯道路的面試者,本來就很難有太多的範例與經驗去回答這些需要時間累積的問題。
2. 作者推薦誠實的告訴面試官自己這方面經驗不太多,然後可以針對這個範例去探討假如你未來遇到的話,你可能會怎麼面對之類的。

What if I’ve never had to let go of someone from my team?
1. 這是個非常常見的問題,但是就跟前述問題一樣,如果沒有這方面的經驗就誠實以對
2. 可以改從團隊中有人績效不太好為替代方式去探討,講述自己之前的管理哲學與處理方式
ref: https://www.hwchiu.com/ping-implementation.html

本篇文章是難得的自產文章,該文章分享一下自己觀察不同 ping 指令與不同發行版本下的實作方式,主要探討的點是 ICMP 封包是如何產生的。
就我目前認知,目前至少有三種常見方式來設定 ping 指令讓其能夠順利收送 ICMP 封包。
常見的 TCP/UDP 應用程式實際上都是讓 Kernel 幫忙處理底層的 L3/L4 封包,使用者的應用程式則是專注於資料的交換與處理,簡單的說法就是專心處理 L7 資料。
但是 ICMP 封包不同於上述的 TCP/UDP 封包,一種方式就是透過 RAW Socket 的形式自行去拼湊組裝 ICMP 格式,自行處理一切封包的處理。
RAW Socket 本身也不允許每個使用者都能輕易開啟,必須要有相關的權限才可以執行,因此一種 PING 的實作方式就是透過 SetUID 的方式,讓所有能夠執行 ping 指令的使用者會短暫瞬間提權變成 Root 的身份
也因為是 Root 就可以順利的開啟 RAW Socket。
SetUID 強大且方便,簡簡單單就可以讓使用者瞬間變成 Root,但是也因為簡單好像就安全角度來看會覺得不太嚴謹,畢竟我想要的只是一個能夠開啟 RAW Socket 的權限,你去把整個 Root 都送給我。
因此第二種實作方式就是透過 Linux Capability 來達到更細緻化的權限控管,讓任何可以執行 ping 指令的使用者都可以短暫獲得 cap_net_raw 的權限,最終順利的開啟 RAW Socket
而第三種方式則是跳脫的權限的概念,與其透過 RAW Socket 來自行打造 ICMP 封包,不如讓 Linux Kernel 幫忙處理 ICMP 封包,ping 的程式只要跟 Kernel 要求建立一個基於 ICMP 協定的 socket 即可。
透過第三種方式最終可以達到 setuid-less 的架構,ping 的應用程式再也不需要任何的特殊權限,每個使用者都可以順利執行來收送 ICMP 封包。

文章內會針對三種方式進行實驗跟觀察,對 PING 指令有興趣別忘了參考看看
ref: https://www.cncf.io/blog/2021/09/03/kubescape-the-first-open-source-tool-for-running-nsa-and-cisa-kubernetes-hardening-tests/

本篇文章是一個專案介紹文,該專案是個名為 Kubescape 的安全性掃描專案,該專案主要是用來檢驗目標 Kubernetes 是否能夠通過 NSA/CISA 等安全性檢查。

National Security Agency(NSA) 以及 Cybersecurity and Infrastructure Security Agency (CISA) 最近有發佈一個高達 52 頁的安全性指南,
該指南探討如何設立與強化 Kubernetes 叢集的安全性。
https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF

而 Kubescape 專案是一個基於 OPA(OpenPolicyAgent) 引擎的安全性檢查專案,該專案會從 Kubernetes API 取得各類型 Kubernetes 專案的資訊並且針對這些資訊去進行檢查。
檢查是基於上述 NSA/CISA 發布的安全性報告,該檢查的類別包含

1. Non-root containers
2. Immutable container filesystem
3. Building secure container images
4. Privileged containers
5. hostPID, hostIPC privileges
6. hostNetwork access
7. allowedHostPaths field
8. Protecting pod service account tokens
9. Pods in kube-system and kube-public
10. Resource policies
11. Control plane hardening
12. Encrypted secrets
13. Anonymous Requests

有興趣的可以試試看這個專案
ref: https://levelup.gitconnected.com/why-full-time-programmers-are-decreasing-faster-than-ever-ad67d2697bbf

本篇文章是作者的個人發想文,其透過 StackOverflow's 的年度調查觀察到全職工程師的比例正在逐年下降,從 2019 年的 84.20% 到 2021 年的 80.68%。
相反的是今年的統計有高達 11.21% 的人表達目前自己是 independent contractors/freelancers。

作者認為以下原因導致全職工程師的數量有愈來愈低
軟體工作有逐漸往 印第安/孟加拉/巴基斯坦移動的趨勢
1. Indian Developer 與 US Developer 的薪水差距大概有 5-15 倍
2. 軟體開發是一個可以遠端學習與練習的技能,因此有愈來愈多的公司開出基於短期簽約的工作給印第安/孟加拉等地區的 freelancers。
3. 目前全美大概有 440 萬的工程師,不過估計印度 2023 年就會有高達 520 萬的工程師
4. 印度/南亞會有愈來愈多的簽約工程師

COVID 的全球影響
雖然 COVID 對全球的生態都產生了巨大改變,不過對於工程師來說的影響並沒有其他行業這麼巨大。
根據 Hackreator 的調查,其他行業大概有 20% 的人因為疫情而沒了工作,而工程師大概只有5%不到。
不過要注意的是因為疫情的變化,整個數位產生都有極具的改變,因此也有很多新的職缺因應產業變化而誕生

Freelancers 數量逐漸提高
從 StackOverflow 的調查來看, Freelancers 的數量從 2019 的 9.5% 提升到 2021 的 11.2%。
根據 Upwork's 2017年的調查報告,全美擁有世界最多高達 5800萬的 Freelancers,幾乎佔了全美工作人力的 36%。
Google 本身雇用的 Freelancers 數量甚至也已經超過其全職工作者的數量,大概佔了 54%。

公司想要節省成本。
大部分的公司都不太需要一個長期的全職工作者,很多專案都沒有後期維護與更新的需求,因此相對於雇用長期的全職工作者,雇用短期的 Freelancers 更能夠節省公司
成本。

作者最近才幫某個大公司玩了一個非常非常小的專案,完成該專案後每個月可以獲得 $500 美金的維護費用,作者表示該專案小的幾乎沒有什麼維護需求,就是一個被動收入而已。
文章作者也有分享 LinkedIn 於 2018 分享的文章
該文章中指出
1. 70% 的中小型企業都有與 Freelancers 共事過
2. 參與過的中小型企業中,有 83% 表明這些 Freelancers 的確對公司是有幫助的,而 81% 表明可能會繼續僱用來處理其他專案

預測
作者認為因應遠端工作這一年多的變化,後兩年應該會有愈來愈多的工程師轉為獨立工作者。過往招僱長期全職工作者的一個主要目的就是可以一群人一同於辦公室內激發出高效率的生產模式。
隨者遠端工作逐漸證明 Work From Home 也能夠帶來相對應的高產出,作者認為有不少公司可能會開始考慮雇用 Freelancers 來完成短期專案。

不過作者認為工程師們也不需要太擔心,只要掌握好自己的技能,其實這類型的趨勢不會影響太多。
ref: https://www.hwchiu.com/cncf-tech-radar-multicluster.html

這篇是 CNCF 科技雷達六月份的調查

這次題目為 Multicluster Management,主要想要探討 CNCF 團隊是如何管理多套 Kubernetes 叢集的。

不過 RADAR 團隊將結果分成兩類,分別是 Cluster Deployment 以及 Core Services/Add-ons,前者主要探討如何去管理與部署 Kubernetes Cluster,後者則是探討當前述的 Cluster 搭建完畢後,接下來會部署哪些核心服務來提供更上層的使用者去使用。

結論大概是
1. 多叢集管理目前沒有一個銀色子彈可以一統江山,不同環境與需求都有各自的一片天
2. 社群目前很期待 ClusterAPI 的茁壯發展,希望能夠減少更多客製化的需求與複雜度。
3. 眾多社群工具一起結合來解決問題,特別觀察到 GitOps 最常搭配 Helm 使用,而 Operator 的解決方案也很常透過 GitOps/Helm 的方式給部署到叢集中
4. Operator 真的很棒

詳細內容可以參閱全文
ref: https://vivek-singh.medium.com/system-design-cheat-sheet-318ba2e34723

本篇文章是一個筆記文,紀錄關於 System Design 路上常遇到的架構與元件,譬如
1. LoadBalancer
2. Caches
3. Queues
4. Configuration Service
5. API Gateway
6. Service Mesh
7. CDN
8. Cassandra
9. Snowflake
10. Numbers

每個概念都還會附上一些相關影片與文章,也因為是個筆記內容,因此每個元件的介紹都不會非常詳細,都是小小段落介紹每個元件的最基本概念。
譬如 LoadBalancer 的筆記有
1. L4/L7 兩種的差異
2. AWS 上 ELB/ALB/NLB 的三種差異
3. LB 的演算法, Round Robin,Weighted RR, Least Connection/Response Time/Resource based 等

Caches
1. 實作有 Memcached, Redis 等相關專案
2. 什麼時候會使用 Memcached:
a. 需求簡單,譬如單純 Key/Value 字串,可以輕易地透過調整 cores/threads 來調整效能。
b. Volatile,沒有儲存機制
c. 只有 LRU 的 Cache 演算法
d. Key 最多 250B, Value 最多 1MB
3. 什麼時候使用 Redis
a. 需要儲存 object,而非單純 string
b. 支援多種演算法
c. 支援 data store,可以達到 non-volatile 效果
d. 可以支援 Set/Hash/List/Sorted Set 不同型態

這類型的文章對於踏入 System Design 能夠提供一個簡易的入門介紹,先有哪些類別需要學習,再針對每個類別獨立學習也是一個不錯的學習路徑。
ref: https://faun.pub/kubernetes-is-the-future-of-infrastructure-but-whats-the-future-of-kubernetes-c7446531df51

本篇文章是個 Kubernetes 探討文,作者認為 Kubernetes 的發展已經勢不可擋,想要探討有哪些不同的領域未來能夠跟 Kubernetes 並肩作戰來面對各種不同環境,譬如說
1. Micro VMs
2. Unikernels
3. No/Low-code containerization and orchestration platforms
4. Security improvements on Kubernetes
5. Lightweight Kubernetes distributions
6. Kubernetes for edge and IoT
7. Kubernetes multi-cluster management will be easier using some tools

以下針對這幾個類別簡單摘要

# Micro VMs
作者認為 AWS Firecracker 是目前這個市場上最受歡迎的解決方案,透過以 VM 的形式取代傳統的容器,讓 Kubernetes 的容器能夠有更加安全與隔離的環境,
此外,由 Weaveworks 所推出的 VM 管理專案 Ignite 也是需要注意的,其透過基於 Container 般的管理模式與 GitOps 的更新方式,讓管理者可以更方便地管理這些微 VM
最後提到 slim 這個能夠基於 Dockerfile 產生出 Micro VM 的解決方案,對於這個領域有興趣的都可以參考看看

# Unikernels
不同於 MicroVM 是希望能夠產生一個更精準符合應用的小 VM, Unikernels 更像是 Container 與 VM 的混合體,不同於過往需要與 Host 共享整個 Kernel, Unikernel 會針對每個應用程式準備一個非常小型的 Kernel
該 Kernel 只擁有最基本的運算資源以及運行應用程式所需要的所有依賴函式庫與相關套件。
也因為有這個小 Kernel 的架構,所以 Unikernel 的應用程式跟 Host 可以是完全不同的 OS,畢竟不需要共享 Kernel,此外整體的安全性也會因為非共用 Kernel 而比 Container 更好。

# No/Low-code containerization and orchestration platforms
隨者雲端架構的複雜化,愈來愈多 DevOps/Cloud 工程師探討有沒有辦法讓整個工作流程更加簡單,使用更簡易的方式來設計與管理工作流程。

譬如 ShuttleOps/CloudPlex 等宣稱要達到 no-code 的平台解決方案所述,希望能夠透過拖拉簡易的方式來設計各種 CI/CD 流程。
ref: https://thenable.io/monorepos-will-ruin-your-life-but-theyre-worth-it

本文「Monorepos 可能會摧毀你的人生,但是值得!」 是作者分享自己對於 Monorepos 的看法,一直以來 monorepo 與 multi repo 兩者之間的討論都沒有停止過,每個團隊都必須要思考要使用哪種架構方式,同時團隊還有 CI/CD 流程要跑時,到底要如何符合當前架構去執行。

Monorepo 使用單一 repository 來存放多個應用程式的產物,包含各種版本,部署資源以及應用程式本身。作者認為 monorepo 的架構針對特定問題來說是個非常漂亮的解法,但是就如同人生一樣,計算機科學的領域其實也是各種優缺點妥協而來的。
Monorepo 有其價值,勢必也會有其不擅長的領域與時機。

以 NodeJs 來說,使用 Monorepo 能夠使用根目錄的 node_modules 來提供底下所有應用程式依賴的函式庫,相對於 multi repo 來說,這種架構使得安裝與建置速度更快,同時可以減少重複的程式碼。
但是講到 CI/CD 架構時,Multi repo 的架構非常直覺,每個 repo 都會設定自己的 pipeline 來處理各種事項,但是使用 Monorepo 的話,整個流程變得非常麻煩,特別是當應用程式之間有依賴性的時候,建制順序就會變得很重要。
假如今天要 release 某個 package 時,也要一併處理所有依賴的 package。如果中間有任何一個 package 失敗,那到底該怎麼辦,繼續 release 還是要 rollback 全部?
monorepo 一個非常實際的案例就是,假設今天想要針對其中一個 package 進行簡單的 hotfix,需要建置並釋出新版本,
結果 CI/CD pipeline 需要跑過整個 repo,所以這時候就會發現一個小小的修改卻需要花費很多時間來釋出新版本。

那為什麼妥協後的 monorepo 還是值得使用?
1. 更容易針對不同環境去準備整包解決方案,譬如環境變數的設定就會相對簡單,可以讓所有應用程式輕鬆共用。以 Single source of truth 概念來說,除了程式碼之外,連相關的設定檔案與變數都可以一起管理。
2. 一個 Pull Request 就可以處理一個新功能。對於那些全端工程師來說,新功能的開發需要修改前端與後端等多個應用程式,使用 multi repo 就需要針對每個 repo 單獨發送 PR 來修改,同時也很容易看到「do not merge until you merge the API feature related to it」
這類型的留言。monorepo 架構下的話,全端工程師就可以一次性的處理相關功能,就不會有這種依賴關係
3. 版本控管更加容易,版本需要跳板時能夠更簡單的一次處理。 multi repo 的架構上就要針對每個 repo 去專門處理,數量一多的話可能還會忘記,而且每個進版還要注意相關的 dependency 是否有一併更新。

文章最後還有探討使用 monorepo 的一些小技巧與方式,有興趣的可以看看全文
ref: https://kubernetes.io/blog/2021/08/09/run-nodes-with-swap-alpha/

所有透過 kubeadm 安裝過 Kubernetes 的玩家有很大的機率會因為忘記關 swap 而導致 kubeadm 安裝不順利,一直以來都有人討論為什麼 Kubernetes 不能於開啟 swap 的節點上運行,看到的理由大致上都與
Memory 控管有關,swap 的開啟會使得 Kubernetes 沒有辦法保證每個 Pod 設定的 Memory 正常運作。
Kubernetes 早期的設計就直接將 swap 的支援給排除,甚至 kubelet 會自動檢查是否有開啟 swap,一旦有開啟則 kubelet 就會自殺不打算正常啟動。

不過實際上有某些 Kubernetes 的使用案例會希望,譬如
1. Improved Node Stability
a. cgroups v2 大大的提升了記憶體管理的機制,而這個機制會推薦使用 swap 來幫忙處理,所以如果叢集中有些節點有支援 swap 能夠更有效地去處理資源的分配
2. Long-running applications that swap out startup memory
a. 譬如 Jave/Node 這類型的應用程式可以透過 swap 來最佳化整體效能
b. 初始化過程可以透過 swap 給予額外的 memory 來處理,初始化完畢後則是按照最初 Pod 的設定
3. Memory Flexibility
a. 有時候 Cron job 會需要比較高的 memory 來運行,但是 cron job 又不是一個整天運行的服務,因此若沒有 swap 的支援,則整個叢集需要安裝更多的 memory 來支援偶而運行的 cron job。
b. 透過 swap 能夠更彈性的去分配 memory,減少整體硬體成本的開銷,對於 on-premise 的環境更為需要。
4. Local development and systems with fast storage
5. Low footprint systems
6. Virtualization management overhead

文章中有介紹該功能大概是怎麼運作的,更重要的是有介紹開啟該功能可能的注意事項,畢竟當初就是有些許考量才沒有完全支援,因此貿然開啟前必定要對該功能有完整的瞭解,確保開啟可能帶來的負面效果以及帶來的好處是否值得去使用

# Kubernetes
Kubernetes v1.22 開始支援 swap,不過這個功能是 alpha 階段,這意味者使用需要去設定 kubelet 來打開這個功能 "NodeSwap",而目前 SIG 希望能夠於 v1.23 能夠讓該功能變成 beta 階段。
因此如果對於這個功能有興趣的朋友,可以針對測試環境去試試看 NodeSwap 的效果,或是慢慢等待 v1.23 之後的正式開放。
ref: https://sruthakeerthi-k.medium.com/powerful-k8s-concepts-that-every-k8s-developer-must-know-ac2b37c37254

作者這篇文章提出了六個所有 Kubernetes 使用者都應該要知道的重要概念,分別是
1. PDB (Pod Disruption Budget)
2. IDS (Initial Delay Seconds)
3. NodeSelector
4. Node Affinity
5. Pod Anninity & Pod Anti-Affinity
6. Taints and Tolerations

這六個概念都不是一個運行 Kubernetes Pod 的必要資源,但是的確理解這些資源並活用能夠讓你的 k8s 叢集更加彈性,更有機會去符合你的使用需求。

# PDB (Pod Disruption Budget)
PDB 的目的是用來保護 Pod 再某些情況下能夠維持最低運行數量,確保服務不中斷。這類型的情況統稱為 voluntary distruption,大抵上就是由叢集管理人員主動去控制的刪除與管理。

舉例來說,今天叢集中有某個節點想要更新,需要針對該節點進行維護,所有該節點上的 Pod 都必須要轉移到其他節點上,假設某服務剛剛好部署了三個 Pod 而這三個 Pod 也很湊巧的都部署到該節點上,那如果今天搬移的過程中這三個 Pod
同時間被 Reschedule 到其他節點,可能就會有一個短暫時間點內沒有任何一個 Pod 可以滿足 Readiness 的需求來幫 Client 提供服務,所以使用者這時候可能會發現服務不正常。

而 PDB 就可以定義最小運作單位,可以讓 Kubernetes 知道如果要搬移這些 Pod 的話,一定要保留一定比率的 Pod 處於 Running 狀態,藉此讓使用者可以繼續使用達到服務不中斷的效果。
熟悉 Deployment 的朋友可能會想說 Deployment 裡面不是已經有 maxUnavailable 這種類型資源了嗎?

maxUnavailable 偏向的是應用程式更新過程需要考慮的,而 PDB 考慮的則是節點的更新過程中上面的應用程式該如何過度轉移,諸如 pod,statefulset, deployment 等都可以管理。

# IDS
多數使用者都會針對 Pod 去進行 liveness 以及 readiness 的設定,大部分情況下這些設定都運作良好。
但是某些應用程式有所謂的暖身期,應用程式啟動到正式可以接受處理可能花上的時間會達到分鐘之久,雖然 liveness 內可以透過 interval/retry 這些設定來處理這類型行為,但是這可能會導致 liveness 的設定變得非常不精準
而且暖身所花費的時間也是一次性的,把這些時間加入到 liveness 的週期時間內其實也頗怪。
為了解決問題, liveness/readiness 都有一個 initialDelaySeconds 的參數可以用,該參數可以控制到底 liveness/readiness 的啟動時間要延後多久,用這個數值來處理暖身需要的時間就可以讓 liveness probe 專注處理後續的觀察

# Taints and Tolerations
Taints/Tolerations 的功能算是 NodeSelector 的反向操作, NodeSelector 代表的是如何透過 Label 去尋找符合標準的目標,而 Taints 則是給節點一個反抗的能力(污點),讓節點可以主動拒絕被 Pod 給部署到該節點上。
執意要部署的 Pod 需要透過 Tolerations 的方式去容忍這些污點,一旦所有條件符合,那 Pod 就可以順利地被部署過去。
使用的情境有
1. 節點出問題,預設情況下譬如 Memory/Disk 出現問題,這時候 Kubernetes 就會自動幫這些節點補上一個 NoSchedule 的 Taint(污點),因此所有新增的 Pod 都沒有辦法順利的部署上去。
2. 節點有不同要求,譬如某節點可能架構是 ARM 的,希望預設情況下所有應用程式都不該部署過來,只有特定符合的 Pod 才可以部署

此外,有些 Pod 的要求更特別,譬如 Monitoring/Logging Agent 等用途的 Pod,這些 Pod 會希望不論何種架構與環境都能夠部署,因此 Tolerations 有類似 wildcard 的方式可以處理,讓該 Pod 去容忍各種污點

剩下的有興趣就點選全文觀看
ref: https://medium.com/@siri.c/inject-aws-secrets-to-containers-be55c859fbf6

不少撰寫應用程式的人都會透過設定檔案或是環境變數的方式來客製化應用程式行為,這種模式下只要該應用程式搭配不同的設定就可以部署到不同的環境
然而這個想法跑到 Kubernetes 內時就變得有點棘手,因為 Kubernetes 內預設情況下沒有一個加密系統來幫忙處理這些設定檔案,常見的 Secret 只是 base64 編碼本身,任何可以閱讀到該 secret 的使用者都有能力可以解編碼得到真正的數值。
更大的問題則是要如何將這些 secret 的物件存放到 Git 專案之中,如何跟 CI/CD 整合來達到自動部署同時又要維持安全性,確保該機密資訊不會輕易洩漏。
大部分的管理者都會使用第三方的解決方案來處理,最知名的莫過於 Hachicorp 的 Vault 專案。

作者這邊想要分享另外一套能夠更輕鬆將 AWS Secret Mananager 管理的資訊給整合到應用程式的開源專案 Piggy.

該專案的概念很簡單,監控所有 Pod 的事件,一旦該 Pod 即將被創造時,就會從 AWS Secret Manager 內相關的機密資訊抓下來然後動態產生一組 Secret 並且將其掛載到 Pod 的環境中。
每個想要使用這個方式的 Pod 只需要於 Annotation 上去描述相關資訊即可使用。
該專案最初開發是基於 EKS 的環境使用,因此整個邏輯都完全綁定 AWS 的服務,所以使用的範圍也限縮於 AWS 的服務,這意味如果團隊的服務如果橫跨多個架構時,這種綁定單一架構的解決方案並不一定適用,挑選時還是要多加看看。
ref: https://devtron-labs.medium.com/ultimate-guide-of-pod-eviction-on-kubernetes-243fa5d551d9

Kubernetes 中最小的工作單位就是 Pod,不論你採用的是何種高階的運算資源(Deployment/DaemonSet/Job...etc),其底層都是呼叫一個又一個 Pod 來完成相關任務。
Pod 的生命週期包含了,被創造,被刪除,被 Scheduler 重新安排節點,也包含了被踢除(evicted)。

本篇文章將會探討兩個會讓 Pod 被踢除的情境,分別是
1. Pod 互相競爭
2. 節點資源不足

以及如何透過 QoS 以及 Pod 優先度的設定來保護 Pod 不會輕易的被系統給踢除。

# QoS
Kubernetes 並沒有一個很直接描述 QoS 的方式,取而代之的是透過 Resource Request/Limit 來決定。
1. 如果 Pod 有同時 CPU 與 Memory 去設定 Request 以及 Limit, 同時 Request 與 Limit 的設定一致,則該 Pod 的 QoS 會被認定為 Guaranteed,使用的資源 (CPU/Memory)
2. 如果 Pod 有設定任何一種資源的 Request,則該 Pod 被定義為 Burstable,大意就是其用量有規範,但是可以超量使用,畢竟沒有完全設定一致的 Request/Limit
3. 以上兩種都不屬於的就屬於 Best Effort,大概就是量力而為。

# Pod priority
Kubernetes 透過 priority/priorityClassName 來定義 Pod 的相關優先度,這些資源會搭配 preemptionPolicy 共同使用。
Scheduler 會優先處理高優先度的 Pod,這意味如果將 preemptionPolicy 給設定為 PreemptLowerPriority 時, Scheduler 有可能就會根據這個規則將一些正在運行的 Pod 給踢掉,把資源讓出來給高優先度的 Pod 去執行。

接下來文章探討要如何透過上述兩個概念來讓你的 Pod 更加穩定

# Pod Preemption
當 Pod 準備被創立前, Pod 這個物件會根據其優先度被放到 Queue 中適當的位置。接者 Scheduler 會從 queue 中挑選出下個要部署的 Pod 並且開始過濾所有條件,找到一個適合的節點來部署該 Pod.
如果找不到任何一個符合需求的節點同時該 Pod 本身有去設定 preemptionPolicy 的話,Pod 就會開始嘗試搶奪其他 Pod 的位置,找到一個受害者將其踢掉。
簡單的想法就是找一個比當前 Pod 更低優先度的 Pod,將其踢掉然後將目標 Pod 給部署到該節點上。

註: 要注意的是 QoS 的概念跟搶奪無關, Pod 的競爭搶奪完全是依據優先度以及 preemptionPolicy 決定。

實務上設定時要非常非常小心,如果今天要啟動這個功能,一定要先從最高優先度的 Pod 開始設定,因為預設情況下每個 Pod 的優先度都是一樣低,都是 0。
因此如果先針對一個稍微重要的 Pod 去進行設定優先度(譬如1),則很有可能運氣非常不好,就會將非常重要的 Pod 給踢掉,這樣就有可能會造成 Cluster 出現問題。

如果有使用過 PodDisruptionBudget(PDB) 的讀者可能會好奇這之間的關係, PDB 的目的是當 Pod 數量要修正時(Drain Node, Downscale),同一時間會被移除的 Pod 數量,透過這個方式來確保 Pod 能夠服務不會中斷。

文章中還有探討 Affinity 與 Pod 優先度的相關關係,非常建議閱讀瞭解一下這邊的概念,最後作者給出幾個建議
1. 使用 PodClassPriority 而不要 Pod 裡面直接使用 priority 欄位設定數值。
2. 不要設定太多層級的優先度,否則你光理解跟管理會把自己逼瘋
3. 只針對非常非常重要的 Pod 去設定 preemptPolicy,然後設定類似 cluster-critical, node-critical 這類型的名稱來標示該 priority 的意圖
ref: https://upstart.chrishic.com/the-future-of-containers-whats-next/

隨者 Container 的發展與應用逐年成熟,現在有更多新的名詞再探討下一代的 Container 技術,譬如 microVS, unikernel, sandbox 等
本篇文章會針對當前 container 的問題是什麼,接者針對這三個名詞背後的概念進行簡單介紹。

# VM
1. 完整虛擬化,不同作業系統可以互跑,硬體會透過模擬的方式呈現
2. VM 之間有很好的隔離性與安全性
3. 因為完整虛擬化,所以包袱過大導致啟動速度慢,系統本身所需要的資源也相對高。

# Container
1. 相對於 VM 來說非常輕量,不虛擬化整個作業系統,而是以應用程式為出發點,整體運行很依賴 Host 的環境,不同作業系統不能交互使用。
2. 底層 OS 會想辦法將這些不同的 Container 做到類似隔離的效果,但是說到底還是同一個 Kernel,安全度不如 VM
3. 啟動速度快,消耗資源少

隨者 Kubernetes 的流行,愈來愈多的團隊使用 Container 來部署與管理應用程式,但是其天生的架構使得其安全度本身就沒有 VM 來得強大,
愈來愈多使用情境想要擁有一個可以融合兩者優點的技術,有 Container 的方便與速度,有 VM 的安全性與隔離性。

而本文的三種技術 microVMs, Unikernels 以及 container sandbox 就是想要解決這問題的三種不同技術

# MicroVMs
相對於 VM 能夠完整支援各種功能與作業系統, microVM 想要透過客製化 VM 的需求,將用不到的功能給移除,透過限縮功能與降低複雜度來提升 VM 的效能與使用資源

舉例來說,大部分雲端應用程式需要的硬體裝置只會有網路/儲存等,其他如鍵盤,滑鼠,螢幕顯示等相關的驅動程式其實完全不需要,從這個角度來看,為什麼要模擬一個完善環境結果裡面大部分的資源其實都是不需要的?
對於傳統的 VM 來說,一個簡易的 microVM 的開機速度可以低到毫秒等級,使用的記憶體資源也只需要 5MB 左右,這些數據使得要快速部署大量 microVM 不再是個夢,而是真真實實可能發生的。

AWS 的 Firecracker. 可能是 microVM 中最知名的專案。 AWS 透過 Firecracker 來提供 serverless 的服務,因應 microVM 的特性,使用者的服務可以更快速地被部署,同時因為 VM 的特性使得這些程式相對於傳統容器來說安全性更高。
microVM 的架構與願景聽起來很美好,但是其終究還是一套基於 VM 的環境,目前大部分的開發與 CI/CD 流程都是基於 Container 的概念去開發與設計的,要如何將這些流程與 microVM 整合實際上才是導入最大的難題。
因此大部分的 microVM 實作上都會疊加一層 Container 的管理介面,譬如 VM 起來後內建 Container 的環境,能夠直接部署 Container 來應用,透過這樣的設計讓使用者可以繼續使用 container 般的操作流程同時又享有 VM 的安全性。

# Unikernel
Unikernel 解決的目標完全一致,就是又安全又快速又輕量的虛擬化技術,不過其採用的方式跟 microVM 是截然不同的。
其透過打造一個輕量且不可修改的 OS 來運行目標應用程式,該 OS 是動態編譯的,編譯內容包含應用程式原始碼,相關驅動程式以及會使用到的各種函式庫,全部東西一起編譯後產生最後的 OS。

Unikernel 透過限縮某些特性來提升整體效能,譬如
1) 整個 OS 只能有一個 process,這意味使用者的應用程式沒有辦法 fork 出其他的 process. 也因為這個特性使得其安全性頗高
2) OS 跟 Application 的記憶體是採用同個記憶體空間,透過這個機制減少需要轉換的次數來達成效能提升
3) 由於只能運行一個應用程式,所以如果應用程式死了那基本上 OS 也沒有活者的必要,這時候重啟 OS 即可。
4) Unikernel 最大的問題就是整個技術跟 Container 是完全不同走向,整合難度非常的高,要落地感覺不太有機會。

# Container Sandbox
Sandbox 的目的是希望能夠提升 Container 架構的安全性,主要著重點是如何透過 Kernel Proxy 的概念讓 Kernel 不再共用,每個 Container 看起來都會有一個屬於自己的 Kerenl.

Kernel Proxy 會去實作所有 Container 會需要的 kernel 功能,藉此讓每個 container 能夠不用修改的情況下就套入 kernel proxy,然後獲得更好的安全性。
Google 的 gVisor 專案就是這類型的產物,其透過 Go 語言開發了一套 kernel proxy 來實作各種 system call。
Kernel Proxy 透過其第三者的機制來確保不同容器之間的惡意攻擊不會影響到彼此的 Kernel,甚至是 Host 本身。但是多了一層角色實際上整個處理的速度就會比純 Container 來得慢一些。