设置服务器初始配置
设置历史记录
为了保留更多命令历史、防止覆盖并显示执行时间,需要修改用户 Shell 配置文件(通常为 ~/.bashrc 或 ~/.bash_profile)。
vim /root/.bashrc
添加一下配置
# 设置 history 条数(例如 10000 条)
export HISTSIZE=10000
export HISTFILESIZE=10000
# 显示命令执行时间
HISTTIMEFORMAT="【%F %T】" # 年-月-日 时:分:秒
# 防止历史记录被覆盖,每次登录追加到历史文件
shopt -s histappend
# 每次执行命令后立即保存历史记录
export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
# 自定义历史文件路径(可选,避免覆盖)
export HISTFILE="/root/.bash_history"
设置计算机名
hostnamectl set-hostname [myservername]
设置时区
设置服务器为北京时间
timedatectl set-timezone Asia/Shanghai
启动时间同步(NTP)
sudo yum install chrony
sudo systemctl enable chronyd
sudo systemctl start chronyd
配置NTP服务器
vim /etc/chrony.conf
添加或修改为中国 NTP 服务器:
server ntp.aliyun.com iburst
server cn.pool.ntp.org iburst
重启chronyd并验证同步
sudo systemctl restart chronyd
chronyc sources
3. 安装常用工具
# Ubuntu/Debian
sudo apt update
sudo apt install -y vim net-tools curl wget htop git tree unzip telnet
# CentOS/RHEL
sudo yum install -y epel-release
sudo yum install -y vim net-tools curl wget htop git tree unzip telnet
4. 配置 Swap
如果服务器内存不足,添加 Swap:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
5. 优化网络
增大 TCP 缓冲区(适用于高并发)
sudo vim /etc/sysctl.conf
添加:
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
应用:
sudo sysctl -p
安装Docker
使用国内源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
创建安装脚本
vim install_docker.sh
#!/bin/bash
read -p "安装(y/n):" judge_1
if [ "$judge_1" = "y" ]; then
# 安装 yum-utils
sudo yum install -y yum-utils
if [ $? != 0 ]; then
echo "安装 yum-utils 失败"
exit 1
fi
# 使用阿里云镜像源并添加重试机制
for i in {1..3}; do
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
if [ $? == 0 ]; then
break
fi
echo "设置远程仓库失败,尝试第 $i 次重试..."
sleep 3
done
if [ $? != 0 ]; then
echo "设置远程仓库失败,请检查网络或更换其他镜像源"
exit 1
fi
# 安装 Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
if [ $? != 0 ]; then
echo "安装 Docker 失败"
exit 1
fi
echo "Docker 安装完成"
# 启动并启用 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
echo "Docker 服务已启动并设置为开机自启"
else
echo "退出"
exit 0
fi
bash install_docker.sh
安装docker-compose
安装脚本
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
如果大陆下载失败,可在香港服务器下载后导入/usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
安装jumperver
参考官方文档:https://docs.jumpserver.org/zh/v4/installation/setup_linux_standalone/online_install/
cd /opt
wget https://resource.fit2cloud.com/jumpserver/installer/releases/download/v4.10.1/jumpserver-installer-v4.10.1.tar.gz
tar -xf jumpserver-installer-v4.10.1.tar.gz
cd jumpserver-installer-v4.10.1
# 安装
./jmsctl.sh install
# 启动
./jmsctl.sh start
在安装的时候如果提示无法pull镜像
这是因为网络的原因。可以在海外服务器上执行上述操作,下载完镜像后导出镜像,再在国内服务器导入镜像
# 导出镜像(下面几个镜像都需要)
docker save -o jumpserver_koko.tar jumpserver/koko
docker save -o jumpserver_lion.tar jumpserver/lion
docker save -o jumpserver_chen.tar jumpserver/chen
docker save -o jumpserver_core.tar jumpserver/core
docker save -o jumpserver_web.tar jumpserver/web
docker save -o redis.tar redis
docker save -o postgres.tar postgres
# 导入镜像
docker load -i jumpserver_koko.tar
docker load -i jumpserver_lion.tar
docker load -i jumpserver_chen.tar
docker load -i jumpserver_core.tar
docker load -i jumpserver_web.tar
docker load -i redis.tar
docker load -i postgres.tar
然后再执行上面的安装脚本(因为已存在镜像,所以脚本将跳过拉取镜像的步骤)
# 安装
./jmsctl.sh install
# 启动
./jmsctl.sh start
安装完成后 JumpServer 配置文件路径为: /opt/jumpserver/config/config.txt
将HTTP_PORT=80改为HTTP_PORT=8080,便于安装宝塔
设置DOMAINS="10.8.0.1:8080",便于登录web页(由于堡垒机不想暴露到公网,若不指定内网地址,内网将无法登录web堡垒机后台页面)
在jumpserver-installer-v4.10.1/config-example.txt也设置DOMAINS="10.8.0.1:8080"
设置好后重启堡垒机:
cd /opt/jumpserver-installer-v4.10.1
# 启动
./jmsctl.sh start
# 停止
./jmsctl.sh down
# 卸载
./jmsctl.sh uninstall
# 帮助
./jmsctl.sh -h
访问堡垒机
端口8080
账号账号密码:admin/ChangeMe
地址: http://<JumpServer服务器IP地址>:<服务运行端口>
用户名: admin
密码: ChangeMe
安装spug
spug是运维发布系统。
参考之前写的文章:https://www.moyuwa.com/1893.html
同样在海外服务器导出镜像
# 导出镜像(下面几个镜像都需要)
docker save -o spug-service.tar openspug/spug-service
docker save -o mariadb.tar mariadb
# 导入镜像
docker load -i mariadb.tar
docker load -i spug-service.tar
创建脚本
mkdir /opt/spug && cd /opt/spug
vi docker-compose.yml
version: "3.3"
services:
db:
image: mariadb:10.8.2
container_name: spug-db
restart: always
command: --port 3306 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- /data/spug/mysql:/var/lib/mysql
environment:
- MYSQL_DATABASE=spug
- MYSQL_USER=spug
- MYSQL_PASSWORD=spug.cc
- MYSQL_ROOT_PASSWORD=spug.cc
spug:
image: openspug/spug-service
container_name: spug
privileged: true # 特权模式
restart: always
volumes:
- /data/spug:/data/spug
- /data/repos:/data/repos
- /var/run/docker.sock:/var/run/docker.sock # 挂载docker套接字,容器内能运行docker命令
- /usr/bin/docker:/usr/bin/docker # 挂载docker客户端工具,容器内能运行docker命令
- /data/scripts:/scripts
ports:
# 如果80端口被占用可替换为其他端口,例如: - "8000:80"
- "8088:80"
environment:
- DOCKER_HOST=unix:///var/run/docker.sock # 设置环境变量,确保Spug容器知道如何连接到 Docker守护进程
- MYSQL_DATABASE=spug
- MYSQL_USER=spug
- MYSQL_PASSWORD=spug.cc
- MYSQL_HOST=spug-db
- MYSQL_PORT=3306
depends_on:
- db
启动容器
docker compose up -d
初始化
docker exec spug init_spug ops 123456
这将创建一个用户名为ops密码为123456的管理员账户,可自行替换管理员账户/密码。
安装宝塔
注意,安装宝塔后,会默认启动防火墙。在宝塔的控制面板的安全里管理安全规则
安装openvpn
使用的脚本是:https://github.com/angristan/openvpn-install
但是大陆访问会因为网络问题安装失败。
所以我在没有网络限制的海外Linux服务器上提前下载所需的软件包,并修改脚本以使用这些本地包。
以下为已修改的软件包
点击下载
安装Apollo
参考该文档
注意,apollo、eureka为内部使用,不要将端口暴露到公网,可用openvpn服务器的nginx转发
比如运维服务器为服务器A,基础环境为服务器B
在A上安装了openvpn、堡垒机、宝塔
在B上安装了apollo、eureka
可在A的宝塔上配置反代,将B的8070和8080转发到服务器B
这样,用户在连接openvpn后,就可通过http://10.8.0.1:8070 访问到B的8070了
安装rabbitmq
导入rabbitmq镜像
准备用docker安装rabbitmq,但是由于大陆服务器无法拉取docker镜像
所以在海外服务器上下载rabbitmq镜像
# 在海外服务器拉取镜像
sudo docker pull rabbitmq:3.13-management
# 保存镜像
docker save -o rabbitmq3.13.tar rabbitmq:3.13-management
# 拷贝到国内服务器后,导入到docker
docker load -i rabbitmq3.13.tar
创建持久化目录
默认情况下,RabbitMQ 数据存储在容器内,容器删除后数据会丢失。为持久化数据,添加卷挂载:
假如要创建三台MQ集群
为每台机器创建持久化目录,用于存储 RabbitMQ 数据和日志
sudo mkdir -p /data/rabbitmq/{node1,node2,node3}
sudo chown -R 999:999 /data/rabbitmq
# 999:999 是 RabbitMQ 镜像默认的用户/组 ID,确保容器有写权限。
配置主机名解析
RabbitMQ 集群依赖主机名通信,需确保节点主机名可解析。编辑每台机器的 /etc/hosts 文件:
vim /etc/hosts
# 给mq的节点创建主机名
172.17.32.9 rabbitmq-node1
172.17.32.10 rabbitmq-node2
172.17.32.11 rabbitmq-node3
测试是否正常
ping rabbitmq-node1
ping rabbitmq-node2
ping rabbitmq-node3
部署RabbitMQ节点
将在三台机器上各部署一个 RabbitMQ 节点(rabbitmq-node1、rabbitmq-node2、rabbitmq-node3),使用 rabbitmq:3.13-management 镜像(带管理界面,稳定版本)。每个节点配置相同的用户、密码和 Erlang Cookie。
节点1
运行以下命令启动第一个节点:
sudo docker run -d \
--name rabbitmq-node1 \
--hostname rabbitmq-node1 \
--net host \
--add-host rabbitmq-node1:172.17.0.15 \
--add-host rabbitmq-node2:172.17.0.10 \
--add-host rabbitmq-node3:172.17.16.7 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=qyBegs0SeQ5b9H \
-e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' \
-e RABBITMQ_NODENAME=rabbit@rabbitmq-node1 \
-v /data/rabbitmq/node1:/var/lib/rabbitmq \
--restart=always \
rabbitmq:3.13-management
节点2
sudo docker run -d \
--name rabbitmq-node2 \
--hostname rabbitmq-node2 \
--net host \
--add-host rabbitmq-node1:172.17.0.15 \
--add-host rabbitmq-node2:172.17.0.10 \
--add-host rabbitmq-node3:172.17.16.7 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=qyBegs0SeQ5b9H \
-e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' \
-e RABBITMQ_NODENAME=rabbit@rabbitmq-node2 \
-v /data/rabbitmq/node2:/var/lib/rabbitmq \
--restart=always \
rabbitmq:3.13-management
节点3
sudo docker run -d \
--name rabbitmq-node3 \
--hostname rabbitmq-node3 \
--net host \
--add-host rabbitmq-node1:172.17.0.15 \
--add-host rabbitmq-node2:172.17.0.10 \
--add-host rabbitmq-node3:172.17.16.7 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=qyBegs0SeQ5b9H \
-e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' \
-e RABBITMQ_NODENAME=rabbit@rabbitmq-node3 \
-v /data/rabbitmq/node3:/var/lib/rabbitmq \
--restart=always \
rabbitmq:3.13-management
配置说明:
- –hostname:设置唯一主机名,用于集群通信。
- -e RABBITMQ_ERLANG_COOKIE:所有节点必须使用相同的 Cookie(rabbitmqCookie)。
- -v:持久化数据到 /data/rabbitmq/nodeX。
- –add-host:确保容器内部能解析所有节点的主机名,避免手动修改 /etc/hosts
- –restart=always:容器自动重启。
验证端口监听
在每台服务器上运行:
sudo netstat -tuln | grep -E '4369|25672|5672|15672'
确保看到 0.0.0.0:4369、0.0.0.0:25672 等端口在监听。
验证 Erlang Cookie 一致性
由于使用了持久化卷,需确保 .erlang.cookie 文件一致:
检查 Cookie 文件
进入每个容器,查看 Cookie:
docker exec -it rabbitmq-node1 bash
cat /var/lib/rabbitmq/.erlang.cookie
重复检查 rabbitmq-node2 和 rabbitmq-node3,确保内容均为 rabbitmqCookie。
同步 Cookie
如果不一致,复制主节点的 Cookie:
docker cp rabbitmq-node1:/var/lib/rabbitmq/.erlang.cookie ./cookie
docker cp ./cookie rabbitmq-node2:/var/lib/rabbitmq/.erlang.cookie
docker cp ./cookie rabbitmq-node3:/var/lib/rabbitmq/.erlang.cookie
设置权限
docker exec rabbitmq-node2 chmod 400 /var/lib/rabbitmq/.erlang.cookie
docker exec rabbitmq-node3 chmod 400 /var/lib/rabbitmq/.erlang.cookie
如果 Cookie 问题反复出现,清理持久化数据:
docker rm -f rabbitmq-node2 rabbitmq-node3
sudo rm -rf /data/rabbitmq/node2/* /data/rabbitmq/node3/*
然后重启容器
docker restart rabbitmq-node2 rabbitmq-node3
配置集群
将节点 2 和节点 3 加入节点 1 的集群,节点 1 作为主节点(磁盘节点),节点 2 和 3 为内存节点(RAM)以提高性能。
加入节点2
在节点2服务器上:
sudo docker exec -it rabbitmq-node2 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq-node1
rabbitmqctl start_app
exit
加入节点3
在节点3服务器上:
sudo docker exec -it rabbitmq-node3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq-node1
rabbitmqctl start_app
exit
命令说明:
- stop_app:停止 RabbitMQ 应用(不停止容器)。
- reset:清除节点状态。
- join_cluster –ram:以内存节点加入集群,rabbit@rabbitmq-node1 是节点 1 的标识。
- start_app:启动 RabbitMQ 应用。
验证集群状态
在任意节点(建议主节点 rabbitmq-node1)上运行:
docker exec -it rabbitmq-node1 rabbitmqctl cluster_status
应看到类似输出,显示所有节点(rabbit@rabbitmq-node1、rabbit@rabbitmq-node2、rabbit@rabbitmq-node3)在集群中,且 rabbit@rabbitmq-node2 和 rabbit@rabbitmq-node3 为 RAM 节点。
访问管理界面
访问(http://172.17.32.9:15672)
使用用户名 admin 和密码 qyBegs0SeQ5b9H,确认所有节点出现在集群中。
检查日志
如果加入集群仍失败,查看日志:
容器日志
docker logs rabbitmq-node1
docker logs rabbitmq-node2
RabbitMQ日志
docker exec -it rabbitmq-node2 bash
cat /var/log/rabbitmq/rabbit@rabbitmq-node2.log
其他注意事项
时间同步
确保所有服务器时间同步:
sudo ntpdate pool.ntp.org
验证 Erlang 节点
确认 Erlang 节点名称
docker exec -it rabbitmq-node1 rabbitmqctl eval 'net_adm:names().'
应返回类似 {ok, [{"rabbitmq-node1", 4369}]}。
清理并重新部署
如果问题持续,删除容器和数据,重新部署
docker rm -f rabbitmq-node1 rabbitmq-node2 rabbitmq-node3
sudo rm -rf /data/rabbitmq/*
搭建 ZooKeeper
ZooKeeper 是一个分布式协调服务,广泛用于分布式系统,比如 Kafka、Hadoop 等
搭建方式:通过docker方式安装。(docker安装方式略)
准备 ZooKeeper 配置文件
ZooKeeper 集群需要一个配置文件来定义集群的节点。我们会在每台服务器上创建一个 zoo.cfg 文件,内容基本相同,但需要指定每台服务器的角色。
- 创建目录
在每台服务器上创建目录存放配置文件:mkdir -p /data/zookeeper/data mkdir -p /data/zookeeper/datalog chmod -R 777 /data/zookeeper chown -R 1000:1000 /data/zookeeper - 在每台服务器上创建 /data/zookeeper/data/myid 文件,用于标识 ZooKeeper 节点的 ID:
服务器 1(192.168.1.101):echo "1" > /data/zookeeper/data/myid 服务器 2(192.168.1.102):echo "2" > /data/zookeeper/data/myid 服务器 3(192.168.1.103):echo "3" > /data/zookeeper/data/myid - 在每台服务器上创建 /data/zookeeper/zoo.cfg 文件,内容如下:
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/zookeeper/data dataLogDir=/zookeeper/datalog clientPort=2181 admin.serverPort=8081 server.1=192.168.1.101:2888:3888 server.2=192.168.1.102:2888:3888 server.3=192.168.1.103:2888:3888解释
- tickTime:ZooKeeper 的基本时间单位(毫秒)。
- initLimit 和 syncLimit:控制节点间通信的超时时间。
- dataDir 和 dataLogDir:数据和日志存储目录(Docker 容器内路径)。
- clientPort:客户端连接 ZooKeeper 的端口。
- server.X:定义集群中的节点,格式是
server.<ID>=<IP>:<数据同步端口>:<选举端口>。
运行 ZooKeeper 容器
我们使用官方的 zookeeper Docker 镜像来启动服务。在每台服务器上运行以下命令,注意替换 myid 的值:
# 在海外服务器并打包保存下载
docker pull zookeeper:latest
docker save -o zookeeper.tar zookeeper:latest
sz zookeeper.tar
# 在大陆服务器
docker load -i zookeeper.tar
服务器1(ID=1):
docker run -d --name zookeeper \
--network host \
-v /data/zookeeper/data:/zookeeper/data \
-v /data/zookeeper/datalog:/zookeeper/datalog \
-v /data/zookeeper/zoo.cfg:/conf/zoo.cfg \
-e ZOO_MY_ID=1 \
zookeeper:latest
服务器2(ID=2):
docker run -d --name zookeeper \
--network host \
-v /data/zookeeper/data:/zookeeper/data \
-v /data/zookeeper/datalog:/zookeeper/datalog \
-v /data/zookeeper/zoo.cfg:/conf/zoo.cfg \
-e ZOO_MY_ID=2 \
zookeeper:latest
服务器3(ID=3):
docker run -d --name zookeeper \
--network host \
-v /data/zookeeper/data:/zookeeper/data \
-v /data/zookeeper/datalog:/zookeeper/datalog \
-v /data/zookeeper/zoo.cfg:/conf/zoo.cfg \
-e ZOO_MY_ID=3 \
zookeeper:latest
解释:
- -d:后台运行容器。
- –network host:使用主机网络模式,避免端口映射问题。
- -v:挂载本地目录到容器,持久化数据和配置文件。
- -e ZOO_MY_ID:设置 ZooKeeper 节点的 ID,与 myid 文件对应。
验证集群状态
检查容器是否正常运行:
docker ps
连接到任意一台服务器的 ZooKeeper 实例,检查集群状态:
docker exec -it zookeeper zkServer.sh status
输出会显示当前节点的角色(leader 或 follower)和集群状态。如果看到类似 Mode: leader 或 Mode: follower,说明集群正常运行!
也可以用 ZooKeeper 客户端测试连接:
docker run -it --rm zookeeper zkCli.sh -server 192.168.1.101:2181
进入 ZooKeeper 命令行后,输入 ls / 检查是否能正常访问。
搭建 kafka
什么是 Kafka?
Apache Kafka 是一个分布式流处理平台,简单来说,它是一个“消息中间件”,可以处理海量实时数据。想象 Kafka 像一个超级快递站:
- 生产者(Producer):把包裹(消息)送到快递站。
- 主题(Topic):包裹被分类放到不同的货架(比如“订单”、“日志”)。
- 消费者(Consumer):从货架取走包裹进行处理。
Kafka 的典型用途包括:
- 收集和传输日志(如服务器日志、用户点击数据)。
- 构建实时数据管道(比如从数据库到分析系统)。
- 实现事件驱动的微服务架构。
搭建 kafka 集群
0. 搭建集群前置条件
- 三台 CentOS 服务器:IP 分别为 172.17.0.15 \ 172.17.0.10 \ 172.17.16.7,已安装 Docker。
- ZooKeeper 集群已运行(也是在这3台服务器通过docker运行),端口 2181、2888 和 3888 已开放。
- 网络连通性:三台服务器之间网络可达,防火墙已配置好。
- 磁盘空间:Kafka 需要存储消息数据,建议每台服务器预留至少 10GB 磁盘空间。
1. 准备 Kafka 数据目录
Kafka 需要存储消息数据和日志,我们为每台服务器创建一个持久化目录。
在每台服务器上执行:
mkdir -p /data/kafka
chown 1001:1001 /data/kafka # 1001是bitnami镜像默认用户
2. 运行 Kafka 容器
载入镜像
我们使用官方的 bitnami/kafka 镜像来启动 Kafka 集群。
# 在海外服务器下载镜像并打包传到大陆服务器
docker pull bitnami/kafka:3.8
docker save -o kafka.tar bitnami/kafka:3.8
scp kafka.tar x.x.x.x:/usr/local/src/
# 把镜像传到大陆服务器并载入
docker load -i kafka.tar
运行容器
在每台服务器上运行以下命令,每台服务器都需要指定唯一的 broker.id,并配置 zookeeper 集群地址
服务器 1(172.17.0.15):
docker run -d --name kafka --network host \
-v /data/kafka:/bitnami/kafka \
-e KAFKA_BROKER_ID=1 \
-e KAFKA_CFG_ZOOKEEPER_CONNECT="172.17.0.15:2181,172.17.0.10:2181,172.17.16.7:2181" \
-e KAFKA_CFG_LISTENERS="PLAINTEXT://172.17.0.15:9092" \
-e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://172.17.0.15:9092" \
bitnami/kafka:3.8
服务器 2(172.17.0.10):
docker run -d --name kafka --network host \
-v /data/kafka:/bitnami/kafka \
-e KAFKA_BROKER_ID=2 \
-e KAFKA_CFG_ZOOKEEPER_CONNECT="172.17.0.15:2181,172.17.0.10:2181,172.17.16.7:2181" \
-e KAFKA_CFG_LISTENERS="PLAINTEXT://172.17.0.10:9092" \
-e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://172.17.0.10:9092" \
bitnami/kafka:3.8
服务器 3(172.17.16.7):
docker run -d --name kafka --network host \
-v /data/kafka:/bitnami/kafka \
-e KAFKA_BROKER_ID=3 \
-e KAFKA_CFG_ZOOKEEPER_CONNECT="172.17.0.15:2181,172.17.0.10:2181,172.17.16.7:2181" \
-e KAFKA_CFG_LISTENERS="PLAINTEXT://172.17.16.7:9092" \
-e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://172.17.16.7:9092" \
bitnami/kafka:3.8
解释:
- -d:后台运行容器。
- -v:挂载数据目录和配置文件到容器,持久化数据。
- 如果你的 Zookeeper 服务监听的不是 2181,请相应修改端口。
- KAFKA_CFG_ADVERTISED_LISTENERS 必须是本机在网络中的可访问地址(建议用实际 IP)。
- 如果服务器防火墙开启,请开放 9092、2181 端口。
- 生产环境建议配置 KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP、KAFKA_CFG_INTER_BROKER_LISTENER_NAME 等参数以增强安全性。
集群验证
1. 查看 Kafka Broker
在任意一台机器上进入容器:
docker exec -it kafka bash
使用 kafka-topics.sh 工具查看 broker 列表:
kafka-topics.sh --bootstrap-server 172.17.0.15:9092 --list
或通过 zookeeper 查询 broker:
kafka-broker-api-versions.sh --bootstrap-server 172.17.0.15:9092
2. 创建测试 Topic
创建一个名为 test-topic 的 Kafka 主题,有 3 个分区和 3 个副本。
kafka-topics.sh --create --topic test-topic \
--bootstrap-server 172.17.0.15:9092 \
--partitions 3 --replication-factor 3
含义说明
- kafka-topics.sh
Kafka 提供的主题管理工具脚本,可以用来创建、列出、删除、修改主题(topic)。 - –create
创建新的 topic。 - –topic test-topic
新建的 topic 名字叫 test-topic。 - –bootstrap-server 172.17.0.15:9092
指定 Kafka 集群的 broker 地址(IP:端口),用来连接集群。此地址必须是advertised.listeners 设置的那个 IP 和端口。 - –partitions 3
这个 topic 分为 3 个分区。分区越多,写入和消费的并发能力越强。 - –replication-factor 3
这个 topic 的数据有 3 份副本,也就是在集群的 3 个 broker 上各保存一份,增强容错能力。
3. 生产与消费消息
生产消息:
启动一个命令行界面,输入的每一行内容都会作为一条消息发送到 test-topic。
kafka-console-producer.sh --broker-list 172.17.0.15:9092 --topic test-topic
含义说明
- kafka-console-producer.sh
Kafka 提供的命令行生产者客户端,用来向指定 topic 发送消息。 - –broker-list 172.17.0.15:9092
指定 Kafka broker 的地址(IP:端口)。 - –topic test-topic
指定要发送消息的 topic 名称。
消费消息:
启动一个消费者,从 test-topic 读取消息,并在命令行实时显示出来。
kafka-console-consumer.sh --bootstrap-server 172.17.0.15:9092 --topic test-topic --from-beginning
含义说明
- kafka-console-consumer.sh
Kafka 提供的命令行消费者客户端,用来从指定 topic 消费消息。 - –bootstrap-server 172.17.0.15:9092
指定 Kafka broker 的地址(IP:端口)。 - –topic test-topic
指定要消费的 topic 名称。 - –from-beginning
表示从 topic 的第一条消息开始消费(否则只会消费启动后新产生的消息)。
常用命令
查看 topic 列表:
kafka-topics.sh --bootstrap-server 172.17.0.15:9092 --list
查看指定 topic 详情:
kafka-topics.sh --describe --topic test-topic --bootstrap-server 172.17.0.15:9092
ElasticSearch
0. 架构说明
- Filebeat:轻量级日志收集器,部署在每台需要收集日志的服务器上。Filebeat 读取日志文件(如应用日志、系统日志),并将日志发送到 Kafka 或直接发送到 Elasticsearch。
- Kafka:作为消息队列,接收 Filebeat 发送的日志数据,起到缓冲和解耦的作用。在上面的步骤中, Kafka 集群已经部署在三台服务器上,可以直接复用。
- Elasticsearch:分布式搜索和分析引擎,存储和索引日志数据,支持全文搜索和分析。Elasticsearch 集群将部署在三台服务器上,形成高可用分布式架构。
- Kibana:Elasticsearch 的可视化界面,用于展示和查询日志数据。Kibana 通常部署在一台服务器上,连接到 Elasticsearch 集群。
- ZooKeeper:Kafka 依赖的协调服务,上面已经部署好,可以继续使用。
数据流向:
- Filebeat 收集日志 → 发送到 Kafka(可选)或直接到 Elasticsearch。
- 如果使用 Kafka,日志从 Kafka 消费到 Elasticsearch(需要 Logstash 或 Kafka Connect)。
- Kibana 连接 Elasticsearch,展示日志数据。
# 架构图 `[应用服务器] -> Filebeat -> Kafka -> Logstash/Kafka Connect -> Elasticsearch -> Kibana` # 或者不通过kafka `[应用服务器] -> Filebeat -> Elasticsearch -> Kibana`
建议:
- 由于服务器资源有限(三台),建议 Filebeat 直接发送日志到 Elasticsearch,简化架构,减少资源占用。
- 如果需要 Kafka 的缓冲功能,可以使用 Logstash 或 Kafka Connect 将日志从 Kafka 传输到 Elasticsearch。
- Elasticsearch 和 Kibana 部署在 Docker 容器中,与 Kafka 和 ZooKeeper 保持一致,便于管理。
所需组件
- Elasticsearch:日志存储和搜索。
- Kibana:日志可视化。
- Filebeat:日志收集。
- Logstash 或 Kafka Connect(可选):如果通过 Kafka 传输日志,需要此组件。
- Docker 和 Docker Compose:用于部署和管理容器。
1. 安装步骤
规划集群
节点分配:
- 172.17.0.15:Elasticsearch 节点 1(主节点候选)、Kibana。
- 172.17.0.10:Elasticsearch 节点 2(主节点候选)。
- 172.17.16.7:Elasticsearch 节点 3(主节点候选)。
端口:
- Elasticsearch:9200(HTTP API)、9300(节点间通信)。
- Kibana:5601(Web 界面)。
- 存储:为 Elasticsearch 创建持久化存储卷,避免数据丢失。
配置服务器环境
在每台服务器上执行以下操作:
- 创建数据目录和设置权限:
sudo mkdir -p /data/elasticsearch/data sudo chmod -R 777 /data/elasticsearch/data - 调整系统参数
(Elasticsearch 对系统要求较高): 编辑 /etc/sysctl.conf,添加:vm.max_map_count=262144应用设置
sudo sysctl -w vm.max_map_count=262144 - 开放防火墙端口(如果启用防火墙):
sudo firewall-cmd --permanent --add-port=9200/tcp sudo firewall-cmd --permanent --add-port=9300/tcp sudo firewall-cmd --permanent --add-port=5601/tcp # 仅在 Kibana 节点 sudo firewall-cmd --reload
部署 Elasticsearch 集群
在每台服务器上创建 Docker Compose 文件,配置 Elasticsearch 集群。
-
在 172.17.0.15 创建 docker-compose.yml:
vim /data/elasticsearch/docker-compose.ymlversion: '3.8' services: elasticsearch1: image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0 container_name: elasticsearch1 environment: - node.name=es1 - cluster.name=es-cluster - discovery.seed_hosts=172.17.0.15,172.17.0.10,172.17.16.7 - cluster.initial_master_nodes=es1,es2,es3 - bootstrap.memory_lock=true - xpack.security.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 volumes: - /data/elasticsearch/data:/usr/share/elasticsearch/data network_mode: host kibana: image: docker.elastic.co/kibana/kibana:8.15.0 container_name: kibana environment: - ELASTICSEARCH_HOSTS=["http://172.17.0.15:9200","http://172.17.0.10:9200","http://172.17.16.7:9200"] depends_on: - elasticsearch1 network_mode: host -
在 172.17.0.10 创建 docker-compose.yml:
vim /data/elasticsearch/docker-compose.yml
version: '3.8'
services:
elasticsearch2:
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
container_name: elasticsearch2
environment:
- node.name=es2
- cluster.name=es-cluster
- discovery.seed_hosts=172.17.0.15,172.17.0.10,172.17.16.7
- cluster.initial_master_nodes=es1,es2,es3
- bootstrap.memory_lock=true
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /data/elasticsearch/data:/usr/share/elasticsearch/data
network_mode: host
- 在 172.17.16.7 创建 docker-compose.yml:
vim /data/elasticsearch/docker-compose.yml
version: '3.8'
services:
elasticsearch3:
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
container_name: elasticsearch3
environment:
- node.name=es3
- cluster.name=es-cluster
- discovery.seed_hosts=172.17.0.15,172.17.0.10,172.17.16.7
- cluster.initial_master_nodes=es1,es2,es3
- bootstrap.memory_lock=true
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /data/elasticsearch/data:/usr/share/elasticsearch/data
network_mode: host
-
启动 Elasticsearch 集群:
在每台服务器上依次执行:docker-compose up -d -
验证 Elasticsearch 集群状态:
访问任意节点的 HTTP API:curl http://172.17.0.15:9200/_cluster/health确保返回的 status 为 green 或 yellow,且 number_of_nodes 为 3。
-
验证kibana
访问 http://172.17.0.15:5601 的 Kibana Web 界面,确保能正常加载。
部署 Filebeat
在每台需要收集日志的服务器上部署 Filebeat。以下以 172.17.0.15 为例,其他服务器类似。
1. 创建 Filebeat 配置文件:
在 172.17.0.15 上创建 mkdir /data/filebeat && vim /data/filebeat/filebeat.yml:
filebeat.inputs:
- type: log
enabled: true
paths:
- /data/a/logs/*.log # 第一个日志目录
index: "aa-%{[agent.version]}-%{+yyyy.MM.dd}" # 自定义索引名称为 aa-<version>-<date>
- type: log
enabled: true
paths:
- /data/b/logs/*.log # 第二个日志目录
index: "bb-%{[agent.version]}-%{+yyyy.MM.dd}" # 自定义索引名称为 bb-<version>-<date>
output.elasticsearch:
hosts: ["172.17.0.15:9200", "172.17.0.10:9200", "172.17.16.7:9200"]
ilm.enabled: false # 禁用 ILM 以使用自定义索引名称
setup.kibana:
host: "172.17.0.15:5601"
setup.template.enabled: true
setup.template.name: "custom"
setup.template.pattern: "{aa-*,bb-*}"
配置说明
- 两个输入配置:
- 第一个 filebeat.inputs 收集 /data/a/logs/*.log 的日志,并指定索引名称为 aa-%{[agent.version]}-%{+yyyy.MM.dd}(例如 aa-8.15.0-2025.06.19)。
- 第二个 filebeat.inputs 收集 /data/b/logs/*.log 的日志,并指定索引名称为 bb-%{[agent.version]}-%{+yyyy.MM.dd}(例如 bb-8.15.0-2025.06.19)。
- index 字段允许为每个输入指定独立的索引名称。
- 禁用 ILM:
- output.elasticsearch.ilm.enabled: false 禁用了 Filebeat 的默认索引生命周期管理(ILM),因为 ILM 会强制使用 filebeat-* 样式的索引名称。禁用 ILM 后,Filebeat 会直接使用 index 字段指定的名称。
- 自定义索引模板:
- setup.template.enabled: true 启用自定义索引模板。
- setup.template.name: "custom" 和 setup.template.pattern: "{aa-,bb-}" 定义了一个名为 custom 的索引模板,匹配 aa- 和 bb- 索引。这确保 Elasticsearch 正确应用模板到你的自定义索引。
2. 创建 Filebeat 的 Docker Compose 文件:
创建 /data/filebeat/docker-compose.yml:
version: '3.8'
services:
filebeat:
image: docker.elastic.co/beats/filebeat:8.15.0
container_name: filebeat
volumes:
- /data/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/log:/var/log:ro
network_mode: host
创建网络(如果未自动创建):
docker network create es-net
3. 启动Filebeat
cd /data/filebeat
docker-compose up -d
在 172.17.0.10 和 172.17.16.7 上配置和启动 Filebeat,修改 filebeat.yml 中的日志路径为对应服务器的日志文件路径。
4. 初始化索引模板
初始化索引模板和仪表板: 在每台服务器上运行以下命令,确保 Filebeat 设置正确的索引模板:
docker exec filebeat filebeat setup --template
docker exec filebeat filebeat setup --dashboards
5. 配置kibana
打开 Kibana(http://172.17.0.15:5601)。
进入 Management -> Stack Management -> Index Patterns,创建索引模式(如 filebeat-*)。
进入 Discover,查看 Filebeat 收集的日志数据。
创建仪表板(Dashboard)或可视化(Visualize)以展示日志分析结果。
6. 验证和测试
-
检查 Elasticsearch:
curl http://172.17.0.15:9200/_cat/indices?v预期看到类似
aa-8.15.0-2025.06.19和bb-8.15.0-2025.06.19的索引。
登录 Kibana(http://172.17.0.15:5601) 在“Discover”页面选择 aa- 和 bb- 索引模式,确认日志数据正确显示。 -
检查 Kibana: 在 Kibana 的 Discover 页面,查看是否有日志数据。
-
检查 Filebeat: 查看 Filebeat 容器日志:
docker logs filebeat注意事项
- 资源分配:
Elasticsearch 和 Kafka 都消耗较多内存和 CPU。确保每台服务器有足够资源(建议至少 4GB 内存)。
调整 ES_JAVA_OPTS(如 -Xms2g -Xmx2g)根据实际内存大小。 - 安全性:
本示例禁用 Elasticsearch 的 X-Pack 安全功能(xpack.security.enabled=false)。生产环境中建议启用认证和 TLS。
配置防火墙,限制对 9200、9300、5601 端口的访问。 - 日志路径:
确保 Filebeat 挂载的日志路径正确,且容器有读权限。 - 版本兼容性:
确保 Elasticsearch、Kibana、Filebeat、Logstash 版本一致(本例使用 8.15.0)。
- 资源分配:
导入redis数据
ucloud可以在控制台备份redis数据(RDB备份)
下载备份文件后,上传到腾讯云主机
下载导入工具
wget https://redis-doc-2020-1254408587.cos.ap-guangzhou.myqcloud.com/redis-port.tgz
tar -zxvf redis-port.tgz
cd redis-port
./redis-restore dump.rdb -t 172.17.0.10:6379
XXL-JOB安装
在香港服务器传输xuxueli/xxl-job-admin:3.1.1镜像并导入到服务器
在服务器编辑docker-compose.yml文件
version: '3'
services:
xxl-job-admin:
image: xuxueli/xxl-job-admin:3.1.1
container_name: xxl_job_admin
restart: always
ports:
- "8311:8080"
environment:
PARAMS: "--spring.datasource.url=jdbc:mysql://172.17.32.16:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=jyb --spring.datasource.password=YHNBGT"
volumes:
- "./applogs:/data/applogs"
networks:
- xxl_job_net
networks:
xxl_job_net:
driver: bridge
运行容器
docker-compose up -d

评论(0)