文章目录
统一日志管理
日志管理
在Kubernetes集群环境中,一个完整的应用或服务都会涉及为数众多的组件运行,各组件所在的Node及实例数量都是可变的。日志子系统如果不做集中化管理,则会给系统的运维支撑造成很大的困难,因此建议在集群层面对日志进行统一收集和检索等工作。
在容器中输出到控制台的日志,都会以*-json.log的命名方式保存在/var/lib/docker/containers/目录下。
Kubernetes推荐采用Fluentd+Elasticsearch+Kibana完成对系统和容器日志的采集、查询和展现工作。
部署统一的日志管理系统,需要以下两个前提条件。
- API Server正确配置了CA证书。
- DNS服务启动、运行。
EFK简介
Kubernetes 配套一个 Elasticsearch 附加组件来实现集群的日志管理。这是一个 Elasticsearch、Fluentd或Filebeat 和 Kibana 的组合。
- Elasticsearch 是一个搜索引擎,负责存储日志并提供查询接口;
- Fluentd/Filebeat 负责从 Kubernetes 搜集日志,每个node节点上面的fluentd监控并收集该节点上面的系统日志,并将处理过后的日志信息发送给Elasticsearch;
- Kibana 提供了一个 Web GUI,用户可以浏览和搜索存储在 Elasticsearch 中的日志。
通过在每台node上部署一个以DaemonSet方式运行的fluentd来收集每台node上的日志。Fluentd将docker日志目录/var/lib/docker/containers和/var/log目录挂载到Pod中,然后Pod会在node节点的/var/log/pods目录中创建新的目录,可以区别不同的容器日志输出,该目录下有一个日志文件链接到/var/lib/docker/contianers目录下的容器日志输出。
即相对应的三个组件整个流程大体如下:
在各Node上都运行了一个Fluentd/Filebeat容器,采集本节点/var/log和/var/lib/docker/containers两个目录下的日志进程,将其汇总到Elasticsearch集群,最终通过Kibana完成和用户的交互工作。因此Fluentd必须在每个Node上运行。为了满足这一需求,可通过以下几种方式部署Fluentd/Filebeat。
- 直接在Node主机上部署Fluentd/Filebeat。
- 利用kubelet的–config参数, 为每个Node都加载Fluentd/Filebeat Pod。
- 利用DaemonSet让Fluentd/Filebeat Pod在每个Node上运行。
架构设计
节点 | IP | 角色 | 组件 |
---|---|---|---|
master01 | 172.24.8.11 | Kubernetes master控制平面 | Kibana、Filebeat |
master02 | 172.24.8.12 | Kubernetes master控制平面 | Kibana、Filebeat |
master03 | 172.24.8.13 | Kubernetes master控制平面 | Kibana、Filebeat |
worker01 | 172.24.8.14 | Kubernetes master控制平面 | elasticsearch、Filebeat |
worker02 | 172.24.8.15 | Kubernetes master控制平面 | elasticsearch、Filebeat |
worker03 | 172.24.8.16 | Kubernetes master控制平面 | elasticsearch、Filebeat |
elasticsearch:部署在worker节点(172.24.8.14-16),worker节点为业务节点
部署方式:StatefulSet(ES) + Deployment(Kibana)
Fluentd/Filebeat:部署在所有节点(包括master和worker),需要收集每个节点的容器日志
部署方式:DaemonSet(每个节点一个Pod)
Kibana:部署在master节点(172.24.8.11-13),只暴露服务,Elasticsearch不直接暴露。
提示:本环境基于学习目的,把Elasticsearch也暴露。
EFK部署
设置标签
针对需要部署的节点,进行打标签,从而实现定向调度。
[root@master01 ~]# kubectl label nodes worker0{1,2,3} elasticsearch=enable
[root@master01 ~]# kubectl label nodes master0{1,2,3} kibana=enable
获取EFK chart包
[root@master01 ~]# helm repo add elastic https://helm.elastic.co
[root@master01 ~]# helm repo update
[root@master01 ~]# helm search repo elastic/
NAME CHART VERSION APP VERSION DESCRIPTION
elastic/apm-attacher 1.1.3 A Helm chart installing the Elastic APM Kuberne...
elastic/apm-server 8.5.1 8.5.1 Official Elastic helm chart for Elastic APM Server
elastic/eck-agent 0.15.0 Elastic Agent managed by the ECK operator
elastic/eck-apm-server 0.15.0 Elastic APM Server managed by the ECK operator
elastic/eck-beats 0.15.0 Elastic Beats managed by the ECK operator
elastic/eck-elasticsearch 0.15.0 Elasticsearch managed by the ECK operator
elastic/eck-enterprise-search 0.15.0 Elastic Enterprise Search managed by the ECK op...
elastic/eck-fleet-server 0.15.0 Elastic Fleet Server as an Agent managed by the...
elastic/eck-kibana 0.15.0 Kibana managed by the ECK operator
elastic/eck-logstash 0.15.0 Logstash managed by the ECK operator
elastic/eck-operator 3.0.0 3.0.0 Elastic Cloud on Kubernetes (ECK) operator
elastic/eck-operator-crds 3.0.0 3.0.0 ECK operator Custom Resource Definitions
elastic/eck-stack 0.15.0 Elastic Stack managed by the ECK Operator
elastic/elastic-agent 9.0.3 9.0.3 Elastic-Agent Helm Chart
elastic/elasticsearch 8.5.1 8.5.1 Official Elastic helm chart for Elasticsearch
elastic/filebeat 8.5.1 8.5.1 Official Elastic helm chart for Filebeat
elastic/kibana 8.5.1 8.5.1 Official Elastic helm chart for Kibana
elastic/kube-state-metrics 5.30.1 2.15.0 Install kube-state-metrics to generate and expo...
elastic/logstash 8.5.1 8.5.1 Official Elastic helm chart for Logstash
elastic/metricbeat 8.5.1 8.5.1 Official Elastic helm chart for Metricbeat
elastic/pf-host-agent 8.14.3 8.14.3 Hyperscaler software efficiency. For everybody.
elastic/profiling-agent 9.0.3 9.0.3 Hyperscaler software efficiency. For everybody.
elastic/profiling-collector 9.0.3 9.0.3 Universal Profiling. Hyperscaler software effic...
elastic/profiling-symbolizer 9.0.3 9.0.3 Universal Profiling. Hyperscaler software effic...
创建证书
默认 elasticsearch 没有开启ingress,本环境已部署ingress,因此规划启用ingress来基于https暴露服务。
同时相关证书使用自签名创建证书,同时使用对应证书创建secret。
- 脚本快速自签名基于实验目的,采用自签名证书。
[root@master01 ~]# mkdir elasticsearch
[root@master01 ~]# cd elasticsearch/
[root@master01 elasticsearch]# wget http://down.linuxsb.com/myshell/signcert.sh
[root@master01 elasticsearch]# vim signcert.sh
#!/bin/sh
#***************************************************************#
# ScriptName: signcert.sh
# Author: xhy
# Create Date: 2025-02-25 21:49
# Modify Author: xhy
# Modify Date: 2025-04-27 19:11
# Version: v1
#***************************************************************#
# 配置参数
#PARENT_DOMAIN="linuxsb.com" # 父级域名
#SUB_DOMAINS=("aaa" "bbb" "ccc") # 子域名列表,可选配置
PARENT_DOMAIN="linuxsb.com"
SUB_DOMAINS=("es" "kibana")
#…… #其他保持默认
[root@master01 dashboard]# bash signcert.sh
[root@master01 dashboard]# ll certs/
total 24K
-rw-r--r-- 1 root root 2.4K Jul 19 20:50 fullchain.crt
-rw-r--r-- 1 root root 1.3K Jul 19 20:50 linuxsb.com.crt
-rw------- 1 root root 1.7K Jul 19 20:50 linuxsb.com.key
-rw-r--r-- 1 root root 1.2K Jul 19 20:50 myCA.crt
-rw------- 1 root root 1.7K Jul 19 20:50 myCA.key
-rw-r--r-- 1 root root 41 Jul 19 20:50 myCA.srl
手动创建secret
自定义证书的场景,建议提前使用对应的证书创建secret。
后续用于使用https暴露elasticsearch。
[root@master01 elasticsearch]# kubectl create ns es #dashboard独立ns
[root@master01 elasticsearch]# kubectl -n es create secret tls elasticsearch-ui-tls \
--cert=/root/elasticsearch/certs/linuxsb.com.crt \
--key=/root/elasticsearch/certs/linuxsb.com.key
[root@master01 elasticsearch]# kubectl -n es get secret kubernetes-elasticsearch-certs -o yaml #查看证书信息
创建elasticsearch自定义配置
根据实际情况修改默认的chart values,未配置的项表示使用默认值。
如下自定义yaml主要做了几项自定义配置:
- 指定elasticsearch部署在master节点;
- 指定了使用自有的TLS证书,及https的ingress域名;
- 指定了污点能接受master节点;
- 指定了Pod挂载本地时间文件,使Pod时钟正确;
- 使用Longhorn提供的持久化存储保存数据。
[root@master01 elasticsearch]# helm show values elastic/elasticsearch > defaults-elasticsearch-values.yaml #查看默认配置
[root@master01 elasticsearch]# vim my-elasticsearch-values.yaml
---
replicas: 2
# 此部分配置将直接写入elasticsearch.yml
# 此部分配置将直接写入elasticsearch.yml
# 磁盘空间管理 - 防止磁盘写满导致集群崩溃
# 低水位线(85%) - 达到此使用率时停止分配新分片
# 高水位线(90%) - 达到此使用率时尝试迁移分片
esConfig:
elasticsearch.yml: |
cluster.routing.allocation.disk.threshold_enabled: true
cluster.routing.allocation.disk.watermark.low: "85%"
cluster.routing.allocation.disk.watermark.high: "90%"
# 启用密码存储(自动创建Kubernetes Secret)
secret:
enabled: true
password: "redhat123"
image: "uhub.service.ucloud.cn/imxhy/elasticsearch"
imageTag: "8.5.1"
# 持久化存储配置
volumeClaimTemplate:
accessModes: ["ReadWriteOnce"]
storageClassName: "longhorn"
resources:
requests:
storage: 5Gi
# 时间同步配置
extraVolumeMounts:
- name: timeconfig
mountPath: /etc/localtime
readOnly: true
extraVolumes:
- name: timeconfig
hostPath:
path: /etc/localtime
# 节点调度配置
nodeSelector: {"elasticsearch": "enable"}
# Ingress配置
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
className: "nginx"
hosts:
- host: es.linuxsb.com
paths:
- path: /
tls:
- secretName: elasticsearch-ui-tls
hosts:
- es.linuxsb.com
正式部署elasticsearch
根据生产环境最佳实践进行调优,调优完成后开始部署。
[root@master01 elasticsearch]# helm upgrade --install elasticsearch elastic/elasticsearch --create-namespace --namespace es -f my-elasticsearch-values.yaml
确认验证
使用浏览器访问 https://es.linuxsb.com ,使用默认用户 elastic 和自定义的密码登录。
创建filebeat自定义配置
根据实际情况修改默认的chart values,未配置的项表示使用默认值。
如下自定义yaml主要做了几项自定义配置:
- 指定filebeat部署在所有节点,对master打上容忍;
- 修改镜像为国内。
[root@master01 elasticsearch]# helm show values elastic/filebeat > defaults-filebeat-values.yaml #查看默认配置
[root@master01 elasticsearch]# vim my-filebeat-values.yaml
---
daemonset:
tolerations:
# 主节点容忍
- key: node-role.kubernetes.io/control-plane
operator: "Exists"
effect: "NoSchedule"
deployment:
enabled: false
image: "uhub.service.ucloud.cn/imxhy/filebeat"
imageTag: "8.5.1"
正式部署filebeat
根据生产环境最佳实践进行调优,调优完成后开始部署。
[root@master01 elasticsearch]# helm upgrade --install filebeat elastic/filebeat --create-namespace --namespace es -f my-filebeat-values.yaml
创建kibana自定义配置
根据实际情况修改默认的chart values,未配置的项表示使用默认值。
如下自定义yaml主要做了几项自定义配置:
- 指定kibana部署在所有节点,对master打上容忍;
- 修改镜像为国内。
[root@master01 elasticsearch]# helm show values elastic/kibana > defaults-kibana-values.yaml #查看默认配置
[root@master01 elasticsearch]# vim my-kibana-values.yaml
---
replicas: 1
image: "uhub.service.ucloud.cn/imxhy/kibana"
imageTag: "8.5.1"
kibanaConfig:
kibana.yml: |
server.publicBaseUrl: "https://kibana.linuxsb.com"
elasticsearch.ssl.certificateAuthorities: /usr/share/kibana/config/certs/ca.crt
# 时间同步配置
extraVolumeMounts:
- name: timeconfig
mountPath: /etc/localtime
readOnly: true
extraVolumes:
- name: timeconfig
hostPath:
path: /etc/localtime
ingress:
enabled: true
className: "nginx"
hosts:
- host: kibana.linuxsb.com
paths:
- path: /
tls:
- secretName: elasticsearch-ui-tls
hosts:
- kibana.linuxsb.com
# 节点调度(与ES相同节点)
nodeSelector: {"kibana": "enable"}
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: "Exists"
effect: "NoSchedule"
正式部署kibana
根据生产环境最佳实践进行调优,调优完成后开始部署。
[root@master01 elasticsearch]# helm upgrade --install kibana elastic/kibana --create-namespace --namespace es -f my-kibana-values.yaml
提示:若部署kibana过程异常,需要重新卸载再部署,但卸载和重部署报错某个资源already exists,可如下操作:
报错:
Error: failed pre-install: warning: Hook pre-install kibana/templates/pre-install-rolebinding.yaml failed: 1 error occurred:
* rolebindings.rbac.authorization.k8s.io "pre-install-kibana-kibana" already exists
[root@master01 elasticsearch]# kubectl -n es get configmap,secret,serviceaccount,role,rolebindings,jobs #查询所有相应的资源
[root@master01 elasticsearch]# kubectl -n es delete configmap/kibana-kibana-config secret/kibana-kibana-es-token secret/sh.helm.release.v1.kibana.v1 configmaps/kibana-kibana-helm-scripts serviceaccounts/pre-install-kibana-kibana roles/pre-install-kibana-kibana rolebindings/pre-install-kibana-kibana jobs.batch/pre-install-kibana-kibana
#其他资源类似手动全部删除
[root@master01 elasticsearch]# helm -n es uninstall kibana
确认验证
查看部署的资源
[root@master01 elasticsearch]# kubectl -n es get all -o wide
[root@master01 elasticsearch]# kubectl -n es get ingress -o wide
访问验证
浏览器访问 https://kibana.linuxsb.com ,使用elasticsearch默认用户 elastic 和自定义的密码 redhat123 登录。
基础使用
确认连接
浏览器访问后确认正常连接filebeat-8.5.1 。
进入 Index Management 中的 Data Streams 中可以看到 filebeat-8.5.1 已被列为数据索引项目。
测试日志
创建一个生产日志的Pod,用于生成日志,确认能正常获取。
[root@master01 elasticsearch]# vim test-logging-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: testpods01
spec:
containers:
- name: count
image: uhub.service.ucloud.cn/imxhy/busybox:1.37.0
args: [/bin/sh, -c,'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
[root@master01 elasticsearch]# kubectl apply -f test-logging-pod.yaml
pod/testpods01 created
[root@master01 elasticsearch]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
testpods01 1/1 Running 0 6s 10.10.30.91 worker02 <none> <none>
kibana界面中查看 Observability->Logs->Stream:
创建索引
配置Kibana,要查询和分析 Elasticsearch 中的哪些日志,因此需要配置一个 Index Pattern。从 Filebeat 中可知 Index 是 filebeat-timestamp 这种格式,因此需要定义 Index Pattern 为 filebeat-*
提示:当前版本已存在一个包含filebeat-*格式的索引模式。
日志查看与搜索
基本日志查看:
左侧菜单 > Analytics > Discover
选择默认创建的视图即可。
可根据时间范围选择: Last 15 minutes
也可以使用kubernetes.namespace: “es” 查看特定namespace下的日志。
还可以根据需要创建一个dashboard,用于展示。
尝试查找error关键字日志。
参考: