轻量级 CI/CD 实战(三): Kafka 消费者容器化部署
目录
- 背景与目标
- 项目结构
- 关键配置文件
- Dockerfile
- requirements.txt
- [consumer.py 注意事项](#consumer.py 注意事项)
- 部署流程
- 常见问题排查
- 容器不断重启
- [Kafka 连接失败(NoBrokersAvailable)](#Kafka 连接失败(NoBrokersAvailable))
- [Python 语法错误](#Python 语法错误)
- 一键重启脚本
- 总结
背景与目标
在日志分析系统中,Nginx 日志通过 Filebeat 发送到 Kafka 集群,需部署一个长期运行的消费者程序,将日志解析后写入 MySQL 并缓存到 Redis。
为提升部署效率、避免环境依赖冲突,采用 Docker 容器化方案,实现:
- 服务开机自启(
--restart=always) - 网络直连宿主机(
--network host) - 代码更新后快速重建
项目结构
项目存放于 /opt/log_consumer/,目录结构如下:
bash
/opt/log_consumer/
├── consumer.py # 主程序:Kafka消费 + MySQL写入 + Redis缓存
├── requirements.txt # Python依赖列表
└── Dockerfile # Docker镜像构建定义
关键配置文件
Dockerfile
使用官方 python:3.9-slim 镜像,轻量且兼容性好:
bash
# 使用轻量 Python 镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖(禁用缓存确保干净构建)
RUN pip install --no-cache-dir -r requirements.txt
# 复制主程序
COPY consumer.py .
# 启动命令
CMD ["python", "consumer.py"]
requirements.txt
bash
kafka-python==2.0.2
PyMySQL==1.1.0
redis==5.0.1
consumer.py 注意事项
Kafka 消费者初始化时,必须使用集群主机名,不可用 localhost 或 127.0.0.1:
bash
consumer = KafkaConsumer(
'nginx-logs',
bootstrap_servers=["kafka1:9092", "kafka2:9092", "kafka3:9092"], # ← 关键!
auto_offset_reset='latest',
enable_auto_commit=True,
group_id='log-consumer-group'
)
同时确保:
所有依赖库已正确导入
每行参数末尾加英文逗号 ,(避免 SyntaxError)
异常处理完善(防止进程意外退出)
部署流程
清理旧容器
容器名称冲突是常见错误,务必先删除旧容器
bash
docker stop log-consumer 2>/dev/null && docker rm log-consumer 2>/dev/null
即使容器已停止,仍占用名称,必须 rm
语法预检
避免因语法错误导致容器无限重启
bash
cd /opt/log_consumer
python3 -m py_compile consumer.py
无输出即表示语法正确。
构建镜像
bash
docker build -t log-consumer .
构建成功后,可通过 docker images 查看镜像
启动容器
使用 host 网络模式直连 Kafka,开启自启:
bash
docker run -d \
--network host \
--name log-consumer \
--restart=always \
log-consumer
--network host:容器共享宿主机网络,可直接访问 kafka1:9092
验证运行状态
查看实时日志:
bash
docker logs -f log-consumer
成功标志(你的程序应输出类似内容):
bash
OK MySQL连接成功
OK Redis连接成功
OK Kafka消费者创建成功
TARGET 开始监听日志...

常见问题排查
容器不断重启
现象:docker ps 显示容器状态为 Restarting
原因:程序启动后立即退出(如语法错误、连接失败)
解决:
bash
停止容器:docker stop log-consumer
前台运行查看错误:docker run -it --network host --rm log-consumer
根据报错修复代码
Kafka 连接失败(NoBrokersAvailable)
现象:日志报 kafka.errors.NoBrokersAvailable
原因:
bootstrap_servers 写成 localhost:9092(这里检查kafka配置文件)
Kafka 未监听外网 IP
防火墙阻断 9092 端口
解决:
bash
使用 kafka1:9092 等主机名(需 DNS 或 hosts 解析)
在宿主机测试:telnet kafka1 9092
Python 语法错误
现象:SyntaxError: invalid syntax,报错行看似正常
原因:
上一行缺少逗号(最常见!)
中文标点混入
文件含 BOM 头或 CRLF 换行符
kafka3:9092末尾要加上逗号,否则系统将这一行和下一行当作同一行处理就报错了

解决:
bash
用 cat -A 检查隐藏字符
用 python3 -m py_compile 提前校验
重写可疑行(手动输入英文标点)
一键重启脚本
bash
#!/bin/bash
cd /opt/log_consumer
# 停旧容器
docker stop log-consumer 2>/dev/null
docker rm log-consumer 2>/dev/null
# 构建新镜像
docker build -t log-consumer .
# 启动
docker run -d --network host --name log-consumer --restart=always log-consumer
echo "✅ 消费者已启动,查看日志:docker logs -f log-consumer"
总结
通过容器化 Kafka 消费者,我们实现了:
环境隔离:依赖不污染宿主机
快速部署:6 条命令完成上线
高可用:崩溃自动重启
标准化:任何人拿到代码均可一键运行
作者:subencai
环境:CentOS 7 + Docker 24.0 + Kafka 3.3
最后更新:2025年11月