本篇是一個 GKE 上面的使用經驗談,主要問題發生調整 StatefulSet 數量時(3->5),發現新增出來的 Pod 都沒有辦法順利的被排程到節點上。
作者團隊遇到的錯誤訊息是

FailedScheduling 4m42s (x3 over 4m44s) default-scheduler 0/9 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims, 6 node(s) didn’t match node selector.

根據上述訊息,可以觀察到兩個點
1) 3個 Pod 因為 PVC 的問題過不去
2) 6個節點沒有符合 node selector 的敘述

這個錯誤訊息讓團隊覺得很莫名,畢竟本來的 StatefulSet 運行的很好,只是改個 replica 的數量就出問題了。

經過調查與研究後發現, GKE 創造的 PV(PersistentVOlume)全部都綁定於 europe-west4-b 上,然而所有的 Pod 全部都綁定於 europe-west4-a 上。
Zone 的使用上沒有一致導致這個問題發生。
作者本來是期許 GKE 要可以更聰明的去處理這個問題,所有自動創立的 PV 應該要針對 Node Selector 有符合的 Zone 去設定,這樣才可以確保運行的 Pod 有對應的 PV 可以使用。

最後作者閱讀了相關文件,得到兩個結論
1. 根據官方文件,Regional persistent disk 只會針對同 regional 內的兩個 zone 去複製與同步 Disk,因此對於一個有 3個 zone 的 Region,是有機會存取到一個沒有該 Disk 的 Zone。
2. 根據 GKE 的文件,使用者最好維護自己的 StorageClass 物件,透過該物件去來 select 多個 zone,同時團隊也比較有能力針對多zone的情況去控管

https://faun.pub/a-story-about-gke-zonal-nodes-and-stateful-set-scaling-1e15acfe5523
這次帶來的是個人的原創文章「從網路觀點來看導入 Kubernetes 的可能痛點
」,就我個人的理解與經驗跟大家討論導入 Kubernetes 到現有環境中會遇到的各種網路問題。

雲端平台的方便性使得架設 Kubernetes 簡單容易上手,然而對於地端環境來說,要導入 Kubernetes 並沒有想像中的簡單。團隊服務沒有辦法一夜轉換到 Kubernetes 的情況下,最麻煩的便是轉換過渡期中要如何讓 k8s 與現有架構整合。

Kubernetes 原生的 Service 與 CNI 架構為其提供低門檻的使用方式,讓 Kubernetes 運作起來不需要太深的網路背景與概念即可順利使用。本篇文章就地端環境來討論幾個可能需要的網路情境,而這些情境為什麼於 Kubernetes 內難以實現與完成,如果真的有需求時可以用何種角度與方式去解決。

長話短說就是本篇文章探討如何透過 Multus/DANM 等 Metaplugin CNI 搭配 SR-IOV/DHCP/Static CNI/IPAM 來滿足

1. Pod 固定 IP
2. K8s 叢集支援多個底層網路,針對需要讓不同流量走不同底層網路
3. 不同強度的網路隔離

https://www.hwchiu.com/k8s-network-issue.html
本篇文章主要探討的是如何打造一個 GitHub 個人帳號的 README 檔案。
作者因為某份職缺招募者告訴他,我們看了很多你的 GitHub 紀錄,建議寫一個 READEME 來好好的介紹你自己,因此作者開始思考如何透過 README 來好好的銷售自己展示自己的能力。

去年開始所有 GitHub 帳號都可以創造一個基於自己名稱的 repo,並且該 repo 內的 README 則會是自己帳號首頁的自我介紹,而本文則是示範如何設計一個有特色的 README 內容,從排版,選色,字型等議題都有所涉略

有興趣的也可以參考這個網站: https://awesomegithubprofile.tech/
裡面列出了非常多有趣很酷的 README,必須說很多都超乎我的想像.....

https://emmanueljose.medium.com/readme-a-makeover-story-b9c7be37a6de
這次跟大家分享一個 ConfigMap 相關的小 issue,當透過 configmap 來存放任何 json 格式資料時,某些情況會導致 configmap 內最後存放的資料格式全部跑掉,所有的換行符號都以\n的方式出現於資料中,導致整個 json 變得非常醜陋,這個醜陋會使得想要手動去編輯這個 json 資料非常困難,必須要手動修復後再修改。

最常遇到這個問題的一個情境是,透過 kubectl create configmap xxxx --from-file=xxx.json 的方式將一個已知的 json 轉化成 configmap 的資料並存放。
該 Issue 回報於 2016 然而實際上就算於 k8s v1.19 都還是可以遇到這類型的問題,Issue 列表中有不少人在討論如何解決這個問題,基本上有幾大重點,掌握這些重點就可以避免 json 格式跑版
1. 避免使用 tab,全面使用空白
2. 移除任何 trailing whitespaces

如果有遇到這類型需求的的不彷試試看這些解法
https://github.com/kubernetes/kubernetes/issues/36222
本文闡述三個為什麼即使身為管理職缺,依然需要寫程式

網路上有非常多的文章再探討到底身為工程團隊的管理者,需不需要繼續寫程式來保持手感?
作者更好奇的是為什麼會有這類型的問題出現,假設今天目標是需要領導整個工程團隊並且讓每個工程人員都能夠更好發揮的情況下,管理人員為什麼要把時間花在沒有辦法達到上述目標的過程?

作者根據自身的經驗來思考這些問題,最後整理出三個理由想要分享給大家

1. Coding Give You Energy
"通常"會變成工程團隊領導者過去也都身為軟體開發人員或是相關的技術人員,能夠長時間位居於此職位且被考慮升等成領導人員的人,勢必都曾經對於 coding 與技術相關的工作擁有熱情。

某些人很享受撰寫程式的過程,能夠找到問題並且動手解決這些問題,透過這些行動讓自己感受到自己是真的有在工作,是有成果的。
相反的,作為一個管理人員,很多時候很難去解釋跟展示自己的能力與進度,沒有辦法像過往一樣簡單的說「這個功能我做的」來簡單展現自我成就,反而其績效可能會變成團隊是否有準時遞交新功能等以團隊為主的表現。

更重要的是,作為管理人員,每一週重新審思一週進度時,都很不好回答到底本週做了什麼樣的事情,更多時候都在處理底下人員間的互動與情緒。
透過重新 coding 能夠讓你找回自己的成就與存在感,讓你重新從撰寫程式中取得快樂,為枯燥的生活添加一些樂趣。

除此之外,還有提到一個是未來職涯的考慮,如果對於自身的職涯還處於一個探索期,甚至最後有想要從管理職轉回到IC (Individual Contributor)等職位,勢必到時候可能又會有一番的Coding面試。
為了確保自己繼續保持那些動手實作的能力與習慣以及隨時準備好轉職一番,培養撰寫程式的習慣能夠讓你更容易得去轉換跑道。

最後提到,最重要的一點其實是要先了解自己,知道自己到底需不需要繼續寫更多程式,如果自己從撰寫程式這個過程可以得到更多的成就,活力與喜悅,可能就要思考管理職缺是否是一個自己追求的長久目標。


https://betterprogramming.pub/why-engineering-managers-still-want-to-write-code-d1c04b4cadaf
本篇文章探討的也是資安系列問題,而這次的目標主角則是 MAC 系統上廣為流傳的 Homebrew 系統。

結論:
作者透過觀察 Homebrew 的 Github Action 流程,成功得上傳一個會列印一行的程式碼到 iterm2 套件中,讓所有安裝的使用者都會於 Terminal 上看到一行作者客製化的訊息。

本次的漏洞是作者刻意從 Homebrew 的 Vulnerability Disclosure Program 專案中去嘗試尋找可能的問題,所有的操作都有跟官方專案的人探討過流程,並且一切的 PoC 都是單純證明該攻擊的可行性,所以有興趣研究的人請遵循一樣的想法去做,不要認真的想攻擊。

原因:
1. Homebrew 透過 Github Action 執行 CI/CD 動作
2. Homebrew 撰寫了一個自動合併 Pull Request 的 Action
3. CI 內會透過一個Ruby的 Git Diff 第三方函式庫來驗證,只要符合下列條件就可以自動合併
- Modifying only 1 file
- Not moving/creating/deleting file
- Target filepath matches \ACasks/[^/]+\.rb\Z
- Line count of deletions/additions are same
- All deletions/additions matches /\A[+-]\s*version "([^"]+)"\Z/ or - -\A[+-]\s*sha256 "[0-9a-f]{64}"\Z
- No changes to format of versions (e.g. 1.2.3 => 2.3.4)

作者一開始想要從該規則下手,找尋有沒有可能塞入惡意攻擊並且騙過系統讓其自動合併,然而這些規則看起來沒有什麼太多問題,於是作者轉往其他領域去找尋問題,其中一個想法就是到底該 Ruby 的 Git Diff 是如何實作,也許從實作下手更有辦法去欺騙這一切。

很順利的是,作者真的於該函式庫中找到問題,對於一個 Git Diff 的結果來說,該函式庫會透過 +++ "?b/(.*) 這樣的正規表達式來判別檔案路徑的資訊而並非程式修改內容,譬如下列 diff
```
diff --git a/source file path b/destination file path
index parent commit hash..current commit hash filemode
--- a/source file path
+++ b/destination file path
@@ line information @@
Details of changes (e.g.: `+asdf`,`-zxcv`)
```

作者就開始思考,如果讓程式碼可以符合 +++ "?b/(.*) 的規則,是否有辦法讓程式碼不被視為一個檔案的修改,因此就可以修改多行程式碼但是讓 CI 系統認為只有一行程式碼於是進行自動合併

作者最初的想法如下,第一行用來放惡意程式碼,第二行用來偽裝檔案路徑,經過一番嘗試後作者真的成功塞入了類似 PRINTF 的程式碼到環境中並觸發自動合併。接者各地使用者透過 brew 安裝 iterm 版本都會看到使用者塞入的程式碼。
```
++ "b/#{Arbitrary codes here}"
++ b/Casks/cask.rb
```

原文還有更多作者的思路過程,有興趣的不要錯過

原文:
https://blog.ryotak.me/post/homebrew-security-incident-en/#fn:7
測試用PR:
https://github.com/Homebrew/homebrew-cask/pull/104191
這篇文章探討的是關於 Serverless 使用上的經驗分享

作者基於自身實戰經驗探討於 AWS 上使用 Serverless 的七種架構模式

模式一:
作者認為最簡單的模式,使用 API Gateway, Lambda Functions 配上 DynamoDB 來處理商業需求
團隊可以透過 API Gateway 來達到快取,限速等不同的調整


模式二:
針對微服務的架構調整,基於模式一進行延伸。
因為 API Gateway 以及 Lambda 相關的限制都是基於帳戶設定的(可以聯絡客服調高),因此模式二就是用更多的帳戶來處理更多的服務,藉此讓這些限制不會被許多服務共享。

模式三:
該模式是標準有前(SPA)後端應用程式的架構。

前端(Single Page Application)網頁放到不公開的 S3,前方透過 AWS CloudFront 來處理應用並且將 Request 給 Proxy 到後方 S3。而後端則是如同模式一的方式去部署

模式四:
模式三的延伸,如果需要使用者是來自於不同的地理位置,想要針對地理位置去進行更多處理時,會透過 CloudFront 作為 Proxy 來處理 Regional API Gateway.

剩下三種模式就不詳述,有興趣的可以閱讀原文看看七種模式

https://waswani.medium.com/serverless-architecture-patterns-in-aws-edeab0e46a32
這篇文章是個專案教學文,探討的是如何使用由 Rancher 所開發維護的 Harvester(HCI, 超融合基礎架構)專案。

雲端架構的特性能夠應付大部分的應用與場景,但是部分的應用則必須要繼續使用地端實體機器去架設服務。

虛擬化的時代,要如何將一個又一個硬體機器轉變成簡單好用的 VM 供上層應用程式使用則是一個有趣但困難的操作,開源的 Openstack 或是各種商業軟體則是眾多企業過往的選擇。

當這一切碰到 Kubernetes 時又變得複雜,主要是 Openstack 等專案強大卻難以駕馭,複雜的元件與架構讓它沒有辦法如 Kubernetes 一樣簡單好用,輕易上手。

如何讓一群硬體機器上面部署一個 Kubernetes 叢集不是一個困難問題,目前有眾多的解決方案幫忙處理,但是如何讓一群硬體機器上面跑出各種不同的 VM,並且於 VM 上面運行 Kubernetes 則是一個難以搞定但確實存在的需求。

Rancher 本身很擅長如何於一群 VM 上運行這些 Kubernetes 叢集,因此其發展了 Harvester 這個專案,該專案基於 Rancher 的 K3OS 作為底層作業系統。接者透過 Kubevirt 專案來管理與創建 VMs,儲存方面則是使用 Longhorn 來管理,網路的話則是 Kubevirt 本身已經導入 Multus CNI 來提供更多的網路操作。

這個專案還非常新,還在持續開發中,對於地端環境部署有需求的話,可以持續關注這個專案

https://blog.linnovate.net/baremetal-kubernetes-with-harvester-and-k3s-25fe9e7ab695
今天這篇文章要跟大家介紹的是 kubectl 一個好用的 plguin, flame,這個名稱就是大家所熟悉的火焰圖,所以長話短多。 kubectl flame 用來幫助維運人員針對任何已經運行的 Container 透過不同的 proflier 來進行效能分析,並且畫出相對應的火焰圖供研究。

對於維運人員來,透過 profiling 分析程式碼中存在的效能瓶頸是個非常常見的行為,有效的工具能夠幫助開發人員更快速的找到效能瓶頸並加以修正,而火焰圖則是一個非常知名的視覺化方式,將這些 profiling 的結果透過 stack 的方式顯示出來,讓開發人員一目了然地找到痛點。

雖然 profiling 聽起來如此強大,但是要於 Kubernetes 中針對運行的應用程式進行效能分析並不是如此簡單,主要是 profiling 通常會伴隨兩個條件
1. 程式碼需要修改,加入相對應的參數或是函數才能夠正確地將 function symbol 給顯示出來
2. 針對正式生產環境的除錯同時也會帶來效能影響的取捨,為了分析應用程式的效能意味者 profiler 必須要針對應用程式進行取樣與分析,這些都會帶整體效能上的影響。

更重要的事,如果今天要對一個已經運行的應用程式加上 profiling 需要的修改與參數,代表整個 Pod 會需要重啟來部署新版本的 Container Image。這類型的重啟可能會導致效能問題消失,整個除錯過程變得非常困難。

Kubectl flame 透過部署一個全新的 Container 到目標 Container 所在的節點上,同時透過 PIDNamespace 與 MountFilesystem 等方式來達到透過外部應用程式來幫忙進行 profiling,不過要注意的是不同的 profilter 所支援的程式語言不同。

有興趣的可以參考下列文章,甚至可以使用 pyroscope 這套 continuous profiling platform 來達成長時間的效能分析。

https://medium.com/swlh/introducing-kubectl-flame-effortless-profiling-on-kubernetes-4b80fc181852
本篇是一個 Kubernetes 的入門介紹文,探討 Kubernetes 內要如何透過 SSL/TLS 憑證來加強應用程式之間的連線。

本篇文章不使用任何第三方套件,反而是從 Kubernetes 內建的資源功能出發去探討,理解 Kubernetes 的能力與極限其實長久下來對於評估各種專案都滿有幫助的。

Kubernetes 的 Secret 除了使用 base64 作為編碼技術外,其實本身也提供不少類型方便管理人員使用,譬如本文提到的 tls 類型, container registry credential 以及最廣泛使用的 generic 等。

Secret(tls類型)本身創建時會吃兩個參數,分別是 tls.crt 與 tls.key,接者這類型的 secret 可以與 ingress 進行整合,將 TLS 給掛載到 Ingress 物件中並且同時執行 TLS Termination,讓 Ingres 與外部連線使用 HTTPS 而內部服務則使用 HTTP 來溝通。

文章中提到如何透過 openssl 創建一個 self-signed 的憑證,並且針對 self-signed 的特性進行討論,其列出了四個 self-signed 的缺點

1. 瀏覽器連接到這些 self-signed 憑證的網站時都會露出警告告知使用者,因此這類型的憑證不適合任何正式生產環境使用
2. 因為 self-signed 就是開發者自行創造,缺少第三方可信任機關的認證,因此惡意攻擊者可以輕鬆換掉服務上的簽證,畢竟瀏覽器本來就覺得簽證有問題,無法分辨到底是先前的自簽憑證還是被替換的憑證。
3. 第三方CA都會針對發行的憑證給予一些保固與服務,這部分是自簽沒有辦法擁有的
4. 愈來愈多的使用者會不太願意瀏覽與使用沒有合法且信任憑證的網站

作者提到 Kubernetes 內部雖然有一個 CA,但是不推薦把任何服務相關的憑證都跟其扯上關係,
因為該 CA 是給 Kubernetes 內部控制平面使用的,譬如 kubelet, API Server, Controller, Scheduler 等元件彼此溝通中間使用的。

文章最後作者示範透過 cfssl 的該指令幫一個內部服務創建一個憑證,由於內部服務會透過 Kubernetes Service 提供的 DNS 來存取,因此創建憑證時會於 CN 欄位補上 alternative 的名稱,把 service.svc.... 之類的全部都補上。


https://medium.com/avmconsulting-blog/how-to-secure-applications-on-kubernetes-ssl-tls-certificates-8f7f5751d788
本篇是一個入門介紹文,探討的議題是微服務架構下的監控架構要有什麼樣的元件與功能

Observability 基本上現在已經是個顯學,任何的叢集架構都需要有一個匹配的監控系統來(主動or被動)告知當前各種元件的狀況,讓維運人員能夠儘早地針對問題處理,減少任何損失。

普遍主流認為可觀測性底下目前有三大類別,分別是
- Metrics
- Logs
- Tracing

監控系統必須要能夠讓維運人員知道什麼元件壞掉以及為什麼,維運人員能夠快速簡單的定位問題的可能點,並且快速的找到真正的 root cause。作者認為發生問題時最重要的就是要找對地方,就算今天環境中架設了各式各樣的儀表板並且收集了四面八方的資料,如果發生問題時沒有辦法準確的找到進入點,那再多的工具也都沒有用途。
作者列舉了四個必須要從任何服務都要收集的相關 Metrics,包含
- Latency: 每個服務請求花費的時間
- Errors: 系統中發生錯誤的訊息,甚至是沒有辦法被正確處理的請求
- Traffic
- Saturation: 服務用量的測量,譬如CPU/Memory/Disk/Network

接者要針對每個 Metrics 選決定一個適合的觀察類別,譬如說
1. Counters: 透過數值來表示各種可累積的 metrics,譬如 request 的數量, error 的數量。
2. Gauges: 透過數值來表示一種會上下起伏變化的 metrics, 譬如跟 database 的連線數量, 記憶體/CPU 的使用量,系統平均負載值
3. Histograms: 需要將取樣觀察結果依照不同類別來分類顯示,譬如 I/O latency

當監控系統建置完畢後,接下來就要有能力使用該系統來進行主動回報,也就是所謂的 Alert 系統。
當元件的狀況符合預先設定的條件時,就要通知維運人員來檢查與處理,這邊作者特別提到針對 Alert 的規則必須要仔細的設定分類與優先度,特別是當某些服務或是底層架構觸發時,可能會一口氣觸發多個 Alert 通知,這時候要如何快速的從眾多警報中找到真正的源頭就經驗搭配良好的系統規劃。

https://medium.com/@milan.brankovic/monitoring-microservices-e0f89496fa9e
本篇文章要介紹的是 2021 年熱門的日誌視覺化分析工具,作者於本篇文章列出 8 種不同的工具,分別是

1. Logiq.ai (2019 創立)
2. Datadog (2010 創立)
4. Dynatrace (2005 創立)
5. Logz.io (2014 創立)
6. Graylog (2009 創立)
7. Google Cloud Logging
8. Scalyr (2011 創立)
9. LOGalyze (開源專案,但是官網連 HTTPS 都沒有....)

作者列出的基本上都是商業解決方案,要使用開源方案還是商業解決方案一直以來都沒有絕對的答案,畢竟一個解決方案除了功能完整性之外,技術支援也是非常重要的一環。

好奇上述的解決方案大家有沒有相關使用經驗?

https://medium.com/nerd-for-tech/top-log-visualization-tools-in-2021-fa0a2d897ad1
今天帶來的內容是關於 DevSecOps 的介紹,由 synk 這間公司所撰寫的 DevSecOps 介紹,與其說是文章更像是一個專欄,內文非常豐富,從基本的介紹,到文化,人員組成,運作流程以及相關技術探討都包含其中,我認為對這個領域有興趣的人很值得花些時間咀嚼一下這系列文章,來看看到底別人認知的 DevSecOps 到底是什麼。

本篇文章針對 overview 的部分進行介紹,其餘詳細部分請到連結中閱讀囉

What is DevSecOps:
1. 將 Security 的概念帶入到 DevOps 的軟體交付流程
2. Dev & Ops 共享責任來交付安全的應用與軟體

從功能面來看,盡可能地於整個軟體開發交付流程中盡可能早的發現安全並且修復,要特別注意的是"安全是所有人共享的責任"並不是單純 DevOps 團隊人員的責任,大夥還是努力合作一起解決問題,就如同 DevOps 的概念一致。

6 Benefits of the DevSecOps Model
- Faster delivery: 將 Security 等概念整合到軟體交付流程中時,可以讓任何漏洞於正式部署前就發現與解決,這樣可以使得整體的開發流程更加順利與快速。
- Improved security posture: 資安不再是個上線後才要擔心的議題,而是打成軟體設計開發初期就要關注的點,透過這個方式才有辦法把資安跟建置,部署進行一個緊密的整合
- Reduced costs: 正式部署前能夠定位找到任何 vulnerabilities 能夠有效率地減少各種維運上的風險成本。
...等

原文非常有趣,非常推薦有興趣的閱讀這整篇專欄

https://snyk.io/devsecops/
本篇文章是ㄧ個 Kubernetes 相關工具經驗分享文,作者認為即使是前端開發工程師也必須要瞭解一下 Kubernetes 這個容器管理平台,作者認為 k8s 基本上已經算是這個領域的標準(de-facto)。

因此作者於本篇文章介紹一些搭建一個 K8s 叢集時需要注意的工具,透過這些自動化工具來減少反覆動作的執行藉此簡化每天的工作流程。

工具包含
1. ArgoCD
2. MetalLB
3. External-secrets
4. Cert-manager
5. External-dns


Simplify deploying of new apps
作者大力推薦使用 ArgoCD 來簡化部署應用程式,作者提到一開始使用 ArgoCD 時也是感到無比煩感,因為心中一直存在要於 `GitLab CI/CD pipeline` 透過 kubectl apply 的方式來部署應用程式,並不想要導入其他的元件來加入更多的複雜性。

然而當作者嘗試 ArgoCD 後,第一眼發現的是其架構不如想像中複雜,完全依賴 GitOps 的原則來簡化整個部署流程,同時透過一個 WebUI 的方式來呈現當前應用程式的部署狀況

Load balancer for your on-prem clusters
地端環境的 Load-Balancer,沒什麼好說就是 MetalLB。

Managing your secrets
Secrets 是 Kubernetes 內一個非常重要的物件,然而大部分的團隊都會思考如何有效且安全的去管理 Kubernetes 內的 Secret 物件。雲端供應商譬如 AWS Secrets Manager, Azure Key Vault 或是廣受熱門的 HashiCorp Vault.

作者推薦使用 external-secrets operator 這個專案來將外部的管理系統給同步到 Kubernetes 內並且產生對於的 secrets。


詳細全文可以參考下列原文

https://chris-blogs.medium.com/tools-that-should-be-used-in-every-kubernetes-cluster-38969ed3e603
本篇文章是經驗分享文,作者分享為什麼其跟最初學習 Kubernetes 使用的 minikube 說掰掰,而轉換到新歡 KIND 的故事

作者之前演講分享時,透過 minikube 架設所有 demo 環境,平常使用都好好的然而活動前幾天開始覺得叢集有點慢,但是作者並沒有特別注意去處理。
活動當天 demo 直接爆炸,系統變得很慢,不論是 pod 的各種操作都很慢,作者沒有辦法很漂亮的清除 minikube 內的環境,最後只好砍掉VM全部重來。

活動結束後作者重新創建了一次整個 VM(使用 VirtualBox),結果整個系統還是很慢,作者開始思考有沒有其他的替代方案,後來找到了 Kind 這套解決方案。

KIND 是 Kubernetes In Docker 的縮寫,透過 Docker Container 的方式創建節點並基於該節點創建 Kubernetes 叢集。

這邊要注意的是 KIND 透過 Docker 創建節點,而節點內卻使用 Contaeinrd 作為 k8s 的 CRI 解決方案。

除了 KIND 之外, Rancher 維護的 K3D 也是一樣類型的創建方式,其中 K3D 支持動態加入與移除節點,KIND 只能一開始創建時就定好 cluster 的大小。

https://nfrankel.medium.com/goodbye-minikube-340070edc5af
本篇文章是一個經驗分享文,作者探討使用 Rancher 遇到的問題,以及最後是如何使用 Kubecost 來解決成本使用的分析問題。

作者認為 Rancher 對自己公司的 DevOps Team 來說是個非常好用的工具,透過 Rancher 的視覺化工具,任何人都可以清楚的去管理以及檢視當前 K8s 叢集內的各種資訊,對於任何加入團隊還不熟悉 Kubernetes 的開發者來說,Rancher 的特色讓這些新開發者容易上手,熟悉概念後再轉往理解 kubectl 等工具的使用。

不過作者公司團隊遇到的問題是 Kubernetes 內不同專案彼此的成本用量難以計算,雖然 Rancher 內有再提供一個 Project 的抽象介面,可以控管 Project 底下的 CPU/Memory 以及相關物件的分配。

但是這樣還是有三個問題沒有辦法解決
1. 無法有效且快速的知道每個 namsepace 底下於 Node 上所佔的資源比例
2. 當一個 Team 本身會使用到多個 namespace 時上述的計算會變得更加麻煩。
3. 團隊看透過 kubectl top 去計算,或是使用 Prometheus/Grafana 來整合計算,但是實際上還是一個困難的麻煩事

作者最後從 Rancher 的線上研討會中,聽到了 Kubecost 有趣的專案,該專案可以順利的與 Rancher 整合,基於 Rancher Project 作為基本分類,來檢視每個 Project 底下各種資源的使用量,同時搭配金額的分配還可以把使用量轉換成實際的金額,團隊更有能力去估算使用量。

有興趣的可以閱讀全文並且嘗試看看 kubecost 這個工具
https://itnext.io/kubecost-rancher-saved-df30fe77135b
本篇文章是一個技術探討文,探討 Docker 是如何使用硬碟空間以及當維運人員發現空間不足時應該要如何清理系統上的空間。

Docker 的便利使用方式使得開發人員可以非常簡的透過的 Container 的概念來運行各式各樣的應用程式,這中間牽扯包含 Image 的建置,抓取以及透過其產生出一個運行的 Container。
隨者時間愈用愈久,系統內可用的空間也會愈來愈少,這時候可以透過 docker system df 來觀看一下目前系統上的空間資訊,主要包含下列四種類型,而每個類型也會包含目前使用量以及可以回收的量有多少
1. Images
2. Containers
3. Local Volumes
4. Build Cache(只有 docker 18.09 後使用 buildkit 才會有)

當 Contaienr 被創建時, /var/lib/docker 底下會有很多檔案以及資料夾都被創建出來,譬如

- /var/lib/docker/containers/ID (資料夾):如果 container 使用的是預設的 logging driver,則 log 檔案都會以 JSON 的格式存放於這個資料夾底下。
所以要注意,當 contaienr 有太多 log 時,其會透過這個方式影響節點檔案系統的容量
- /var/lid/docker/overlay2 (資料夾): 這邊包含了 containers 本身的 read-write layer 的檔案,大部分 Linux 發行版預設都會使用 overlay2 來管理。此外 contaienr 內如果有存放任何額外檔案於系統中,實際上都會放這節點上的這個資料夾內。

接下來作者透過一個實際的範例,讓一個全新的 contaienr 內透過 dd 指令來產生一些檔案,並且觀察上述資料夾的變化以及 docker system df 的結果,最後介紹 docker prune 以及 docker rm 針對 contaienr 的處理。

關於 image 的部分,除了常規使用的 Image 外,還有
1. Dangling images: 不再被參考使用的 image,譬如 ID/Tag 都是 None 的
這邊可以透過 docker image ls -f dangling=true 的指令

文章後半部分還有介紹 docker volume 以及 build cache 的部分,這篇文章非常推薦大家閱讀,除了基本使用外還會介紹底層 docker 實際上用到的資料夾,有了這些概念未來對於如何清除 docker 環境就會更有概念,知道要刪除哪些資料夾以及為什麼要刪除。

https://betterprogramming.pub/docker-tips-clean-up-your-local-machine-35f370a01a78
這篇文章是 Tekton 這套號稱完全針對 Cloud-Native 所發展的 CI/CD 工具教學文,作者從基本概念到如何使用都詳細的介紹一番,讓讀者看完就對 Tekton 能夠有基本的認知。

就如同其他常見的 Pipeline 系統一樣,Tekton 的工作流程是由 Step, Task 以及 Pipeline 組成。Tekton 使用 Step 描述每個最小工作事項,而每個 Task 則由數個 Step 組成,這些 Step 會依序執行,且彼此會共用相同環境,譬如 Volume.
Pipeline 則是由數個 Task 所組成,不過比較特別的是這些 Task 可以有更為靈活的執行順序,譬如依序執行,平行執行,甚至是 DAG 這種有向無環圖的執行順序。


Tekton 的一大特色是其完全寄生於 Kubernetes 內,必須要搭配 k8s 的環境來使用,也因此上述的 Step,Task 以及 Pipeline 實質上都是屬於 K8s 的 CRD 一種,部署時需要透過 YAML 來撰寫,並且用常見的方式 (kubectl, helm, kustomize) 來安裝到 k8s 內去設定 Tekton。

這種模式帶來的一個好處就是每個元件都是獨立的 YAML 檔案與類別,因此相同的部分可以非常輕易的被重複使用,舉例來說一個運行 Git-Clone 的 Task 就可以被多個不同的 Pipeline 重複使用,而有需求需要修改的時候也只需要修改一個 Task 即可。

對於 Tekton 這套解決方案有興趣的可以參閱下列全文玩耍看看
https://lambda.grofers.com/adopting-tekton-cloud-native-ci-solution-67fb229f4992
本篇文章是個經驗分享系列文,作者探討 Kubernetes 內 15 種不被建議的部署策略與模式。
作者之前曾經撰寫過 Contianer 架構底下的部署模式探討,而本系列文(三篇)則是著重於如何將這些 containers 透過 Kubernetes 給部署到生產環境,總共會探討十五種不推薦的模式,接下來的三篇文章將會介紹各五種不好的模式。

Using containers with the latest tag in Kubernetes deployments
任何 container 的 image 都不應該使用 latest,因為 latest 本身沒有任何意義,這會使得維運人員沒有辦法掌握到底當前部署的版本是什麼,更嚴重的情況適當 latest 搭配 PullPolicy:Always 時會產生更為嚴重的問題。因為 Always 的策略導致每次 Pod 部署時都會重新抓取 image,所以一個 deployment 中,多個使用 latest tag 的 Pod 但是其實使用的 image hash 是不同的。

作者認為比較好的做法有
1. 所有 container image 都是不可修改的,一旦建立就禁止覆蓋,有任何改動就進版
2. 部署用的 image tag 使用有意義的版本名稱

補充: 實際上 pull image 也可以使用 sha256,譬如 "docker pull hwchiu/kubectl-tools@sha256:acfb56059e6d60bf4a57946663d16dda89e12bfb1f8d7556f277e2818680e4c8"


Baking the configuration inside container images
任何 contaienr image 建置的時候應該都要往通用的方向去設計,而不是參雜各種設定在裡面。著名的 12-factor app 裡面也有提到類似個概念,建置好的 image 應該要可以 build once, run everywhere,動態的方式傳入不同的設定檔案,而不是把任何跟環境有關的資訊都寫死
舉例來說,如果 image 內包含了下列設定(舉例,包含不限於)
1. 任何 IP 地址
2. 任何帳號密碼
3. 任何寫死的 URL

作者認為比較好的做法有
1. 透過動態載入的方式來設定運行時的設定,譬如Kubernetes configmaps, Hashicorp Consul, Apache Zookeeper 等
2. 根據不同程式語言與框架甚至可以做到不需要重啟容器就可以載入新的設定


Coupling applications with Kubernetes features/services for no reason
作者認為除了很明確專門針對 Kubernetes 使用,或是用來控制 Kubernetes 的應用程式外,大部分的 應用程式包裝成 Container 時就不應該假設只能運行在 Kubernetes 內。作者列舉了幾個常見的使用範例,譬如

1. 從 K8s label/annotation 取得資訊
2. 查詢當前 Pod 運行的資訊
3. 呼叫其他 Kubernetes 服務(舉例,假設環境已經存在 Vault,因此直接呼叫 vault API 來取得資訊)

作者認為這類型的綁定都會使得該應用程式無法於沒有 Kubernetes 的環境運行,譬如就沒有辦法使用 Docker-compose 來進行本地開發與測試,這樣就沒有辦法滿足 12-factor 中的精神。
對於大部分的應用程式測試,除非其中有任何依賴性的服務是跟外部 Kubernetes 綁定,否則這些測試應該都要可以用 docker-compose 來叫起整個服務進行測試與處理。
服務需要使用的資訊應該是運行期間透過設定檔案,環境變數等塞入到 Container 內,這樣也呼應上述的不要將與環境有關的任何資訊都放入 image 內。

Mixing application deployment with infrastructure deployment (e.g. having
Terraform deploying apps with the Helm provider)
作者認為近年來伴隨者 IaC 概念的熱門,愈來愈多的團隊透過 Terraform/Pulumi 這類型的工具來部署架構,作者認為將部署架構與部署應用程式放到相同一個 Pipeline 則是一個非常不好的做法。

將基礎架構與應用程式同時放在相同 pipeline 可以降低彼此傳遞資訊的困難性,能夠一次部署就搞定全部,然而這種架構帶來的壞處有
1. 通常應用程式改動的頻率是遠大於基礎架構的改變,因此兩者綁在一起會浪費許多時間在架構上
假如部署基礎架構需要 25 分鐘而應用
本文延續前一篇文章,作者探討十五種 Kubernetes 不該使用的部署與維運模式,總共三篇,每篇五種。


Using Kubectl as a debugging tool
作者認為一個良好的 Kubernetes 叢集必定要有一個相對應個可觀測性工具,包含 Metrics/Log/Tracing 等。對於一個維運人說來說,今天要處理事情時,第一件事情如果還是慢慢的用 kubectl 來執行 get, describe ,log 等指令找問題的話就太慢了,這類型的工具都應該只是輔助使用,真正還是要依賴有效的監控系統,不論是常見的系統指標,應用程式狀態甚至是應用程式獨特的指標等,將這些資訊整合到一個方便顯示的儀表板,甚至搭配對應的 Alert 功能來達到主動通知。


Misunderstanding Kubernetes network concepts
Kubernetes 內提供的網路功能很容易被搞混,Service(ClusterIP, NodePort, LoadBalancer) 與 Ingress 的差異到底是什麼,很多初次踏入 Kubernetes 的玩家沒有特別去理解差異,只知道應用程式部署後就可以通了。Service Mesh 這個概念作者也推薦去學習與瞭解,知道這個概念是什麼,以及想要什麼解決問題就好,因為並非不是每個叢集都真的需要一套 Service Mesh 的解決方案,但是理解這個概念未來就有能力知道什麼時候需要導入。

Using permanent staging environments instead of dynamic environments
對於應用程式開發者來說,如何於 Kubernetes 環境上測試新功能一直都是一個困難的問題。大部分的團隊中都會有 QA/Staging/Production/Dev(甚至更多)的環境,假設 Dev 環境可以供開發者測試,這些開發者要如何確保自己的修改沒有問題且通過整合測試。
一個常見的問題是假如多個開發者同事部署自己的程式碼到固定環境中,有可能會造成互相干擾,導致問題發生時沒有辦法正確的判別問題是誰產生的。
作者提到一種作法就是透過預借的概念,確保每個開發者使用叢集時都不會有他人干擾,然而這個問題也會引發其他問題,譬如開發者間要互相協調時間,同時每個人用完環境後都要還原成穩定的狀態,以免干擾下一位的使用。

作者推薦使用動態叢集的方式來進行測試,使用 Github PR 為範例,當 PR 開啟時,動態創建 Kubernetes 叢集供測試,當 PR 合併後就會將該 Cluster 給移除。透過這種範例每個開發者都可以有獨立的環境進行測試彼此不干擾,同時也會隨者程式碼的合併而自動回收環境,也不需要擔心環境污染問題。

Mixing production and non-production clusters
任何團隊一定要有正式生產環境的叢集跟其他叢集分隔開來,千萬不能使用 namespace 的方式於一個叢集中同時維護生產與非生產環境。譬如
1. 任何人操作 Kubernetes 都很容易失誤,譬如指令下錯,指向錯的物件。這類型的操作都有可能導致該叢集上生產環境被誤刪
2. namespace 的隔離性不好,實際上很多物件彼此還是可以互相存與溝通,這部分也有其他的隱憂

詳細原文可以參考下列連結。

https://medium.com/containers-101/kubernetes-deployment-antipatterns-part-2-2af25a710bc0
本篇文章是個經驗分享文,作者分享使用 Docker 作為開發環境時值得注意的 Best practices,透過這些經驗分享希望能夠讓開發者少走一些冤枉路。

原文提出了 15 個經驗談,這邊幫大家節錄幾個,有興趣的可以點選原文瞭解更多!
1. One thing at a time
2. Be ephemeral
3. Utilize .dockerignore
4. Less is more
5. Secrets should be secret
6. PID 1 is your birth right
7. Share and Care
8. Vulnerability Scan
9. Tag like you mean it
10. Permissions are costly
11. Source of Truth
12. Always official
13. Don’t include debug
14. Use entry point script smartly
15. Size does matter

One thing at a time
建置 Image 的時候專注做好一件事情,每個 Image 應該有一個專心要解決的問題,譬如一個應用程式,一個小工具等。對於 Nginx 這類型的 Image 來說,應該沒有人會期望於裡面看到有 Apache 的應用程式吧?

Be ephemeral
這個主要探討的是該 Image 本身建置時應該要以 stateless 的概念去處理,未來不論是透過 docker 或是 Kubernetes 來管理部署時,Contaienr 都很有機會被重啟,每次的重啟都意味該容器是重新啟動。所以千萬不要讓你的 Image 變成多次重啟會導致應用程式出問題的形式,任何的這類型資料應該都要透過外部取得,不要塞到你的 Image 內

Utilize .dockerignore
善用 .dockerignore 這個檔案來將不必要的檔案從 build 過程給排除,使用方法與 .gitignore 類似。透過這個檔案的設定可以避免 docker build 的時候不會把一些過大或是完全不需要的檔案都送給 docker daemon,不當浪費時間也浪費空間。

Less is more
避免安裝任何無關或是非必要的套件到你的 image 中,特別是那些 "nice to have" 的理由。

註: 我個人是滿討厭把 Image 弄得很乾淨的,除錯什麼工具都沒有,連 ash/sh/busybox/bash 都沒有的 image 更是我討厭中的排行榜冠軍

Secrets should be secret
任何機密資訊都應該要於運行期間動態載入,而不是建置期間塞入。請使用其他工具譬如 Vault 來管理這些機密資訊,並且執行期間讓 Container 能夠存取到正確的值。

PID 1 is your birth right
Linux 環境下會使用 SIGTERN, SIGKILL 等相關的 Singal 來戳你的應用程式,請確保你運行的應用程式要能夠攔截這些訊號來處理並完成有效的 Graceful shutdown.

Share and Care
如果環境中有多個 Image 彼此有共享相同的工具與功能,與其每個 Image 都單獨建置維護不如建置一個 Base Image,接者讓所有要使用的 image 去載入使用即可。
透過這種方式可以讓整體的維護性與管理性更為簡單,每個 image 可以減少重複的程式碼,同時要升級時只要針對 base Image 處理即可。


https://medium.com/pradpoddar/avoid-costly-mistakes-using-advanced-docker-development-best-practices-acd812784109