
在微服务和容器化盛行的今天,企业级运维已从“脚本化 + 人工巡检”迈向“自动化 + 可观测 + 高可用”的体系化建设。一个典型的业务系统背后,往往需要承载:
本文基于一套真实的运维架构实践,整合 Prometheus + Docker + Jenkins + ZooKeeper + Nginx + Keepalived + LVS + Kafka 八大组件,手把手搭建一个高可用、可扩展的自动化运维平台。无论你是运维新人还是架构师,都能从中获得实战经验。
┌─────────────────────────────────────────────┐
│ 用户访问 │
└──────────────────┬──────────────────────────┘
│
┌──────────────────▼──────────────────────────┐
│ LVS (VIP) + Keepalived (主备) │
│ 四层负载均衡,提供VIP高可用 │
└──────────────────┬──────────────────────────┘
│
┌──────────────────▼──────────────────────────┐
│ Nginx 集群 (多节点) │
│ 七层反向代理,SSL终结,路由分发 │
└──────────────────┬──────────────────────────┘
│
┌─────────────────────────────┼─────────────────────────────┐
│ │ │
┌─────────▼─────────┐ ┌────────────▼────────────┐ ┌─────────▼─────────┐
│ Web应用容器 │ │ Kafka 集群 │ │ Jenkins 构建 │
│ (Docker) │ │ (生产/消费消息) │ │ (CI/CD流水线) │
└─────────┬─────────┘ └────────────┬────────────┘ └─────────┬─────────┘
│ │ │
│ ┌─────────▼─────────┐ │
│ │ ZooKeeper 集群 │ │
│ │ (协调Kafka) │ │
│ └───────────────────┘ │
│ │
└──────────────────────┬────────────────────────────────────┘
│
┌────────────▼────────────┐
│ Prometheus + AlertManager │
│ 监控所有组件 & 告警 │
└─────────────────────────────┘组件 | 角色 | 关键能力 |
|---|---|---|
LVS + Keepalived | 四层负载均衡 + 高可用 | 提供虚拟IP(VIP),将流量分发至Nginx节点,Keepalived实现主备切换 |
Nginx | 七层反向代理 | 根据URL路径或域名路由到后端服务,可做SSL卸载、限流、缓存 |
ZooKeeper | 分布式协调服务 | 管理Kafka broker元数据、controller选举,也可用于其他分布式锁 |
Kafka | 分布式消息队列 | 异步解耦、日志收集、事件驱动,支持高吞吐持久化 |
Jenkins | CI/CD引擎 | 代码构建、镜像打包、自动化部署至Docker环境 |
Docker | 容器运行时 | 封装应用及依赖,实现环境一致性,便于扩缩容 |
Prometheus | 监控与告警 | 拉取各组件metrics,配合AlertManager发送告警 |
NodeExporter | 主机监控 | 采集系统CPU、内存、磁盘等基础指标 |
我们使用 7 台虚拟机(CentOS 7.9/Ubuntu 20.04,本文以 CentOS 为例),IP 分配如下:
主机名 | IP 地址 | 角色 |
|---|---|---|
lb-master | 192.168.10.10 | LVS + Keepalived(主) |
lb-backup | 192.168.10.11 | LVS + Keepalived(备) |
nginx-1 | 192.168.10.20 | Nginx 节点1 |
nginx-2 | 192.168.10.21 | Nginx 节点2 |
app-1 | 192.168.10.30 | Docker 应用节点1 |
app-2 | 192.168.10.31 | Docker 应用节点2 |
monitor | 192.168.10.40 | Prometheus + AlertManager + Grafana(可选) |
middleware | 192.168.10.50 | ZooKeeper + Kafka 集群(可部署3台,此处简化为1台或2台,生产建议3台) |
为简化演示,ZooKeeper+Kafka 可部署在 middleware 单机(伪集群),或使用多台。本文采用 3 台 ZK + 3 台 Kafka 做高可用,但篇幅所限,仅给出关键配置,单机可类比。
所有节点执行:
# 关闭防火墙与 SELinux
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 更新系统
yum update -y
# 安装常用工具
yum install -y vim wget curl net-tools telnet在 3 台 ZK 节点(例如 192.168.10.50~52)执行:
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.3/apache-zookeeper-3.8.3-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.3-bin.tar.gz -C /usr/local/
mv /usr/local/apache-zookeeper-3.8.3-bin /usr/local/zookeeper创建数据目录:mkdir -p /data/zookeeper
编辑 /usr/local/zookeeper/conf/zoo.cfg:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
server.1=192.168.10.50:2888:3888
server.2=192.168.10.51:2888:3888
server.3=192.168.10.52:2888:3888每台节点创建 myid 文件(内容分别为 1,2,3):
echo 1 > /data/zookeeper/myid # 在 10.50 上/usr/local/zookeeper/bin/zkServer.sh start
/usr/local/zookeeper/bin/zkServer.sh status # 查看角色在三台 Kafka 节点(可与 ZK 同机)下载:
wget https://downloads.apache.org/kafka/3.6.0/kafka_2.13-3.6.0.tgz
tar -zxvf kafka_2.13-3.6.0.tgz -C /usr/local/
mv /usr/local/kafka_2.13-3.6.0 /usr/local/kafka编辑 /usr/local/kafka/config/server.properties,关键配置:
broker.id=1 # 三台分别设为 1,2,3
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://192.168.10.50:9092 # 根据本机IP修改
zookeeper.connect=192.168.10.50:2181,192.168.10.51:2181,192.168.10.52:2181
log.dirs=/data/kafka-logs
num.partitions=3
default.replication.factor=2/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
# 创建测试 topic
/usr/local/kafka/bin/kafka-topics.sh --create --bootstrap-server 192.168.10.50:9092 --topic test --partitions 3 --replication-factor 2
# 生产消费测试
/usr/local/kafka/bin/kafka-console-producer.sh --bootstrap-server 192.168.10.50:9092 --topic test
/usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server 192.168.10.50:9092 --topic test --from-beginning在 lb-master 和 lb-backup 上安装:
yum install -y ipvsadm keepalived编辑 /etc/keepalived/keepalived.conf(主节点):
global_defs {
router_id LVS_MASTER
}
vrrp_instance VI_1 {
state MASTER # 备机为 BACKUP
interface eth0 # 网卡名
virtual_router_id 51
priority 100 # 备机降低,如90
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.10.100/24 dev eth0 label eth0:0
}
}
virtual_server 192.168.10.100 80 {
delay_loop 6
lb_algo rr # 轮询
lb_kind DR # 直接路由模式
protocol TCP
real_server 192.168.10.20 80 {
weight 1
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 2
}
}
real_server 192.168.10.21 80 {
weight 1
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 2
}
}
}启动 Keepalived:systemctl start keepalived,此时 VIP 192.168.10.100 会在主节点生效。
在 nginx-1 和 nginx-2 上安装 Nginx:
yum install -y nginx配置 /etc/nginx/nginx.conf,添加 upstream 和 server:
upstream backend {
server 192.168.10.30:8080 weight=1;
server 192.168.10.31:8080 weight=1;
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}启动 Nginx:systemctl start nginx。
注意:LVS DR 模式需要 Nginx 节点忽略 ARP 响应 VIP,并在 lo 上配置 VIP(但此处 VIP 在 LVS 主机,Nginx 只需监听真实 IP 的 80 端口即可,LVS 会将请求转发至 real_server 的 eth0 IP)。
所有 app 节点执行:
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker && systemctl enable docker编写一个简单的 Flask 应用(或使用现成 nginx:alpine 做演示),这里用 Dockerfile 构建一个返回主机名的应用:
FROM python:3.9-alpine
RUN pip install flask
COPY app.py /app.py
CMD ["python", "/app.py"]app.py:
import socket
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return f"Hello from {socket.gethostname()}\n"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)构建并运行:
docker build -t webapp:v1 .
docker run -d -p 8080:8080 --name webapp1 webapp:v1在另一台节点运行类似容器(或使用不同主机名)。此时通过 Nginx 访问 VIP 即可看到轮询效果。
# 安装 Java
yum install -y java-11-openjdk-devel
# 安装 Jenkins
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
yum install -y jenkins
systemctl start jenkins
systemctl enable jenkins访问 http://jenkins_ip:8080,按提示完成初始化。
安装插件:Docker Pipeline, Git, Kubernetes(可选)等。
创建 Jenkinsfile(在代码仓库根目录):
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'harbor.example.com'
APP_NAME = 'webapp'
}
stages {
stage('Checkout') {
steps { git 'https://github.com/yourrepo/webapp.git' }
}
stage('Build Docker Image') {
steps {
script {
docker.build("${APP_NAME}:${BUILD_NUMBER}")
}
}
}
stage('Push Image') {
steps {
script {
docker.withRegistry("https://${DOCKER_REGISTRY}", 'harbor-cred') {
docker.image("${APP_NAME}:${BUILD_NUMBER}").push()
docker.image("${APP_NAME}:${BUILD_NUMBER}").push('latest')
}
}
}
}
stage('Deploy') {
steps {
script {
// 这里可以调用 ansible 或 ssh 远程执行 docker run
sh '''
ssh app-1 "docker pull ${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER} && docker stop webapp || true && docker rm webapp || true && docker run -d -p 8080:8080 --name webapp ${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
ssh app-2 "docker pull ${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER} && docker stop webapp || true && docker rm webapp || true && docker run -d -p 8080:8080 --name webapp ${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
'''
}
}
}
}
}这样,每次代码提交都会触发构建、推送镜像、滚动更新应用容器。
在 monitor 节点:
wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
tar -zxvf prometheus-2.48.0.linux-amd64.tar.gz -C /usr/local/
mv /usr/local/prometheus-2.48.0.linux-amd64 /usr/local/prometheus创建 systemd service,配置 /usr/local/prometheus/prometheus.yml:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets:
- '192.168.10.10:9100'
- '192.168.10.20:9100'
- '192.168.10.30:9100'
- '192.168.10.40:9100'
- '192.168.10.50:9100'
- job_name: 'nginx'
static_configs:
- targets: ['192.168.10.20:9113', '192.168.10.21:9113'] # nginx-vts-exporter
- job_name: 'kafka'
static_configs:
- targets: ['192.168.10.50:9308'] # kafka-exporter
- job_name: 'jenkins'
metrics_path: '/prometheus'
static_configs:
- targets: ['192.168.10.40:8080']nginx-module-vts,或使用 nginx-prometheus-exporter 读取 stub_status。Prometheus Metrics 插件,暴露 /prometheus。下载 AlertManager,配置 alertmanager.yml:
route:
group_by: ['alertname']
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'ops@example.com'
from: 'alert@example.com'
smarthost: 'smtp.example.com:587'
auth_username: 'user'
auth_password: 'pass'在 Prometheus 中配置 alert rules,例如主机 CPU 过高:
groups:
- name: host_alerts
rules:
- alert: HighCPU
expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU usage over 80%"启动 Prometheus 和 AlertManager,并配置 Grafana 展示(可选)。
http://192.168.10.100(VIP),页面应交替显示 Hello from <hostname>,证明 LVS 将请求转发至不同 Nginx,Nginx 再负载均衡到后端容器。lb-master 的 Keepalived,VIP 自动漂移至 lb-backup,业务不中断。在 Prometheus 中执行查询 node_cpu_seconds_total,能看到所有节点数据;配置 Grafana 面板,展示系统负载、Nginx 请求量、Kafka 消息积压等。
修改 app.py 并推送到 Git,Jenkins 自动构建新镜像,部署到两台 app 节点,刷新页面即看到新版本内容。
编写一个生产者应用,发送消息到 Kafka topic,消费者消费并打印。同时 Prometheus 抓取 Kafka Exporter 的 kafka_consumergroup_lag,当积压过大时触发告警。
kill -9 keepalived 后,VIP 切换 < 3s。--restart=always 策略,或通过 systemd 管理容器。通过本次实践,我们成功搭建了一个覆盖 流量接入(LVS+Nginx)、高可用(Keepalived)、消息中间件(Kafka+ZK)、容器化部署(Docker)、自动化交付(Jenkins)、监控告警(Prometheus) 的全栈运维平台。各个组件协同工作,实现了:
企业级运维没有“银弹”,这套架构可以根据实际业务规模裁剪或扩展。希望本文能为你提供一份可落地的参考,欢迎在评论区交流讨论。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。