Skip to main content

· 2 min read

連結: https://docs.microsoft.com/.../archit.../patterns/ambassador

微軟文件中的系列好文,探討雲端方面的各種設計模式,而本篇探討的是 Ambassador 模式 想法:

  1. 想要提供更多進階的網路功能到應用程式上,譬如 TLS、circuit、breaking、routing 或 metering。
  2. 應用程式不太方便修改來符合上述功能。
  3. 部署一個跟原應用程式相鄰的應用程式來處理這些網路功能。 應用程式過於古老,團隊沒有辦法進行深度修改或是團隊中的應用程式使用過多的語言與框架完成,很難簡易的將這些功能給導入到既有的應用程式中 這時候部署一個全新的應用程式就可以再不修改既有應用程式的前提下來提供這些進階的網路功能。 這個模式普遍被稱為 ambassador 模式,而本篇文章就是針對該模式進行一個科普概念。 文章最後還要探討使用這種模式的一些注意事項,譬如網路的延遲會因為多一個應用程式而提升,所以使用上也要評估看看是否合適。 也有簡單的列出什麼情況適合使用 ambassador 什麼情況不適合。

· One min read

連結: https://pythonspeed.com/articles/stop-using-python-3.6/

本部落格是一個基於 Python & Container 的系列介紹文,而本篇文章是其中一篇探討容器化 Python 要注意的事項。 標題非常簡單:「是時候停止使用 python 3.6了」 Python 3.6 的 EOL 時間就剛好是 2021/12,這也意味到 2022 年後 python 3.6 就不再享受官方的任何維護與更新。 文章中提到建議趕快升級,同時也要注意不要每次都拖到最後一刻才升級相關軟體,應該要把升級軟體的流程給整合到日常流程中,定期掃描定期更新, 否則只會不停的被不同版本的 EOL 追趕而已。

· 2 min read

連結: https://coolshell.cn/articles/21672.html 本篇文章是作者工作 20 年來的經驗分享文,內容非常好,提出了很多不同的觀點,由於是篇中文文章,所以就不幫忙節錄重點,直接列 文章中的十一個原則標題。 每個原則都非常精彩,文章底下的討論也滿有趣的。 原则一:关注于真正的收益而不是技术本身 原则二:以应用服务和 API 为视角,而不是以资源和技术为视角 原则三:选择最主流和成熟的技术 原则四:完备性会比性能更重要 原则五:制定并遵循服从标准、规范和最佳实践 原则六:重视架构扩展性和可运维性 原则七:对控制逻辑进行全面收口 原则八:不要迁就老旧系统的技术债务 原则九:不要依赖自己的经验,要依赖于数据和学习 原则十:千万要小心 X – Y 问题,要追问原始需求 原则十一:激进胜于保守,创新与实用并不冲突

· One min read

連結: https://emmer.dev/blog/docker-shell-vs.-exec-form/

Docker 基本介紹文,不知道常寫 Dockerfile 的讀者能不能分清楚 Dockerfile 內 Shell 與 Exec 兩種格式的差異 RUN, CMD, ENTRYPOINT 等指令都同時支援這兩種格式 Shell 格式就是 RUN command arg1 arg2 arg3 這種直接描述的格式,而 Exec 則是用 [] 包起來,每個參數單獨敘述,譬如 RUN ["command", "arg1", "arg2", "arg3"] 等。 本篇文章推薦 RUN 指令採取 Shell 格式而 CMD/ENTRYPOINT 都應該採用 EXEC 格式。 如果自己不清楚差異以及沒有想法為什麼平常自己這麽寫的話可以參考全文

· 2 min read

連結: https://matduggan.com/mistakes/

本文是作者踩過的各種 Infrastructure 雷,希望讀者能夠避免這些雷。

總共有幾大類,分別

  1. Don't migrate an application from the datacenter to the cloud
  2. Don't write your own secrets system
  3. Don't run your own Kubernetes cluster
  4. Don't Design for Multiple Cloud Providers
  5. Don't let alerts grow unbounded
  6. Don't write internal cli tools in python

其中第六點簡短扼要,大概就是「沒有人知道如何正確地去安裝與打包你的 python apps, 你真的要寫一個內部的 python 工具就給我讓他完全跨平台不然就給我改用 go/rust, 不要浪費生命去思考到底該如何安裝那些東西」

這讓我想到你的 Python 跟我的 Python 每次都不一樣,有已經不支援的 python 2.x, 還有各種可能會互相衝突的 python 3.x....

· 3 min read

ref: https://jpetazzo.github.io/2021/11/30/docker-build-container-images-antipatterns/

本篇文章分享的是建置 Container 中的 Anti-Patterns,不講哪些好反而探討哪些不好。

文內列舉了不同的主題,包含

  1. Big images
    • All-in-one mega images
    • Data sets
  2. Small images
  3. Rebuilding common bases
  4. Building from the root of a giant monorepo
  5. Not using BuildKit
  6. Requiring rebuilds for every single change
  7. Using custom scripts instead of existing tools
  8. Forcing things to run in containers
  9. Using overly complex tools
  10. Conflicting names for scripts and images

以下針對內文幾個部分摘錄一下為什麼作者認為是個不好的模式

Small Images

Image 小本身不是什麼問題,但是有時候過度追求容量會使得一些常用有幫助的工具沒有辦法於容器內執行,這可能會導致未來要除錯時要花費更多的時間去處理,可能要研究如何重新安裝該工具等。

作者有強調這個議題是非常看環境與需求的,有些情況可能團隊根本不需要進入到容器內去執行 shell 來處理,有些可能會需要到容器內執行 ps, netstat, ss 等指令來觀察不同狀態。 作者推薦可以使用 gcr.io/distroless/static-debian11 這個 image 做為基礎然後將其之間的 busybox 給複製環境中,至少確保有基本工具可以使用

Not using BuildKit

BuildKit 是 docker build 的新版建置方式,相對於舊版方式來說 Buildkit 提供了更多功能,譬如平行建置,跨平台建置甚至效能上也會比過往的更好。 為了讓舊有使用者可以無痛轉移,所以 BuildKit 完全相容既有的 Dockerfile 的語法,所以切換方面是完全無腦的。 目前新版的 Docker Desktop 基本上已經預設採用 BuildKit 來進行建置,不過某些系統譬如 Linux 的環境下,還是需要透過設定環境變數來啟用這個功能,譬如 DOCKER_BUILDKIT=1 docker build . 等方式來建置。

此外透過 BuildKit 建置的產生結果跟過往不同,所以只要看建置結果的輸出就可以判別自己是否使用 BuildKit。

剩下的8個項目就留給有興趣的讀者自行閱讀

· 3 min read

連結: https://medium.com/kudos-engineering/increasing-resilience-in-kubernetes-b6ddc9fecf80

今天這篇文章作者跟大家分享一些如何加強 Kubernetes 服務穩定的方式,這篇文章這邊做個簡單摘要一下 發生問題: 作者的 k8s 是基於 Google Kubernetes Service (GKE)的叢集,運作過程中有時候會發現部分節點當掉,最後導致部分的服務不能正確使用。這邊作者團隊從兩個角度出發去改善

  1. 研究為什麼節點會一直當掉,與 Google Supporte Team 來回信件最後有找到問題點
  2. 強化 Kubernetes 服務的韌性,就算有部分節點壞掉也要讓服務能夠繼續運行 ,本文主要的一些觀點也都是基於這邊發展 強化方式
  3. 修正 Deployment 的數量,並且加上 Anti-Affinity,讓這些 Deployment 的副本能夠散落到不同的節點上,避免所有 Pod 都塞到同個節點,最後該節點出問題導致 Pod 全部出問題。
  4. 所有需要被 Service 存取的服務都加上 Readess Probe 來確保這些服務都準備好後才會收到服務,避免一些請求被送過來確又不能正確處理
  5. 加入 Pre-Stop 的使用,再裡面透過 sleep 10的方式,讓 Pod 要被刪除能夠將手上的封包請求給處理完畢 (請看註解補充) 註: 我個人認為第三點其實不太需要,比較漂亮的作法應該是實作 Singal Handler 去處理 SIGTERM 的訊號,收到此訊號後就不要再接受任何 Request 並且把剩下的工作處理完畢,當然如果這部份處理的時間過長,超過預設的 GracePeriod (30sec),就會被 SIGKILL 給強制刪除。 要解決這個問題可能就要從應用程式下手去看如何改善,或是透過修改 Pod Spec 來提昇 GracePeriodTemination 的長短

· 2 min read

連結: https://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts

今天跟大家分享一個 UDP 於 Linux Kernel 內的 Race Condition 問題。這問題我以前於 Linux Kernel 3.14 也有採過一樣的雷,但是到今日都還沒有一個很漂亮的解決方案,這邊就快速的跟大家介紹一下這個問題> 是什麼,以及跟 k8s 有什麼關係

發生前提

  1. 使用 UDP 這種沒有重送機制的協定
  2. Kernel 有開啟 conntrack 此功能

發生條件

相同的 Client 短時間內透過 UDP (也許是不同 thread) 送出兩個 UDP 封包到外面,對於 Linux Kernel 來說,會希望透過 conntrack 來追蹤每一條連線,但是底層建立的時候會有一些會有一些機制,因此當兩個封 包同時進入的時候,有可能就會因為先後順序導致第二個封包被丟棄

可能發生問題

DNS 的請求封包預設情況下會同時透過 UDP 送出 A & AAAA 兩個封包,而這兩個封包如果很巧的採到這個情況,然後你的 A 封包就沒有辦法順利解出 DNS,最後就要等五秒的 timeout 來重新發送 下偏這篇文章就是 weave works 遇到 DNS 5秒 timeout 的問題,然後仔細的將我上面所寫的總結給解釋清楚,每一個步驟發生什麼事情,什麼是 conntrack 以及暫時的 workaround 是什麼 之後會在跟大家分享目前一些解決方法怎麼做