内网容器部署FTP日志监控服务
一、背景说明
随着AI使用的盛行,运维工作人员也可以使用它开发简单的应用服务,协助完成一些重复化的工作以提高效率。
笔者在公司工作耗时较长的一项任务是:给每台应用服务器,以服务为单位,给应用日志配置定时压缩并删除源文件、定时上传压缩日志到归档服务器的脚本。
生产环境有数百台虚拟机,每台虚拟机至少部署1个应用服务,如果长期把时间用在上面,是极其枯燥的。工作成果只能人工手动记录到excel表格,无法在工作汇报时直观展示实时数据。在和AI聊了很久后,完成了FTP上传日志的实时监控工具部署。
二、准备工作
1、本文的重点是从0到1部署容器服务,而不是编写代码或者FTP日志监控中的需求解析。
2、本文用到的py和html文件打包成镜像,在虚拟机运行容器服务。
3、FTP服务端,ftpuser作为ftp上传文件的用户,家目录是 /Logdata,IP是192.168.0.100,主机名是 ftp-server,操作系统版本是 Red Hat Enterprise Linux release 8.10 (Ootpa)
4、FTP客户端,IP是192.168.0.101,主机名是 ftp-client,操作系统版本是 Red Hat Enterprise Linux release 8.10 (Ootpa)
三、操作步骤
1、部署FTP服务
创建FTP服务的用户并指定家目录
bash
useradd -d /Logdata -s /sbin/nologin ftpuser
mkdir /Logdata
chown ftpuser:ftpuser /Logdata
配置好yum源去安装vsftpd服务,请根据实际环境,无论是虚拟机挂载ISO镜像配置本地仓库(file:///) 还是其他某个虚拟机单独作为yum镜像仓库(http://)都可以。
bash
yum install vsftpd -y
编写配置文件
bash
[root@ftp-server ~]# cat /etc/vsftpd/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/xferlog
xferlog_std_format=YES
chroot_local_user=YES
chroot_list_enable=NO
listen=YES
pam_service_name=vsftpd
userlist_enable=NO
allow_writeable_chroot=YES
配置服务端访问白名单
bash
[root@ftp-server ~]# cat /etc/vsftpd/user_list
ftpuser
启动服务并设置开机自动启动
bash
systemctl start vsftpd
systemctl enable vsftpd
systemctl status vsftpd
以下状态表示服务启动正常

如果服务启动失败,可以检查shells文件,是否存在 /sbin/nologin 如果没有,则添加,并重启服务。
bash
[root@ftp-server ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/usr/bin/tmux
/bin/tmux
/sbin/nologin
最后记得修改ftpuser用户的密码,如果是测试环境,可以简单设置为 123456 如果是生产环境,请根据需求配置。
2、镜像和文件上传
新建日志监控服务目录,并将所有安装包和镜像上传于/opt/目录下。
bash
cd /opt/
文件如下

ftp-log-monitor-v1.0.tar.gz 是镜像
ftp-log-monitor-dir-v1.0.tar.gz是源码归档包,包含 Dockerfile、应用代码(app/)、依赖清单(requirements.txt)等所有构建所需的文件。
剩余3个是部署docker环境需要的安装包和配置文件
需要注意的是, ftp-log-monitor-dir-v1.0.tar.gz 是笔者自己在构建镜像时准备的文件,在实际从0到1的容器服务部署时,这个文件可以忽略,我们已经拥有了镜像。
为了和其他容器服务区分开,我们把相关文件迁移到 /opt/ftp-log-monitor/ 目录下。笔者的源码归档包直接解压,也是这个目录文件。
bash
[root@ftp-server opt]# tar xf ftp-log-monitor-dir-v1.0.tar.gz
[root@ftp-server opt]# ll -h
total 151M
-rw-r--r-- 1 root root 67M Oct 26 2023 docker-24.0.7.tgz
-rw-r--r-- 1 root root 31M Sep 24 10:37 docker-compose
-rw-r--r-- 1 root root 587 Sep 24 10:05 docker-compose.yaml
drwxr-xr-x 4 root root 97 Sep 23 17:33 ftp-log-monitor
-rw-r--r-- 1 root root 136K Sep 23 17:41 ftp-log-monitor-dir-v1.0.tar.gz
-rw-r--r-- 1 root root 53M Sep 23 17:41 ftp-log-monitor-v1.0.tar.gz
[root@ftp-server opt]# cd ftp-log-monitor/
[root@ftp-server ftp-log-monitor]# tree
.
├── app
│ ├── database.py
│ ├── exporter.py
│ ├── exporter.py.bad
│ ├── __init__.py
│ ├── log_parser.py
│ ├── main.py
│ ├── new_detection.py
│ ├── __pycache__
│ │ ├── database.cpython-311.pyc
│ │ ├── exporter.cpython-311.pyc
│ │ ├── __init__.cpython-311.pyc
│ │ ├── log_parser.cpython-311.pyc
│ │ ├── main.cpython-311.pyc
│ │ ├── new_detection.cpython-311.pyc
│ │ ├── script_generator.cpython-311.pyc
│ │ ├── script_task_manager.cpython-311.pyc
│ │ ├── statistics.cpython-311.pyc
│ │ ├── storage.cpython-311.pyc
│ │ └── users.cpython-311.pyc
│ ├── script_generator.py
│ ├── script_task_manager.py
│ ├── statistics.py
│ ├── storage.py
│ ├── templates
│ │ ├── cron_config.html
│ │ ├── dashboard.html
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── script_generator.html
│ │ ├── script_tasks_history.html
│ │ ├── script_tasks.html
│ │ ├── script_tasks_import.html
│ │ ├── storage.html
│ │ └── users.html
│ └── users.py
├── data
│ ├── monitor.db
│ └── users.db
├── docker-compose.yml
├── Dockerfile
└── requirements.txt
理论上,我们在虚拟机上有了镜像和启动命令参数的yaml文件,就可以运行容器了。

3、部署容器环境
由于我们生产环境的日志归档服务器是一台虚拟机,并且也只部署1个FTP日志监控的容器服务,不需要K8S管理调度,只需要简单的docker就可以了。
3.1 安装docker
笔者的docker安装包是个人虚拟机离线下载的,直接执行命令即可。
bash
wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.7.tgz
解压安装
bash
tar xzvf docker-24.0.7.tgz
cp docker/* /usr/bin/
chmod +x /usr/bin/docker*
启动 Docker 守护进程
bash
dockerd &
验证版本
bash
[root@ftp-server opt]# docker --version
Docker version 24.0.7, build afdd53b
为便于启停docker,配置systemd服务
bash
[root@ftp-server opt]# cat /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
由于我们在安装docker时已经启动服务,此时再使用systemd启动时会报错,因此需要先杀掉对应的服务进程。
bash
pkill -9 dockerd
pkill -9 containerd
pkill -9 containerd-shim
此时可以启动docker服务
bash
# 让 systemd 重新加载配置,识别到新服务
systemctl daemon-reload
# 启动 Docker 服务
systemctl start docker
# 设置开机自动启动
systemctl enable docker
3.2 安装docker-compose(可选择)
实际上在docker安装完成后,我们就可以直接用docker命令,针对导入系统的镜像,启动容器服务了。但为了保存本地环境的启停参数,笔者使用yaml文件启动容器,为此需要额外部署docker-compose
如果不想安装docker-compose,直接使用docker命令启动容器,请先把镜像导入系统,再执行以下命令即可。
bash
docker run -d \
--name ftp-log-monitor \
--restart unless-stopped \
--log-opt max-size=10m \
--log-opt max-file=3 \
-p 5021:5000 \
-e USER_DB=/app/data/users.db \
-e MONITOR_DB=/app/data/monitor.db \
-e XFERLOG_PATH=/var/log/xferlog \
-e LOGDATA_ROOT=/Logdata \
-e TZ=Asia/Shanghai \
-v /opt/ftp-log-monitor/data:/app/data \
-v /var/log/xferlog:/var/log/xferlog:ro \
-v /Logdata:/Logdata:ro \
ftp-log-monitor:v1.0
同样的,先下载docker-compose的安装包
bash
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose
移动为可执行文件并授权
bash
mv /opt/docker-compose /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
验证版本
bash
[root@ftp-server opt]# docker-compose --version
Docker Compose version v5.5.1
4、启动容器服务
首先导入镜像到系统

其次进入yaml文件所在目录,确保没有多余的yaml或者yml文件干扰,直接用docker-compose启动容器。

贴一下我的其他文件内容。
bash
[root@ftp-server ftp-log-monitor]# cat docker-compose.yaml
version: '3.8'
services:
ftp-log-monitor:
image: ftp-log-monitor:v1.0
container_name: ftp-log-monitor
restart: unless-stopped
ports:
- "5021:5000"
environment:
- USER_DB=/app/data/users.db
- MONITOR_DB=/app/data/monitor.db
- XFERLOG_PATH=/var/log/xferlog
- LOGDATA_ROOT=/Logdata
- TZ=Asia/Shanghai
volumes:
- /opt/ftp-log-monitor/data:/app/data
- /var/log/xferlog:/var/log/xferlog:ro
- /Logdata:/Logdata:ro
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
[root@ftp-server ftp-log-monitor]# cat Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
COPY app/ ./app/
# 创建挂载点目录
# /var/log - 挂载 xferlog 日志文件
# /Logdata - 挂载实际日志存储目录
# /app/data - 存放 users.db 和 monitor.db(持久化)
RUN mkdir -p /var/log /Logdata /app/data && \
chmod 755 /var/log /Logdata /app/data
EXPOSE 5000
CMD ["python", "-m", "app.main"]
[root@ftp-server ftp-log-monitor]# cat requirements.txt
Flask==2.3.2
flask-cors==4.0.0
openpyxl==3.1.2
xlwt==1.3.0
检查容器正常启动。
bash
[root@ftp-server ftp-log-monitor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b331e18fe100 ftp-log-monitor:v1.0 "python -m app.main" 45 seconds ago Up 43 seconds 0.0.0.0:5021->5000/tcp, :::5021->5000/tcp ftp-log-monitor
四、结果展示
浏览器访问 http://192.168.0.100:5021/login
此处的账密是自己与AI沟通后确定的。

到此结束。
