自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

日志架構(gòu)演進(jìn):從集中式到分布式的Kubernetes日志策略

云計(jì)算 云原生
理想情況下,我們需要將可觀測(cè)性的三個(gè)重要組件都關(guān)聯(lián)起來才能更好的排查定位問題。比如當(dāng)收到監(jiān)控系統(tǒng)通過指標(biāo)變化發(fā)出的報(bào)警時(shí),可以通過鏈路追蹤定位具體是哪個(gè)系統(tǒng)觸發(fā)的問題。

當(dāng)我們沒有使用云原生方案部署應(yīng)用時(shí)采用的日志方案往往是 ELK 技術(shù)棧。

這套技術(shù)方案比較成熟,穩(wěn)定性也很高,所以幾乎成為了當(dāng)時(shí)的標(biāo)配。

可是隨著我們使用 kubernetes 步入云原生的時(shí)代后, kubernetes 把以往的操作系統(tǒng)上的許多底層都屏蔽,再由他提供了一些標(biāo)準(zhǔn)接口。

同時(shí)在 kubernetes 中的日志來源也比傳統(tǒng)虛擬機(jī)多,比如可能有容器、kubernetes 自身的事件、日志等。

我們的日志采集方案也得與時(shí)俱進(jìn),kubernetes 的官方博客有介紹提供一下幾種方案:

節(jié)點(diǎn)采集

第一種方案是在節(jié)點(diǎn)中采集日志,我們知道 kubernetes 是分為 master 調(diào)度節(jié)點(diǎn)以及 worker 工作節(jié)點(diǎn);我們的應(yīng)用都是運(yùn)行在 worker 節(jié)點(diǎn)中的。

在 kubernetes 環(huán)境中更推薦使用標(biāo)準(zhǔn)的 stdout/stderr 作為日志輸出,這樣 kubernetes 更方便做統(tǒng)一處理。

以我們的 docker 運(yùn)行時(shí)為例,默認(rèn)情況下我們的標(biāo)準(zhǔn)輸入文件會(huì)寫入到 /var/log 目錄中。

如上圖所示:我們可以在 kubernetes 的每一個(gè) worker 節(jié)點(diǎn)中部署一個(gè) DaemonSet 類型的采集器(filebeat 等),再由他去采集該節(jié)點(diǎn)下 /var/log 的日志,最終由他將日志采集后發(fā)往日志處理的后端,比如 elasticsearch 等組件中。

這種方案的好處是資源占用較低,往往是有多少個(gè) worker 節(jié)點(diǎn)就可以部署多少個(gè)采集器。

而且和業(yè)務(wù)的耦合度低,業(yè)務(wù)和采集器不管誰進(jìn)行重啟或升級(jí)互相都不會(huì)產(chǎn)生影響。

但缺點(diǎn)也比較明顯,整個(gè)節(jié)點(diǎn)的日志采集瓶頸都在這個(gè)采集器這里了,如果某些 worker 節(jié)點(diǎn)的 Pod 數(shù)量不均衡,或者是本身日志產(chǎn)生也不平均時(shí)就會(huì)出現(xiàn)明顯的負(fù)債不平衡。

而且也無法針對(duì)某些日志高峰場(chǎng)景進(jìn)行調(diào)優(yōu)(畢竟所有的 Pod 都是使用的一個(gè)日志采集器)。

所以節(jié)點(diǎn)級(jí)的日志采集更適用與該 worker 節(jié)點(diǎn)負(fù)債較低的時(shí)候使用,也更容易維護(hù)。

Sidecar 代理模式

第二種相對(duì)于第一種可以理解為由集中式的日志采集分散到各個(gè)應(yīng)用 Pod 中自行采集。

需要為每一個(gè)業(yè)務(wù) Pod 掛載一個(gè)邊車(sidecar)進(jìn)行日志采集,由于邊車和業(yè)務(wù) Pod 共享的是一個(gè)存儲(chǔ),所以可以很方便的讀取到日志。

由于它是和應(yīng)用掛載在一起的,所以資源占用自然會(huì)比節(jié)點(diǎn)采集更多,同理耦合度也增加了,采集組件的升級(jí)可能還會(huì)影響的業(yè)務(wù) Pod。

但同樣的帶來好處就是可以針對(duì)單個(gè) Pod 更精細(xì)的控制采集方案。

比如對(duì)于一些日志寫入頻繁的應(yīng)用,可以將 filebeat 的配置提高,甚至還可以將這種高負(fù)載的日志單獨(dú)寫入一個(gè) elasticsearch 中,這樣可以與普通負(fù)載的日志進(jìn)行資源隔離。

這個(gè)方案更適用與集群規(guī)模較大的場(chǎng)景,需要做一些精細(xì)化配置。

我們其實(shí)也是采用的也是這個(gè)方案,不過具體細(xì)節(jié)稍有不同。

我們沒有直接使用標(biāo)準(zhǔn)輸入和輸出,原因如下:

日志格式?jīng)]法統(tǒng)一,導(dǎo)致最終查詢的時(shí)候無法做一些標(biāo)準(zhǔn)化的限制(比如我們要求每個(gè)日志都需要帶業(yè)務(wù) id、traceId 等,查詢時(shí)候有這些業(yè)務(wù)指標(biāo)就很容易沉淀一些標(biāo)準(zhǔn)的查詢語句。)

最終我們還是采用了 Java 的老朋友,logback 配置了自己的日志格式,所有的應(yīng)用都會(huì)根據(jù)這個(gè)模版進(jìn)行日志輸出。

同時(shí)利用日志框架的批量寫入、緩沖等特性還更容易進(jìn)行日志的性能調(diào)優(yōu)。(只使用標(biāo)準(zhǔn)輸出時(shí)對(duì)應(yīng)用來說是黑盒。)

最終我們的技術(shù)方案是:

直接寫入

還有一種方案是直接寫入,這個(gè)其實(shí)和 kubernetes 本身就沒有太多關(guān)系了。

由業(yè)務(wù)自己調(diào)用 elasticsearch 或者其他的存儲(chǔ)組件的 API 進(jìn)行寫入,這種通常適用于對(duì)性能要求較高的場(chǎng)景,略過了中間的采集步驟,直接寫入存儲(chǔ)端。

這個(gè)我在 VictoriaLogs:一款超低占用的 ElasticSearch 替代方案中介紹過,我需要在 broker 的攔截器中埋點(diǎn)消息信息,從而可以生成一個(gè)消息??的鏈路信息。

因?yàn)樾枰獢r截消息的發(fā)送、消費(fèi)的各個(gè)階段,加上并發(fā)壓力較高,所以對(duì)日志的寫入性能要求還是蠻高的。

因此就需要在攔截器中直接對(duì)寫入到日志存儲(chǔ)。

這里考慮到我這里的但一場(chǎng)景,以及對(duì)資源的消耗,最終選取了 victoriaLog 這個(gè)日志存儲(chǔ)。

而在發(fā)送日志的時(shí)候也得用了高性能的日志發(fā)生框架,這里選取了aliyun-log-java-producer然后做了一些定制。

這個(gè)庫(kù)支持以下一些功能:

  • 高性能:批量發(fā)送、多線程等
  • 自動(dòng)重試
  • 異步非阻塞
  • 資源控制(可以對(duì)內(nèi)存、數(shù)量進(jìn)行控制)

因?yàn)檫@是為阿里云日志服務(wù)的一個(gè)組件,代碼里硬編碼了只能寫入阿里的日志服務(wù)。

所以拿來稍加改造后,現(xiàn)在可以支持自定義發(fā)送到任意后端,只需要在初始化時(shí)自定義實(shí)現(xiàn)發(fā)送回調(diào)接口即可:

ProducerConfig producerConfig = new ProducerConfig();
producerConfig.setSenderArgs(new Object[]{vlogUrl, client});
producerConfig.setSender((batch, args) -> {
    StringBuilder body = new StringBuilder();
    for (String s : batch.getLogItemsString()) {
        body.append("{\"create\":{}}");
        body.append("\n");
        body.append(s);
        body.append("\n");
    }
    RequestBody requestBody =
            RequestBody.create(MediaType.parse("application/json"), body.toString());
    Request request =
            new Request.Builder()
                    .url(String.format("%s/insert/elasticsearch/_bulk", args[0]))
                    .post(requestBody)
                    .build();

    OkHttpClient okHttpClient = (OkHttpClient) args[1];
    try (Response response = okHttpClient.newCall(request).execute()) {
        if (response.isSuccessful()) {
        } else {
            log.error("Request failed with error code: " + response);
        }
    } catch (IOException e) {
        log.error("Send vlogs failed", e);
        throw e;
    }
});
logProducer = new LogProducer(producerConfig);

考慮到這個(gè)庫(kù)只是對(duì)阿里云日志服務(wù)的一個(gè)組件,加上代碼已經(jīng)很久沒維護(hù)了,所以就沒有將這部分代碼提交到社區(qū),感興趣的評(píng)論區(qū)留言。

日志安全

日志是一個(gè)非?;A(chǔ)但又很敏感的功能,首先是編碼規(guī)范上要避免打印一些敏感信息;比如身份證、密碼等;同時(shí)對(duì)日志的訪問也要最好權(quán)限控制。

在我們內(nèi)部的研效平臺(tái)中,對(duì)于日志、監(jiān)控等功能都是和應(yīng)用權(quán)限掛鉤的。

簡(jiǎn)單來說就是關(guān)閉了統(tǒng)一查詢 ES 的入口,只在應(yīng)用層級(jí)提供查詢,類似于:

圖來自于 orbit 產(chǎn)品。

OpenTelemetry

當(dāng)然講到日志目前自然也逃不過 OpenTelemetry,作為當(dāng)前云原生可觀測(cè)性的標(biāo)準(zhǔn)也提供了對(duì)應(yīng)的日志組件。

OpenTelemetry 也定義了結(jié)構(gòu)化的日志格式:

{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeLogs":[{"scope":{},"logRecords":[{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info""body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]}

我們可以配置 otel.logs.exporter=otlp (default) 可以將日志輸出到 oetl-collector 中,再由他輸出到后端存儲(chǔ)中。

雖然這樣 otel-collectoer 就成為瓶頸了,但我們也可以部署多個(gè)副本來降低壓力。

同時(shí)也可以在應(yīng)用中指定不同的 endpoint(otel.exporter.otlp.endpoint=http://127.0.0.1:4317) 來區(qū)分日志的 collector,與其他類型的 collector 做到資源隔離。

不過目前社區(qū)關(guān)于日志的實(shí)踐還比較少,而且由于版本 1.0 版本 release 的時(shí)間也不算長(zhǎng),穩(wěn)定性和之前的 filebeat 相比還得需要時(shí)間檢驗(yàn)。

總結(jié)

理想情況下,我們需要將可觀測(cè)性的三個(gè)重要組件都關(guān)聯(lián)起來才能更好的排查定位問題。

比如當(dāng)收到監(jiān)控系統(tǒng)通過指標(biāo)變化發(fā)出的報(bào)警時(shí),可以通過鏈路追蹤定位具體是哪個(gè)系統(tǒng)觸發(fā)的問題。

之后通過 traceID 定位到具體的日志,再通過日志的上下文列出更多日志信息,這樣整個(gè)鏈條就可以串聯(lián)起來,可以極大的提高效率。

參考鏈接:

  • https://github.com/aliyun/aliyun-log-java-producer。
  • https://kubernetes.io/docs/concepts/cluster-administration/logging/。
  • https://coding.net/help/docs/orbit/env/logs-event/intro.html。
  • https://opentelemetry.io/docs/concepts/signals/logs/。
責(zé)任編輯:姜華 來源: crossoverJie
相關(guān)推薦

2024-01-22 13:55:00

2014-08-05 09:15:14

SDN

2013-07-10 16:36:02

集中式VDI分布式VDI

2011-10-19 13:53:11

2022-03-10 09:56:03

分布式云云計(jì)算架構(gòu)

2017-06-27 10:21:12

vRealize LoNSX日志管理

2015-08-20 09:25:46

2022-03-29 14:28:03

架構(gòu)安全設(shè)計(jì)

2023-11-27 08:33:42

2012-02-23 23:33:37

開源memcached

2024-06-07 07:41:03

2021-06-16 11:37:19

云計(jì)算

2024-12-05 07:31:16

2017-12-05 09:43:42

分布式系統(tǒng)核心

2018-04-03 09:27:42

分布式架構(gòu)系統(tǒng)

2024-05-16 07:51:55

分布式系統(tǒng)架構(gòu)

2021-07-09 05:49:53

分布式代碼算法

2023-08-22 14:20:21

2023-08-18 09:00:00

Kubernetes數(shù)據(jù)庫(kù)SQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)