基于 EFK 栈的集中式日志记录实践指南
1. 正则表达式与 EFK 栈部署准备
在处理正则表达式时,可能会面临一些挑战。不过,有一些网站可以提供帮助。在使用 Fluentd 时,推荐使用网站:https://fluentular.herokuapp.com/ 。
了解了 Fluentd 的工作原理和配置文件的构建方式后,就可以开始部署 EFK 栈了。在 Kubernetes 上部署 EFK 栈,将采用与部署微服务相同的方式,即使用 Kubernetes 清单文件来创建 Deployment、Service 和 ConfigMap 等对象。EFK 栈的部署分为三个部分:
- 部署 Elasticsearch 和 Kibana
- 部署 Fluentd
- 设置对 Elasticsearch 和 Kibana 的访问
但在此之前,需要先构建和部署自己的微服务。
1.1 构建和部署微服务
构建、部署和验证微服务的部署可以按照以下步骤进行:
1. 从源代码构建 Docker 镜像:
cd $BOOK_HOME/Chapter19
eval $(minikube docker-env -u)
./gradlew build
eval $(minikube docker-env)
docker-compose build
-
重新创建
hands-on命名空间并将其设置为默认命名空间:
kubectl delete namespace hands-on
kubectl apply -f kubernetes/hands-on-namespace.yml
kubectl config set-context $(kubectl config current-context) --namespace=hands-on
eval $(minikube docker-env -u)
命令确保
./gradlew build
命令使用主机的 Docker 引擎,而不是 Minikube 实例中的 Docker 引擎。构建命令使用 Docker 运行测试容器。
3. 解析 Helm 图表依赖项:
for f in kubernetes/helm/components/*; do helm dep up $f; done
for f in kubernetes/helm/environments/*; do helm dep up $f; done
- 使用 Helm 部署系统环境并等待所有部署完成:
helm install hands-on-dev-env kubernetes/helm/environments/dev-env -n hands-on --wait
- 如果 Minikube 隧道尚未运行,请在单独的终端窗口中启动它:
minikube tunnel
此命令需要用户具有 sudo 权限,并且在启动时需要输入密码。
6. 运行常规测试以验证部署:
./test-em-all.bash
- 手动测试 API:
ACCESS_TOKEN=$(curl -k https://writer:secret-writer@minikube.me/oauth2/token -d grant_type=client_credentials -d scope="product:read product:write" -s | jq .access_token -r)
echo ACCESS_TOKEN=$ACCESS_TOKEN
curl -ks https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" | jq .productId
1.2 部署 Elasticsearch 和 Kibana
将 Elasticsearch 和 Kibana 部署到
logging
命名空间。使用 Kubernetes Deployment 和 Service 对象进行开发和测试部署,Elasticsearch 内部端口为 9200,Kibana 内部端口为 5601。通过创建 Istio 对象提供外部 HTTP 访问,使 Elasticsearch 和 Kibana 可通过
https://elasticsearch.minikube.me
和
https://kibana.minikube.me
访问。
使用的版本如下:
| 组件 | 版本 |
| ---- | ---- |
| Elasticsearch | 7.17.10 |
| Kibana | 7.17.10 |
1.2.1 清单文件分析
- Elasticsearch 清单文件(elasticsearch.yml) :
apiVersion: apps/v1
kind: Deployment
...
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.10
resources:
limits:
cpu: 500m
memory: 2Gi
requests:
cpu: 500m
memory: 2Gi
解释:使用 Elastic 官方 Docker 镜像,版本为 7.17.10。为了保证查询性能,Elasticsearch 容器分配了 2GB 内存。
-
Kibana 清单文件(kibana.yml)
:
apiVersion: apps/v1
kind: Deployment
...
containers:
- name: kibana
image: docker.elastic.co/kibana/kibana:7.17.10
env:
- name: ELASTICSEARCH_URL
value: http://elasticsearch:9200
解释:使用 Elastic 官方 Docker 镜像,版本为 7.17.10。通过环境变量
ELASTICSEARCH_URL
指定 Elasticsearch 服务地址。
-
Istio 清单文件
:
expose-elasticsearch.yml
和
expose-kibana.yml
提供外部请求转发:
-
https://elasticsearch.minikube.me → http://elasticsearch:9200
-
https://kibana.minikube.me → http://kibana:5601
1.2.2 部署命令
- 预拉取 Docker 镜像:
eval $(minikube docker-env)
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.10
docker pull docker.elastic.co/kibana/kibana:7.17.10
-
使用 Helm 图表创建
logging命名空间并部署 Elasticsearch 和 Kibana:
helm install logging-hands-on-add-on kubernetes/helm/environments/logging -n logging --create-namespace --wait
- 验证 Elasticsearch 是否运行:
curl https://elasticsearch.minikube.me -sk | jq -r .tagline
期望响应为
You Know, for Search
。
4. 验证 Kibana 是否运行:
curl https://kibana.minikube.me -kLs -o /dev/null -w "%{http_code}\n"
期望响应为 200。
2. 部署 Fluentd
部署 Fluentd 相对复杂。使用 Docker Hub 上 Fluentd 项目发布的 Docker 镜像
fluent/fluentd-kubernetes-daemonset
和 GitHub 上 Fluentd 项目的示例 Kubernetes 清单文件。Fluentd 将作为 DaemonSet 部署,每个节点运行一个 Pod,负责收集同一节点上进程和容器的日志输出。
使用的版本如下:
| 组件 | 版本 |
| ---- | ---- |
| Fluentd | 1.4.2 |
| fluent-plugin-detect-exceptions | 0.0.12 |
2.1 清单文件分析
- Dockerfile(kubernetes/efk/Dockerfile) :
FROM fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
RUN gem install fluent-plugin-detect-exceptions -v 0.0.12 \
&& gem sources --clear-all \
&& rm -rf /var/lib/apt/lists/* \
/home/fluent/.gem/ruby/2.3.0/cache/*.gem
解释:以
fluent/fluentd-kubernetes-daemonset
为基础镜像,安装 Google 提供的
fluent-plugin-detect-exceptions
插件。
-
DaemonSet 清单文件(kubernetes/efk/fluentd-ds.yml)
:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
spec:
template:
spec:
containers:
- name: fluentd
image: hands-on/fluentd:v1
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.logging"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
- name: journal
mountPath: /var/log/journal
readOnly: true
- name: fluentd-extra-config
mountPath: /fluentd/etc/conf.d
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: journal
hostPath:
path: /run/log/journal
- name: fluentd-extra-config
configMap:
name: "fluentd-hands-on-config"
解释:DaemonSet 将在
kube-system
命名空间创建。Pod 使用
hands-on/fluentd:v1
镜像,通过环境变量指定 Elasticsearch 服务的主机名和端口。将主机上的
/var/log
、
/var/lib/docker/containers
和
/run/log/journal
文件夹映射到 Pod 中,用于收集日志。使用 ConfigMap
fluentd-hands-on-config
映射自定义配置文件。
2.2 部署命令
- 构建 Docker 镜像:
eval $(minikube docker-env)
docker build -f kubernetes/efk/Dockerfile -t hands-on/fluentd:v1 kubernetes/efk/
- 创建 ConfigMap 并部署 DaemonSet:
kubectl apply -f kubernetes/efk/fluentd-hands-on-configmap.yml
kubectl apply -f kubernetes/efk/fluentd-ds.yml
kubectl wait --timeout=120s --for=condition=Ready pod -l app=fluentd -n kube-system
- 验证 Fluentd Pod 是否健康:
kubectl logs -n kube-system -l app=fluentd --tail=-1 | grep "fluentd worker is now running worker"
期望响应为
2023-05-22 14:59:46 +0000 [info]: #0 fluentd worker is now running worker=0
。
4. 检查 Elasticsearch 收集的日志记录数量:
curl https://elasticsearch.minikube.me/_all/_count -sk | jq .count
以下是 EFK 栈部署的 mermaid 流程图:
graph LR
A[准备工作] --> B[构建和部署微服务]
B --> C[部署 Elasticsearch 和 Kibana]
C --> D[部署 Fluentd]
D --> E[验证部署]
3. 试用 EFK 栈
在试用 EFK 栈之前,需要先初始化 Kibana,使其知道在 Elasticsearch 中使用哪些索引。完成初始化后,可以尝试以下常见任务:
1. 分析 Fluentd 收集并存储在 Elasticsearch 中的日志记录类型。
2. 查找微服务在处理外部请求时创建的所有相关日志记录。
3. 使用 Kibana 进行根本原因分析,找出错误的实际原因。
3.1 初始化 Kibana
在使用 Kibana 之前,需要指定在 Elasticsearch 中使用的搜索索引以及索引中保存日志记录时间戳的字段。执行以下步骤初始化 Kibana:
1. 在 Web 浏览器中使用
https://kibana.minikube.me
URL 打开 Kibana 的 Web UI。
2. 在欢迎主页上,点击左上角的汉堡菜单(≡),然后点击左侧菜单底部的“Stack Management”。
3. 在管理菜单中,滚动到底部并选择“Index Patterns”。
4. 点击“Create index pattern”按钮。
5. 输入
logstash-*
作为索引模式名称,然后点击“Next Step”按钮。
6. 点击“Timestamp field”下拉列表,选择唯一可用的字段
@timestamp
。
7. 点击“Create index pattern”按钮。
3.2 分析日志记录
Fluentd 部署后会立即开始收集大量日志记录。首先需要了解 Fluentd 收集并存储在 Elasticsearch 中的日志记录类型。使用 Kibana 的可视化功能按 Kubernetes 命名空间划分日志记录,然后查看每个命名空间内按容器类型划分的日志记录。创建饼图的步骤如下:
1. 在 Kibana 的 Web UI 中,再次点击汉堡菜单,选择“Analytics”下的“Visualize Library”。
2. 点击“Create new visualization”按钮,在下一步中选择“Lens”类型。
3. 验证左上角的下拉菜单中选择的索引模式为
logstash-*
。
4. 在索引模式旁边的“Bar vertical stacked”下拉菜单中,选择“Pie”作为可视化类型。
5. 在饼图上方的时间选择器(日期间隔选择器)中,设置一个足够大的日期间隔以覆盖感兴趣的日志记录(在以下截图中设置为“Last 15 minutes”)。点击其日历图标调整时间间隔。
6. 在索引模式下方的“Search field names”字段中,输入
kubernetes.namespace_name.keyword
。
7. 在“Available fields”列表中,现在会出现
kubernetes.namespace_name.keyword
字段。将此字段拖到页面中间的大框中,Kibana 会立即开始分析日志记录并渲染按 Kubernetes 命名空间划分的饼图。
8. 在“Search field names”字段中,输入
kubernetes.container_name.keyword
。
9. 在“Available fields”列表中,现在会出现
kubernetes.container_name.keyword
字段。将此字段拖到显示饼图的大框中,Kibana 会立即开始分析日志记录并渲染按 Kubernetes 命名空间和容器名称划分的饼图。
10. 如果发现大量来自
coredns
的日志记录,可以通过以下步骤添加过滤器将其移除:
- 点击左上角的“+ Add filter”。
- 选择字段
kubernetes.container_name.keyword
和操作符“is not”。
- 输入值
coredns
,然后点击“Save”按钮。
11. 将此饼图保存到仪表板中,点击右上角的“Save”按钮。
12. 在“Save Lens visualization”页面上,执行以下操作:
- 为其提供一个标题,例如
hands-on-visualization
。
- 输入描述,例如
This is my first visualization in Kibana
。
- 在“Add to dashboard”框中,选择“New”。
以下是试用 EFK 栈的操作步骤列表:
| 操作步骤 | 具体内容 |
| ---- | ---- |
| 初始化 Kibana | 打开 Kibana Web UI,设置索引模式和时间戳字段 |
| 分析日志记录 | 创建饼图,按命名空间和容器类型划分日志记录,添加过滤器移除不感兴趣的日志记录,保存可视化结果到仪表板 |
以下是试用 EFK 栈的 mermaid 流程图:
graph LR
A[初始化 Kibana] --> B[分析日志记录类型]
B --> C[查找相关日志记录]
C --> D[进行根本原因分析]
通过以上步骤,完成了 EFK 栈的部署和试用。现在可以深入了解收集的日志记录,分析系统运行状况,找出潜在问题的根本原因。
超级会员免费看
11万+

被折叠的 条评论
为什么被折叠?



