DevOps 实验项目阶段 8 笔记: Kafka + ELK 日志系统部署与问题处理
DevOps 实验项目阶段 8 笔记: Kafka + ELK 日志系统部署与问题处理
阶段目标
在已有 Kubernetes + Jenkins + Harbor CI/CD 平台基础上,引入完整日志链路:
Spring Boot Pod -> stdout -> /var/log/containers/*.log
-> Filebeat DaemonSet -> Kafka -> Logstash -> Elasticsearch -> Kibana
最终实现:Kubernetes 中的 SpringBoot 应用日志自动采集、缓存、处理、存储,并在 Kibana 展示。
环境规划
节点规划
| IP | hostname | 服务 |
|---|---|---|
| 192.168.205.141 | k8s-master | Kubernetes Control Plane |
| 192.168.205.142 | k8s-node1 | Worker |
| 192.168.205.143 | k8s-node2 | Worker |
| 192.168.205.144 | devops | Ansible + Jenkins |
| 192.168.205.145 | elk | Kafka + Elasticsearch + Logstash + Kibana |
| 192.168.205.146 | infra | Harbor + MySQL |
二、阶段 8 整体流程
最终日志链路:
Spring Boot (Kubernetes stdout)
-> /var/log/containers/*.log
-> Filebeat DaemonSet
-> Kafka topic: springboot-log
-> Logstash
-> Elasticsearch index
-> Kibana Discover
三、阶段 8.1 Kafka 部署 (KRaft 模式)
目标
替代传统 Kafka + Zookeeper,采用 Kafka KRaft,无需 Zookeeper。
部署节点
192.168.205.145 elk
目录
ansible/files/kafka/
- docker-compose.yml
Kafka 启动
进入 elk:
cd /opt/kafka
启动:
docker compose up -d
创建测试 Topic
进入 Kafka 容器:
docker exec -it kafka bash
创建:
/opt/kafka/bin/kafka-topics.sh \
--create \
--topic springboot-log \
--bootstrap-server localhost:9092 \
--partitions 3 \
--replication-factor 1
查看:
/opt/kafka/bin/kafka-topics.sh \
--list \
--bootstrap-server localhost:9092
结果:
springboot-log
Kafka 消费测试
消费者:
/opt/kafka/bin/kafka-console-consumer.sh \
--topic springboot-log \
--bootstrap-server localhost:9092 \
--from-beginning
生产者:
/opt/kafka/bin/kafka-console-producer.sh \
--topic springboot-log \
--bootstrap-server localhost:9092
输入:
hello kafka elk
消费者收到:
hello kafka elk
Kafka 部署成功。
四、阶段 8.2 Elasticsearch 部署
节点
192.168.205.145 elk
版本
Elasticsearch 8.15.3
Docker Compose
目录:
ansible/files/elasticsearch/
部署:
ansible-playbook elasticsearch.yml -K
验证
访问:
curl http://192.168.205.145:9200
返回:
{"name":"es-node","cluster_name":"devops-es","version":{"number":"8.15.3"}}
说明:Elasticsearch OK
五、阶段 8.3 Logstash 部署
作用
负责:Kafka -> Logstash -> ES
文件结构
ansible/files/logstash/
- docker-compose.yml
- logstash.conf
初始问题 1: Logstash 无法连接 ES
错误:
elasticsearch: Temporary failure in name resolution
原因:配置 hosts => ["http://elasticsearch:9200"],但 Docker compose 不存在该 hostname。
解决
修改:
output {
elasticsearch {
hosts => ["http://192.168.205.145:9200"]
}
}
重新启动:
docker compose down
docker compose up -d
验证
查看:
docker logs -f logstash
正常输出:
Subscribed to topic(s): springboot-log
六、阶段 8.4 Kibana 部署
部署
节点:192.168.205.145
目录:
ansible/files/kibana/
执行:
ansible-playbook kibana.yml -K
访问:
http://192.168.205.145:5601
创建 Data View
Kibana -> Discover -> Create data view -> springboot-log*
时间字段:@timestamp
七、阶段 8.5 Filebeat Kubernetes 日志采集
目标
采集:Pod stdout
发送:Kafka
文件结构
devops 节点:
ansible/files/filebeat/
- filebeat.yml
- filebeat-rbac.yml
- filebeat-daemonset.yml
八、Filebeat 配置
文件:filebeat.yml
核心:
filebeat.inputs:
- type: container
enabled: true
paths:
- /var/log/containers/*.log
processors:
- add_kubernetes_metadata: ~
九、部署 Filebeat
注意:不是在 devops 部署 K8S 资源,正确操作如下:
RBAC
创建:
kubectl apply -f filebeat-rbac.yml
ConfigMap
创建:
kubectl create configmap filebeat-config \
--from-file=filebeat.yml=/tmp/filebeat.yml \
-n default \
--dry-run=client -o yaml | kubectl apply -f -
DaemonSet
部署:
kubectl apply -f filebeat-daemonset.yml
验证
kubectl get pods -l app=filebeat -o wide
结果:
filebeat Running node1
filebeat Running node2
说明:Filebeat 成功。
十、完整链路测试
1. Spring Boot 接口测试
访问:
curl http://192.168.205.142:30881/api/users
2. 查看 Pod 日志
kubectl logs -l app=devops-demo --tail=50
3. Kafka 消费
elk 节点:
docker exec -it kafka bash
消费:
/opt/kafka/bin/kafka-console-consumer.sh \
--topic springboot-log \
--bootstrap-server localhost:9092 \
--from-beginning
收到日志。
4. Kibana 查看
进入 Discover,看到 springboot-log 日志出现。
十一、阶段遇到的问题总结
问题 1: Kafka 镜像不存在
错误:
manifest for bitnami/kafka:3.9 not found
原因: 镜像 tag 不存在。
解决: 更换存在版本,例如 bitnami/kafka:3.8,然后重新:
docker compose pull
docker compose up -d
问题 2: Ansible playbook 语法错误
错误:
Unable to parse argument string line xx-name: Start Elasticsearch
原因: YAML 缩进错误。
解决: 检查并修正缩进:
ansible-playbook xxx.yml --syntax-check
问题 3: Logstash 连接 ES 失败
错误:
elasticsearch:9200 DNS failure
原因: Docker 内部 hostname 不存在。
解决: 修改为:
hosts => ["http://192.168.205.145:9200"]
问题 4: Filebeat 部署后 kubectl 连接 localhost
错误:
failed to download openapi, localhost:8080 connection refused
原因: 执行 kubectl 的机器没有 Kubeconfig。错误在 devops 直接执行 kubectl。
解决: 让 Ansible 远程 master 执行:
ansible k8s_control_plane -a "kubectl get nodes"
成功输出:
k8s-master Ready
k8s-node1 Ready
k8s-node2 Ready
问题 5: Harbor 突然不可用
现象:
docker login 192.168.205.146
错误:
Get https://192.168.205.146/v2/: 443 connection refused
原因: Docker 配置丢失 insecure-registries。Docker 默认使用 HTTPS 443,但 Harbor 使用 HTTP 80。
根因: docker-install.sh 中的 cat > /etc/docker/daemon.json 覆盖了配置。
解决: 加入:
"insecure-registries": ["192.168.205.146"]
统一由 Ansible 管理。
验证:
docker info | grep -A3 "Insecure Registries"
结果:
192.168.205.146
问题 6: cri-dockerd 重复安装问题
现象: 每次执行 ansible-playbook kubernetes.yml 都会重新下载 cri-dockerd。
原因: 脚本没有判断是否已安装。
优化: 增加幂等判断:
if command -v cri-dockerd >/dev/null
then
echo "already installed"
exit 0
fi
十二、当前完成状态
| 阶段 | 状态 |
|---|---|
| 阶段1 基础环境 | ✅ |
| 阶段2 Ansible | ✅ |
| 阶段3 Docker | ✅ |
| 阶段4 Kubernetes | ✅ |
| 阶段5 Spring Boot | ✅ |
| 阶段6 Harbor/MySQL | ✅ |
| 阶段7 Jenkins CI/CD | ✅ |
| 阶段8.1 Kafka | ✅ |
| 阶段8.2 Elasticsearch | ✅ |
| 阶段8.3 Logstash | ✅ |
| 阶段8.4 Kibana | ✅ |
| 阶段8.5 Filebeat | ✅ |
更多推荐

所有评论(0)