Skip to main content

· 2 min read

Kubernetes 內的容器運行上可能會遇到 OOM (Out Of Memory),通長會有兩種情況

  1. 應用程式本身的 Memory Limit 沒有設定好,因此踩到上限被移除
  2. 眾多應用程式的 Memory Request 沒有設定好,導致系統資源被互搶直到系統沒有足夠記憶體,因此觸發 OOM 開始砍人

這類型的事件可以透過下列的方式去觀測

  1. 安裝 kube event exporter,該專案會將所有 event 以不同的方式輸出。簡易方式可以採用 stdout 的方式輸出
  2. 透過 Logging 系統收集 stdout 的 log,從中分析是否有 OOM 的事件發生,有的話可以發送 Alert

以 Loki 來說,可以採用下列語法去過ㄌㄩ

count_over_time({container="kube-event-exporter"}[1m] | json | __error__ != "JSONParserErr" | reason="OOMKilling")

· 2 min read

GCP 本身有自己的 IAM roles,可以讓所有 GCP 使用者有特定的權限去存取 GKE 叢集,譬如

  1. Kubernetes Engine Cluster Admin
  2. Kubernetes Engine Cluster Viewer
  3. Kubernetes Engine Developer

然而這類型的設定卻有一些限制

  1. 沒有辦法針對 namespace 內去詳細設定
  2. 不方便針對 cluster 層級設定,譬如一個專案內若是有多個 GKE cluster,則權限會全部套用

但是這類型的操作與 gcloud 的整合非常順,可以很輕鬆的就讓所有團得人員獲得 GKE 的存取權限,進而使用 kubectl 等指令

若今天想要修改權限改使用 Kubernetes RBAC 的方式,達到稍微細緻以 namespace 為基底的權限, 並且以群組信箱來當作 subjet 的話則需要一些額外步驟

  1. 將 Google Group 與 GKE 連動,可參考 GKE RBAC
  2. 於 Google Group 將使用者都加入到該群組中
  3. 於 GCP 給予該 Google Group ([email protected]) 一個 Kubernetes Engine Cluster Viewer 的權限,因為所有人都至少要能夠透過 gcloud 去認證獲得 KUBECONFIG 來存取,因此至少要可讀

另外群組的部分,可以採用 nested group,就是所有真正的 group 都加入到上述的 gke-security-groups 內,因此 RBAC 設定的部分就可以採用 [email protected], [email protected] 等方式來設定。

一切完畢後就依照 Kubernetes RBAC 的設定,準備 Role/RoleBinding,其中 RoleBinding 的 Subjects 改成

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: xxxxxxxxxx
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: xxxxxxxxxxxx
roleRef:
kind: Role
name: xxxxxxxxxx
apiGroup: rbac.authorization.k8s.io

· One min read

練習可以使用各種網頁資源來產生 token,但是如果是內部服務則不要使用那類型的服務,以免有任何資訊被第三方掌握

快速產生的方式可以採用 nodejs 來搞定

先準備一個下列檔案

$ cat jwt.js
var jwt = require('jsonwebtoken');
var token = jwt.sign({
"data": "my value",
"permissions": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
}, 'secret_file', {expiresIn: "365 days"});

console.log(token)

$ node jwt.js
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJnZyI6Im5vbm9ubyIsInBlcm1pc3Npb25zIjpbMSwyLDMsNCw1LDYsNyw4LDksMTBdLCJpYXQiOjE2OTY5OTM1NjksImV4cCI6MTcyODUyOTU2OX0.b-5UiuaNdFPuwgJMn8Ji3v803OA00qA8aSwetY7XDEY

· One min read

ArgoCD 安裝方式多元化,本身有簡單部署也有 HA 狀態的部署,以下示範如何用 Kustomize 來安裝 ArgoCD 並且之後還可以用 ArgoCD 控管 ArgoCD 自己本身的設定

使用 https://github.com/argoproj/argo-cd/tree/master/manifests/cluster-install 這個簡易安裝

準備一個 kustomizatiom.yaml,然後如果想要客製化就準備其他的 yaml 來調整 最後搭配一個 Application Yaml 來控管自己

$ cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- https://github.com/argoproj/argo-cd/manifests/cluster-install?ref=v2.7.7

patchesStrategicMerge:
- argocd-rbac-cm.yaml
- argocd-application-controller.yaml
- argocd-applicationset-controller.yaml
- argocd-cm.yaml
- argocd-cmd-params-cm.yaml
- argocd-dex-server.yaml
- argocd-redis.yaml
- argocd-repo-server.yaml
- argocd-server.yaml
- argocd-notifications-cm.yaml

· 2 min read

CircleCI 專案夠多且每個專案都有相關權限要存取時,推薦使用 Context 的概念來簡化設定。 Context 是一個抽象化的物件,其可以描述

  1. 所有的環境變數
  2. 限制使用的專案

而所有運行 CircleCI 的專案都可以繼承該 Context 來自動獲取所有環境變數

假設環境需要存取雲端資源,可以把用到的所有資訊寫到一個 Context 內,並且設定好所有環境變數 接下來每個專案的 CircleCI 就只需要使用類似下面的語法

workflows:
test:
jobs:
- test:
filters:
branches:
only: master
context:
- AWS

就會把 AWS Context 內的環境變數都繼承近來,因此未來要維護只需要針對 Context 去維護,就不需要每個專案都去設定

使用上不要使用任何員工的帳號去綁定 Project,不然員工離職很麻煩,最好創建一個 machine account,用該 account 的 ssh key 來串連 GitHub 與 CircleCI,這樣離職才不會產生太多問題

· 2 min read

透過基本的 GKE + Serviec + Ingress 部署網站後通常都沒有太多存取問題,但是對於公開服務這件事情就需要考量資安,所有網站是否都需要經過認證與授權才可以讓外部存取? 有些第三方服務開源版本可能不方便銜接或是沒有實作這一塊,這時候可以透過 GCP 的 Identity-Aware Proxy(IAP) Gateway 快速搭建一個機制,所有存取該網站的人都會被導向 Google 登入,且只有符合設定 domain 的人登入後才可以存取網站內容。

流程需要

  1. 到 OAuth 2.0 Consent 頁面那邊去創立一個物件,並且取得 client_id 以及 client_secret.
  2. 產生一個 Secret 物件包含對應的 client_id 與 client_secret
  3. 產生一個 BackendConfig 的物件,將上述的 secret 綁定到該 Backend 物件
  4. 將 BackendConfig 與 Service 物件綁定

前三個步驟可以參考官網設定 Enabling IAP for GKE

apiVersion: v1
kind: Service
metadata:
annotations:
cloud.google.com/backend-config: '{"default": "my-backend"}'
name: dev-service
namespace: dev
spec:
ports:
- name: http2
port: 80
protocol: TCP
targetPort: 8080
- name: https
port: 443
protocol: TCP
targetPort: 8443
selector:
app: service
sessionAffinity: None
type: ClusterIP

一切設定完畢後,接下來還要到 GKE 那邊開啟 IAP 的設定,參考 Setting up IAP access

· 2 min read

標題: 「SRE 的工作介绍」 類別: others 連結: https://www.kawabangga.com/posts/4481

本篇是簡體中文的文章,所以就不針對文章進行導讀。

文內我覺得有趣的部分是從各個面向來探討 SRE 這個職位的可能內容,畢竟一直以來 DevOps, SRE 等相關概念的詢問就沒有停止過,而事實上每個公司的 DevOps 工程師, SRE 工程師的工作內容也都不盡相同。

也因為不盡相同,本來就很難一言概括到底 SRE 的可能內容,因此個人算是滿推崇本篇文章的分析與整理方式,從不同角度出發去列舉各種可能的工作內容,譬如文章中分成三大類

  1. 架構
  2. 服務平台
  3. 業務導向

三種不同類型的 SRE 面對的對象不同,專注的事物也不同,我猜想很多人看完架構類型的論述可能第一個想法就跟以前的 SA/NA 網管有什麼不同?

也許從 SRE 的 R 出發,去探討你今天到底想要針對什麼樣的目標去提供高可用性,也許更能夠方便探討彼此對於 SRE 的需求與認知

· 6 min read

標題: 「DevOps is a failure」 類別: others 連結: https://leebriggs.co.uk/blog/2022/06/21/devops-is-a-failure

本篇文章作者從不同的角度來聊聊 DevOps 這個詞所代表的含義與實作意義

第一段作者先閒聊一下自己與 DevOps 詞的歷史,接者直接拋出一個作者長期好奇的觀點 「每個人都一定聽過 DevOps 是一個需要 Dev + Ops 共同參與的文化,但是作者自己參與的 DevOps 相關會議與討論,與會者大部分都是 Ops 人員,而不是那些真正參與開發的 Dev 人」

困惑時期

接者作者聊聊自身多年前的經驗,當時的開發團隊宣稱該團隊是「true devops」,同時不跟作者的維運團隊討論各種維運需求,這過程讓作者非常困惑,為什麼對方會說自己是 true devops 而又不找自己探討維運需求

作者後來與該開發團隊深聊後終於理解對方的意思,原來該開發團隊身兼開發與維運,該團隊使用 boto3 加上一些腳本來管理應用程式的生命週期,同時該團隊招募的 「full stack engineer」除了基本的後端技術外,也要對 AWS 有不少的熟悉與經驗。

對方的舉動更加困惑了作者,畢竟公司當時採取類似 Netflix 的方式來打造一個平台來讓所有開發者可以更輕鬆的去管理這些東西,而該開發團隊的舉動完全是反其道而行,到底為什麼要這麼做??

Pulumi 時期

當作者加入 Pulumi 時期時,作者開始使用一些知名工具如 GitLab, Terraform, Kubernetes 等工具來打造一個適合開發者的好用平台,然而每次想要將該平台給推廣給開發者時總是屢屢碰壁,總是會聽到如「你們的東西我不熟悉,我們還是習慣自己打造的工具」等類似說詞給打發掉。

作者接下來不斷嘗試說服開發團隊來使用自己打造的超級平台,鼓勵他們參加 DevOps 相關活動等各種方式,最終得到的還是類似「我們會按照我們自己的方式去嘗試~謝囉」之類的回覆

回顧

回顧過往,作者發現錯的是自己,一直以來相信的 DevOps 願景「讓 Ops 停止說 No, 讓 Dev 停止說"yo~ 今天部署吧"」 其實並不真實,作者認為 2022 的今天, DevOps 真正的含義是 「維運端的人努力說服開發人員按照維運人員的想法去做事情」

綜觀所有號稱跟 DevOps 有關的工具,你會發現幾乎都跟維運有關,每個跟 DevOps 有關的職缺列舉的技能也是滿滿的跟維運有關,對作者來說, DevOps 工程師跟過往的 System Admin 根本沒有太大分別,差異只有把「實體機房建置,上架機器」 v.s 「雲端機器建置,創立VM」而已。

文章內後半部分還有一些作者的想法,有興趣的可以閱讀完畢

本篇文章的想法滿有趣的,譬如作者提到想要幫開發團隊建立一個維運平台卻屢屢碰壁。

Ops 可能會覺得 Dev 一直不停重複打造工具沒有效率,不如使用自己打造的好平台 Dev 可能會覺得 Ops 不懂自己的需求,不如自己根據需求打造

同樣的敘述放到不同的規模,譬如

dev -> 5 人的專職開發團隊 dev -> 50 人的專職產品團隊

後者的角度也許會覺得團隊人數夠多,可以自己處理自己的需求,不需要仰賴公司提供一個萬能平台來處理一切,同時跨 team 合作可能還會使得很多事情效率低落,溝通成本過大。

歡迎留言探討你的想法

· 4 min read

標題: 「面試人生 - 設計一個簡易的分散式 Job Scheduler」 類別: others 連結: https://medium.com/@raxshah/system-design-design-a-distributed-job-scheduler-kiss-interview-series-753107c0104c

本篇文章是一個面試技術文,探討開發一個類似 Job Scheduler 的專案時應該要如何去設計整體系統來完成需求,整體的架構基於 KISS 的原則,就是簡單為主。

整個流程原則基本上是

  1. 理解所有功能需求,包含功能面以及非功能面
  2. 瞭解可能的資料,根據規模大小與功能需求去推估出整體的規模大小
  3. 根據上述需求去規劃整體架構,其中規模大小有時候可以幫忙歸納出 ”讀寫“彼此的比例,這個會影響架構設計

功能面常見類型如

  1. 針對使用者提供何種操作,譬如遞交一個 Job, 列出所有 Job(當前,歷史)
  2. 每個 Job 的運行時間限制(ex, 5min),同時 Job 可以重複運行或是只運行一次等不同用法
  3. Job 本身也有優先度的設計,可以插隊等

非直接功能面如

  1. 可動態擴充規模來支援不同量級的需求
  2. 不論發生任何錯誤問題,使用者提交過的 Job 資訊都不能遺失
  3. 非同步設計,使用者遞交 Job 後就可以繼續別的工作, Job 完成後會主動通知使用者

有了功能面的需求,接下來就是數量大小的需求,譬如該架構要可以達到每秒 1000 個 Job(1000QPS), 從這些需求下去估算大概需要多少 CPU 以及多少 Memory,同時這些數量還可以滿足功能面的需求,譬如每個 Job 可以運行最多五分鐘。

所以也許會得到需要 10,000 台的 (16C) 機器,以及 100 台(16GB) 的機器來提供服務 基本的運算可以快速的理解該需求到底需不需要分散式的架構來處理,本文的範例資料量就很明顯是 scale up 沒有辦法完成的。

接下來就基於分散式的架構去設計相關架構,包含如

  1. Load Balancer
  2. Backend
  3. DB
  4. Job scheduler
  5. Job Executor
  6. Queue
  7. File system

逐步的規劃這些架構,並且探討彼此元件之間的溝通方式,這些方式是如何互相組合來滿足功能面/非功能面的需求

詳細需求可以參考全文

· 5 min read

標題: 「Cloudflare 06/21 災後報告」 類別: networks 連結: https://blog.cloudflare.com/cloudflare-outage-on-june-21-2022/

Cloudflare 官方文章詳細解釋 06/21/2022 當天到底發生什麼事情導致用戶受到影響,

這次的問題影響範圍概括了 Cloudflare 底下的 19 個資料中心,而很不幸的這 19 個資料中心剛好都是負責處理繁忙的全球流量,所以受到影響的用戶數量才會如此的多。 問題主因是網路設定的調整(有問題先猜BGP,不行再猜DNS...),整體的發生時間沒有非常長

  1. 06:27 UTC 問題發生
  2. 06:58 UTC 第一個資料中心修復並且上線
  3. 07:42 UTC 所有資料中心修復並且上線

背景

過去 18 個月以來, Cloudflare 致力於將其底下繁忙的資料中心進行架構改造來達成更為堅韌與彈性的網路架構,內部稱該架構為 Multi-Colo POP(MCP),影響的 19 個資料中心包含 Tokyo, Singapore ... 等

新架構最重要的部分就是其網路的部分是基於 Clos network 的架構設計,透過多層次的設計達成類似 mesh network 般的網路連結,該架構使得未來要維護與調整時能夠更輕鬆針對部分網路設備去處理而不會影響到整體網路(文章有架構圖片)。

問題

這次的問題主要跟 BGP 有關,Cloudflare 更新 BGP 的過程中有部分的 subnet 沒有順利的被傳遞出去,最終使得部分 subnet 的流量無法被順利轉發,進而導致整個網路問題。

文章內部有針對 BGP 問題更詳細的介紹,熟悉 BGP 的朋友可以花點時間看一下

反思

這次的問題影響範圍很廣,Cloudflare 針對下列三面向反思了一下問題的發生原因

Process

雖然嶄新的 MCP 架構其目的就是要提供更好更強的可用性,但是將舊架構給升級到新架構的過程中還是不夠完善。整體的更新流程直到最後一步驟才算是真正的接觸到全新 MCP 架構,這使得如果中間更新流程有錯必須要到最後才會觀察到 MCP 資料中心的網路炸了。 改善的方式則是未來的這些流程與自動化必須要加入更多關於 MCP 架構的測試來確保整體部署不會遇到預期外的結果。

Architecture

路由器的錯誤設定使得正確的路由規則沒有辦法順利的被傳達下去,最終使得網路封包無法如預期般地到達這些資料中心。 所以修復過程中就是要找出這些錯誤的設定並且修正,最終使得這些 BGP 能夠將正確的路由政策給轉發下去。

Automaiton

當前的自動化流程中有非常多的部分可以改進,這些改進有機會完全或是部分的去減緩問題發生時的影響程度。 有兩個目標是想要透過改善自動化機制達成的

  1. 減少問題發生時的影響範圍
  2. 減少問題發生時的修復時間

結論

CDN 不通先上社群看同業有沒有哀嚎,大概就可以知道是不是自己的問題了?