国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

k8s搭建EFK日志系統(tǒng)

這篇具有很好參考價(jià)值的文章主要介紹了k8s搭建EFK日志系統(tǒng)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

搭建 EFK 日志系統(tǒng)

前面大家介紹了 Kubernetes 集群中的幾種日志收集方案,Kubernetes 中比較流行的日志收集解決方案是 Elasticsearch、Fluentd 和 Kibana(EFK)技術(shù)棧,也是官方現(xiàn)在比較推薦的一種方案。

Elasticsearch?是一個(gè)實(shí)時(shí)的、分布式的可擴(kuò)展的搜索引擎,允許進(jìn)行全文、結(jié)構(gòu)化搜索,它通常用于索引和搜索大量日志數(shù)據(jù),也可用于搜索許多不同類型的文檔。

Elasticsearch 通常與?Kibana?一起部署,Kibana 是 Elasticsearch 的一個(gè)功能強(qiáng)大的數(shù)據(jù)可視化 Dashboard,Kibana 允許你通過 web 界面來瀏覽 Elasticsearch 日志數(shù)據(jù)。

Fluentd是一個(gè)流行的開源數(shù)據(jù)收集器,我們將在 Kubernetes 集群節(jié)點(diǎn)上安裝 Fluentd,通過獲取容器日志文件、過濾和轉(zhuǎn)換日志數(shù)據(jù),然后將數(shù)據(jù)傳遞到 Elasticsearch 集群,在該集群中對其進(jìn)行索引和存儲(chǔ)。

我們先來配置啟動(dòng)一個(gè)可擴(kuò)展的 Elasticsearch 集群,然后在 Kubernetes 集群中創(chuàng)建一個(gè) Kibana 應(yīng)用,最后通過 DaemonSet 來運(yùn)行 Fluentd,以便它在每個(gè) Kubernetes 工作節(jié)點(diǎn)上都可以運(yùn)行一個(gè) Pod。

安裝 Elasticsearch 集群?

在創(chuàng)建 Elasticsearch 集群之前,我們先創(chuàng)建一個(gè)命名空間,我們將在其中安裝所有日志相關(guān)的資源對象。

$ kubectl create ns logging

環(huán)境準(zhǔn)備?

ElasticSearch 安裝有最低安裝要求,如果安裝后 Pod 無法正常啟動(dòng),請檢查是否符合最低要求的配置,要求如下:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

這里我們要安裝的 ES 集群環(huán)境信息如下所示:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

這里我們使用一個(gè) NFS 類型的 StorageClass 來做持久化存儲(chǔ),當(dāng)然如果你是線上環(huán)境建議使用 Local PV 或者 Ceph RBD 之類的存儲(chǔ)來持久化 Elasticsearch 的數(shù)據(jù)。

此外由于 ElasticSearch 7.x 版本默認(rèn)安裝了?X-Pack?插件,并且部分功能免費(fèi),需要我們配置一些安全證書文件。

1、生成證書文件

# 運(yùn)行容器生成證書,containerd下面用nerdctl
$ mkdir -p elastic-certs
$ nerdctl run --name elastic-certs -v elastic-certs:/app -it -w /app elasticsearch:7.17.3 /bin/sh -c  \
  "elasticsearch-certutil ca --out /app/elastic-stack-ca.p12 --pass '' && \
    elasticsearch-certutil cert --name security-master --dns \
    security-master --ca /app/elastic-stack-ca.p12 --pass '' --ca-pass '' --out /app/elastic-certificates.p12"
# 刪除容器
$ nerdctl rm -f elastic-certs
# 將 pcks12 中的信息分離出來,寫入文件
$ cd elastic-certs && openssl pkcs12 -nodes -passin pass:'' -in elastic-certificates.p12 -out elastic-certificate.pem

需要注意 nerdctl 如果是 v0.20.0 版本,需要更新 CNI 插件版本,否則會(huì)出現(xiàn)錯(cuò)誤?FATA[0000] failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: Running hook #0:: error running hook: exit status 1, stdout: , stderr: time="2022-06-06T16:37:03+08:00" level=fatal msg="failed to call cni.Setup: plugin type=\"bridge\" failed (add): incompatible CNI versions; config is \"1.0.0\", plugin supports [\"0.1.0\" \"0.2.0\" \"0.3.0\" \"0.3.1\" \"0.4.0\"]",將 CNI 插件從?https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz?下載下來覆蓋?/opt/cni/bin?目錄即可。

2、添加證書到 Kubernetes

# 添加證書
$ kubectl create secret -n logging generic elastic-certs --from-file=elastic-certificates.p12
# 設(shè)置集群用戶名密碼
$ kubectl create secret -n logging generic elastic-auth --from-literal=username=elastic --from-literal=password=ydzsio321

安裝 ES 集群?

首先添加 ELastic 的 Helm 倉庫:

$ helm repo add elastic https://helm.elastic.co
$ helm repo update

ElaticSearch 安裝需要安裝三次,分別安裝 Master、Data、Client 節(jié)點(diǎn),Master 節(jié)點(diǎn)負(fù)責(zé)集群間的管理工作;Data 節(jié)點(diǎn)負(fù)責(zé)存儲(chǔ)數(shù)據(jù);Client 節(jié)點(diǎn)負(fù)責(zé)代理 ElasticSearch Cluster 集群,負(fù)載均衡。

首先使用?helm pull?拉取 Chart 并解壓:

$ helm pull elastic/elasticsearch --untar --version 7.17.3
$ cd elasticsearch

在 Chart 目錄下面創(chuàng)建用于 Master 節(jié)點(diǎn)安裝配置的 values 文件:

# values-master.yaml
## 設(shè)置集群名稱
clusterName: 'elasticsearch'
## 設(shè)置節(jié)點(diǎn)名稱
nodeGroup: 'master'

## 設(shè)置角色
roles:
  master: 'true'
  ingest: 'false'
  data: 'false'

# ============鏡像配置============
## 指定鏡像與鏡像版本
image: 'elasticsearch'
imageTag: '7.17.3'
imagePullPolicy: 'IfNotPresent'

## 副本數(shù)
replicas: 3

# ============資源配置============
## JVM 配置參數(shù)
esJavaOpts: '-Xmx1g -Xms1g'
## 部署資源配置(生成環(huán)境要設(shè)置大些)
resources:
  requests:
    cpu: '2000m'
    memory: '2Gi'
  limits:
    cpu: '2000m'
    memory: '2Gi'
## 數(shù)據(jù)持久卷配置
persistence:
  enabled: true
## 存儲(chǔ)數(shù)據(jù)大小配置
volumeClaimTemplate:
  storageClassName: local-path
  accessModes: ['ReadWriteOnce']
  resources:
    requests:
      storage: 5Gi

# ============安全配置============
## 設(shè)置協(xié)議,可配置為 http、https
protocol: http
## 證書掛載配置,這里我們掛入上面創(chuàng)建的證書
secretMounts:
  - name: elastic-certs
    secretName: elastic-certs
    path: /usr/share/elasticsearch/config/certs
    defaultMode: 0755

## 允許您在/usr/share/elasticsearch/config/中添加任何自定義配置文件,例如 elasticsearch.yml、log4j2.properties
## ElasticSearch 7.x 默認(rèn)安裝了 x-pack 插件,部分功能免費(fèi),這里我們配置下
## 下面注掉的部分為配置 https 證書,配置此部分還需要配置 helm 參數(shù) protocol 值改為 https
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
## 環(huán)境變量配置,這里引入上面設(shè)置的用戶名、密碼 secret 文件
extraEnvs:
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: username
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: password

# ============調(diào)度配置============
## 設(shè)置調(diào)度策略
## - hard:只有當(dāng)有足夠的節(jié)點(diǎn)時(shí) Pod 才會(huì)被調(diào)度,并且它們永遠(yuǎn)不會(huì)出現(xiàn)在同一個(gè)節(jié)點(diǎn)上
## - soft:盡最大努力調(diào)度
antiAffinity: 'soft'
# tolerations:
#   - operator: "Exists" ##容忍全部污點(diǎn)

然后創(chuàng)建用于 Data 節(jié)點(diǎn)安裝的 values 文件:

# values-data.yaml
# ============設(shè)置集群名稱============
## 設(shè)置集群名稱
clusterName: 'elasticsearch'
## 設(shè)置節(jié)點(diǎn)名稱
nodeGroup: 'data'
## 設(shè)置角色
roles:
  master: 'false'
  ingest: 'true'
  data: 'true'

# ============鏡像配置============
## 指定鏡像與鏡像版本
image: 'elasticsearch'
imageTag: '7.17.3'
## 副本數(shù)(建議設(shè)置為3,我這里資源不足只用了1個(gè)副本)
replicas: 3

# ============資源配置============
## JVM 配置參數(shù)
esJavaOpts: '-Xmx1g -Xms1g'
## 部署資源配置(生成環(huán)境一定要設(shè)置大些)
resources:
  requests:
    cpu: '1000m'
    memory: '2Gi'
  limits:
    cpu: '1000m'
    memory: '2Gi'
## 數(shù)據(jù)持久卷配置
persistence:
  enabled: true
## 存儲(chǔ)數(shù)據(jù)大小配置
volumeClaimTemplate:
  storageClassName: local-path
  accessModes: ['ReadWriteOnce']
  resources:
    requests:
      storage: 10Gi

# ============安全配置============
## 設(shè)置協(xié)議,可配置為 http、https
protocol: http
## 證書掛載配置,這里我們掛入上面創(chuàng)建的證書
secretMounts:
  - name: elastic-certs
    secretName: elastic-certs
    path: /usr/share/elasticsearch/config/certs
## 允許您在/usr/share/elasticsearch/config/中添加任何自定義配置文件,例如 elasticsearch.yml
## ElasticSearch 7.x 默認(rèn)安裝了 x-pack 插件,部分功能免費(fèi),這里我們配置下
## 下面注掉的部分為配置 https 證書,配置此部分還需要配置 helm 參數(shù) protocol 值改為 https
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
## 環(huán)境變量配置,這里引入上面設(shè)置的用戶名、密碼 secret 文件
extraEnvs:
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: username
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: password

# ============調(diào)度配置============
## 設(shè)置調(diào)度策略
## - hard:只有當(dāng)有足夠的節(jié)點(diǎn)時(shí) Pod 才會(huì)被調(diào)度,并且它們永遠(yuǎn)不會(huì)出現(xiàn)在同一個(gè)節(jié)點(diǎn)上
## - soft:盡最大努力調(diào)度
antiAffinity: 'soft'
## 容忍配置
# tolerations:
#   - operator: "Exists" ##容忍全部污點(diǎn)

最后一個(gè)是用于創(chuàng)建 Client 節(jié)點(diǎn)的 values 文件:

# values-client.yaml
# ============設(shè)置集群名稱============
## 設(shè)置集群名稱
clusterName: 'elasticsearch'
## 設(shè)置節(jié)點(diǎn)名稱
nodeGroup: 'client'
## 設(shè)置角色
roles:
  master: 'false'
  ingest: 'false'
  data: 'false'

# ============鏡像配置============
## 指定鏡像與鏡像版本
image: 'elasticsearch'
imageTag: '7.17.3'
## 副本數(shù)
replicas: 1

# ============資源配置============
## JVM 配置參數(shù)
esJavaOpts: '-Xmx1g -Xms1g'
## 部署資源配置(生成環(huán)境一定要設(shè)置大些)
resources:
  requests:
    cpu: '1000m'
    memory: '2Gi'
  limits:
    cpu: '1000m'
    memory: '2Gi'
## 數(shù)據(jù)持久卷配置
persistence:
  enabled: false

# ============安全配置============
## 設(shè)置協(xié)議,可配置為 http、https
protocol: http
## 證書掛載配置,這里我們掛入上面創(chuàng)建的證書
secretMounts:
  - name: elastic-certs
    secretName: elastic-certs
    path: /usr/share/elasticsearch/config/certs
## 允許您在/usr/share/elasticsearch/config/中添加任何自定義配置文件,例如 elasticsearch.yml
## ElasticSearch 7.x 默認(rèn)安裝了 x-pack 插件,部分功能免費(fèi),這里我們配置下
## 下面注掉的部分為配置 https 證書,配置此部分還需要配置 helm 參數(shù) protocol 值改為 https
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
## 環(huán)境變量配置,這里引入上面設(shè)置的用戶名、密碼 secret 文件
extraEnvs:
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: username
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: password

# ============Service 配置============
service:
  type: NodePort
  nodePort: '30200'

現(xiàn)在用上面的 values 文件來安裝:

# 安裝 master 節(jié)點(diǎn)
$ helm upgrade --install es-master -f values-master.yaml --namespace logging .
# 安裝 data 節(jié)點(diǎn)
$ helm upgrade --install es-data -f values-data.yaml --namespace logging .
# 安裝 client 節(jié)點(diǎn)
$ helm upgrade --install es-client -f values-client.yaml --namespace logging .

在安裝 Master 節(jié)點(diǎn)后 Pod 啟動(dòng)時(shí)候會(huì)拋出異常,就緒探針探活失敗,這是個(gè)正?,F(xiàn)象。在執(zhí)行安裝 Data 節(jié)點(diǎn)后 Master 節(jié)點(diǎn) Pod 就會(huì)恢復(fù)正常。

安裝 Kibana?

Elasticsearch 集群安裝完成后接下來配置安裝 Kibana

使用?helm pull?命令拉取 Kibana Chart 包并解壓:

$ helm pull elastic/kibana --untar --version 7.17.3
$ cd kibana

創(chuàng)建用于安裝 Kibana 的 values 文件:

# values-prod.yaml
## 指定鏡像與鏡像版本
image: 'kibana'
imageTag: '7.17.3'

## 配置 ElasticSearch 地址
elasticsearchHosts: 'http://elasticsearch-client:9200'

# ============環(huán)境變量配置============
## 環(huán)境變量配置,這里引入上面設(shè)置的用戶名、密碼 secret 文件
extraEnvs:
  - name: 'ELASTICSEARCH_USERNAME'
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: username
  - name: 'ELASTICSEARCH_PASSWORD'
    valueFrom:
      secretKeyRef:
        name: elastic-auth
        key: password

# ============資源配置============
resources:
  requests:
    cpu: '500m'
    memory: '1Gi'
  limits:
    cpu: '500m'
    memory: '1Gi'

# ============配置 Kibana 參數(shù)============
## kibana 配置中添加語言配置,設(shè)置 kibana 為中文
kibanaConfig:
  kibana.yml: |
    i18n.locale: "zh-CN"

# ============Service 配置============
service:
  type: NodePort
  nodePort: '30601'

使用上面的配置直接安裝即可:

$ helm install kibana -f values-prod.yaml --namespace logging .

下面是安裝完成后的 ES 集群和 Kibana 資源:

$ kubectl get pods -n logging
NAME                             READY   STATUS    RESTARTS   AGE
elasticsearch-client-0           1/1     Running   0          9m25s
elasticsearch-data-0             1/1     Running   0          9m33s
elasticsearch-master-0           1/1     Running   0          8m29s
kibana-kibana-79b9878cd7-7l75v   1/1     Running   0          6m12s
$ kubectl get svc -n logging
NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
elasticsearch-client            NodePort    10.108.226.197   <none>        9200:30200/TCP,9300:32746/TCP   3m25s
elasticsearch-client-headless   ClusterIP   None             <none>        9200/TCP,9300/TCP               3m25s
elasticsearch-data              ClusterIP   10.104.121.49    <none>        9200/TCP,9300/TCP               3m33s
elasticsearch-data-headless     ClusterIP   None             <none>        9200/TCP,9300/TCP               3m33s
elasticsearch-master            ClusterIP   10.102.72.71     <none>        9200/TCP,9300/TCP               6m8s
elasticsearch-master-headless   ClusterIP   None             <none>        9200/TCP,9300/TCP               6m8s
kibana-kibana                   NodePort    10.109.35.219    <none>        5601:30601/TCP                  12s

上面我們安裝 Kibana 的時(shí)候指定了 30601 的 NodePort 端口,所以我們可以從任意節(jié)點(diǎn)?http://IP:30601?來訪問 Kibana。

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

我們可以看到會(huì)跳轉(zhuǎn)到登錄頁面,讓我們輸出用戶名、密碼,這里我們輸入上面配置的用戶名?elastic、密碼?ydzsio321?進(jìn)行登錄。登錄成功后進(jìn)入如下所示的 Kibana 主頁:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

部署 Fluentd?

Fluentd?是一個(gè)高效的日志聚合器,是用 Ruby 編寫的,并且可以很好地?cái)U(kuò)展。對于大部分企業(yè)來說,F(xiàn)luentd 足夠高效并且消耗的資源相對較少,另外一個(gè)工具?Fluent-bit?更輕量級,占用資源更少,但是插件相對 Fluentd 來說不夠豐富,所以整體來說,F(xiàn)luentd 更加成熟,使用更加廣泛,所以這里我們使用 Fluentd 來作為日志收集工具。

工作原理?

Fluentd 通過一組給定的數(shù)據(jù)源抓取日志數(shù)據(jù),處理后(轉(zhuǎn)換成結(jié)構(gòu)化的數(shù)據(jù)格式)將它們轉(zhuǎn)發(fā)給其他服務(wù),比如 Elasticsearch、對象存儲(chǔ)等等。Fluentd 支持超過 300 個(gè)日志存儲(chǔ)和分析服務(wù),所以在這方面是非常靈活的。主要運(yùn)行步驟如下:

  • 首先 Fluentd 從多個(gè)日志源獲取數(shù)據(jù)
  • 結(jié)構(gòu)化并且標(biāo)記這些數(shù)據(jù)
  • 然后根據(jù)匹配的標(biāo)簽將數(shù)據(jù)發(fā)送到多個(gè)目標(biāo)服務(wù)去

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

配置?

一般來說我們是通過一個(gè)配置文件來告訴 Fluentd 如何采集、處理數(shù)據(jù)的,下面簡單和大家介紹下 Fluentd 的配置方法。

日志源配置?

比如我們這里為了收集 Kubernetes 節(jié)點(diǎn)上的所有容器日志,就需要做如下的日志源配置:

<source>
  @id fluentd-containers.log
  @type tail                             # Fluentd 內(nèi)置的輸入方式,其原理是不停地從源文件中獲取新的日志。
  path /var/log/containers/*.log         # 掛載的宿主機(jī)容器日志地址
  pos_file /var/log/es-containers.log.pos
  tag raw.kubernetes.*                   # 設(shè)置日志標(biāo)簽
  read_from_head true
  <parse>                                # 多行格式化成JSON
    @type multi_format                   # 使用 multi-format-parser 解析器插件
    <pattern>
      format json                        # JSON 解析器
      time_key time                      # 指定事件時(shí)間的時(shí)間字段
      time_format %Y-%m-%dT%H:%M:%S.%NZ  # 時(shí)間格式
    </pattern>
    <pattern>
      format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
      time_format %Y-%m-%dT%H:%M:%S.%N%:z
    </pattern>
  </parse>
</source>

上面配置部分參數(shù)說明如下:

  • id:表示引用該日志源的唯一標(biāo)識符,該標(biāo)識可用于進(jìn)一步過濾和路由結(jié)構(gòu)化日志數(shù)據(jù)
  • type:Fluentd 內(nèi)置的指令,tail?表示 Fluentd 從上次讀取的位置通過 tail 不斷獲取數(shù)據(jù),另外一個(gè)是?http?表示通過一個(gè) GET 請求來收集數(shù)據(jù)。
  • path:tail?類型下的特定參數(shù),告訴 Fluentd 采集?/var/log/containers?目錄下的所有日志,這是 docker 在 Kubernetes 節(jié)點(diǎn)上用來存儲(chǔ)運(yùn)行容器 stdout 輸出日志數(shù)據(jù)的目錄。
  • pos_file:檢查點(diǎn),如果 Fluentd 程序重新啟動(dòng)了,它將使用此文件中的位置來恢復(fù)日志數(shù)據(jù)收集。
  • tag:用來將日志源與目標(biāo)或者過濾器匹配的自定義字符串,F(xiàn)luentd 匹配源/目標(biāo)標(biāo)簽來路由日志數(shù)據(jù)。
路由配置?

上面是日志源的配置,接下來看看如何將日志數(shù)據(jù)發(fā)送到 Elasticsearch:

<match **>
  @id elasticsearch
  @type elasticsearch
  @log_level info
  include_tag_key true
  type_name fluentd
  host "#{ENV['OUTPUT_HOST']}"
  port "#{ENV['OUTPUT_PORT']}"
  logstash_format true
  <buffer>
    @type file
    path /var/log/fluentd-buffers/kubernetes.system.buffer
    flush_mode interval
    retry_type exponential_backoff
    flush_thread_count 2
    flush_interval 5s
    retry_forever
    retry_max_interval 30
    chunk_limit_size "#{ENV['OUTPUT_BUFFER_CHUNK_LIMIT']}"
    queue_limit_length "#{ENV['OUTPUT_BUFFER_QUEUE_LIMIT']}"
    overflow_action block
  </buffer>
</match>
  • match:標(biāo)識一個(gè)目標(biāo)標(biāo)簽,后面是一個(gè)匹配日志源的正則表達(dá)式,我們這里想要捕獲所有的日志并將它們發(fā)送給 Elasticsearch,所以需要配置成**。
  • id:目標(biāo)的一個(gè)唯一標(biāo)識符。
  • type:支持的輸出插件標(biāo)識符,我們這里要輸出到 Elasticsearch,所以配置成 elasticsearch,這是 Fluentd 的一個(gè)內(nèi)置插件。
  • log_level:指定要捕獲的日志級別,我們這里配置成?info,表示任何該級別或者該級別以上(INFO、WARNING、ERROR)的日志都將被路由到 Elsasticsearch。
  • host/port:定義 Elasticsearch 的地址,也可以配置認(rèn)證信息,我們的 Elasticsearch 不需要認(rèn)證,所以這里直接指定 host 和 port 即可。
  • logstash_format:Elasticsearch 服務(wù)對日志數(shù)據(jù)構(gòu)建反向索引進(jìn)行搜索,將 logstash_format 設(shè)置為?true,F(xiàn)luentd 將會(huì)以 logstash 格式來轉(zhuǎn)發(fā)結(jié)構(gòu)化的日志數(shù)據(jù)。
  • Buffer: Fluentd 允許在目標(biāo)不可用時(shí)進(jìn)行緩存,比如,如果網(wǎng)絡(luò)出現(xiàn)故障或者 Elasticsearch 不可用的時(shí)候。緩沖區(qū)配置也有助于降低磁盤的 IO。
過濾?

由于 Kubernetes 集群中應(yīng)用太多,也還有很多歷史數(shù)據(jù),所以我們可以只將某些應(yīng)用的日志進(jìn)行收集,比如我們只采集具有?logging=true?這個(gè) Label 標(biāo)簽的 Pod 日志,這個(gè)時(shí)候就需要使用 filter,如下所示:

# 刪除無用的屬性
<filter kubernetes.**>
  @type record_transformer
  remove_keys $.docker.container_id,$.kubernetes.container_image_id,$.kubernetes.pod_id,$.kubernetes.namespace_id,$.kubernetes.master_url,$.kubernetes.labels.pod-template-hash
</filter>
# 只保留具有l(wèi)ogging=true標(biāo)簽的Pod日志
<filter kubernetes.**>
  @id filter_log
  @type grep
  <regexp>
    key $.kubernetes.labels.logging
    pattern ^true$
  </regexp>
</filter>

安裝?

要收集 Kubernetes 集群的日志,直接用 DasemonSet 控制器來部署 Fluentd 應(yīng)用,這樣,它就可以從 Kubernetes 節(jié)點(diǎn)上采集日志,確保在集群中的每個(gè)節(jié)點(diǎn)上始終運(yùn)行一個(gè) Fluentd 容器。當(dāng)然可以直接使用 Helm 來進(jìn)行一鍵安裝,為了能夠了解更多實(shí)現(xiàn)細(xì)節(jié),我們這里還是采用手動(dòng)方法來進(jìn)行安裝。

可以直接使用官方的對于 Kubernetes 集群的安裝文檔:?Kubernetes - Fluentd。

首先,我們通過 ConfigMap 對象來指定 Fluentd 配置文件,新建?fluentd-configmap.yaml?文件,文件內(nèi)容如下:

# fluentd-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd-conf
  namespace: logging
data:
  # 容器日志
  containers.input.conf: |-
    <source>
      @id fluentd-containers.log
      @type tail                              # Fluentd 內(nèi)置的輸入方式,其原理是不停地從源文件中獲取新的日志
      path /var/log/containers/*.log          # Docker 容器日志路徑
      pos_file /var/log/es-containers.log.pos  # 記錄讀取的位置
      tag raw.kubernetes.*                    # 設(shè)置日志標(biāo)簽
      read_from_head true                     # 從頭讀取
      <parse>                                 # 多行格式化成JSON
        # 可以使用我們介紹過的 multiline 插件實(shí)現(xiàn)多行日志
        @type multi_format                    # 使用 multi-format-parser 解析器插件
        <pattern>
          format json                         # JSON解析器
          time_key time                       # 指定事件時(shí)間的時(shí)間字段
          time_format %Y-%m-%dT%H:%M:%S.%NZ   # 時(shí)間格式
        </pattern>
        <pattern>
          format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
          time_format %Y-%m-%dT%H:%M:%S.%N%:z
        </pattern>
      </parse>
    </source>

    # 在日志輸出中檢測異常(多行日志),并將其作為一條日志轉(zhuǎn)發(fā)
    # https://github.com/GoogleCloudPlatform/fluent-plugin-detect-exceptions
    <match raw.kubernetes.**>           # 匹配tag為raw.kubernetes.**日志信息
      @id raw.kubernetes
      @type detect_exceptions           # 使用detect-exceptions插件處理異常棧信息
      remove_tag_prefix raw             # 移除 raw 前綴
      message log
      multiline_flush_interval 5
    </match>

    <filter **>  # 拼接日志
      @id filter_concat
      @type concat                # Fluentd Filter 插件,用于連接多個(gè)日志中分隔的多行日志
      key message
      multiline_end_regexp /\n$/  # 以換行符“\n”拼接
      separator ""
    </filter>

    # 添加 Kubernetes metadata 數(shù)據(jù)
    <filter kubernetes.**>
      @id filter_kubernetes_metadata
      @type kubernetes_metadata
    </filter>

    # 修復(fù) ES 中的 JSON 字段
    # 插件地址:https://github.com/repeatedly/fluent-plugin-multi-format-parser
    <filter kubernetes.**>
      @id filter_parser
      @type parser                # multi-format-parser多格式解析器插件
      key_name log                # 在要解析的日志中指定字段名稱
      reserve_data true           # 在解析結(jié)果中保留原始鍵值對
      remove_key_name_field true  # key_name 解析成功后刪除字段
      <parse>
        @type multi_format
        <pattern>
          format json
        </pattern>
        <pattern>
          format none
        </pattern>
      </parse>
    </filter>

    # 刪除一些多余的屬性
    <filter kubernetes.**>
      @type record_transformer
      remove_keys $.docker.container_id,$.kubernetes.container_image_id,$.kubernetes.pod_id,$.kubernetes.namespace_id,$.kubernetes.master_url,$.kubernetes.labels.pod-template-hash
    </filter>

    # 只保留具有l(wèi)ogging=true標(biāo)簽的Pod日志
    <filter kubernetes.**>
      @id filter_log
      @type grep
      <regexp>
        key $.kubernetes.labels.logging
        pattern ^true$
      </regexp>
    </filter>

  ###### 監(jiān)聽配置,一般用于日志聚合用 ######
  forward.input.conf: |-
    # 監(jiān)聽通過TCP發(fā)送的消息
    <source>
      @id forward
      @type forward
    </source>

  output.conf: |-
    <match **>
      @id elasticsearch
      @type elasticsearch
      @log_level info
      include_tag_key true
      host elasticsearch-client
      port 9200
      user elastic # FLUENT_ELASTICSEARCH_USER | FLUENT_ELASTICSEARCH_PASSWORD
      password ydzsio321
      logstash_format true
      logstash_prefix k8s
      request_timeout 30s
      <buffer>
        @type file
        path /var/log/fluentd-buffers/kubernetes.system.buffer
        flush_mode interval
        retry_type exponential_backoff
        flush_thread_count 2
        flush_interval 5s
        retry_forever
        retry_max_interval 30
        chunk_limit_size 2M
        queue_limit_length 8
        overflow_action block
      </buffer>
    </match>

上面配置文件中我們只配置了 docker 容器日志目錄,收集到數(shù)據(jù)經(jīng)過處理后發(fā)送到?elasticsearch-client:9200?服務(wù)。

然后新建一個(gè)?fluentd-daemonset.yaml?的文件,文件內(nèi)容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd-es
  namespace: logging
  labels:
    k8s-app: fluentd-es
    kubernetes.io/cluster-service: 'true'
    addonmanager.kubernetes.io/mode: Reconcile
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: fluentd-es
  labels:
    k8s-app: fluentd-es
    kubernetes.io/cluster-service: 'true'
    addonmanager.kubernetes.io/mode: Reconcile
rules:
  - apiGroups:
      - ''
    resources:
      - 'namespaces'
      - 'pods'
    verbs:
      - 'get'
      - 'watch'
      - 'list'
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: fluentd-es
  labels:
    k8s-app: fluentd-es
    kubernetes.io/cluster-service: 'true'
    addonmanager.kubernetes.io/mode: Reconcile
subjects:
  - kind: ServiceAccount
    name: fluentd-es
    namespace: logging
    apiGroup: ''
roleRef:
  kind: ClusterRole
  name: fluentd-es
  apiGroup: ''
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: logging
  labels:
    app: fluentd
    kubernetes.io/cluster-service: 'true'
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
        kubernetes.io/cluster-service: 'true'
    spec:
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      serviceAccountName: fluentd-es
      containers:
        - name: fluentd
          image: quay.io/fluentd_elasticsearch/fluentd:v3.4.0
          volumeMounts:
            - name: fluentconfig
              mountPath: /etc/fluent/config.d
            - name: varlog
              mountPath: /var/log
      volumes:
        - name: fluentconfig
          configMap:
            name: fluentd-conf
        - name: varlog
          hostPath:
            path: /var/log

我們將上面創(chuàng)建的?fluentd-config?這個(gè) ConfigMap 對象通過 volumes 掛載到了 Fluentd 容器中,另外為了能夠靈活控制哪些節(jié)點(diǎn)的日志可以被收集,還可以添加了一個(gè)?nodSelector?屬性:

nodeSelector:
  beta.kubernetes.io/fluentd-ds-ready: 'true'

意思就是要想采集節(jié)點(diǎn)的日志,那么我們就需要給節(jié)點(diǎn)打上上面的標(biāo)簽。

!!! info "提示" 如果你需要在其他節(jié)點(diǎn)上采集日志,則需要給對應(yīng)節(jié)點(diǎn)打上標(biāo)簽,使用如下命令:kubectl label nodes node名 beta.kubernetes.io/fluentd-ds-ready=true。

另外由于我們的集群使用的是 kubeadm 搭建的,默認(rèn)情況下 master 節(jié)點(diǎn)有污點(diǎn),所以如果要想也收集 master 節(jié)點(diǎn)的日志,則需要添加上容忍:

tolerations:
  - operator: Exists

分別創(chuàng)建上面的 ConfigMap 對象和 DaemonSet:

$ kubectl create -f fluentd-configmap.yaml
configmap "fluentd-conf" created
$ kubectl create -f fluentd-daemonset.yaml
serviceaccount "fluentd-es" created
clusterrole.rbac.authorization.k8s.io "fluentd-es" created
clusterrolebinding.rbac.authorization.k8s.io "fluentd-es" created
daemonset.apps "fluentd" created

創(chuàng)建完成后,查看對應(yīng)的 Pods 列表,檢查是否部署成功:

$ kubectl get pods -n logging
NAME                            READY   STATUS    RESTARTS   AGE
elasticsearch-client-0          1/1     Running   0          64m
elasticsearch-data-0            1/1     Running   0          65m
elasticsearch-master-0          1/1     Running   0          73m
fluentd-5rqbq                   1/1     Running   0          60m
fluentd-l6mgf                   1/1     Running   0          60m
fluentd-xmfpg                   1/1     Running   0          60m
kibana-66f97964b-mdspc          1/1     Running   0          63m

Fluentd 啟動(dòng)成功后,這個(gè)時(shí)候就可以發(fā)送日志到 ES 了,但是我們這里是過濾了只采集具有?logging=true?標(biāo)簽的 Pod 日志,所以現(xiàn)在還沒有任何數(shù)據(jù)會(huì)被采集。

下面我們部署一個(gè)簡單的測試應(yīng)用, 新建?counter.yaml?文件,文件內(nèi)容如下:

apiVersion: v1
kind: Pod
metadata:
  name: counter
  labels:
    logging: 'true' # 一定要具有該標(biāo)簽才會(huì)被采集
spec:
  containers:
    - name: count
      image: busybox
      args:
        [
          /bin/sh,
          -c,
          'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done',
        ]

該 Pod 只是簡單將日志信息打印到?stdout,所以正常來說 Fluentd 會(huì)收集到這個(gè)日志數(shù)據(jù),在 Kibana 中也就可以找到對應(yīng)的日志數(shù)據(jù)了,使用 kubectl 工具創(chuàng)建該 Pod:

$ kubectl create -f counter.yaml
$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
counter                          1/1     Running   0          9h

Pod 創(chuàng)建并運(yùn)行后,回到 Kibana Dashboard 頁面,點(diǎn)擊左側(cè)最下面的?Management?->?Stack Management,進(jìn)入管理頁面,點(diǎn)擊左側(cè)?Kibana?下面的?索引模式,點(diǎn)擊?創(chuàng)建索引模式?開始導(dǎo)入索引數(shù)據(jù):

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

在這里可以配置我們需要的 Elasticsearch 索引,前面 Fluentd 配置文件中我們采集的日志使用的是 logstash 格式,定義了一個(gè)?k8s?的前綴,所以這里只需要在文本框中輸入?k8s-*?即可匹配到 Elasticsearch 集群中采集的 Kubernetes 集群日志數(shù)據(jù),然后點(diǎn)擊下一步,進(jìn)入以下頁面:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

在該頁面中配置使用哪個(gè)字段按時(shí)間過濾日志數(shù)據(jù),在下拉列表中,選擇@timestamp字段,然后點(diǎn)擊?創(chuàng)建索引模式,創(chuàng)建完成后,點(diǎn)擊左側(cè)導(dǎo)航菜單中的?Discover,然后就可以看到一些直方圖和最近采集到的日志數(shù)據(jù)了:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

現(xiàn)在的數(shù)據(jù)就是上面 Counter 應(yīng)用的日志,如果還有其他的應(yīng)用,我們也可以篩選過濾:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

我們也可以通過其他元數(shù)據(jù)來過濾日志數(shù)據(jù),比如您可以單擊任何日志條目以查看其他元數(shù)據(jù),如容器名稱,Kubernetes 節(jié)點(diǎn),命名空間等。

安裝 Kafka?

對于大規(guī)模集群來說,日志數(shù)據(jù)量是非常巨大的,如果直接通過 Fluentd 將日志打入 Elasticsearch,對 ES 來說壓力是非常巨大的,我們可以在中間加一層消息中間件來緩解 ES 的壓力,一般情況下我們會(huì)使用 Kafka,然后可以直接使用?kafka-connect-elasticsearch?這樣的工具將數(shù)據(jù)直接打入 ES,也可以在加一層 Logstash 去消費(fèi) Kafka 的數(shù)據(jù),然后通過 Logstash 把數(shù)據(jù)存入 ES,這里我們來使用 Logstash 這種模式來對日志收集進(jìn)行優(yōu)化。

首先在 Kubernetes 集群中安裝 Kafka,同樣這里使用 Helm 進(jìn)行安裝:

$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update

首先使用?helm pull?拉取 Chart 并解壓:

$ helm pull bitnami/kafka --untar --version 17.2.3
$ cd kafka

這里面我們指定使用一個(gè)?StorageClass?來提供持久化存儲(chǔ),在 Chart 目錄下面創(chuàng)建用于安裝的 values 文件:

# values-prod.yaml
## @section Persistence parameters
persistence:
  enabled: true
  storageClass: 'local-path'
  accessModes:
    - ReadWriteOnce
  size: 8Gi

  mountPath: /bitnami/kafka

# 配置zk volumes
zookeeper:
  enabled: true
  persistence:
    enabled: true
    storageClass: 'local-path'
    accessModes:
      - ReadWriteOnce
    size: 8Gi

直接使用上面的 values 文件安裝 kafka:

$ helm upgrade --install kafka -f values-prod.yaml --namespace logging .
Release "kafka" does not exist. Installing it now.
NAME: kafka
LAST DEPLOYED: Thu Jun  9 14:02:01 2022
NAMESPACE: logging
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: kafka
CHART VERSION: 17.2.3
APP VERSION: 3.2.0

** Please be patient while the chart is being deployed **

Kafka can be accessed by consumers via port 9092 on the following DNS name from within your cluster:

    kafka.logging.svc.cluster.local

Each Kafka broker can be accessed by producers via port 9092 on the following DNS name(s) from within your cluster:

    kafka-0.kafka-headless.logging.svc.cluster.local:9092

To create a pod that you can use as a Kafka client run the following commands:

    kubectl run kafka-client --restart='Never' --image docker.io/bitnami/kafka:3.2.0-debian-10-r4 --namespace logging --command -- sleep infinity
    kubectl exec --tty -i kafka-client --namespace logging -- bash

    PRODUCER:
        kafka-console-producer.sh \

            --broker-list kafka-0.kafka-headless.logging.svc.cluster.local:9092 \
            --topic test

    CONSUMER:
        kafka-console-consumer.sh \

            --bootstrap-server kafka.logging.svc.cluster.local:9092 \
            --topic test \
            --from-beginning

安裝完成后我們可以使用上面的提示來檢查 Kafka 是否正常運(yùn)行:

$ kubectl get pods -n logging -l app.kubernetes.io/instance=kafka
kafka-0             1/1     Running   0          7m58s
kafka-zookeeper-0   1/1     Running   0          7m58s

用下面的命令創(chuàng)建一個(gè) Kafka 的測試客戶端 Pod:

$ kubectl run kafka-client --restart='Never' --image docker.io/bitnami/kafka:3.2.0-debian-10-r4 --namespace logging --command -- sleep infinity
pod/kafka-client created

然后啟動(dòng)一個(gè)終端進(jìn)入容器內(nèi)部生產(chǎn)消息:

# 生產(chǎn)者
$ kubectl exec --tty -i kafka-client --namespace logging -- bash
I have no name!@kafka-client:/$ kafka-console-producer.sh --broker-list kafka-0.kafka-headless.logging.svc.cluster.local:9092 --topic test
>hello kafka on k8s
>

啟動(dòng)另外一個(gè)終端進(jìn)入容器內(nèi)部消費(fèi)消息:

# 消費(fèi)者
$ kubectl exec --tty -i kafka-client --namespace logging -- bash
I have no name!@kafka-client:/$ kafka-console-consumer.sh --bootstrap-server kafka.logging.svc.cluster.local:9092 --topic test --from-beginning
hello kafka on k8s

如果在消費(fèi)端看到了生產(chǎn)的消息數(shù)據(jù)證明我們的 Kafka 已經(jīng)運(yùn)行成功了。

Fluentd 配置 Kafka?

現(xiàn)在有了 Kafka,我們就可以將 Fluentd 的日志數(shù)據(jù)輸出到 Kafka 了,只需要將 Fluentd 配置中的?<match>?更改為使用 Kafka 插件即可,但是在 Fluentd 中輸出到 Kafka,需要使用到?fluent-plugin-kafka?插件,所以需要我們自定義下 Docker 鏡像,最簡單的做法就是在上面 Fluentd 鏡像的基礎(chǔ)上新增 kafka 插件即可,Dockerfile 文件如下所示:

FROM quay.io/fluentd_elasticsearch/fluentd:v3.4.0
RUN echo "source 'https://mirrors.tuna.tsinghua.edu.cn/rubygems/'" > Gemfile && gem install bundler
RUN gem install fluent-plugin-kafka -v 0.17.5 --no-document

使用上面的?Dockerfile?文件構(gòu)建一個(gè) Docker 鏡像即可,我這里構(gòu)建過后的鏡像名為?cnych/fluentd-kafka:v0.17.5。接下來替換 Fluentd 的 Configmap 對象中的?<match>?部分,如下所示:

# fluentd-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd-conf
  namespace: logging
data:
  ......
  output.conf: |-
    <match **>
      @id kafka
      @type kafka2
      @log_level info

      # list of seed brokers
      brokers kafka-0.kafka-headless.logging.svc.cluster.local:9092
      use_event_time true

      # topic settings
      topic_key k8slog
      default_topic messages  # 注意,kafka中消費(fèi)使用的是這個(gè)topic
      # buffer settings
      <buffer k8slog>
        @type file
        path /var/log/td-agent/buffer/td
        flush_interval 3s
      </buffer>

      # data type settings
      <format>
        @type json
      </format>

      # producer settings
      required_acks -1
      compression_codec gzip

    </match>

然后替換運(yùn)行的 Fluentd 鏡像:

# fluentd-daemonset.yaml
image: cnych/fluentd-kafka:v0.17.5

直接更新 Fluentd 的 Configmap 與 DaemonSet 資源對象即可:

$ kubectl apply -f fluentd-configmap.yaml
$ kubectl apply -f fluentd-daemonset.yaml

更新成功后我們可以使用上面的測試 Kafka 客戶端來驗(yàn)證是否有日志數(shù)據(jù):

$ kubectl exec --tty -i kafka-client --namespace logging -- bash
I have no name!@kafka-client:/$ kafka-console-consumer.sh --bootstrap-server kafka.logging.svc.cluster.local:9092 --topic messages --from-beginning
{"stream":"stdout","docker":{},"kubernetes":{"container_name":"count","namespace_name":"default","pod_name":"counter","container_image":"busybox:latest","host":"node1","labels":{"logging":"true"}},"message":"43883: Tue Apr 27 12:16:30 UTC 2021\n"}
......

安裝 Logstash?

雖然數(shù)據(jù)從 Kafka 到 Elasticsearch 的方式多種多樣,比如可以使用?Kafka Connect Elasticsearch Connector?來實(shí)現(xiàn),我們這里還是采用更加流行的 `Logstash`` 方案,上面我們已經(jīng)將日志從 Fluentd 采集輸出到 Kafka 中去了,接下來我們使用 Logstash 來連接 Kafka 與 Elasticsearch 間的日志數(shù)據(jù)。

首先使用?helm pull?拉取 Chart 并解壓:

$ helm pull elastic/logstash --untar --version 7.17.3
$ cd logstash

同樣在 Chart 根目錄下面創(chuàng)建用于安裝的 Values 文件,如下所示:

# values-prod.yaml
fullnameOverride: logstash

persistence:
  enabled: true

logstashConfig:
  logstash.yml: |
    http.host: 0.0.0.0
    # 如果啟用了xpack,需要做如下配置
    xpack.monitoring.enabled: true
    xpack.monitoring.elasticsearch.hosts: ["http://elasticsearch-client:9200"]
    xpack.monitoring.elasticsearch.username: "elastic"
    xpack.monitoring.elasticsearch.password: "ydzsio321"

# 要注意下格式
logstashPipeline:
  logstash.conf: |
    input { kafka { bootstrap_servers => "kafka-0.kafka-headless.logging.svc.cluster.local:9092" codec => json consumer_threads => 3 topics => ["messages"] } }
    filter {}  # 過濾配置(比如可以刪除key、添加geoip等等)
    output { elasticsearch { hosts => [ "elasticsearch-client:9200" ] user => "elastic" password => "ydzsio321" index => "logstash-k8s-%{+YYYY.MM.dd}" } stdout { codec => rubydebug } }

volumeClaimTemplate:
  accessModes: ['ReadWriteOnce']
  storageClassName: nfs-storage
  resources:
    requests:
      storage: 1Gi

其中最重要的就是通過?logstashPipeline?配置 logstash 數(shù)據(jù)流的處理配置,通過?input?指定日志源 kafka 的配置,通過?output?輸出到 Elasticsearch,同樣直接使用上面的 Values 文件安裝 logstash 即可:

$ helm upgrade --install logstash -f values-prod.yaml --namespace logging .
Release "logstash" does not exist. Installing it now.
NAME: logstash
LAST DEPLOYED: Thu Jun  9 15:02:49 2022
NAMESPACE: logging
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Watch all cluster members come up.
  $ kubectl get pods --namespace=logging -l app=logstash -w

安裝啟動(dòng)完成后可以查看 logstash 的日志:

$ logstash kubectl get pods --namespace=logging -l app=logstash
NAME         READY   STATUS    RESTARTS   AGE
logstash-0   1/1     Running   0          2m8s
$ kubectl logs -f logstash-0 -n logging
......
{
      "@version" => "1",
        "stream" => "stdout",
    "@timestamp" => 2022-06-09T07:09:16.889Z,
       "message" => "4672: Thu Jun  9 07:09:15 UTC 2022",
    "kubernetes" => {
         "container_image" => "docker.io/library/busybox:latest",
          "container_name" => "count",
                  "labels" => {
            "logging" => "true"
        },
                "pod_name" => "counter",
          "namespace_name" => "default",
                  "pod_ip" => "10.244.2.118",
                    "host" => "node2",
        "namespace_labels" => {
            "kubernetes_io/metadata_name" => "default"
        }
    },
        "docker" => {}
}

由于我們啟用了 debug 日志調(diào)試,所以我們可以在 logstash 的日志中看到我們采集的日志消息,到這里證明我們的日志數(shù)據(jù)就獲取成功了。

現(xiàn)在我們可以登錄到 Kibana 可以看到有如下所示的索引數(shù)據(jù)了:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

然后同樣創(chuàng)建索引模式,匹配上面的索引即可:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

創(chuàng)建完成后就可以前往發(fā)現(xiàn)頁面過濾日志數(shù)據(jù)了:

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

到這里我們就實(shí)現(xiàn)了一個(gè)使用?Fluentd+Kafka+Logstash+Elasticsearch+Kibana?的 Kubernetes 日志收集工具棧,這里我們完整的 Pod 信息如下所示:

$ kubectl get pods -n logging
NAME                            READY   STATUS    RESTARTS   AGE
elasticsearch-client-0          1/1     Running   0          128m
elasticsearch-data-0            1/1     Running   0          128m
elasticsearch-master-0          1/1     Running   0          128m
fluentd-6k52h                   1/1     Running   0          61m
fluentd-cw72c                   1/1     Running   0          61m
fluentd-dn4hs                   1/1     Running   0          61m
kafka-0                         1/1     Running   3          134m
kafka-client                    1/1     Running   0          125m
kafka-zookeeper-0               1/1     Running   0          134m
kibana-kibana-66f97964b-qqjgg   1/1     Running   0          128m
logstash-0                      1/1     Running   0          13m

當(dāng)然在實(shí)際的工作項(xiàng)目中還需要我們根據(jù)實(shí)際的業(yè)務(wù)場景來進(jìn)行參數(shù)性能調(diào)優(yōu)以及高可用等設(shè)置,以達(dá)到系統(tǒng)的最優(yōu)性能。

上面我們在配置?logstash?的時(shí)候是將日志輸出到?"logstash-k8s-%{+YYYY.MM.dd}"?這個(gè)索引模式的,可能有的場景下只通過日期去區(qū)分索引不是很合理,那么我們可以根據(jù)自己的需求去修改索引名稱,比如可以根據(jù)我們的服務(wù)名稱來進(jìn)行區(qū)分,那么這個(gè)服務(wù)名稱可以怎么來定義呢?可以是 Pod 的名稱或者通過 label 標(biāo)簽去指定,比如我們這里去做一個(gè)規(guī)范,要求需要收集日志的 Pod 除了需要添加?logging: true?這個(gè)標(biāo)簽之外,還需要添加一個(gè)?logIndex: <索引名>?的標(biāo)簽。

比如重新更新我們測試的 counter 應(yīng)用:

apiVersion: v1
kind: Pod
metadata:
  name: counter
  labels:
    logging: 'true' # 一定要具有該標(biāo)簽才會(huì)被采集
    logIndex: 'test' # 指定索引名稱
spec:
  containers:
    - name: count
      image: busybox
      args:
        [
          /bin/sh,
          -c,
          'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done',
        ]

然后重新更新 logstash 的配置,修改 values 配置:

# ......
logstashPipeline:
  logstash.conf: |
    input { kafka { bootstrap_servers => "kafka-0.kafka-headless.logging.svc.cluster.local:9092" codec => json consumer_threads => 3 topics => ["messages"] } }
    filter {}  # 過濾配置(比如可以刪除key、添加geoip等等)
    output { elasticsearch { hosts => [ "elasticsearch-client:9200" ] user => "elastic" password => "ydzsio321" index => "k8s-%{[kubernetes][labels][logIndex]}-%{+YYYY.MM.dd}" } stdout { codec => rubydebug } }

# ......

使用上面的 values 值更新 logstash,正常更新后上面的 counter 這個(gè) Pod 日志會(huì)輸出到一個(gè)名為?k8s-test-2022.06.09?的索引去。

k8s搭建EFK日志系統(tǒng),kubernetes,容器,云原生

這樣我們就實(shí)現(xiàn)了自定義索引名稱,當(dāng)然你也可以使用 Pod 名稱、容器名稱、命名空間名稱來作為索引的名稱,這完全取決于你自己的需求。文章來源地址http://www.zghlxwxcb.cn/news/detail-757186.html

到了這里,關(guān)于k8s搭建EFK日志系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • EFK簡單部署收集K8S日志

    EFK簡單部署收集K8S日志

    安裝ES kibana K8S部署

    2024年04月27日
    瀏覽(25)
  • 【云原生、k8s】管理Kubernetes應(yīng)用搭建與部署

    官方提供Kubernetes部署3種方式 (一)minikube Minikube是一個(gè)工具,可以在本地快速運(yùn)行一個(gè)單點(diǎn)的Kubernetes,嘗試Kubernetes或日常開發(fā)的用戶使用。不能用于生產(chǎn)環(huán)境。 官方文檔:https://kubernetes.io/docs/setup/minikube/ (二)二進(jìn)制包 從官方下載發(fā)行版的二進(jìn)制包,手動(dòng)部署每個(gè)組件,

    2024年01月21日
    瀏覽(122)
  • 【云原生-K8s-1】kubeadm搭建k8s集群(一主兩從)完整教程及kubernetes簡介

    【云原生-K8s-1】kubeadm搭建k8s集群(一主兩從)完整教程及kubernetes簡介

    ?? 博主簡介 ????云計(jì)算領(lǐng)域優(yōu)質(zhì)創(chuàng)作者 ????華為云開發(fā)者社區(qū)專家博主 ????阿里云開發(fā)者社區(qū)專家博主 ?? 交流社區(qū): 運(yùn)維交流社區(qū) 歡迎大家的加入! ??Kubernetes(簡稱:k8s) 是Google在2014年6月開源的一個(gè)容器集群管理系統(tǒng),使用Go語言開發(fā),用于管理云平臺中多

    2024年02月07日
    瀏覽(28)
  • 【云原生 | Kubernetes 系列】— 部署K8S 1.28版本集群部署(基于Containerd容器運(yùn)行)

    主機(jī)名 IP地址 備注 k8s-master01 192.168.0.109 master k8s-node1 192.168.0.108 node1 k8s-node2 192.168.0.107 node1 k8s-node3 192.168.0.105 node1 1、主機(jī)配置 2、升級內(nèi)核 3、配置內(nèi)核轉(zhuǎn)發(fā)以及過濾 4、安裝ipset ipvsadm,IPVS(IP Virtual Server)是一個(gè)用于負(fù)載均衡的 Linux 內(nèi)核模塊,它可以用來替代 kube-proxy 默認(rèn)的

    2024年02月20日
    瀏覽(101)
  • 云上攻防-云原生篇&Kubernetes&K8s安全&API&Kubelet未授權(quán)訪問&容器執(zhí)行

    云上攻防-云原生篇&Kubernetes&K8s安全&API&Kubelet未授權(quán)訪問&容器執(zhí)行

    Kubernetes是一個(gè)開源的, 用于編排云平臺中多個(gè)主機(jī)上的容器化的應(yīng)用,目標(biāo)是讓部署容器化的應(yīng)用能簡單并且高效的使用, 提供了應(yīng)用部署,規(guī)劃,更新,維護(hù)的一種機(jī)制 。其核心的特點(diǎn)就是能夠自主的管理容器來保證云平臺中的容器按照用戶的期望狀態(tài)運(yùn)行著,管理員可

    2024年02月08日
    瀏覽(31)
  • 【云原生 | Kubernetes 系列】K8s 實(shí)戰(zhàn) 如何給應(yīng)用注入數(shù)據(jù) II 將pod數(shù)據(jù)傳遞給容器

    【云原生 | Kubernetes 系列】K8s 實(shí)戰(zhàn) 如何給應(yīng)用注入數(shù)據(jù) II 將pod數(shù)據(jù)傳遞給容器

    在上一篇文章中,我們學(xué)習(xí)了針對容器設(shè)置啟動(dòng)時(shí)要執(zhí)行的命令和參數(shù)、定義相互依賴的環(huán)境變量、為容器設(shè)置環(huán)境變量,三種設(shè)置方式,本篇文章,我們將繼續(xù)學(xué)習(xí)數(shù)據(jù)的傳遞。 有兩種方式可以將 Pod 和 Container 字段傳遞給運(yùn)行中的容器: 環(huán)境變量 卷文件 這兩種呈現(xiàn) Pod

    2024年01月25日
    瀏覽(526)
  • 云原生Kubernetes:K8S集群實(shí)現(xiàn)容器運(yùn)行時(shí)遷移(docker → containerd) 與 版本升級(v1.23.14 → v1.24.1)

    云原生Kubernetes:K8S集群實(shí)現(xiàn)容器運(yùn)行時(shí)遷移(docker → containerd) 與 版本升級(v1.23.14 → v1.24.1)

    目錄 一、理論 1.K8S集群升級 2.環(huán)境 3.升級策略 4.master1節(jié)點(diǎn)遷移容器運(yùn)行時(shí)(docker → containerd)? 5.master2節(jié)點(diǎn)遷移容器運(yùn)行時(shí)(docker → containerd)? 6.node1節(jié)點(diǎn)容器運(yùn)行時(shí)遷移(docker → containerd)? 7.升級集群計(jì)劃(v1.23.14 →?v1.24.1) 8.升級master1節(jié)點(diǎn)版本(v1.24.1) 9.升級master2節(jié)點(diǎn)版本

    2024年02月03日
    瀏覽(38)
  • 云原生之容器編排實(shí)踐-在K8S集群中使用Registry2搭建私有鏡像倉庫

    云原生之容器編排實(shí)踐-在K8S集群中使用Registry2搭建私有鏡像倉庫

    基于前面搭建的3節(jié)點(diǎn) Kubernetes 集群,今天我們使用 Registry2 搭建私有鏡像倉庫,這在鏡像安全性以及離線環(huán)境下運(yùn)維等方面具有重要意義。 Note: 由于是測試環(huán)境,以下創(chuàng)建了一個(gè) local-storage 的 StorageClass ,并使用本地磁盤的方式創(chuàng)建使用 PV ,實(shí)際建議使用 NFS 。 共用到了三臺

    2024年02月19日
    瀏覽(22)
  • 云上攻防-云原生篇&;Kubernetes&;K8s安全&;API&;Kubelet未授權(quán)訪問&;容器執(zhí)行

    云上攻防-云原生篇&;Kubernetes&;K8s安全&;API&;Kubelet未授權(quán)訪問&;容器執(zhí)行

    curl -XPOST -k “https://192.168.139.132:10250/run///” -d “cmd=id” 執(zhí)行的命令是test03容器里的命令,需要進(jìn)行容器逃逸。 1、攻擊8080端口:API Server(Master)未授權(quán)訪問 舊版本的k8s的API Server默認(rèn)會(huì)開啟兩個(gè)端口:8080和6443。 6443是安全端口,安全端口使用TLS加密;但是8080端口無需認(rèn)證,

    2024年04月22日
    瀏覽(71)
  • 使用kubeshpere創(chuàng)建k8s容器日志系統(tǒng)grafana-loki

    使用kubeshpere創(chuàng)建k8s容器日志系統(tǒng)grafana-loki

    k8s日志聚合平臺grafana-loki,可以統(tǒng)一查看所有容器的日志運(yùn)行。 效果: ?使用kubeshpere創(chuàng)建loki應(yīng)用十分的方便,減少了很多操作,易用的同時(shí)也實(shí)用,k8s不再是精通人員才能使用的編排系統(tǒng)。 1、在企業(yè)空間中,添加bitnami應(yīng)用倉庫 https://charts.bitnami.com/bitnami ?2、創(chuàng)建loki應(yīng)用

    2024年02月12日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包