關鍵字: conntrack, DNS, CoreDNS-autoscaler
影響: 部分正式生產環境崩壞

整個問題是簡單來說就是正式叢集再不預期的情況下,發生了 DNS 的問題,導致內部服務大概有 15000 筆 query 失敗。造成錯誤的原因是因為 kube-proxy 沒有順利地去移除過期的 conntrack,導致有些 DNS封包被導向到一個已經不存在的Pod。

這個問題的發生前提是,因為某些情境的發生,譬如系統負載過低, CoreDNS-autoscaler 就被觸發起來,將運行的 Pod 數量從三個降為兩個。所以系統上能夠處理 DNS 的Pod剩下兩個,但是如果有節點上的 conntrack 沒有順利清理乾淨,導致所有的封包都被導向那個被刪除的 CoreDNS,問題就這樣發生了。

詳細的過程跟一些學習重點可以參考原文

註:想要掌握 kubernetes 網路,對於 conntrack 的認識絕對不可以少,有太多太多的問題都跟 conntrack 有關,從 race condition, max 等眾多選項都牽扯所有運行的封包。有時間的話一定要好好的複習一下 conntrack 的概念

https://medium.com/preply-engineering/dns-postmortem-e169efd45afd
關鍵字: GKE, CPU Limit, CPU throttling
影響: 服務出現高延遲性,甚至出現錯誤

總結: 作者推薦關閉 Kubernetes 內任何 CPU Limit 的功能(或是從 kubelet 關閉 CFS quota)直到節點上的系統都已經修復 CFS 的相關問題,這個問題會導致不必要的 CPU throttling 並可能導致應用程式短暫時間卡住不回應。

這篇文章內容非常豐富,開頭介紹 container & kubernetes 的基本概念,接下來探討到底 CPU request/limit 是如何實作的,並且透過一個範例來介紹為什麼 kernel bug 會導致整個應用程式卡住


原文下方還有列出各種相關連結,包含 kernel 內的相關文件以及 kubernetes 內探討這個問題的 issue。

https://medium.com/omio-engineering/cpu-limits-and-aggressive-throttling-in-kubernetes-c5b20bd8a718
關鍵字: KIAM, DNS, AWS IAM, latency
影響: 存取服務會花上高達十倍的延遲時間

這篇文章準確的說,問題其實跟 Kubernetes 本身關係不大,反而是遷移 Kubernetes 到系統中常見的溝通問題。作者的標題是真真實實來自 Dev Team 的回饋,當應用程式搬移到 kubernetes 後得到的效果不如預期,也許最後不是 kubernetes 的問題,但是 SRE/DevOps 還是得必須針對這些質疑去探討,找出最後真正的原因。

作者團隊當初要將一個微服務從 EC2 上給整合到 Kubernetes內,卻發現存取該服務的延遲性相對於直接部署到 EC2 上大幅度上升十倍。根據團隊的調查,EC2 的應用程式只需要 20ms 左右回覆請求,而 kubernetes 版本則需要 200ms 左右。

最後來來回回除錯找到問題根源,主要是 AWS Jave SDK 裏面的用法於不同的情境下會有不同的效果。其於 Kubernetes 下會發生每個 request 都強迫去刷新當前的 certificate 資訊,因此每個 request 都還會額外發送一個新的 request 去取得 certificate。

基本上整個問題都跟 Kubernetes 的架構無關,單純是 AWS 架構的用法,如果你有使用 KIAM 相關的服務,同時也有使用 AWS Java SDK,可以參考本篇的問題

https://srvaroa.github.io/kubernetes/migration/latency/dns/java/aws/microservices/2019/10/22/kubernetes-added-a-0-to-my-latency.html
關鍵字: Weave Scope, public AWS ELB
影響: 安全漏洞,系統被挖礦

結論: 作者團隊(JW Player) 的 dev/stage 團隊被發現種植了惡意挖礦程式,因此撰寫了這篇文章來跟大家分享他們的經過,並且期許大家都可以強化自家的 Kubernetes 叢集,避免被各種惡意程式攻破。

1. 一開始是透過監控軟體發現 stage 中有過高的 CPU 使用量,然而系統服務本身就會造成這些過高的使用量,因此團隊沒有第一時間懷疑有問題。隔天於 dev 中也有相關報告,團隊也沒有特別處理,直到這些逐漸提高的 CPU 持續過久,團隊才覺得有問題,開始介入調查。
2. 發現一個名為 gcc 的應用程式是透過 docker 運行的,然而團隊中沒有任何使用 gcc 為 entrypoint 的容器,輾轉發現這個容器的 parent process 則是 weave scope.
3. Weave scope 是一個用來監控 kubernetes 的應用程式,完全沒有理由去運行 gcc,與此同時觀察到這個 gcc 是一個挖礦軟體
4. 最後發現 Weave scope 這個應用程式對應的 Load Balancer 是完全對外公開的,同時也沒有任何認證登入機制
5. Weave scope 本身提供了一個功能可以讓使用者於網頁上去跟容器互動,這邊最後就導致了惡意攻擊,被注入了挖礦程式

文章內有更多的細節關於惡意程式的探討與回顧,有興趣的別忘記點擊原文看看

https://medium.com/jw-player-engineering/how-a-cryptocurrency-miner-made-its-way-onto-our-internal-kubernetes-clusters-9b09c4704205
今天帶來的是 CNCF 使用者科技雷達第四篇的介紹,這篇報導探討的是 Storage/Database 的調查報告

報告中顯示了六個最被大家推崇的解決方案分別是
1. Redis
2. Elasticsearch
3. PostgreSQL
4. MySQL
5. Memcached
6. Kafka

同時根據調查報告, CNCF 團隊觀察到公司對於 Storage/Database 的選擇是非常謹慎小心的,沒有必要不會隨便遷移解決方案。特別是當本來的資料已經達到 TB 甚至 PB 等級時,遷移帶來的成本非常巨大,如果新專案帶來的好處沒有辦法蓋過這些成本時,很難說服團隊去遷移。

詳細的報導介紹可以參考下列原文

https://www.hwchiu.com/cncf-tech-radar-storage.html
今天帶來的是一篇 Podman 的介紹文,有關注 Container 發展的讀者想必對於 Podman 這個詞一定很熟,然而有真的實際將 podman 導入日常工作流程的我想屈指可數。
本篇文章開頭針對 Podman 與 docker 的差異進行了簡單介紹,並且分析 Podman 透過
1) 沒有 Daemon, 2)不需要 Root 也可以運行 等特性帶來的好處。

接者針對 MacOS, Windows 等兩種不常見的平台介紹如何運行 Podman, 對於非 Linux 工作環境的讀者如果有想要嚐鮮使用 Podman 的話,非常推薦可以參考這篇文章的方式去使用與安裝

最最最重要的是,本篇文章是繁體中文所撰寫的,請大多多給予這類型的文章一點鼓勵,大家才會更有動力去分享各類技術文章,否則都只能看國外文章了:(

https://hazel.style/2021/01/14/%E5%9C%A8Laptop%E7%92%B0%E5%A2%83%E4%BD%BF%E7%94%A8Podman%20(%E5%90%AB%20Windows%20&%20MacOS)/
#NetDevOps

今天這篇文章是一個數據調查文,主要內容是探討基於 NetDevOps 的文化下,網路維運人員使用哪些工具來協助日常的網路工作。

這份 2020 的報告總共有 333 的投票者,總共有一個月的投票時間。
整個文章總共有 49 個表格,非常的多...
這邊就列舉幾個大家可能比較有興趣的表格來幫大家預覽,當然對於整體有興趣的人還是不要忘了點選全文瀏覽!


每個項目都列舉前六名,標準基於使用正式於生產環境的票數
感興趣或是已經使用的工具
1. Ansible
2. Grafana
3. Netbox
4. ELK
5. EVE-NG
6. Promethes

感興趣或是已經整合的主題
1. Source of Truth
2. Network Health Moniroting
3. IaC
4. DevOps
5. CI
6. CI/CD

使用何種解決方案來自動化處理設定檔案
1. Ansible
2. 內部開發工具
3. NAPALM
4. Nomir
5. Terraform
6. 網路供應商的自主工具

如何控管設定檔案的改變
1. VCS
2. Rancid/Oxidized
3. 內部開發工具
4. 網路供應商的自主工具
5. FTP/SCP/TFTP
6. Solarwind NCM

管理哪些網路廠商的設備
1. Cisco IOS/IOS XE/Viptela
2. Cisco NX-OS/ACI
3. Juniper
4. Cisco IOS XR
5. Cisco ASA
6. Palo Alto

使用何種工具來模擬虛擬網路設備或是功能驗證
1. GNS3
2. VMWare
3. EVE-NG
4. 網路供應商工具
5. Docker Compose
6. Vagrant


網通業者的生態與軟體業者是截然不同的,很多軟體業習慣的操作流程與直覺並不是這容易的直接套用到網通業者的環境中。
舉例來說,使用公有雲創建 VM 並且於 VM 叢集上搭建出一個初始的工作流程並不難,Kubernetes 套上去後,就可以用容器的方式把各種應用,譬如 Prometheus, Grafana, logging, tracing, message queue 等服務都搭建到各個伺服器上。
對於網通業者來說,今天掌管的目標是 Switch 跟少部分的 Server,光 Switch 要買哪一家就是一個問題。
Switch 不太像 X86 架構一樣,想換什麼 OS 就換什麼 OS 這麼輕鬆,不走 whitebox 的架構下,一旦採購了某家廠商的解決方案,有可能就終生是對方的形狀了。這也是很多人都在提倡希望透過標準化來避免 vendor lock-in 的狀況。
上述的報告也可以看到前六名管理的機器中有四名都來自 Cisco 的機器,這種情況下很多事情都會受限於 Cisco 機器本身的設定與狀況,並不是想要做什麼就做什麼。

為了讓這一切變得簡單,如果可以透過標準化的方式去定義 switch 的架構,讓這一切變得如操作 Server 般簡單時,網通業者就會有另外一種方法來管理環境。
如果相關的軟體都有開源專案可以使用,這樣維運人員就可以用更省錢的方式來安裝與控管這一切的網通設備,聽起來真的很棒
現實生活上則是,網路產業對於 uptime 的需求非常的強,一旦出問題不是單純服務不能連,而是可能影響數千數萬甚至更多的使用者。這種情況下如果團隊全部使用開源專案而沒有 SI 公司的支援與維護,誰敢冒這個險去使用這些呢

最後要說的是,隔行如隔山,永遠不要用自己習慣的工作流程去看待別的產業,很容易被打臉。

https://dgarros.github.io/netdevops-survey/reports/2020
本篇文章來自於 CNCF 使用者雷達第四篇,探討 secret managemetn 的解決工具

如同前面三篇調查一樣,主題比較是一個大方向的探討,CNCF 會員會基於這個主題去提出用到的所有工具,所以可以觀察到結果內會有 Cert-Manager 也同時會有 KMS, Vault 等工具

結論來說: Vault & Cert-Manager 各自於自己的領域撐起一片天
詳細的可以點選下列內容觀看更多介紹與分析


https://www.hwchiu.com/cncf-tech-radar-secrets.html
本篇文章是個技術分享文,Netflix 分享內部過去四年來是如何打造一個分散式的 Tracing System。
Netflix 的串流服務想必大家都很熟悉,但是作為服務提供者來說,要如何維運這套分散式的串流服務就沒有這麼簡單。

舉例來說,當一個特定的使用者回報其服務有問題時,內部的系統要如何把下列資訊給全部串接起來組合出一個可以讓內部工程人員除錯的機制
1. Streaming Session
2. 微服務之間的流量
3. CDN 的處理

對使用者來說就是串流有問題,但是背後的網路封包實際上經過哪些 app,走過哪些節點,踏過哪些機房都是很複雜的事情,不把這些全部資訊都組合起來則非常困難除錯。

Netflix 決定要針對這個問題打造一個分散式的 Tracing 平台,而那時還沒有這麼多如 Opentracing, Zipkin, Jaeger 等相關的開源專案可以用,所以 Netflix 必須要自己去打造這套系統。
這套系統的組成跟現今常見的架構雷同,Application 本身要透過 Library 來產生出 Tracing 需要的資料,接者透過一套串流處理將資料給傳送到後端的儲存空間,最後則是由UI等相關服務來讀取資料方便使用

本篇文章基於這種架構下去探討 Netflix 的心路歷程,其中幾個比較有趣的問題這邊列出來
1. Tracing 資料的取樣該如何設計,過於頻繁會造成資料空間使用過量,過於稀少則會造成資料不夠完整,這部分 Netflix 採用基於 hybrid head-based 的取樣方式,針對特定區間採用 100% 的取樣方式,而其餘則是根據設定來隨機取樣
2. 資料儲存的部分則是有非常豐富的變化歷史,早期使用 ElasticSearch 後來對其 R/W 的效能感到不滿而輾轉到使用 Cassandra,而 Cassandra 最初使用 AWS 的 SSD 做為底層應用,後來改轉使用 EBS 並且搭配資料壓縮與一些過濾機制, 2021 決定要引入 Storage Gateway 的方式來處理

儲存方面幾乎是每年都在改善與改進,真的要遇到問題才有辦法針對問題下藥,這也是架構方面很難一口氣做到最好,隨者業務與流量擴大,很多現有的架構可能都需要打掉重來才有辦法應付

全文不算太短,但是推薦有興趣的人可以閱讀全文來看看 Netflix 是如何打造這套系統的

https://netflixtechblog.com/building-netflixs-distributed-tracing-infrastructure-bb856c319304
本篇文章標題為四個為什麼要於 Serverless 年代使用 Kubernetes 的理由,文章主要從幾個方向下手
1. 什麼是 Serverless, 為什麼 Serverless 這麼熱門
2. 使用純 Serverless 遇到的問題是什麼
3. 為什麼 Kubernetes 很棒

標題看似 Serverless & Kubernetes 是個二選一的議題,實際上文章內強調的反而是兩者設計目的不同,無法互相取代彼此,各自有適合使用的場景。

這種文章值得閱讀的地方我認為是欣賞別人如何分析 Serverless 與 Kubernetes 的好處與壞處,各自特色以及適合的應用場景,透過這些步驟來達成

1) 幫自己複習對於這些概念的理解
2) 幫助自己補充不確定與不熟悉的領域
3) 自己二次思考這些問題,也許能夠想出作者講得不夠明確的地方


這種科普文章也許沒有技術文章來得這麼硬,技術學習上也可能無法讓讀者有所成長
但是有時候這些文章的說詞與說法,可能會是團隊內導入一些新技術時可以使用的說詞與參考

https://betterprogramming.pub/4-reasons-to-use-kubernetes-in-the-serverless-era-cf77ea3b018b
本篇文章作為一個經驗談,探討於 AWS EKS 的環境中要如何避免 IP 發放完畢。
對於 Kubernetes 來說,CNI 負責的功能主要有兩個,分別是 IPAM 以及 Network Connectivity.

公有雲管理的 Kubernetes 為了讓整體操作環境可以與其雲端內的其他元件有更好的整合,通常都會開發屬於自己的 CNI 系統,譬如 Azure, AWS, Google 都有這方面的設計。
這種設計的最大好處就是可以將 Pod 使用的 IP地址透過本來 VPC 內的設計去管理,而本文要討論的就是 AWS EKS 環境中可能會遇到的 IP 地址分配問題。

EKS 預設會使用 AWS VPC CNI 來提供相關服務,其底層實作主要牽扯到底層 ENI 的配置與設定,主要會影響到底還有多少個 IP 地址可以用來分配給新的 Pod 使用。

從 Cluster 的角度來看,要先注意的 VPC 內的網段設定,如果一開始分割的子網段是/28,這情況下你整個叢集內只能有30個左右的 IP 地址可以發放,這數量根本完全不太夠使用。

從單一節點的角度來看,要注意每個節點上可以配置多少個 ENI 以及每個 ENI 能夠配置多少網卡
該 CNI 分配 IP 時會先想辦法把現有網卡上面能夠分配的 IP 填滿,一旦填滿就會創立新的網卡,接者繼續分配 IP,當運行的 Pod 數量超過節點上現時就沒有辦法繼續分配 IP。
官方針對這種情況提供了一個公式去計算
(Number of network interfaces for the instance type × (the number of IP addressess per network interface - 1)) + 2

對於一個 m5.large 的機器來說,支援三張 ENI,且每個都有 10 個 IP 可以分配,因此根據上述公式
(3*(10-1))+2 = 29, 意味 m5.large 的機器上最多只能運行29個不使用 hostnetwork:true 的 Pod。

為了解決這些問題,作者提出了兩個想法,分別是
1. Adding additional IPv4 CIDR blocks to VPC
2. Change VPC CNI to Calico CNI

對這兩個想法有興趣的可以參考原文囉
https://matiaszilli.medium.com/avoiding-ip-consumption-in-amazon-eks-32fc7320253d
Kubernetes 中最基本的運作單元是 Pod,基於 Pod 之上則有各種不同作用的高階抽象層,譬如 DaemonSet, Job, Deployment 等。
使用 Kubernetes 來部署應用程式時,遲早都要面臨資源使用的問題,到底每個 Pod 要使用多少的 CPU/Memory,同時如果是 Deployment 時到底要設定多少個 replica 來符合應用程式的需求。

Kubernetes 提供了 HPA 的方式來水平擴展 Pod 的數量,透過 HPA 的幫助, Pod 的數量可以根據當前的使用情況而自動改變。前述提到除了數量外, CPU 與 Memory 的設定也是一個煩惱的議題,因此就有一個名為 VPA (Vertical Pod Autoscaler) 的專案來處理這個情況,根據當前 Pod 的運行情況來調整 CPU/Memory 的設定(Request/Limit)。

這個專案並非 Kubernetes 的內建資源,必須要額外安裝相關的 CRD 與 Controller 來使用
今天這篇文章針對 VPA 的專案進行詳細的介紹,包括如何安裝,基本架構介紹, VPA 的概念以及使用上的限制都有詳細介紹。

特別要注意的是 VPA 與 HPA 不能同時針對一個 Pod 使用,否則會出現不可預期的行為。這部分也可以理解,畢竟兩個專案並沒有良好的整合,因此兩個 Controller 都會互相一直調整 Pod 行為時,可能會導致不預期的結果。


對於 VPA 這種調整 CPU/Memory (Request/Limut) 專案有興趣的人不仿參考下列文章
https://medium.com/infrastructure-adventures/vertical-pod-autoscaler-deep-dive-limitations-and-real-world-examples-9195f8422724
本文是一篇 2017 年的文章,雖然已經四年之久,但是我認為本篇文章值得一讀。
作者團隊於 2017 年時正在經歷如何將 VM 上的各種 Java 應用程式轉移到 Kubernetes 內的 Container,而本篇文章則是探討到底 Container 是如何透過 Linux Control Group 以及 namespace 實作的,透過對這些底層實作的瞭解,才有辦法針對 Container 效能部分去除錯與提升。

這種文章探討的都是很底層的概念,建議所有人都閱讀一遍,好好複習關於 cgroups/namespace 的概念,透過對這些概念的理解與掌握,能夠更有系統的去解釋何謂Docker Container,何謂輕量級虛擬化。

以下幫大家節錄一些重點,還是推薦自行閱讀全文

1. cgroup 用來隔離與限制 CPU,Memory,Disk,Network Bandwidth 等資源的用量
2. namespace 則是用來限制 ipc, pid, mount ,network, utc 等資訊的可視性,不同 namespace 內看到的資訊是獨立的,但是最終彼此還是屬於同一個 Kernel。
3. 任何沒有被 cgroup 規範的應用程式都會被自動包含到 root cgroup 的規範,不同發行版其位置不同,譬如 /sys/fs/cgropu.

假設今天透過 docker run 去運行一個 java 應用程式
a. Docker 會創建一個 pid namespace,接者運行 Java 前先把該應用程式給掛到新的 pid namespace 上並且賦予該 java 應用程式 PID 1
註: Host 上還是可以觀察到該 Java 應用程式,因為除了 Host 本身外,每個 pid namespace 都有自己的老爸,而老爸是可以看到小孩資訊的,這意味 docker dameon 雖然創建新的 pid namespace,但是host的pid namespace 實際是新 namespace 的老爸
b. 從老爸的視角來看,可以看到該 Java 應用程式也會有一個不同的 PID,而這個 PID 也會於 cgroup 系統中有自己的設定

4. CPU Cgroup 則是會用 share 為單位來定義每個 task 可以獲得多少相對的 CPU 時間,相對的算法是去計算 task 擁有的 share 數量佔了整個 cgroup 階層元件中的多少百分比。
舉例: 捨去其他服務單純考慮運行三個 Container 且有 4 Core CPU 的環境,三個 Container Task 分別給予 2048,1024,1024 share 的話,第一個 Container 大致是會被分配到兩個 CPU Time

5. CPU shares 沒有辦法去保證每個 task 最小用量是多少,所以需要透過 CPU Quotas 的概念來設定 CPU.cfs_quota_us(假設使用 CFS 這個排成演算法)以及 CPU.cfs_period_us(預設100ms)。
概念大概就是 cfs_period_us 定義的時間內,你最小可以使用多少時間,所以假如設定 cfs_quota_us 為 100ms,則預設情況下該 process 可以使用的量就是 100ms/100ms = 1 ~= 1 Core CPU

k8s 與上述的相關bug 可參考下列 issue
https://github.com/kubernetes/kubernetes/issues/67577


6. JVM 看到的是系統上全部的 CPU 資源,但是 Contaienr 本身當被限制 CPU 用量時,會有資訊落差,造成 GC 運行的效果不如預期,因為其認為系統有超多 CPU,而不知道自己其實被限制的CPU很少。

原文滿精彩的,推薦閱讀
https://engineering.squarespace.com/blog/2017/understanding-linux-container-scheduling
今天這篇文章是經驗談,由 Intuit 的人來探討管理 200 個不同大小 Kubernetes Cluster 上關於 Scale 的各種經驗。Intuit 同時管理由 AWS EKS 提供的 Kubernetes 服務以及地端自行架設管理的 K8s。

針對 Scale 這個議題,其探討了五個面向帶來的各種挑戰,每個挑戰分成
1. What -> 這個議題要探討什麼
2. How -> 如何做
3. Benefits -> 帶來的好處
4. Leaning -> 學到的經驗

這五個議題分別是
1. Vertical Scale
2. Horizontal Scale
3. Reliability
4. Upgrade
5. Stability

整篇文章算偏長,這邊針對第一個議題進行介紹,對於後續有興趣的人可以在參閱全文

Vertical Scale
What:
目標就是提高應用程式的效能,主要方向是
1) 找到合適的機器規格等級
2) 應用程式根據機器規格能夠最佳化其效能
3) 提升整體的 TPS 數值

How:
1) 針對 GC 的規則調整,提升應用程式效能
2) 節點規格調整,從 Largr -> 4XLarge
3) 確認限定的 CPU/Memory 中可以運行多少個 Pod
4) 使用 HAP 來調整 Pod 的數量

Benefits:
1) TPS 從一開始轉移的 10TPS 提升到最高 10K TPS

Learning:
1) 動態建立節點且將服務部署上去大概需要 5-7 分鐘的時間,事先創好節點的話可以節省時間
2) 團隊需要於 10 分鐘內 scale 超過100以上的資源,這部分預設的 HPA 沒有辦法順利達成,團隊真的問題修改 Scale 的條件

對全文有興趣的可以參考看看,裡面文章滿長的,並不是很容易讀懂全部,需要閱讀多次才好懂。
https://sumitnagal.medium.com/operating-kubernetes-at-scale-65a3e76d74ad
這篇文章算是一個資安問題的討論文章,作者透過一系列的手法成功地獲取了大量使用者的電腦資訊,由於這次的實驗只是要證明資安問題,因此作者的程式只有獲取如 IP, Hostname 等簡單資訊,若是惡意的話是可以執行更多危險程式碼的。

作者開門見山表示,現在的程式語言有太多的豐富的第三方函式庫,譬如 NodeJs(NPM), Ruby(RubyGem), Python(PyPI),豐富的第三方實作讓開發者可以更快速的完成任務。
開發者在使用這些套件函式庫時,大部分情況都不會去檢查太多,而是直接信賴般的去使用這些函式庫,而這種盲點般的信任是否有可能讓攻擊者有跡可循?

作者基於這個想法進行了一系列研究,發現 PayPal 公開專案(NodeJs) 內的 package.json 內交互使用了公開與內部的 packages。 公開部分勢必來自 npm 而那些內部的應該是來自於 PayPal 內部系統,同時也注意到這些內部的 package name 目前於 npm 上也不存在。

針對這個情境,作者提出一些問題
1) 如果有人上傳跟 PayPal 內部 package 相同名稱的套件到 npm 服務器上,有沒有可能 PayPal 內部某些專案會預設使用 npm 上的套件而非內部自架的伺服器?
2) 開發者或是其他自動化系統有沒有可能運行這些 packages 內的程式碼,這樣有沒有機會造成一個漏洞的可能性?
3) 其他的公司是否也會有類似的問題?

為了證實這個問題,作者設計了一系列的實驗與準備來測試上述問題,譬如更有系統的去尋找這種有跡可循的 package.json(Tesla, Apple, Yelp 等公司都被到可以利用的 package names)。

作者將自己這系列的攻擊行為稱為 depdendency confusion 來呼應本文標題。

結果來看是令人非常震驚的,作者打造同名的npm的確被大量下載與執行,也讓作者收集到大量運行的內部服務器IP與名稱。
與 Apple 合作通報相關報告後, Apple 也於兩週內修復相關問題。

原文滿長的,非常推薦閱讀
我個人認為資安這概念就是不出問題不被重視,但是一但出問題可能造成的影響卻非常巨大的。團隊內每個人都要培養基本的資安理念,同時與相關的安全團隊合作逐漸地提高整個產品的安全性,永遠不要想一聲令下明天就可以反轉一切。


https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610
本篇是一個 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