干货分享 | 阿里PB级Kubernetes日志平台建设实践
嘉賓 | 元乙
隨著近兩年的發展,Kubernetes 早已成為容器編排領域的標準,現在非常多的企業基于 Kubernetes 構建整個微服務的開發、運維平臺,而日志是其中必不可少的核心功能。本文整理自阿里云日志服務技術專家元乙在 QCon 全球軟件開發大會(北京站)2019 上的演講,他的分享主要介紹了阿里超大規模下 Kubernetes 日志平臺的架構實踐,通過日志采集、處理、分析、監控、異常診斷等全方位技術,實現 Kubernetes 以及業務應用真正意義上的可觀察性。
QCon 是由 InfoQ 主辦的綜合性技術盛會,每年在倫敦、北京、紐約、圣保羅、上海、舊金山召開。我有幸在 QCon 10 周年之際,作為分享嘉賓在 QCon 全球軟件開發大會(北京站)2019 中劉宇老師的運維專場發表了《Kubernetes 日志平臺建設最佳實踐》,現將 PPT 和文字稿整理下來,希望和更多的愛好者分享。
計算形態的發展與日志系統的演進
在阿里的十多年中,日志系統伴隨著計算形態的發展在不斷演進,大致分為 3 個主要階段:
-
在單機時代,幾乎所有的應用都是單機部署,當服務壓力增大時,只能切換更高規格的 IBM 小型機。日志作為應用系統的一部分,主要用作程序 Debug,通常結合 grep 等 Linux 常見的文本命令進行分析。
-
隨著單機系統成為制約阿里業務發展的瓶頸,為了真正的 Scale out,飛天項目啟動:2009 年開始了飛天的第一行代碼,2013 年飛天 5K 項目正式上線。在這個階段各個業務開始了分布式改造,服務之間的調用也從本地變為分布式,為了更好的管理、調試、分析分布式應用,我們開發了 Trace(分布式鏈路追蹤)系統、各式各樣的監控系統,這些系統的統一特點是將所有的日志(包括 Metric 等)進行集中化的存儲。
-
為了支持更快的開發、迭代效率,近年來我們開始了容器化改造,并開始了擁抱 Kubernetes 生態、業務全量上云、Serverless 等工作。要實現這些改造,一個非常重要的部分是可觀察性的工作,而日志是作為分析系統運行過程的最佳方式。在這階段,日志無論從規模、種類都呈現爆炸式的增長,對日志進行數字化、智能化分析的需求也越來越高,因此統一的日志平臺應運而生。
日志平臺的重要性與建設目標
日志不僅僅是服務器、容器、應用的 Debug 日志,也包括各類訪問日志、中間件日志、用戶點擊、IoT/ 移動端日志、數據庫 Binlog 等等。這些日志隨著時效性的不同而應用在不同的場景:
-
準實時級別:這類日志主要用于準實時(秒級延遲)的線上監控、日志查看、運維數據支撐、問題診斷等場景,最近兩年也出現了準實時的業務洞察,也是基于這類準實時的日志實現。
-
小時 / 天級別:當數據積累到小時 / 天級別的時候,這時一些 T+1 的分析工作就可以開始了,例如用戶留存分析、廣告投放效果分析、反欺詐、運營監測、用戶行為分析等。
-
季度 / 年級別:在阿里,數據是我們最重要的資產,因此非常多的日志都是保存一年以上或永久保存,這類日志主要用于歸檔、審計、攻擊溯源、業務走勢分析、數據挖掘等。
在阿里,幾乎所有的業務角色都會涉及到各式各樣的日志數據,為了支撐各類應用場景,我們開發了非常多的工具和功能:日志實時分析、鏈路追蹤、監控、數據清洗、流計算、離線計算、BI 系統、審計系統等等。其中很多系統都非常成熟,日志平臺主要專注于智能分析、監控等實時的場景,其他功能通常打通的形式支持。
阿里日志平臺現狀
目前阿里的日志平臺覆蓋幾乎所有的產品線和產品,同時我們的產品也在云上對外提供服務,已經服務了上萬家的企業。每天寫入流量 16PB 以上,對應日志行數 40 萬億 + 條,采集客戶端 200 萬,服務數千 Kubernetes 集群,是國內最大的日志平臺之一。
為何選擇自建
日志系統存在了十多年,目前也有非常多的開源的方案,例如最典型的 ELK(Elastic Search、Logstash、Kibana),通常一個日志系統具備以下功能:日志收集 / 解析、查詢與檢索、日志分析、可視化 / 告警等,這些功能通過開源軟件的組合都可以實現,但最終我們選擇自建,主要有幾下幾點考慮:
數據規模:這些開源日志系統可以很好的支持小規模的場景,但很難支持阿里這種超大規模(PB 級)的場景。
資源消耗:我們擁有百萬規模的服務器 / 容器,同時日志平臺的集群規模也很大,我們需要減少對于采集以及平臺自身的資源消耗。
多租戶隔離:開源軟件搭建的系統大部分都不是為了多租戶而設計的,當非常多的業務 / 系統使用日志平臺時,很容易因為部分用戶的大流量 / 不恰當使用而導致打爆整個集群。
運維復雜度:在阿里內部有一套非常完整的服務部署和管理系統,基于內部組件實現會具備非常好的運維復雜度。
高級分析需求:日志系統的功能幾乎全部來源與對應的場景需求,有很多特殊場景的高級分析需求開源軟件沒辦法很好的支持,例如:上下文、智能分析、日志類特殊分析函數等等。
Kubernetes 日志平臺建設難點
圍繞著 Kubernetes 場景的需求,日志平臺建設的難點主要有以下幾點:
-
日志采集:采集在 Kubernetes 中極其關鍵和復雜,主要因為 Kubernetes 是一個高度復雜的場景,Kubernetes 中有各式各樣的子系統,上層業務支持各種語言和框架,同時日志采集需要盡可能的和 Kubernetes 系統打通,用 K8 的形式來完成數據采集。
-
資源消耗:在 Kubernetes 中,服務通常都會拆的很小,因此數據采集對于服務自身的資源消耗要盡可能的少。這里我們簡單的做一個計算,假設有 100W 個服務實例,沒個采集 Agent 減少 1M 的內存、1% 的 CPU 開銷,那整體會減少 1TB 的內存和 10000 個 CPU 核心。
-
運維代價:運維一套日志平臺的代價相當之大,因此我們不希望每個用戶搭建一個 Kubernetes 集群時還需再運維一個獨立的日志平臺系統。因此日志平臺一定是要 SaaS 化的,應用方 / 用戶只需要簡單的操作 Web 頁面就能完成數據采集、分析的一整套流程。
-
便捷使用:日志系統最核心的功能是問題排查,問題排查的速度直接決定了工作效率、損失大小,在 K8s 場景中,更需要一套高性能、智能分析的功能來幫助用戶快速定位問題,同時提供一系列簡單有效的可視化手段進行輔助。
阿里 PB 級 Kubernetes 日志平臺建設
Kubernetes 日志數據采集
無論是在 ITOM 還是在未來的 AIOps 場景中,日志獲取都是其中必不可少的一個部分,數據源直接決定了后續應用的形態和功能。在十多年中,我們積累了一套物理機、虛擬機的日志采集經驗,但在 Kubernetes 中不能完全適用,這里我們以問題的形式展開:
問題 1:DaemonSet or Sidecar
日志最主要的采集工具是 Agent,在 Kubernetes 場景下,通常會分為兩種采集方式:
-
DaemonSet 方式:在 K8S 的每個 node 上部署日志 agent,由 agent 采集所有容器的日志到服務端。
-
Sidecar 方式:一個 POD 中運行一個 sidecar 的日志 agent 容器,用于采集該 POD 主容器產生的日志。
每種采集方式都有其對應的優缺點,這里簡單總結如下:
| 采集日志類型 | 標準輸出 + 部分文件 | 文件 |
| 部署運維 | 一般,需維護 DaemonSet | 較高,每個需要采集日志的 POD 都需要部署 sidecar 容器 |
| 日志分類存儲 | 一般,可通過容器 / 路徑等映射 | 每個 POD 可單獨配置,靈活性高 |
| 多租戶隔離 | 一般,只能通過配置間隔離 | 強,通過容器進行隔離,可單獨分配資源 |
| 支持集群規模 | 中小型規模,業務數最多支持百級別 | 無限制 |
| 資源占用 | 較低,每個節點運行一個容器 | 較高,每個 POD 運行一個容器 |
| 查詢便捷性 | 較高,可進行自定義的查詢、統計 | 高,可根據業務特點進行定制 |
| 可定制性 | 低 | 高,每個 POD 單獨配置 |
| 適用場景 | 功能單一型的集群 | 大型、混合型、PAAS 型集群 |
在阿里內部,對于大型的 PAAS 集群,主要使用 Sidecar 方式采集數據,相對隔離性、靈活性最好;而對與功能比較單一(部門內部 / 產品自建)的集群,基本都采用 DaemonSet 的方式,資源占用最低。
問題 2:如何降低資源消耗
我們數據采集 Agent 使用的是自研的 Logtail,Logtail 用 C++/Go 編寫,相對開源 Agent 在資源消耗上具有非常大的優勢,但我們還一直在壓榨數據采集的資源消耗,尤其在容器場景。通常,為了提高打日志和采集的性能,我們都使用本地 SSD 盤作為日志盤。這里我們可以做個簡答的計算:假設每個容器掛載 1GB 的 SSD 盤,1 個物理機運行 40 個容器,那每臺物理機需要 40GB 的 SSD 作為日志存儲,那 5W 物理機則會占用 2PB 的 SSD 盤。
為了降低這部分資源消耗,我們和螞蟻金服團隊的同學們一起開發了 FUSE 的日志采集方式,使用 FUSE(Filesystem in Userspace,用戶態文件系統)虛擬化出日志盤,應用直接將日志寫入到虛擬的日志盤中,最終數據將直接從內存中被 Logtail 采集到服務端。這種采集的好處有:
-
物理機無需為容器提供日志盤,真正實現日志無盤化。
-
應用程序視角看到的還是普通的文件系統,無需做任何額外改造。
-
數據采集繞過磁盤,直接從內存中將數據采集到服務端。
-
所有的數據都存在服務端,服務端支持橫向擴展,對于應用來說他們看到的日志盤具有無線存儲空間。
問題 3:如何與 Kubernetes 無縫集成
Kubernetes 一個非常大的突破是使用聲明式的 API 來完成服務部署、集群管理等工作。但在 K8s 集群環境下,業務應用 / 服務 / 組件的持續集成和自動發布已經成為常態,使用控制臺或 SDK 操作采集配置的方式很難與各類 CI、編排框架集成,導致業務應用發布后用戶只能通過控制臺手動配置的方式部署與之對應的日志采集配置。因此我們基于 Kubernetes 的 CRD(CustomResourceDefinition)擴展實現了采集配置的 Operator,用戶可以直接使用 K8s API、Yaml、kubectl、Helm 等方式直接配置采集方式,真正把日志采集融入到 Kubernetes 系統中,實現無縫集成。
問題 4:如何管理百萬級 Logtail
對于人才管理有個經典的原則:10 個人要用心良苦,100 個人要殺伐果斷,1000 個人要甩手掌柜。而同樣對于 Logtail 這款日志采集 Agent 的管理也是如此,這里我們分為 3 個主要過程:
-
百規模:在好幾年前,Logtail 剛開始部署時,也就在幾百臺物理機上運行,這個時期的 Logtail 和其他主流的 Agent 一樣,主要完成數據采集的功能,主要流程為數據輸入、處理、聚合、發送,這個時期的管理基本靠手,采集出現問題的時候人工登錄機器去看問題。
-
萬規模:當越來越多的應用方接入,每臺機器上可能會有多個應用方采集不同類型的數據,手動配置的接入過程也越來越難以維護。因此我們重點在多租戶隔離以及中心化的配置管理,同時增加了很多控制相關的手段,比如限流、降級等。
-
百萬規模:當部署量打到百萬級別的時候,異常發生已經成為常態,我們更需要的是靠一系列的監控、可靠性保證機制、自動化的運維管理工具,讓這些機制、工具來自動完成 Agent 安裝、監控、自恢復等一系列工作,真正做到甩手掌柜。
Kubernetes 日志平臺架構
上圖是阿里 Kubernetes 日志平臺的整體架構,從底到上分為日志接入層、平臺核心層以及方案整合層:
-
平臺提供了非常多的手段用來接入各種類型的日志數據。不僅僅只有 Kubernetes 中的日志,同時還包括和 Kubernetes 業務相關的所有日志,例如移動端日志、Web 端應用點擊日志、IoT 日志等等。所有數據支持主動 Push、被動 Agent 采集,Agent 不僅支持我們自研的 Logtail,也支持使用開源 Agent(Logstash、Fluentd、Filebeats 等)。
-
日志首先會到達平臺提供的實時隊列中,類似于 Kafka 的 consumer group,我們提供實時數據訂閱的功能,用戶可以基于該功能實現 ETL 的相關需求。平臺最核心的功能包括:
-
實時搜索:類似于搜索引擎的方式,支持從所有日志中根據關鍵詞查找,支持超大規模(PB 級)。
-
實時分析:基于 SQL92 語法提供交互式的日志分析方法。
-
機器學習:提供時序預測、時序聚類、根因分析、日志聚合等智能分析方法。
-
流計算:對接各類流計算引擎,例如:Flink、Spark Stream、Storm 等。
-
離線分析:對接離線分析引擎,例如 Hadoop、Max Compute 等。
-
基于全方位的數據源以及平臺提供的核心功能,并結合 Kubernetes 日志特點以及應用場景,向上構建 Kubernetes 日志的通用解決方案,例如:審計日志、Ingress 日志分析、ServiceMesh 日志等等。同時對于有特定需求的應用方 / 用戶,可直接基于平臺提供的 OpenAPI 構建上層方案,例如 Trace 系統、性能分析系統等。
下面我們從問題排查的角度來具體展開平臺提供的核心功能。
PB 級日志查詢
排查問題的最佳手段是查日志,大部分人腦海中最先想到的是用 grep 命令查找日志中的一些關鍵錯誤信息, grep 是 Linux 程序員最受歡迎的命令之一,對于簡單的問題排查場景也非常實用。如果應用部署在多臺機器,那還會配合使用 pgm、pssh 等命令。然而這些命令對于 Kubernetes 這種動態、大規模的場景并不適用,主要問題有:
-
查詢不夠靈活,grep 命令很難實現各種邏輯條件的組合。
-
grep 是針對純文本的分析手段,很難將日志格式化成對應的類型,例如 Long、Double 甚至 JSON 類型。
-
grep 命令的前提條件是日志存儲在磁盤上。而在 Kubernetes 中,應用的本地日志空間都很小,并且服務也會動態的遷移、伸縮,本地的數據源很可能會不存在。
-
grep 是典型的全量掃描方式,如果數據量在 1GB 以內,查詢時間還可以接受,但當數據量上升到 TB 甚至 PB 時,必須依賴搜索引擎的技術才能工作。
我們在 2009 年開始在飛天平臺研發過程中,為夠解決大規模(例如 5000 臺)下的研發效率、問題診斷等問題,開始研支持超大規模的日志查詢平臺,其中最主要的目標是“快”,對于幾十億的數據也能夠輕松在秒級完成。
日志上下文
當我們通過查詢的方式定位到關鍵的日志后,需要分析當時系統的行為,并還原出當時的現場情況。而現場其實就是當時的日志上下文,例如:
-
一個錯誤,同一個日志文件中的前后數據
-
一行 LogAppender 中輸出,同一個進程順序輸出到日志模塊前后順序
-
一次請求,同一個 Session 組合
-
一次跨服務請求,同一個 TraceId 組合
在 Kubernetes 的場景中,每個容器的標準輸出(stdout)、文件都有對應的組合方式構成一個上下文分區,例如 Namesapce+Pod+ContainerID+FileName/Stdout。為支持上下文,我們在采集協議中對每個最小區分單元會帶上一個全局唯一并且單調遞增的游標,這個游標對單機日志、Docker、K8S 以及移動端 SDK、Log4J/LogBack 等輸出中有不一樣的形式
為日志而生的分析引擎
在一些復雜的場景中,我們需要對日志中的數據進行統計來發現其中規律。例如根據 ClientIP 進行聚合來查找攻擊源 IP、將數據聚合計算 P99/P9999 延遲、從多個維度組合分析等。傳統的方式需要配合流計算或離線計算的引擎進行聚合計算,再對接可視化系統進行圖形化展示或對接告警系統。這種方式用戶需要維護多套系統,數據實時性變差,并且各個系統間的銜接很容易出現問題。
因此我們平臺原生集成了日志分析、可視化、告警等相關的功能,盡可能減少用戶配置鏈路。通過多年的實踐,我們發現用戶最容易接受的還是 SQL 的分析方式,因此我們分析基于 SQL92 標準實現,在此基礎上擴展了很多針對日志分析場景的高級函數,例如:
-
同比環比:前后數據對比是日志分析中最常用的方式之一,我們提供了同比 / 環比函數,一個函數即可計算今日 PV 同比昨日、上周的增幅。
-
IP 地理函數:基于淘寶高精度 IP 地理庫,提供 IP 到國家、省、市、運營商、經緯度等的轉換,例如常見的 Nginx 訪問日志、K8s Ingress 訪問日志中的 remote-ip 可以直接用來分析地理位置分布。
-
Join 外部數據源:將日志和 MySQL、CSV 等做 Join 分析,例如根據 ID 從數據庫中查找用戶對應的信息、和 CMDB 中的網絡架構數據做關聯等。
-
安全函數:支持日志安全分析中的常見方式,例如高危 IP 庫查找、SQL 注入分析、高危 SQL 檢測等。
智能日志分析
在日志平臺上,應用方 / 用戶可以通過日志接入、查詢、分析、可視化、告警等功能可以完成異常監控、問題調查與定位。但隨著計算形態、應用形態以及開發人員職責的不斷演變,尤其在近兩年 Kubernetes、ServiceMesh、Serverless 等技術的興起,問題的復雜度不斷上升,常規手段已經很難適用。于是我們開始嘗試向 AIOps 領域發展,例如時序分析、根因分析、日志聚類等。
時序分析
通過時序預測相關方法,我們可以對 CPU、存儲進行時序建模,進行更加智能的調度,讓整體利用率如絲般平滑;存儲團隊通過對磁盤空間的增長預測,提前制定預算并采購機器;在做部門 / 產品預算時,根據歷年賬單預測全年的消費,進行更優的成本控制。
稍微大一些的服務可能會有幾百、上千甚至上萬臺的機器,通過人肉很難發現每臺機器行為(時序)的區別,而通過時序聚類就可以快速得到集群的行為分布,定位出異常的機器;同時對于單條時序,可以通過時序異常相關的檢測方法,自動定位異常點。
根因分析
時序相關的函數主要用來發現問題,而查找問題根源還需要模式分析相關的方法(根因分析,Root Cause Analysis)。例如 K8s 集群整體 Ingress 錯誤率(5XX 比例)突然上升時,如何排查是因為某個服務問題、某個用戶引起、某個 URL 引起、某個瀏覽器引起、某些地域網絡問題、某個節點異常還是整體性的問題?通常這種問題都需要人工從各個維度去排查,例如:
-
按照 Service 去 Group,查看 Service 之間的錯誤率有無差別;
-
沒有差別,然后排查 URL;
-
還沒有,按照瀏覽器;
-
瀏覽器有點關系,繼續看移動端、PC 端;
-
移動端錯誤率比較高,看看是 Android 還是 IOS;
-
?...
這種問題的排查在維度越多時復雜度越高,排查時間也越久,可能等到發現問題的時候影響面已經全面擴大了。因此我們開發了根因分析相關的函數,可以直接從多維數據中定位對目標(例如延遲、失敗率等)影響最大的一組(幾組)維度組合。為了更加精確的定位問題,我們還支持對比兩個模式的差異,例如今天發生異常時,和昨天正常的模式進行對比,快速找到問題的原因;在發布時進行藍綠對比以及 A/B Test。
智能日志聚類
上面我們通過智能時序函數發現問題、通過根因分析定位到關鍵的維度組合,但涉及到最終的代碼問題排查,還是離不開日志。當日志的數據量很大時,一次次的手動過濾太過耗時,我們希望可以通過智能聚類的方式,把相似的日志聚類到一起,最終可以通過聚類后的日志快速掌握系統的運行狀態。
上下游生態對接
Kubernetes 日志平臺主要的目標在解決 DevOps、Net/Site Ops、Sec Ops 等問題上,然而這些并不能滿足所有用戶對于日志的所有需求,例如超大規模的日志分析、BI 分析、極其龐大的安全規則過濾等。平臺的強大更多的是生態的強大,我們通過對接上下游廣泛的生態來滿足用戶越來越多的日志需求和場景。
優秀應用案例分析
混合云 PAAS 平臺日志管理
某大型游戲公司在進行技術架構升級,大部分業務會遷移到基于 Kubernetes 搭建的 PaaS 平臺上,為提高平臺整體的可用性,用戶采集混合云架構,對于日志的統一建設與管理存在很大困難:
-
眾多內部應用方:不希望應用方過多的接觸日志采集、存儲等細節,并且能夠為應用方提供全鏈路的日志;
-
1000+ 微服務:需要支持大規模的日志采集方式;
-
多云 + 線下 IDC:希望多個云廠商以及線下 IDC 采用的是同一套采集方案;
-
應用周期短:部分應用的運行生命周期極短,需要能夠及時將數據采集到服務端;
-
海外數據回國:海外節點的日志回國分析,需盡可能保證傳輸穩定性和可靠性。
用戶最終選擇使用阿里云 Kubernetes 日志平臺的方案,使用 Logtail 的方案解決采集可靠性問題,通過公網、專線、全球加速的配合解決網絡問題,由系統管理員使用 DaemonSet 統一采集所有系統組件級別的日志,應用方只需使用 CRD 采集自己的業務日志。對于平臺側,系統管理員可以訪問所有系統級別日志,并進行統一的監控和告警;對于應用側,應用方不僅可以查到自己的業務日志,還能訪問到和業務相關的中間件、Ingress、系統組件日志,進行全鏈路的分析。
二次開發日志管理平臺
在阿里有很多大的業務部門希望基于我們標準的日志平臺進行二次開發,來滿足他們部門的一些特殊需求,例如:
-
通過各類規則以及接口限制規范數據接入。
-
通過 TraceID 將整個調用鏈串聯,構建 Trace 平臺。
-
部門內部多用戶的權限細化管理。
-
部門內部各個子部門的成本結算。
-
與一內部些管控、運維系統打通。
這些需求可以基于我們提供的 OpenAPI 以及各語言的 SDK 快速的實現,同時為了減少前端的工作量,平臺還提供 Iframe 嵌入的功能,支持直接將部分界面(例如查詢框、Dashboard)直接嵌入到業務部門自己的系統中。
未來工作展望
目前阿里 Kubernetes 日志平臺在內外部已經有非常多的應用,未來我們還將繼續打磨平臺,為應用方 / 用戶提供更加完美的方案,后續工作主要集中在以下幾點:
-
數據采集進一步精細化,持續優化可靠性和資源消耗,做到極致化的多租戶隔離,爭取在 PaaS 平臺使用 DaemonSet 采集所有應用的日志。
-
提供更加便捷、智能的數據清洗服務,在平臺內部就可以完成異構數據的清洗、規整等工作。
-
構建面向 Ops 領域的、可自動更新的、支持異構數據的知識圖譜,讓問題排查的經驗可以積累在知識庫中,實現異常搜索與推理。
-
提供交互式的訓練平臺,構建更加智能的 Automation 能力,真正實現 Ops 的閉環。
?
相關工作與參考
阿里云日志服務 https://www.aliyun.com/product/sls
阿里云 Kubernetes : https://www.aliyun.com/product/kubernetes
Kubernetes 審計日志方案 : https://yq.aliyun.com/articles/686982
Kubernetes Ingress 日志方案 : https://yq.aliyun.com/articles/693600
數據采集全球加速 : https://yq.aliyun.com/articles/620453
日志采集 CRD 配置: https://yq.aliyun.com/articles/596310
作者簡介
元乙,阿里云日志服務技術專家,負責阿里巴巴集團、螞蟻金服、阿里云等全站日志采集基礎設施建設與維護,覆蓋數百萬服務器、數萬應用、每天數十 PB 數據,歷經多次雙十一考驗。目前主要關注 Kubernetes、微服務、IoT 等領域的 DevOps、AIOps 技術。
總結
以上是生活随笔為你收集整理的干货分享 | 阿里PB级Kubernetes日志平台建设实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 困扰程序员的30种软件开发问题,你是否时
- 下一篇: 这个开源项目帮你将Linux命令行一网打