#小編

大家午安

Grafana Labs 在 observability 的最後一塊拼圖。

Grafana Labs 於前幾天 ObservabilityCon2020 大會上新開源了一個專案 Grafana Tempo 用於做分布式追蹤(Tracing) 的後端服務,具備了「高擴展性」和「低成本消耗」的系統,儲存系統僅只依賴 S3或 GCS ,並與Loki/Grafana 做了高強度的整合,並兼容Jaeger/Zipkin/OpenTelemetry/OpenCensus 等目前主流的分布式追蹤服務。

ObservabilityCon2020: https://grafana.com/go/observabilitycon/keynote-what-is-observability/

Grafana Tempo: https://github.com/grafana/tempo
今天這篇文章來跟大家介紹一下 Custom Resource Definition (CRD) ,對於大部分的 Kubernetes 使用者來說,日常工作中根本不需要去理解什麼叫做 CRD,但是當你整合了一些第三方解決方案之後,你會發現你的 Kubernetes 內增加了好多 CRD。 一個最簡單的範例就是你會看到 Yaml 中使用的 KIND 是一些 Kubernetes 官方文件中沒有提到的內建型態,反而是跟你使用的解決方案緊密相連的情況。

本篇文章用一種輕鬆簡單的方式,去跟你介紹 CRD 的概念,個人覺得淺顯易懂

但是要注意的,通常只有 CRD 沒有辦法發揮其真正用途,畢竟 CRD 就是一個資料結構,需要一個使用者,而這個使用者往往都是由 Controller 來管理。當這兩者結合後就可以變成大家所熟悉的 Operator Pattern 

https://itnext.io/crd-is-just-a-table-in-kubernetes-13e15367bbe4
今天來分享一篇跟科技完全無關的文章,主要是一位好友近期整理自己減肥 20kg 的血淚史!

對於工程師的日常生活來說,大家習慣坐一整天,這過程可能會因為椅子,滑鼠,鍵盤的高低導致肩膀長期屬於不舒服位置,甚至是坐姿不良導致下背,髖關節,骨盆等各種不舒服

當然體重本身也是一個警訊,肌肉過少甚至內臟脂肪過高也都要注意一下身體狀況


最後,大家工作之餘,也要注意身體健康,吃得好,動得好,有良好的身體才有日子去享受努力的果實

https://speakerdeck.com/pichuang/gong-cheng-shi-de-ni-xi
Docker 網路入門系列第三篇!
本文銜接自第二篇手把手打造 Bridge 網路模型系列,上篇文章中我們透過 veth/brctl 等相關指令,打造出一個讓兩個容器網路互通的簡單環境,但是該環境中這些節點還不能對外上網。
因此本篇文章就會從這邊出發,去探討到底要如何讓容器可以對外上網,這中間牽扯到哪些概念,以及 Docker 實際上做了些什麼事情
基本上整個流程跟 Docker 做的事情思路是一致的,透過瞭解這些網路運作原理,更可以讓我們學習 Docker 的用法,同時未來網路出現問題的時候,也會更有背景知識知道如何去除錯
https://www.hwchiu.com/docker-network-model-snat.html
這邊跟大家分享一個常用小工具 scp 的熱門討論!
LWN.net 這幾天有一個文章是關於基於安全性考量下,改用其他工具取代 scp, 譬如使用 sftp 以及 rsync.
有常常使用 scp 這個工具的人可以看一下這篇文章討論的原因,以及如果要改成使用 rsync, 可以有什麼樣的參數使用
https://lwn.net/SubscriberLink/835962/ae41b27bc20699ad/
不知道有沒有人還是習慣用 vim 來編輯 kubernetes yaml 呢?

這邊介紹一個 vim plugin,能夠針對 kubernetes 物件自動補齊,能夠減少一直查找文件的需求,特別是當本地開發配上 kubeeval 等工具來檢查 k8s yaml 語法與語意時就會更有幫助

有使用 vim 的人可以使用看看

https://octetz.com/docs/2020/2020-01-06-vim-k8s-yaml-support/
這邊跟大家分享下個月的線上活動,主要是探討 Jenkins 的一些有趣用法,內容主軸是探討大型跨企業合作專案下, Jenkins 使用上的痛點與解決方式

https://www.facebook.com/events/1254540821590769
不知道大家有沒有聽過 Open Policy Agent (OPA) 這個 CNCF 專案?

有滿多專案的背後都使用基於 OPA 的語言 Rego 來描述各式各樣的 Policy,譬如可以使用 conftest 來幫你的 kubernetes yaml 檢查語意是否有符合事先設定的 Policy。

本篇文章則是跟大家分享如何使用 OPA 來針對 Ingress 資源進行相關防呆與除錯,一個最基本的範例就是如何避免有多個 Ingress 使用相同的 hostname 卻指向不同的 backend service. 過往可能都是靠人工去維護,確保沒有一致的名稱,但是透過 OPA 的概念我們可以再佈署 Ingress 到 Kubernetes 前先進行一次動態的比對,確保當前設定符合所有 Policy,得到所謂的 Approved 後才能夠佈署進去。

有興趣的人可以看看這篇文章,甚至學習一下 OPA 的使用方式
https://www.cncf.io/blog/2020/09/29/enforce-ingress-best-practices-using-opa/
不知道大家有沒有遇過本地儲存空間滿了,再也抓不了 docker image 的慘痛經驗呢? 本文就想要探討的是遠方 Container Image 上的管理問題,隨者時間演進,愈來愈多的版本產生,那作為管理者,我們要怎麼去看待這些 image,放任他們無限擴張嘛? 這些資源背後都代表一個儲存空間,也就意味額外的成本開銷。

作者想要解決的問題是,如何設計一套自動機制去刪除用不到的 image tag,保留會用到的,為了解決這個問題,要先定義什麼叫做 "用得到的 image tag".

本文列舉了四種需要保留 image tag的情況
1) Production 環境正在使用的 image tag, 如果刪除了,遇到 ImagePullPolicy:Always 的情況那可真的麻煩了
2) 遇到緊急情況,應用程式需要退版,因此保留的 image tag 可不能只有當前版本,過往穩定版本也都要保留
3) 從開發角度來看需要的 image tag, 譬如我們開了一個 PR,這個 PR 有一個對應的 image tag, 再這個 PR 還沒有結束前,這個 image tag 應該都要保留讓開發者去驗證與使用
4) 最後則是特定版本號或是code name等專屬名稱

作者使用 werf 這套 k8s 建置佈署工具來幫忙,這工具除了常見的 build/deploy 外,還可以刪除遠方的 container image。 因此作者整合一套演算法,將其與 werf 整合,讓整個 CI/CD 的過程中能夠自動去產生新的 image,並且根據需求去移除用不到的 image.

有興趣的記得點選下列原文來學習更多

原文:
https://medium.com/flant-com/cleaning-up-container-images-with-werf-ec35b5d46569
今天這篇文章探討的則是 resources 底下的 request/limit 問題。

本文作者之前遇到一個非常規律的服務警告問題,花了非常多時間與步驟去查詢,最後才發現是 Pod 裡面 Resource 的設定不夠嚴謹與完善。

舉例來說,
resources:
     limit: cpu: 1000m
     request: cpu: 100m

今天假設有一個服務描述,我對 cpu 的最低要求是 0.1顆,但是極限是 1顆
且有一個節點本身有 3 顆 CPU,這種情況下,我們對該服務設定多副本運行(10個). 那根據 request 的要求,10個副本頂多只需要 1 顆 cpu,所以非常輕鬆的可以將 10 個服務運行起來,但是如何今天遇到尖峰流量,每個 pod 都瘋狂使用 CPU會發生什麼事情?

每個副本的極限都是 1 顆,因此 10 個副本就可以衝到 10 顆 CPU..而系統上只有 3顆,這就會造成大量的 OOM,然後系統上的 process 就會開始被刪掉,甚至連 kubelet 都沒有辦法回應(案例中就是kubelet)。

這案例中 limit/request = 10x,作者認為這數字太大,它覺得合理的大概是 2x ~ 5x,並且最重要的是要定期去檢視系統上資源的用量, limit 要設定的合理,如果本身有很大量需求,建議還要搭配 node select, affinity/anti-affinity 讓每個 pod 最好找到適合的配置方式,然後也要避免尖峰流量到來時,系統資源被吃光甚至影響到 kubelet/kube-proxy 等底層服務的運作。

https://itnext.io/how-to-set-kubernetes-resource-requests-and-limits-a-saga-to-improve-cluster-stability-and-a7b1800ecff1
今天跟大家分享一個 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 是什麼

之後會在跟大家分享目前一些解決方法怎麼做

https://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts
今天這篇文章來分享一下對於昨天所談的 UDP Race Condition 的解法,主要是針對 Kubernetes dns 問題去探討,

一個作法就是透過 nodelocaldns 這種不同的架構,該架構下會於每個節點上部屬一個 DNS Cache,所有該節點上的 Pod 都會透過 UDP 與該 DNS Cache 溝通。 而這段網路請求因為發生於同節點上,所以 kube-proxy 產生的規則不會介入,因此那些 iptables/ipvs/conntrack 就不會影響到,就不會產生上次所說的 bug.
接者,每個節點上的 DNS cache 會透過 TCP 的方式去跟 kube-dns 來詢問最後的答案,透過 TCP 重送的方式來減緩封包遺失造成的 timeout 問題

https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/
https://github.com/kubernetes/kubernetes/issues/56903
由於這個粉絲頻道大概最少也是每兩天就會有一篇相關的科技分享完,有時候如果不是每天看,可能就沒有追到最新文章,然後過幾天後就被洗掉。為了減緩這個問題,我這邊額外創立了一個網站,專門用來索引這個粉絲頁的內容,會將每次的發文內容根據主題大綱分類,內容都會指向本粉絲頁發過的文,同時每個連結都會標示時間與大綱,方便大家快速查詢自己有興趣的內容。
https://technologynoteniu.github.io/awesome-notes/
今天這篇文章作者跟大家分享一些如何加強 Kubernetes 服務穩定的方式,這篇文章這邊做個簡單摘要一下

發生問題:
作者的 k8s 是基於 Google Kubernetes Service (GKE)的叢集,運作過程中有時候會發現部分節點當掉,最後導致部分的服務不能正確使用。這邊作者團隊從兩個角度出發去改善
1. 研究為什麼節點會一直當掉,與 Google Supporte Team 來回信件最後有找到問題點
2. 強化 Kubernetes 服務的韌性,就算有部分節點壞掉也要讓服務能夠繼續運行
,本文主要的一些觀點也都是基於這邊發展

強化方式
1. 修正 Deployment 的數量,並且加上 Anti-Affinity,讓這些 Deployment 的副本能夠散落到不同的節點上,避免所有 Pod 都塞到同個節點,最後該節點出問題導致 Pod 全部出問題。
2. 所有需要被 Service 存取的服務都加上 Readess Probe 來確保這些服務都準備好後才會收到服務,避免一些請求被送過來確又不能正確處理
3. 加入 Pre-Stop 的使用,再裡面透過 sleep 10的方式,讓 Pod 要被刪除能夠將手上的封包請求給處理完畢

註: 我個人認為第三點其實不太需要,比較漂亮的作法應該是實作 Singal Handler 去處理 SIGTERM 的訊號,收到此訊號後就不要再接受任何 Request 並且把剩下的工作處理完畢,當然如果這部份處理的時間過長,超過預設的 GracePeriod (30sec),就會被 SIGKILL 給強制刪除。
要解決這個問題可能就要從應用程式下手去看如何改善,或是透過修改 API server 來增加 GracePeroid 的數值

可以點選下方連結來瞭解更多全文,內容不長
https://medium.com/kudos-engineering/increasing-resilience-in-kubernetes-b6ddc9fecf80
今天要分享的是來自 lambda 的團隊根據其多年 Kubernetes 的經驗分享,該篇文章篇長,閱讀可能需要15分鐘左右,這邊幫大家重點整理,有興趣的別錯過完整內容,我個人滿推薦細讀的

# 重點整理
1. 團隊一開始是透過 Ansible + Valut + Consul 來管理整個架構+應用程式的部署。
2. 作者認為一個非常重要的東西就是, 想清楚你為什麼需要 Kubernetes,不要隨便盲目的使用
3. Kubernetes 的學習曲線非常高,除了 Kubernetes 本身之外,還有很多整合的東西都需要一起學習,譬如 Monitoring, Logging, CI/CD, Secret Management, Tracing 等,每個領域都不簡單
4. Kubernetes 的導入,並非只有營運團隊需要處理,實際上是整個產品團隊都會連帶影響,譬如對於開發者來說,本地開發要怎麼做,本地測試要怎麼做?
CI/CD 如果要考慮 Kuberntees,有哪些部分需要注意? 應用程式如何打包與上版本? 更新策略是什麼? 
這中間有超多的議題需要整個團隊一起學習與克服,才能夠真正享受到 Kubernetes 帶來的好處
5. 轉移到 Kubernets 中間的過渡期很辛苦,同時維護兩種架構,這需要時間去處理,沒有辦法馬上完成,也不可能一步到位
6. 文章中也有提到作者團隊於各領域所採取的解決方案,這邊就大概列一下

Prometheus, Grafana Loki, Vault, Tekton, Argo Workflow, Telepresence, Skaffold,  Kustomize, AWS, Kops


註: 我個人認為裡面最重要的一點就是第二點,任何領域都一定,不要盲目追求潮流,而是要有充分的理由去說服自己為什麼需要使用某產品。對我來說一個很重要的行動準則是,要先說服自己,才有辦法說服別人

https://lambda.grofers.com/learnings-from-two-years-of-kubernetes-in-production-b0ec21aa2814
跟大家分享一個熱騰騰的消息,來自於 CNCF 上面 Apple Inc 的分享
Apple 未來將會將內部的應用都部署從過去的 Apache Mesos 給逐漸轉移到 Kubernetes 上。


# 重點整理
1. Kubernetes 這種 plug-in 的生態系其實對使用者來說非常方便,針對網路,儲存等相關選擇不會再是一次定生死的玩法。任何時刻都可以根據需求重新評估並且不需要整個系統重新打掉
2.. Kubernetes 透過 CRD + Controller 這種概念讓開發者可以存取其 API 來達到很多客製化的功能
3. 要如何讓整個組織內的團隊都採用 Kubernetes 並且使用其學習曲線非常高,對整個團隊帶來的衝擊也是不可忽視
4. 目前內部已經正在嘗試 Kubernetes 想辦法來符合來自於不同團隊的需求,譬如 Jave/Python/Go 的開發者, SRE 團隊, 硬體團隊與機器學習團隊
5. Apple 打算基於 namespace-as-a-service 以及 cluster-as-a-service 來提供環境給不同團隊使用
6. Apple 工程師也積極的參與 Kubernetes 的開發與貢獻,同時也在研究關於 microVM 等技術,希望能夠針對多租戶的應用情況下有所幫助。


註:
1. Kubernetes 透過 CRI/CNI/CSI 來提供彈性的 運算/網路/儲存 選擇
2. 對於  CNCF 來說,Apple 的公開使用是一個令人振奮的消息,愈來愈多的大公司往這邊邁進。
3. 多年前 Linux Foundation 一段演講中提到, Linux 之於作業系統,就如同 Kubernettes 之餘雲端,不知道這件事情會不會發生?

有興趣的點選下文觀看全部訪談

https://thenewstack.io/apple-plans-to-run-most-of-its-compute-management-on-kubernetes/
今天這篇文章是用一個入學者的角度來探討什麼是 Service Account  

基於 RBAC 的使用情境下,我們除了 Role & Rolebinding 外,我們也會需要一個所謂的 Subject 。 

Subject 大抵上可以分成兩類,分別是 User 以及 Service Account,其中 User 比較偏向是給使用者使用的,不論是管理員或是開發者,背後都可以銜接不同的認證方式,來確保當前使用者是經過認證的,接者搭配 Role & Rolebinding 來幫該 User 授權給予相對的存取能力。 

相反地, Service Account 的目標則不是活生生的人類,更偏向 Process 等自動化程式為主,不論是 Cluster 外部的應用程式,或是 Cluster 內的 Pod,都可以透過 Service Account 與 API Server 溝通來滿足認證。 

預設情況下,我們跑起來的 Pod 都會掛上一個 Default 的 Service Account,然而你如果希望你的應用可以有更多的能力去跟 API Server 溝通,就需要考慮幫忙設定全新的 Service Account 搭配特定的 RBAC 規則。 

 本文會針對 Service Account 去簡單介紹,大致上先瞭解什麼是 Service Accont, 什麼情況會使用,要怎麼使用

https://medium.com/the-programmer/working-with-service-account-in-kubernetes-df129cb4d1cc
Infrastructure as Code (Iac) 近來年蔚為潮流,甚至可以說是必備顯學,如何透過系統化的方式去管理架構是個逃不跳的問題,不論是地端環境,或是雲端環境,這類型的需求都不可能少。 Terraform 我個人認為是這幾年來談到 Iac 解決方案中最熱門的選項,其開放的 Provider 架構讓其生態系非常大,能夠透過一套相同的語法來銜接各式各樣的服務提供者。

本篇文章就從入門角度來看待 Terraform 可以怎麼使用,從開發階段到正式上線階段中間,可能會遇到什麼問題,以及這些問題應該怎麼處理,譬如說
1. Terraform 的 Backend Provider 應該怎麼設定,不同設定對於安全性來說是否會有不同的優劣?
2. Terraform 該由誰運行? 到底是一台專屬的開發機器或是說透過 Continuous Integartion (CI) 的過程來運行 Terraform, 這之間各自的好處是什麼
3. Terraform 透過 Module 的方式來達到 Don't Repeat Yourself(DRY) 的架構,而 Module 本身的架構可以有哪些作法,是一個獨佔的 Repository 或是多個? 這之間的想法有什麼差異

對上述議題有興趣的可以點選全文觀看
https://medium.com/@mike.ensor/terraform-developers-tips-tricks-d5c4be14a553
Docker 網路入門篇最終章
本篇文章延續之前的內容來探討 Docker 的 Bridge 網路模型,這次我們要研究的是到底 docker run -p 12345:80 這種指令背後到底做了哪些事情,除了 iptables 的 DNAT 外,實際上還有一個名為 docker-proxy 的應用程式也被跑了起來。
到底 docker-proxy 是做什麼用的,與 iptables 的關係是什麼,有興趣的可以看看本篇文章。
歡迎留言讓我知道你想要探討學習的任何入門網路議題
https://www.hwchiu.com/docker-network-model-lab-dnat.html
今天這篇文章比較偏向一個範例操作,如何透過 Terraform 這種 Infrastructure as Code 的概念來管理 AWS 資源。
範例中使用到的資源是 ECS (Container Service),一個提供容器運行的服務平台。
一種最簡單的手動範例就是
1. 本地開發應用程式
2. 容器化本地應用程式
3. 找到一個 Container Image Repository 將 Container Image 給推上去
4. 手動創見相關 AWS 資源,譬如 ECS, LoadBalacner, Security Group (Firewall) 等資源
5. 部署該應用程式

本篇文章希望透過 Terraform 的方式將上述的 (3,4,5) 等過程都透過程式碼的方式來描述,這部份帶來的好處其實也是 IaC 所闡述的價值,不論是可以透過 code review 的方式來分享與確保每次變動的品質,對於環境複製等都可以更為快速且品質相當,減少那些不被記錄的人為修改。


註: 我個人認為這類型文章偏向入門,對於還不熟悉 Terraform 的人可以有一個快速的導覽,大概知道 Terraform 可以做到什麼樣的東西
https://medium.com/avmconsulting-blog/how-to-deploy-a-dockerised-node-js-application-on-aws-ecs-with-terraform-3e6bceb48785
如果有在使用 Kubernetes Service 的人可能都有聽過 Load-Balacner 這個類型,然而 Kubernetes 本身並沒有實作 Load-Balacner,而是要仰賴其他的第三方服務,譬如公有雲上提供的 LB。如果今天想要餘地端環境使用,針對這些 bare metal 的機器,我們如果要使用 Load-Balancer 的話,就必須要使用額外的解決方案,譬如 MetalLB
今天要介紹的則是另外一個解決方案, porter,該解決方案的特色有

1. 支援 ECMP (Equal-Cost MultiPath) 多重路由協定
2. 支援 BGP
3. 支援 K8S Service
4. 可以用 Helm Chart 安裝
5. 透過 CRD 的方式來修改 BGP 設定,而不需要重起相關服務


專案內有列出跟 MetalLB 的差異,優點主要是基於 CRD 與 Controller 的概念去整合整個 BGP 的操作,同時與 Calico 衝突時有更好且優雅的方式去解決

有地端環境使用需求的人可以稍微看看這個專案囉

https://github.com/kubesphere/porter