一、项目规划
1. 环境拓扑(IP / 角色 / 核心组件)
| 虚拟机 IP | 主机名 | 角色 | 核心组件 | 备注 |
|---|---|---|---|---|
| 192.168.198.160 | k8s-master | K8s 主控节点 + Keepalived 主节点 | K8s(master)、Keepalived | 已有 K8s 集群主控节点 |
| 192.168.198.161 | k8s-node01 | K8s 工作节点 + Keepalived 备节点 | K8s(node)、Keepalived | 已有 K8s 集群工作节点 |
| 192.168.198.162 | k8s-node02 | K8s 工作节点 | K8s(node) | 已有 K8s 集群工作节点 |
| 虚拟 IP(VIP) | - | 集群统一入口 | Keepalived | 192.168.198.200 |
2. 核心目标
- 基于已有 Docker+K8s 集群,构建自定义 Nginx 镜像(含企业级网页);
- 实现 Nginx 多副本跨节点部署,通过 K8s 探针完成故障自动恢复;
- 部署 Keepalived 实现 VIP 漂移,解决集群入口单点故障;
- 验证负载均衡、容灾容错、故障快速恢复能力。
注意:需要自行提前绑定好VIP和拷贝kubectl,让节点161也能执行kubectl命令
二、部署高可用 Nginx
1. 准备自定义 HTML 文件(主节点)
bash
# 创建ConfigMap存储HTML内容(企业级页面示例)
cat > nginx-index.html << EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>企业级高可用Nginx - K8s部署</title>
<style>
body {
font-family: "Microsoft YaHei", sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background-color: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
text-align: center;
}
h1 {
color: #2c3e50;
margin-bottom: 20px;
}
p {
color: #666;
font-size: 16px;
line-height: 1.6;
}
.footer {
margin-top: 30px;
font-size: 14px;
color: #999;
}
</style>
</head>
<body>
<div class="container">
<h1>🎉 企业级高可用Nginx服务</h1>
<p>部署环境:Kubernetes集群 (CentOS Stream 8)</p>
<p>集群节点:192.168.198.160-162</p>
<p>镜像源:阿里云Docker镜像仓库</p>
<div class="footer">© 2025 云原生实战项目</div>
</div>
</body>
</html>
EOF
# 创建ConfigMap(将HTML文件挂载到Nginx容器)
kubectl create configmap nginx-html --from-file=nginx-index.html=/root/nginx-index.html
2. 编写 Nginx 高可用部署文件(主节点)
bash
cat > nginx-ha.yaml << EOF
# 1. Deployment:保证Pod数量和高可用
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 3 # 3个副本,实现Pod级高可用
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate: # 滚动更新,避免服务中断
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24-alpine # 轻量级镜像
ports:
- containerPort: 80
resources: # 资源限制,避免资源抢占
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
volumeMounts:
- name: nginx-html-volume # 挂载自定义HTML
mountPath: /usr/share/nginx/html/index.html
subPath: nginx-index.html
livenessProbe: # 存活探针:检测容器是否存活
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe: # 就绪探针:检测容器是否可提供服务
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
lifecycle: # 优雅停止
preStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
volumes:
- name: nginx-html-volume
configMap:
name: nginx-html
---
# 2. Service:NodePort类型,对外暴露服务
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
selector:
app: nginx
type: NodePort # 所有节点暴露端口,实现节点级高可用
ports:
- port: 80 # Service端口
targetPort: 80 # Pod端口
nodePort: 30080 # 节点暴露端口(30000-32767)
sessionAffinity: None # 关闭会话亲和性,负载均衡
---
# 3. HPA:自动扩缩容(可选,根据负载调整副本数)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 3 # 最小副本数
maxReplicas: 6 # 最大副本数
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU使用率超过70%自动扩容
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80 # 内存使用率超过80%自动扩容
EOF
3. 部署 Nginx(主节点)
bash
# 应用部署文件
kubectl apply -f nginx-ha.yaml
# 验证部署
kubectl get deployments # 查看Deployment状态
kubectl get pods # 查看Pod状态(应为3个Running)
kubectl get svc # 查看Service(NodePort为30080)
kubectl get hpa # 查看HPA(自动扩缩容配置)
三、部署 Keepalived 实现 VIP 漂移(160/161节点)
1. 安装 Keepalived(160 主 / 161备节点)
yum install -y keepalived
2. 主节点(160)Keepalived 配置
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
router_id K8S_MASTER_160
script_user root
enable_script_security
}
# 健康检查:检测K8s和Nginx可用性
vrrp_script check_nginx_k8s {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -30
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33 # 替换为实际网卡名(ip addr查看)
virtual_router_id 55
priority 120 # 主节点优先级更高
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.198.200/24 # VIP地址
}
track_script {
check_nginx_k8s
}
nopreempt # 关闭抢占,避免频繁切换
preempt_delay 10
}
EOF
3. 备节点(161)Keepalived 配置
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
router_id K8S_WORKER_161
script_user root
enable_script_security
}
vrrp_script check_nginx_k8s {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -30
fall 2
rise 1
}
vrrp_instance VI_1 {
state BACKUP
interface ens33 # 与主节点一致
virtual_router_id 55
priority 100 # 优先级低于主节点
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.198.200/24
}
track_script {
check_nginx_k8s
}
nopreempt
}
EOF
4. 创建健康检查脚本(160/161 节点)
cat > /etc/keepalived/check_nginx.sh << EOF
#!/bin/bash
# 1. 检测kubelet是否运行
if [ "\$(systemctl is-active kubelet)" != "active" ]; then
exit 1
fi
# 2. 检测Nginx Pod是否正常运行(至少2个Ready)
POD_READY=\$(kubectl get pods -l app=nginx -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' | grep -c "True")
if [ \$POD_READY -lt 2 ]; then
exit 1
fi
# 3. 检测VIP访问Nginx是否正常
curl -s --connect-timeout 3 http://192.168.198.200:30080 > /dev/null
if [ \$? -ne 0 ]; then
exit 1
fi
exit 0
EOF
# 添加执行权限
chmod +x /etc/keepalived/check_nginx.sh
# 测试脚本(返回0为正常)
/etc/keepalived/check_nginx.sh
echo $?
5. 启动 Keepalived(160/161节点)
cpp
# 启动并设置开机自启
systemctl start keepalived
systemctl enable keepalived
# 验证状态
systemctl status keepalived
# 主节点查看VIP绑定
ip addr show ens33 # 应看到192.168.198.200/24
四、高可用验证
1. 访问 Nginx 服务
bash
# 访问任意节点的30080端口
curl http://192.168.198.160:30080
# 或浏览器访问:http://192.168.198.161:30080、http://192.168.198.162:30080
2. Pod 级高可用验证
bash
# 删除一个Pod,验证自动重建
kubectl delete pod <nginx-pod-name>
# 查看Pod重建状态
kubectl get pods -w
3. 节点级高可用验证
bash
# 关闭其中一个工作节点(如192.168.198.161)
ssh root@192.168.198.161 "systemctl stop kubelet docker"
# 验证仍可通过其他节点访问Nginx
curl http://192.168.198.162:30080
4.负载均衡能力
bash
# 多次访问VIP,查看访问不同Pod
for i in {1..10}; do
curl -s http://192.168.198.200:30080 | grep "Pod" # 实际可通过日志验证
kubectl logs -l app=nginx --tail=1 # 查看每个Pod的访问日志
done
5.VIP漂移
bash
# 主节点(160)停掉Keepalived
systemctl stop keepalived
# 查看主节点VIP消失
ip addr show ens33 | grep 192.168.198.200 # 无输出
# 备节点(161)查看VIP绑定
ip addr show ens33 | grep 192.168.198.200 # 有输出
# 验证VIP访问
curl http://192.168.198.200:30080 # 正常访问,无中断
# 恢复主节点Keepalived
systemctl start keepalived
# 验证VIP回迁(nopreempt模式下需备节点故障才回迁)
五、日常运维命令
1. 查看 Nginx 日志
bash
kubectl logs <nginx-pod-name>
2. 更新 Nginx HTML 内容
cpp
# 修改HTML文件后,更新ConfigMap
kubectl create configmap nginx-html --from-file=nginx-index.html=/root/nginx-index.html -o yaml --dry-run=client | kubectl apply -f -
# 重启Pod(使ConfigMap生效)
kubectl rollout restart deployment nginx-deployment
3. 滚动更新 Nginx 镜像
bash
# 修改Deployment的镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.25-alpine
# 查看更新状态
kubectl rollout status deployment/nginx-deployment