Skip to main content

· 3 min read

標題: 「強化 Kubernetes 叢集的必備工具」 類別: kubernetes 連結: https://medium.com/mycloudseries/must-haves-for-your-kubernetes-cluster-to-be-production-ready-dc7d1d18c4a2

作者本篇文章想要分享一個其用來讓一個 Kubernetes 變得能夠真正上戰場的相關工具,因此文章中特別強調是 Production-Ready 的情況。 一個 Production Ready 的 K8s 叢集必須對於下列每個大項目都要有相關處理方式,譬如

  1. Reliability and Availability
  2. Security
  3. Network, Monitoring & Observability
  4. Backup/Recovery
  5. Cost Optimization
  6. Cluster Visualization

Reliability and Availability: 該領域的兩個指標代表的意義不太一樣,但是對於一個提供服務的叢集來說都一樣重要

這邊作者列舉了幾個工具譬如

  1. K8s 內建的 HPA
  2. AWS 的 karpenter,讓你針對基於節點為單位來擴充
  3. Cluster-Autoscaler
  4. Goldilocks

Backup/Recovery 有不少人團隊都對於對於叢集的備份與還原感到頭痛,目前最知名的開源專案莫過於 Velero,其支援不同的儲存設備如 Cloud Storage 等來存放,讓不同環境的 k8s 使用者都有辦法去備份其叢集內的資料

Cost Optimization

對於雲端架構來說,基本上雲端業者的內建功能已經可以針對如 VM, 底層架構等各種服務去列舉出各自的花費金錢,將此概念套入到 Kubernetes 本身大抵上只能理解到 Master Node, Worker Node 等之類的花費, 因此透過 Kubecost 之類的專案來將成本的洞察範圍擴充到 Kubernetes 內部,以 namespace, pod 等各種 k8s 的資源為單位來列舉實際花費的金額,能夠讓團隊更有效地去管理相關花費

· 4 min read

標題: 「你真的有正確使用 SSH 嗎?」 類別: tools 連結: https://smallstep.com/blog/use-ssh-certificates/

SSH 基本上是每個系統管理員都熟悉不過的工具,而本文的作者指出 SSH 使用上有一些小缺陷,譬如

  1. 使用者體驗很差,每一個新使用 SSH 的人如果不熟悉其概念,每次連線到新機器都會看到一次 Yes/No 的選擇,就因為不熟大部分的人都會直接選擇 Yes 來通過, 背後實際發生什麼事情都不清楚,只知道會動就好
  2. 大規模的管理 SSH 非常麻煩且花費時間,Hostname 如果前後有出現重複的還會出現問題,需要重新處理 known_hosts 等相關資料
  3. 透過 Key 的管理聽起來很安全,但是其架構使得使用者通常不太會換 key,會一直重富使用固定的那把 Key 來避免重新處理一切問題

舉了一些問題後,作者點出能夠真正駕馭 SSH 的應該是採取 SSH Certificate 而非使用 SSH Public Key 來進行身份驗證。 作者團隊開發了些許工具來幫助其他人能夠更輕鬆的使用 SSH Certificate 但是卻發現這類型的工具卻沒有受到歡迎與採用,因此也針對這個現象 進行問卷調查,想瞭解這類型的工具為什麼不受青睞,原因包含

  1. 根本沒聽過 SSH Certificate
  2. Certificate 以及 PKI 架構對人們來說不容易理解,很難理解其好處
  3. 轉換中間有一些陣痛期,所以與其花時間去學習這些不如就繼續使用本來的 Public Key 機制

文章後半開始介紹 SSH Public Key 與 SSH Certificate 的差異 Public Key 的概念非常簡單,就是透過一組 Private/Public Key 並且將 Public Key 給寫入到目標節點帳戶上的 ~/.ssh/authorrized_keys. 節點數量爆炸多的情況下要如何有效率的去管理這些檔案則是一個非常麻煩但是又不能不處理的事情,這也是作者為什麼要推廣 SSH Certificate 的原因之一

SSH Certificate 的方式移除了關於 SSH Public Key 不停重複上傳與設定的情境,相反的則是將自身的 Public Key 給綁到 Certificate 內,同時也包含如過期時間,名稱等其他資料。 目標 Certificate 本身會由一個 CA 簽署,而每台 Server 都需要去修改 /etc/ssh/sshd_config 來指定相關的 CA Key 讓該 SSH 能夠信任。 文章後半部分介紹更多關於 SSH Certificate 的好處以及用法

· 2 min read

標題: 「透過 Kubernetes Event-Driver Autoscaler(KEDA) 來根據各種指標動態擴充容器」 類別: kubernetes 連結: https://medium.com/@casperrubaek/why-keda-is-a-game-changer-for-scaling-in-kubernetes-4ebf34cb4b61

Kubernetes 內已經有 HPA 的物件可以讓 K8s 根據一些基本的指標來動態調整 Pod 的數量,而 KEDA 這款 CNCF 的孵化專案則是完全強化 HPA 的效果 KEDA 的概念很簡單,就是應用程式應該要可以有更多的指標來幫忙動態擴充,除了最基本的 CPU/Memory 等基本指標外, KEDA 來支援了下列各種不同指標,讓 k8s 可以使用更為廣泛的指標,譬如

  1. Redis 內某個 Queue 的長度
  2. K8s 內其他 Pod 的數量
  3. PostgreSQL Query 的結果
  4. Elasticsearch Query 的結果
  5. 各種雲端服務,如 Azure Event Hubs, AWS CloudWatch, GCP Pub/Sub
  6. Kafka ... 等各種不同指標

使用方式很單純,一切的規則都是基於 K8s 的 CRD 來描述與管理,因此團隊可以使用 YAML 的方式來定義這些擴充的規則 文章中有基於 CPU/Memory 的基本介紹使用,同時文章中也有官方的連結來介紹各種不同指標的示範用法

· 3 min read

標題: 「升級 Kubernetes 1.22 的注意事項」 類別: kubernetes 連結: https://blog.runx.dev/will-that-kubernetes-v1-22-upgrade-break-my-application-cc339dc2e2c7

隨者各大公有雲逐步支援 Kubernetes 1.22,相關使用者可能都會開始進入升級的準備階段,而每次 Kubernetes 升級除了單純 思考 Kubernetes 本身的升級順利與否外,也要確認正在運行的所有 Kubernetes 資源與相關工具是否也能夠順利運行,這使得整個準備工作變得複雜與龐大。

從 Kubernetes 的角度來看,每次的升級除了基本的穩定性與相關功能修正外,最重要的還有 Kubernetes API 的改變,該改變影響巨大,譬如所有 Manifest 的內容,譬如眾多透過 YAML 所描述的各種資源 API 的改變都會提早通知所有社群,於先前的版本先將該 API 標為 deprecated 接者後續版本才會正式移除,譬如 networking.k8s.io/v1beta1 於 1.19 被標示為 deprecated 然後正式於 1.22 移除。 正式的版本 networking.k8s.io/v1 則從 1.19 正式啟用,讓管理者有大概有三個版本的時間轉移。

因此升級前一定要先架設一個測試環境,嘗試部署所有現存的資源來確保升級不會出現不預期的錯誤。

作者整理出關於 1.22 升級要注意的版本變化,如下(幾乎都是從 v1beta 變成 v1)

  1. Webhook: admissionregistration.k8s.io/v1beta1 → admissionregistration.k8s.io/v1
  2. CRD: apiextensions.k8s.io/v1beta1 → apiextensions.k8s.io/v1
  3. APIService: apiregistration.k8s.io/v1beta1 → apiregistration.k8s.io/v1
  4. TokenReview: authentication.k8s.io/v1beta1 → authentication.k8s.io/v1
  5. SubjectAccessReview: authorization.k8s.io/v1beta1 → authorization.k8s.io/v1
  6. CertificateSigningRequest: certificates.k8s.io/v1beta1 → certificates.k8s.io/v1
  7. Lease: coordination.k8s.io/v1beta1 → coordination.k8s.io/v1
  8. Ingress: extensions/v1beta1, networking.k8s.io/v1beta1 → networking.k8s.io/v1
  9. IngressClass: networking.k8s.io/v1beta1 → networking.k8s.io/v1
  10. RBAC resources: rbac.authorization.k8s.io/v1beta1 → rbac.authorization.k8s.io/v1
  11. PriorityClass: scheduling.k8s.io/v1beta1 → scheduling.k8s.io/v1
  12. Storage resources: storage.k8s.io/v1beta1 → storage.k8s.io/v1

· 4 min read

標題: 「kubectl delete 的行為跟 docker delete 完全不同」 類別: kubernetes 連結: https://www.acritelli.com/blog/kubectl-delete-sigkill/

熟悉 Linux 系統的人想必都了解 Signal 的概念,特別是幾個常見的如 SIGTERM, SIGKILL 等,

作者的團隊嘗試透過 SIGKILL 的行為來驗證與測試團隊內部署的 Kubernetes Pod,特別是當遇到 ungraceful shutdown 的情境時這些 Pod 會如何運作。 團隊嘗試透過 kubectl delete 的方式來刪除這些 Pod,但是實驗過程中發現 --grace-period 這個參數的運作行為與團隊的預期行為不同。 kubectl delete 得說明文件中特別指出

      --grace-period=-1: Period of time in seconds given to the resource to terminate gracefully.
Ignored if negative. Set to 1 for immediate shutdown. Can only be set to 0 when --force is true
(force deletion).

作者看文這段文字說明後滿腦問號,提出兩個問題

  1. grace-period 設定為 1 的 immediate shutdown 是直接送出 SIGKILL 嗎? 還是說會有一秒的間隔時間才發送 SIGKILL?
  2. grace-period 設定為 0 是代表沒有間隔,所以也是馬上送出 SIGKILL 嗎? 還是說其只是單純將資源從 k8s API 中移除而沒有等待而已?

作者認為文件沒有辦法解決這些問題,所以設計了一些實驗來測試

--grace-period=1 的實驗結果是

  1. 送出 SIGTERM
  2. 等待一秒
  3. 送出 SIGKILL

作者對於這個行為感到不解,認為 "immediate shutdown" 應該就是要馬上關閉呀,怎麼可以送 SIGTERM 給 Pod 讓 Pod 有機會可以優雅的結束一切? 因為對於這行為的認知不同導致作者團隊的測試行為沒有辦法順利完成。

接下來測試 --grace-period=0 & --force=true

文件中說明這樣設定會立刻將該資源從 API Server 內給刪除並且避開 graceful 的階段。 最後測試的結果是

  1. 發送 SIGTERM
  2. 等待 30 秒
  3. 發送 SIGKILL

作者表示又糊塗了,沒想到設定 grace-period=0 竟然中間還有 30 秒的時間,這完全與預料的不同,更麻煩的是文件也沒有講得非常清楚到底什麼是正確的行為, 此外還提到 Docker 就支援真正的 immediate shutdown,直接送 SIGKILL。

另外作者發現 K8s GitHub 中的也有人提出類似的 issue,對於這些 graceful 的行為感到不解同時文件說明不夠精準。

這件事情很難說誰正確誰不正確,畢竟不同的系統架構下的設計方式與條件都不同,不過的確 K8s 的指令文件有時候是真的不是精準,需要仔細測試才可以理解到底運作行為為何

· 3 min read

標題: 「Dockerfile 中透過 COPY --chomd 比透過 RUN chomd 可以省下更多空間」 類別: containers 連結: https://blog.vamc19.dev/posts/dockerfile-copy-chmod/

本篇文章是作者探討自己建制 Image 中所發現的一些有趣事實。 作者使用一個大概 70MB 的 image,並且安裝與運行大概 90MB 左右的額外空間,結果最後整個 image 高達 267 70MB 因此作者就花了一些時間來研究整體原因並且嘗試理解到底發生什麼事情

作者首先檢視自己的 Dockerfile,其內容簡單不複雜,包含如 COPY 一個 Binary (該 Binary 80 MB 左右) RUN xxxxx 等常見用法。

詳細檢視所有的 layer 資訊後,作者發現 RUN 這個指令竟然產生了 94.4MB 的全新 layer,而就是這個 layer 導致整體空間變成 267 MB. 作者的 RUN 指令執行

  1. 透過 apt-get 安裝四個套件
  2. 透過 chmod 將前述 COPY 來的檔案給予執行的權限
  3. 創建資料夾

作者檢查過安裝的套件,大概只有 6MB 左右,但是整個 layer 很明確就是多了 94.4 MB 出來,因此經過測試與研究後,作者觀察到 當移除第二步(修給檔案給予執行的權限)後整個空間瞬間變得很小,整體 image 最後的大小就符合預期的 174MB。

所以整個問題就出來了,為什麼單純執行一個 RUN chmod 就會使得整個 image layer 變大? 簡單來說 image 的底層是基於 OverlayFS,而 OverlayFS 的一大特色就是 CoW, Copy on Write,作者起初覺得 我只是透過 chmod 去修改該 Binary 一個屬性而以,本身並沒有寫入檔案到檔案系統中,怎麼會產生這麼大的檔案變化?

仔細研究 OverlayFS 的文件後終於水落石出,原來除了寫入檔案外,修改檔案的某些 metadata 也會觸發 CoW 的機制

When a file in the lower filesystem is accessed in a way the requires write-access, such as opening for write access, changing some metadata etc., the file is first copied from the lower filesystem to the upper filesystem (copy_up).

至於為什麼修改個 metadata 也要觸發 CoW 主要是跟安全性有關,文章中有關於這部分的額外連結,有興趣的可以參考

· 3 min read

標題: 「軟體工程師你真的工作的很開心嗎??」 類別: others 連結: https://stackoverflow.blog/2022/03/17/new-data-what-makes-developers-happy-at-work/

疫情這兩年影響全球,其中對於勞動力來說更有甚巨的變化,而科技業更是其中的佼佼者,是所有行業中離職率最高的行業。 2021 的離職率相對於 2020 來說提升了 4.5%。

StackOverflow 基於想要理解科技領域的這個趨勢及原因,所以發起了一個調查想研究工程師工作是否開心,並且將 基於 350 位來自全球開發者的回應統整為報告於三月份釋出。

結果來看

  1. 70.3% 的工程師覺得工作開心
  2. 14.4% 表示不開心
  3. 15.3% 沒感覺

以最令人感到開心的地區排名來看,前五名分別為

  1. 西班牙 (90%)
  2. 印度 (79%)
  3. 德國 (70%)
  4. 美國 (69%)
  5. 英國 (68%)

那到底哪些因素會影響開心與否? 報告中列舉了相關的指標 前五個最令人感到開心的因素有

  1. 薪資(60%感到開心)
  2. work-life 平衡
  3. 工作彈性
  4. 是否有足夠生產力
  5. 職涯發展機會

而令人感到不開心的五個最重要指標其實就是上述指標的反轉,依序為

  1. 工作覺得毫無效率與生產力
  2. 工作生活不平衡
  3. 沒有職涯發展與機會
  4. 薪水太低
  5. 工作無彈性

調查的全部指標除了上述五個之外還有

  1. 工作是否能夠帶來影響力
  2. 是否能夠獨力解決問題
  3. 有一個瞭解我工作的主管 ... 等

其實面試找工作也就是針對這些條件進行排序,與其跟風看大家去什麼公司就想去什麼公司,不如好好跟自己對話,瞭解自己對於工作的目的以及追求是什麼,才有辦法找到一個自己喜歡且舒適的工作環境

· 2 min read

標題: 「如何於 Docker 環境中運行 rootless 模式」 類別: container 連結: https://thenewstack.io/how-to-run-docker-in-rootless-mode/

雖然可以使用非 root 的方式去安裝 Docker 服務,但是 Docker 本身服務中還有其他各種元件需要透過 root 身份去運行,譬如 dockerd, containerd, runc 等元件, 而本篇文章則是探討要如何以真正 rootless 的方式來運行一個 docker container 。

使用 rootless container 有一些要注意的事情,譬如 port number 沒有辦法使用 1024 以下,所以如果你的服務有需要被外界存取時要使用大於 1024 的 port number。 此外 AppArmor, host network mode 這些都不支援,因此使用上會有一些情境要注意。

安裝其實滿簡單的, Docker 官網有提供 rootless 的安裝檔案,安裝後需要針對一個使用者 ID 進行處理,這個處理主要是因為要將 container 內的 root 使用者給轉換到系統上的非 root 使用者,所以才會有相關的 userID 要設定。 當然如果真的要完全追求 rootless 的容器解決方案可以考慮使用 Podman 來使用,其本身的設定就是針對 rootless 去開發的,使用上會相對於 docker 來說更為簡單。

· 2 min read

標題: 「一個用來管理 Kubernetes 開源工具的開源工具」 類別: tools 連結: https://github.com/alexellis/arkade

作者因應過去於 Kubernetes 的教學與開源過程中,必須要一直不停地去安裝各式各樣必備的工具而感到厭煩,譬如每次都要安裝 kubectl, kind, kubectx 等各種常見工具 而每個工具又會有不同的版本,每次都要專寫相關的安裝流程都很麻煩,因此作者萌生出開發一個能夠安裝這些工具的開源工具, arakde.

該工具用起來非常簡單,同時也支援不同版本的工具,除了基本 CLI 工具外也支援 Helm App 的安裝,我個人認為光工具本身就非常好用了,譬如可以透過該指令輕鬆的安裝不同版本的下列工具

  1. dive
  2. helm
  3. gh
  4. jq
  5. k3d
  6. kind
  7. kubectl
  8. k9s
  9. kail
  10. opa
  11. terraform ...

如果你常常需要撰寫文件去分享安裝各種文件的需求,也許可以考慮使用看看此工具來簡化流程

· 2 min read

標題: 「為什麼 3A 大作的遊戲室都不愛喜歡使用 STL」 類別: usecase 連結: https://mobile.twitter.com/m_ninepoints/status/1497768472184430600

熟悉 C++ 語言的讀者必定聽過 STL,而本篇推特系列文則是用來解釋為什麼 3A 大作的遊戲室都不愛使用 STL,這邊節錄一些概念與想法

  1. STL 的實作通常會因為不同平台與編譯器而會有不同變化,但是對於遊戲業者來說很多時候會希望能夠針對所有平台能夠有一個統一一致的實作
  2. 跨平台的統一實作對於開發者來說可以帶來很多好處,譬如除錯可以更有效率,不需要針對每個平台獨立研究問題
  3. STL 由於不同平台的實作方式都不同,所以發生問題或是要客製化都會變得稍嫌麻煩,變成還要根據平台去研究與處理,整體來說就是煩
  4. 某些情況下 STL 的實作是犧牲效能來完成的,但是效能反而是業者所需要的

覺得本篇推文非常有興趣,對這系列有興趣的可以看看大家的討論