前言
最近接到一個需求,需要展示 ingress 上面的通路日志,由于我們的業務系統都部署在 Kubernetes 上面,通過 ingress 進行通路,是以這裡的通路日志,其實就是我們全部業務系統的通路日志。
日志采集方面,阿裡雲天生就提供了 nginx-ingress 日志和采集和展示,本身提供很多不錯的基于 ingress 日志資料的圖表與分析。如果你使用的是阿裡雲 ACK 容器服務,那麼極端推薦使用,配置方法見官方文檔:
https://help.aliyun.com/document_detail/86532.html。

讓人頭秃的是,我們這次不但要采集 ingress 日志上比較正常的
url
client_ip
method
status
等字段,還要采集我們系統在
Request Headers
裡面自定義的參數,這些參數是預設的 ingress 并不展示的,是以需要我們進行調整。
開始
首先明确需要調整的元件:
-
的 ConfigMap:用于列印自定義日志字段nginx-ingress
-
:這個是阿裡雲日志服務的 CRD 擴充,需要在這個裡面加入新增的字段名和修改後的正規表達式AliyunLogConfig
- 在日志服務控制台,添加新增字段的指定字段查詢
- 新增展示儀表盤
調整 ingress 日志輸出
我們 ingress 元件使用的是
nginx-ingress-container
,這裡要調整日志輸出格式,老規矩,直接官方文檔:
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/從文檔可見,隻需要調整
ingress-nginx
的 ConfigMap
nginx-configuration
data 中的
log-format-upstream
字段即可。
官方文檔裡面給的說明不是很詳細,沒有提到
Request Headers
裡自定義的字段應該怎麼表示(也有可能是我眼瘸沒看見),但經過我多次試驗發現,
Request Headers
裡的字段在
log-format-upstream
中應該使用
$http_{your field}
表示,比如
$http_cookie
;而帶
-
的字段則需要将
-
改為
_
,并且使用小寫,比如
app-Id
就應使用
$http_app_id
表示。
修改 ConfigMap,
ingress-controller
将進行熱更新,看到如下日志,就證明配置已完成更新,接下來就可以看到你自定義字段的值已經列印出來了。
I0302 08:20:58.393365 9 controller.go:200] Backend successfully reloaded.
調整阿裡雲日志元件配置
執行下面的步驟請確定已經按照
官方文檔正确部署阿裡雲日志服務在您的 K8S 叢集之後,并且已達到要求的版本。
日志已經成功列印了,接下來就是調整日志采集的字段了,這裡隻需要調整日志服務 CRD 的擴充配置即可。
$ kubectl edit AliyunLogConfig k8s-nginx-ingress
在修改配置之前,推薦先去
https://regex101.com/驗證正規表達式是否正确,将調整過的正規表達式和
ingress-controller
列印的日志貼入下圖指定位置,就可以看出正規表達式是否正确。
然後将添加的字段名稱(這個名稱将作為 key 在日志服務中展示,可以與 header 中的字段不同)和正規表達式貼入如下 CRD 中。
apiVersion: log.alibabacloud.com/v1alpha1
kind: AliyunLogConfig
metadata:
# your config name, must be unique in you k8s cluster
name: k8s-nginx-ingress
spec:
# logstore name to upload log
logstore: nginx-ingress
# product code, only for k8s nginx ingress
productCode: k8s-nginx-ingress
# logtail config detail
logtailConfig:
inputType: plugin
# logtail config name, should be same with [metadata.name]
configName: k8s-nginx-ingress
inputDetail:
plugin:
inputs:
- type: service_docker_stdout
detail:
IncludeLabel:
io.kubernetes.container.name: nginx-ingress-controller
Stderr: false
Stdout: true
processors:
- type: processor_regex
detail:
KeepSource: false
Keys:
- client_ip
- x_forward_for
- remote_user
- time
- method
- url
- version
- status
- body_bytes_sent
- http_referer
- http_user_agent
- request_length
- request_time
- proxy_upstream_name
- upstream_addr
- upstream_response_length
- upstream_response_time
- upstream_status
- req_id
- host
- #需要添加的字段名稱
- ...
NoKeyError: true
NoMatchError: true
Regex: #修改後的正規表達式
SourceKey: content
日志控制台新增字段
如果上面的操作無誤的話,日志服務中就會展示您添加的字段了,如果配置有誤,所有的自定義字段都會不顯示,隻會顯示保留字段名稱。
添加指定字段查詢,就可以快速檢視添加的字段了。
日志既然已經取到了,那麼展示就很容易了,直接在查詢欄中輸入分析語句,日志服務支援 SQL 聚合日志,并直接生成統計圖表,點選添加到儀表盤可以就可以添加到現有儀表盤或者建立一個儀表盤。
成果
之後進行一些微調,添加過濾欄,由于這裡統計的是登入使用者,你甚至都可以添加一個詞雲來看看哪些用于使用系統比較頻繁。當然,想添加什麼都看您的喜好,日志在你手裡,想怎麼分析都可以。
結語
本次實作的功能并不是什麼高深的功能,隻不過是一個簡單的通路日志記錄和展示,相信每個系統其實都有一套這種功能。但是這種實作方式在我看來優點更多:
- 無代碼:全程沒有寫一行代碼,如果有的話,也就是業務需要統一
裡面的字段。Request Headers
- 配置簡單:隻需要修改 nginx ConfigMap 中的一個字段,并在 CRD 中添加字段名稱和正在表達式,唯一的難度可能就是正規表達式。
- 配置快:整體的配置時間很短,加上查文檔和調整圖表也不過半天的時間,肯定比
全流程走一遍,前端後端撕一遍要快的多的多的多。提需求-評估-開發-測試-驗收
- 高度定制:可以根據自己的喜好,随意定制圖表。
最近發現阿裡雲日志服務是一個寶藏産品,從安全到 k8s 業務,從成本控制到疫情動态,日志服務真的就是把所有沒有前端開發資源的服務都幫了一把。
--- 摘自本人朋友圈