四年新創公司基礎設施經驗談:我的抉擇與反思

四年新創基礎建設經驗談:流程與軟體的抉擇與反思。

四年新創公司基礎設施經驗談:我的抉擇與反思
Photo by Taylor Vick / Unsplash

過去四年,我帶領一家 新創公司 的基礎設施團隊經歷快速成長。過程中,我做了一些重要的決策,有好有壞,都影響了公司發展。本文將回顧這些決策,並分享我的想法,希望能幫助其他新創公司。

AWS

AWS vs. Google Cloud

🟩 推薦

早期我們同時使用 GCP 和 AWS。那時我完全找不到 Google Cloud 的客戶經理,但 AWS 的客戶經理卻定期與我們開會。 Google Cloud 感覺很自動化,而 AWS 更重視客戶。 AWS 的支援在我們評估新服務時非常有幫助。此外, AWS 的穩定性和避免 API 的向下不相容性也做得很好。

Google Cloud 曾是 Kubernetes 的首選,尤其當 AWS 還在猶豫是否要發展 EKS 而不是 ECS 的時候。但現在 AWS 上 Kubernetes 的整合服務( external-dns 、 external-secrets 等)越來越完善,這已不再是問題。

EKS

🟩 推薦

除非預算極度緊縮(而且時間成本不計),否則沒有理由捨 EKS 而自行搭建 Kubernetes 控制平面。在 AWS 上,選擇 ECS 之類的替代方案主要優點是能與 AWS 深度整合。現在 Kubernetes 也迎頭趕上,例如: external-dns 就能與 Route53 整合。

EKS managed addons

🟧 不推薦

我們一開始使用 EKS managed addons ,因為我認為 EKS 就該這樣用。但我們總會遇到需要客製化安裝的情況,例如調整 CPU 資源、修改映像檔版本或調整 configmap 。後來我們改用 Helm Chart ,升級更符合現有的 GitOps 流程,也更順暢。

RDS

🟩 推薦

資料是基礎設施的命脈。網路斷線只是停機,資料遺失卻可能毀掉公司。 RDS (或其他雲端託管資料庫)的額外成本絕對值得。

Redis ElastiCache

🟩 推薦

Redis 作為快取及通用產品表現出色。它速度快, API 簡單易懂,且久經考驗。不像 Memcached 等快取方案, Redis 功能多元,不僅能做快取。它是「資料加速」的萬用工具。

我不確定雲端供應商對 Redis 的支援程度,但 AWS 用戶眾多,相信 AWS 會持續提供良好支援。

ECR

🟩 推薦

我們最初使用 quay.io ,問題不斷。搬到 ECR 後,穩定許多。它與 EKS 節點或開發伺服器的深度權限整合也是一大優點。

AWS VPN

🟩 推薦

CloudFlare 等公司提供零信任 VPN 方案。這些產品應該不錯,但 VPN 設定和使用都很簡單(「簡單至上」是我的座右銘)。我們用 Okta 管理 VPN 權限,體驗很好。

AWS premium support

🟧 不推薦

價格高昂,幾乎等於再請一位工程師。如果團隊對 AWS 不熟悉,或許值得考慮。

Control Tower Account Factory for Terraform ( AFT )

🟩 推薦

在整合 AFT 前,用 Control Tower 很麻煩,因為難以自動化。整合 AFT 後,開新帳號變得容易許多。 AFT 也讓帳號標籤標準化更容易。例如,我們用標籤來區分正式環境帳號,以決定 peering 設定。標籤比組織結構更靈活,因為描述帳號的屬性不一定是樹狀結構。

流程

用 Slack 機器人自動化事故檢討流程

🟩 推薦

大家都很忙。提醒大家填寫事故檢討報告很像在扮黑臉。讓機器人扮黑臉效果不錯。它能提醒大家遵循事件嚴重程度分類和事故檢討流程。

一開始不用太複雜。「一小時沒更新,請更新一下」或「一天沒安排檢討會議,請安排一下」就很有幫助。

使用 PagerDuty 事故檢討範本

🟩 推薦

不用重複造輪子。 PagerDuty 提供了事故檢討範本。我們稍作修改,這也是 Notion 好客製化的優點,但它是很好的起點。

定期檢討 PagerDuty 警報

🟩 推薦

公司警報的演變通常是這樣的:

  1. 沒有警報。需要警報。
  2. 有警報了。警報太多,被忽略。
  3. 警報分類了。只有重要警報才會叫醒我。
  4. 不重要的警報被忽略。

我們有兩級警報:重要和不重要。重要警報會叫醒值班人員。不重要警報則透過非同步管道(例如 Email )通知。問題是不重要警報常被忽略。為了解決這點,我們定期(通常兩週一次)檢討所有 PagerDuty 警報。檢視重要警報是否仍需維持重要等級,並挑選一些不重要警報討論如何處理(通常是調整閥值或增加自動化)。

每月追蹤成本

🟩 推薦

早期,我建立每月會議檢討所有 SaaS 成本 ( AWS 、 DataDog 等)。以前財務部門負責檢討,但他們很難判斷成本是否合理。現在財務和工程部門一起開會,檢視每一筆軟體帳單,判斷成本是否合理,並分析高額帳單的細項。

例如,我們用標籤和帳號分類 AWS 資源。加上服務名稱 ( EC2 、 RDS 等),就能清楚看出主要成本來源。我們利用這些資料深入分析 spot instance 使用率,或哪些帳號的網路成本最高。除了 AWS ,也要檢討其他主要花費。

用 DataDog 或 PagerDuty 管理事故檢討

🟥 不推薦

事故檢討很重要。 DataDog 和 PagerDuty 都提供事故檢討功能,我們都試過。但它們都不好客製化。像 Notion 這類 wiki 工具功能強大,更適合用來管理事故檢討。

未充分利用 FaaS

🟥 不推薦

目前沒有好的 GPU FaaS 方案,所以我們無法完全使用 FaaS 。但很多 CPU 工作負載可以用 FaaS ( Lambda 等)。最大的反對意見是成本。有人會說:「一台全天候滿載的 EC2 比 Lambda 便宜」。這是事實,但比較基準不對。沒人會讓服務 CPU 持續 100% 。通常會設定自動擴展:「到 70% 就加開一台」。縮減也很難精確控制,通常是:「 10% 持續 10 分鐘就關掉一台」。而且 spot instance 也不是隨時都有。

Lambda 的另一個好處是成本追蹤更精確。 Kubernetes 的成本常被其他服務或節點資源混淆。

GitOps

🟩 推薦

GitOps 擴展性很好,我們用它管理很多東西:服務、 Terraform 、設定檔等等。主要缺點是傳統 CI/CD 流程很清楚,程式碼提交後會依序執行各步驟。 GitOps 則需要額外工具才能追蹤部署狀態。

即使如此, GitOps 的彈性仍是一大優點,我強烈推薦。

優先團隊效率而非外部需求

🟩 推薦

多數公司不是賣基礎設施,而是賣產品。這讓團隊壓力很大,需要開發新功能,而不是改善基礎設施。但就像飛機上要先戴好自己的氧氣罩,團隊效率很重要。我從不後悔花時間寫自動化腳本或文件。

多個應用程式共用同一個資料庫

🟥 不推薦

這就像大多數技術債,不是刻意造成的,而是不知不覺累積的。一開始只是新增一個表格,加上外鍵連結其他表格,感覺沒什麼問題。但所有資料都與使用者資料有關聯,最後整個系統就糾結在一起了。

資料庫大家都在用,卻沒人負責維護。新創公司通常沒有 DBA ,最後基礎設施團隊就成了冤大頭。

共用資料庫的主要問題:

  • 資料庫累積許多垃圾資料,難以清理。
  • 效能問題發生時,基礎設施團隊(不了解產品細節)得先找出問題,再轉交給負責的團隊。
  • 應用程式程式碼可能影響資料庫效能,觸發基礎設施團隊的 PagerDuty 警報。半夜被叫醒處理別人的問題很惱人。如果每個應用程式都有自己的資料庫,應用程式團隊就能第一時間處理。

我不是完全反對共用資料庫,但要考慮清楚這些問題,並想好應對方案。

SaaS

沒有提早導入身份平台

🟥 不推薦

我一開始用 Google Workspace 建立群組來管理權限。它不夠彈性。早知道就該早點用 Okta 。它功能完善,整合性高,也解決許多資安和合規問題。建議及早導入身份平台,只選用能整合的 SaaS 服務。

Notion

🟩 推薦

每個公司都需要文件管理工具。 Notion 比我以前用過的工具 ( Wiki 、 Google Docs 、 Confluence 等) 都好用。它的資料庫功能讓文件管理更井然有序。

Slack

🟩 推薦

還好不用再用 HipChat 了。 Slack 是很好的溝通工具,但為了減少干擾,我建議:

  • 多用 thread 回覆,讓訊息更集中。
  • 不要期待立即回覆。
  • 少用私訊,多用公開頻道。

從 JIRA 換成 Linear

🟩 推薦

JIRA 太肥大了,在 AI 公司用它,我怕它會有自己的意識。用 Linear 時,我常想「不知道能不能做到 X 」,結果都能!

沒有使用 Terraform Cloud

🟩 不後悔

早期我想把 Terraform 搬到 Terraform Cloud ,但成本太高。後來我們改用 Atlantis ,效果不錯。 Atlantis 不足的地方,我們用 CI/CD 腳本來補足。

用 GitHub Actions 做 CI/CD

🟧 勉強推薦

跟大多數公司一樣,我們的程式碼放在 GitHub 。我們從 CircleCI 換到 GitHub Actions 。它的市集有很多現成的 action ,語法也簡單。主要缺點是自架 runner 的支援不足。我們用 EKS 和 actions-runner-controller 來管理自架 runner ,但整合問題不少(還算能解決)。希望 GitHub 未來能加強對 Kubernetes 自架 runner 的支援。

Datadog

🟥 不推薦

Datadog 很好用,但很貴。更麻煩的是,它的計價方式對 Kubernetes 和 AI 公司很不利。 Kubernetes 的成本效益來自快速增減節點和使用 spot instance 。但 Datadog 依實例數量計價,即使我們同時最多只用到 10 個實例,如果一小時內增減 20 個實例,我們就得付 20 個實例的錢。 AI 公司常用 GPU 。 CPU 節點可以跑很多服務,分攤 Datadog 成本。但 GPU 節點通常只跑單一服務,讓每個服務的 Datadog 成本變得很高。

PagerDuty

🟩 推薦

PagerDuty 好用,價格也合理。我們從沒後悔用它。

軟體

用 Diff 管理資料庫 Schema 遷移

🟧 勉強推薦

資料庫 Schema 遷移很麻煩,因為資料很重要,遷移失敗可能遺失資料。各種解決方案中,我把 Schema 存放在 Git ,用 工具 產生 SQL 同步資料庫,覺得還不錯。

開發伺服器用 Ubuntu

🟩 推薦

我一開始想讓開發伺服器和 Kubernetes 節點用一樣的作業系統,讓開發環境更接近正式環境。現在覺得不值得。 Ubuntu 支援度好,套件也齊全,很適合開發伺服器。

AppSmith

🟩 推薦

我們常需要幫內部工程師自動化一些流程:重啟、升級、診斷等等。寫 API 很容易,但要處理每個人的 CLI/OS/dependency 設定很麻煩。有個簡單的 UI 讓工程師操作腳本就很方便。

我們自架 AppSmith ,堪用。雖然有些缺點,免費版夠用了。我原本想用 Retool ,但當時整合需求不多,價格太貴。

Helm

🟩 推薦

Helm v2 惡名昭彰,但 v3 還不錯。部署 CRD 和教開發人員除錯還是有點麻煩。但整體來說, Helm 很適合打包和部署 Kubernetes 資源。 Go template 雖然難以除錯,但功能強大。

Helm Chart 放在 ECR ( OCI )

🟩 推薦

我們原本把 Helm Chart 放在 S3 ,用 plugin 下載。缺點是要裝 plugin ,還要手動管理生命週期。換成 OCI 後就沒這些問題了。

Bazel

🟧 不確定

很多高手喜歡 Bazel ,所以它應該不錯。

部署 Go 服務時, Bazel 感覺有點殺雞用牛刀。如果你上家公司用 Bazel ,你可能會想念它。不然,只有少數工程師懂的建構系統,不如 GitHub Actions 人人都會用。

沒有提早使用 OpenTelemetry

🟥 不推薦

我們一開始用 DataDog API 傳送數據。現在很難換掉。

四年前 OpenTelemetry 還不成熟,現在好多了。它的 metrics 部分還有待加強,但 tracing 很好用。建議新創公司一開始就用。

Renovatebot vs. Dependabot

🟩 推薦

我真希望早點想到要自動更新依賴套件。版本太舊,升級很麻煩,問題也多。 Renovatebot 好用,也很好客製化。最大缺點是設定和除錯很複雜。它是所有爛選項中最好的。

Kubernetes

🟩 推薦

你需要東西來管理長期運行的服務。 Kubernetes 很熱門,對我們也很有效。社群也做了很多 AWS 整合(例如負載平衡器、 DNS 等)。彈性系統的缺點是設定方法太多,也代表有很多方法會出錯。

設定方法太多,也代表有很多方法會出錯。

— Jack Lindamood

購買自己的 IP

🟩 推薦

跟外部夥伴合作時,常需要提供 IP 白名單。但你之後可能會新增系統,需要更多 IP 。買一整段 IP 區塊,提供更大的 CIDR 給合作夥伴,就能避免這個問題。

用 Flux 做 Kubernetes GitOps

🟩 不後悔

Kubernetes GitOps 方案主要有 ArgoCD 和 Flux 。我選了 Flux (當時是 v1 ),效果不錯。現在用的是 Flux 2 。唯一缺點是要自己寫工具來追蹤部署狀態。

聽說 ArgoCD 也不錯,應該也很好用。

Karpenter

🟩 推薦

如果你用 EKS (不是完全用 Fargate ),一定要用 Karpenter 。我們用過其他自動擴展器,包括 Kubernetes 內建的和 SpotInst 。 Karpenter 最穩定,也最省錢。

用 SealedSecrets 管理 Kubernetes secrets

🟥 不推薦

我原本想用 GitOps 方式管理 secrets 。 SealedSecrets 有兩個缺點:

  • 不熟悉基礎設施的開發人員難以操作 secrets 。
  • AWS 提供的 secrets 輪替功能 (例如) 都不能用了。

用 ExternalSecrets 管理 Kubernetes secrets

🟩 推薦

ExternalSecrets 能順利同步 AWS secrets 到 Kubernetes 。開發人員容易上手,我們可以用 Terraform 或 AWS UI 管理 secrets 。

用 ExternalDNS 管理 DNS

🟩 推薦

ExternalDNS 很好用。它能同步 Kubernetes 的 DNS 紀錄到 Route53 ,四年來沒出過什麼問題。

用 cert-manager 管理 SSL 證書

🟩 推薦

設定簡單,配合 Let's Encrypt 很順暢。強烈推薦用它來產生 Kubernetes 的 Let's Encrypt 證書。有些老舊系統不信任 Let's Encrypt ,需要付費購買證書,這是唯一的缺點。

用 Bottlerocket 跑 EKS

🟥 不推薦

我們的 EKS 叢集原本用 Bottlerocket 。它常有網路 CSI 問題,除錯也比標準 EKS AMI 困難。改用 EKS optimized AMI 後就沒問題了,而且還能直接除錯節點,解決一些奇怪的網路問題。

Terraform vs. CloudFormation

🟩 推薦

IaC 是必備的。在 AWS 上,主要選擇是 CloudFormation 和 Terraform 。我兩個都用過,不後悔選擇 Terraform 。它容易擴展到其他 SaaS 平台(例如 Pagerduty ),語法比 CloudFormation 好懂,也沒造成什麼困擾。

不用程式碼式的 IaC 方案( Pulumi 、 CDK 等)

🟩 不後悔

Terraform 和 CloudFormation 用資料檔( HCL 和 YAML/JSON )描述基礎設施, Pulumi 和 CDK 則用程式碼。程式碼很強大,但我覺得 Terraform HCL 的限制反而降低了複雜度。不是不能寫複雜的 Terraform ,只是複雜的 Terraform 程式碼更容易被識別。

有些方案,例如 Pulumi ,出現時 Terraform 還缺少很多現在的功能。新版 Terraform 已經加入很多簡化設定的功能。我們用程式碼產生 Terraform 程式碼片段,達到抽象化的目的。

不用網路網格( Istio/Linkerd 等)

🟩 不後悔

網路網格很酷,很多高手也推薦,所以它應該不錯。但我覺得大家低估了它的複雜度。我的基礎設施原則是「簡單至上」。

用 Nginx 做 EKS Ingress 負載平衡器

🟩 不後悔

Nginx 歷史悠久,穩定可靠。

用 Homebrew 管理公司腳本

🟩 推薦

公司通常需要發佈腳本和執行檔給工程師用。 Homebrew 在 Linux 和 Mac 上都堪用。

用 Go 開發服務

🟩 推薦

Go 容易上手,整體來說是個好選擇。非 GPU 服務,尤其是網路 IO 密集的服務,應該優先考慮 Go 。