超详细ubuntu22.04部署k8s1.28高可用(二)【结合ingress实现业务高可用】
文章目录
- 超详细ubuntu22.04部署k8s1.28高可用(二)【结合ingress实现业务高可用】
- 一、业务高可用实现原理(Ingress篇)
-
- [1. Kubernetes中业务访问的本质](#1. Kubernetes中业务访问的本质)
- 二、环境准备
- 三、部署Ingress
-
- [1. 安装helm](#1. 安装helm)
- [2. 部署Ingress](#2. 部署Ingress)
- [3. 配置Nginx(192.168.24.35~36)](#3. 配置Nginx(192.168.24.35~36))
- [4. 配置Keepalived(192.168.24.35~36)](#4. 配置Keepalived(192.168.24.35~36))
- [5. 编写Nginx服务检测脚本(192.168.24.35~36)](#5. 编写Nginx服务检测脚本(192.168.24.35~36))
- 四、验证HA
-
- [1. 创建demo](#1. 创建demo)
- [2. 验证HA是否正常](#2. 验证HA是否正常)
- 总结
在上一篇《超详细 Ubuntu 22.04 部署 K8s 1.28 高可用(一)【多 Master + Keepalived + Nginx 实现负载均衡】》中,我们已经完成了 Kubernetes 控制平面的高可用部署:
- 通过多 Master + etcd 集群消除了控制平面的单点故障
- 使用 Keepalived + Nginx 为 kube-apiserver 提供统一的 VIP 访问入口
- 确保在任意单个 Master 或负载均衡节点故障时,集群 API 依然可用
但在真实生产环境中,仅仅保证控制平面高可用是远远不够的,真正承载业务流量的是运行在 Node 节点上的 Pod 和 Service,如果业务访问入口仍然是单点,那么即便 Kubernetes 集群本身是高可用的,业务依然可能因为入口故障而整体不可访问
本文将在上一篇高可用控制平面的基础之上,引入 Ingress 组件,构建一套 面向业务的高可用访问架构,主要包括:
- 使用 Deployment 多副本 保证业务 Pod 的运行高可用
- 通过 Service 对后端 Pod 进行统一抽象
- 使用 Ingress Controller 作为业务流量入口
- 结合 Ingress 规则 实现域名级别、路径级别的流量转发
一、业务高可用实现原理(Ingress篇)
在 Kubernetes 中,控制平面高可用和业务高可用是两个完全不同但又相互依赖的概念
- 控制平面高可用:解决的是 kube-apiserver、调度器、控制器是否可用
- 业务高可用:解决的是用户访问业务时,服务是否稳定、不中断
上一篇我们已经通过 VIP + Nginx + 多 Master,解决了集群能不能被正常管理的问题,而本篇要解决的是业务流量如何稳定进入集群的问题
1. Kubernetes中业务访问的本质
在 kubernetes 里,业务访问链路本质上是
bash
用户请求
↓
访问入口(IP / 域名)
↓
Service
↓
Pod(业务容器)
Ingress 的整体职责大致如下:
- 接收外部 HTTP / HTTPS 请求
- 根据 Ingress 规则进行转发
- 将流量交给对应的 Service
- Service 再将流量分发给后端多个 Pod
将上一篇的控制平面 VIP 和本篇的业务 Ingress 放在一起,整体就比较清晰了
bash
【控制平面流量】
kubectl / API 请求
↓
VIP(Keepalived)
↓
Nginx
↓
kube-apiserver(多 Master)
【业务流量】
用户 / 浏览器
↓
域名访问(如 https://www.hwj.com) #这里我没有真的域名,直接使用本机hosts解析到VIP
↓
DNS 解析
↓
VIP(Ingress 对外入口 IP)
↓
Ingress Controller Service
↓
Ingress Controller Pod(多副本)
↓
Service(业务 Service)
↓
业务 Pod(多副本)
二、环境准备
| 服务器 | 主机名 | IP地址 | 主要组件 |
|---|---|---|---|
| master-01 + etcd-01节点 | k8s-master-1 | 192.168.24.31 | apiserver controller-manager scheduler proxy etcd |
| master-02 + etcd-02节点 | k8s-master-2 | 192.168.24.32 | apiserver controller-manager scheduler proxy etcd |
| master-03 + etcd-03节点 | k8s-master-3 | 192.168.24.33 | apiserver controller-manager scheduler proxy etcd |
| node-01 节点 | k8s-node-1 | 192.168.24.34 | kubelet proxy(资源有限,本demo只使用一个node节点) |
| nginx + keepalive-01节点 | keepalived-1 | 192.168.24.35 | nginx keepalived(主) |
| nginx + keepalive-02节点 | keepalived-2 | 192.168.24.36 | nginx keepalived(备) |
三、部署Ingress
1. 安装helm
bash
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 查看 helm 版本
helm --version
2. 部署Ingress
bash
# 添加ingress-nginx仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 更新本地存储信息
helm repo update
# 搜索ingress-nginx安装包
helm search repo ingress-nginx
# 拉取ingress-nginx并解压
mkdir -p /root/kubernetes/helm
cd /root/kubernetes/helm
helm pull ingress-nginx/ingress-nginx --untar
# 编辑valus.yaml
vim /root/kubernetes/helm/ingress-nginx/values.yaml
#这里各位可能会存在拉不到registry.k8s.io官方源镜像的情况,找到以下红框并像我一样改成国内镜像源即可
sed -i "s/dnsPolicy: ClusterFirst/dnsPolicy: ClusterFirstWithHostNet/" values.yaml #修改dnsPolicy为ClusterFirstWithHostNet
sed -i "s/hostNetwork: false/hostNetwork: true/" values.yaml #修改hostNetwork为true
sed -i "s/kind: Deployment/kind: DaemonSet/" values.yaml #修改控制器种类为DaemonSet
sed -i "s/type: LoadBalancer/type: NodePort/" values.yaml #LoadBalancer修改为NodePort
#修改 http: "" 和 https: "" 为 30080 和 30443
# 部署ingress-nginx
cd /root/kubernetes/helm
helm install ingress ./ingress-nginx -n ingress-nginx --create-namespace
# 检查ingress-nginx服务
#我这里虽然用的Daemonset但是只有一个Pod是因为我只有一个node节点,没开启容忍,有需求自行开启即可(tolerations)
kubectl get pod -n ingress-nginx
kubectl get svc -n ingress-nginx




3. 配置Nginx(192.168.24.35~36)
bash
# 配置nginx
upstream ingress_http {
server 192.168.24.31:30080;
server 192.168.24.32:30080;
server 192.168.24.33:30080;
server 192.168.24.34:30080;
}
#upstream ingress_https {
# server 192.168.24.31:30443;
# server 192.168.24.32:30443;
# server 192.168.24.33:30443;
# server 192.168.24.34:30443;
#}
server {
listen 80;
server_name www.hwj.com; #这里没有真实域名,直接在本地配置hosts解析测试即可
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ingress_http;
}
}
#server {
# listen 443 ssl;
# server_name www.fjzhgd.com;
# ssl_certificate /etc/nginx/ssl/fjzhgd.crt;
# ssl_certificate_key /etc/nginx/ssl/fjzhgd.key;
# location / {
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_pass http://ingress_https;
# }
#}
# 重启nginx
nginx -t && nginx -s reload
4. 配置Keepalived(192.168.24.35~36)
bash
# 配置keepalived
vim /etc/keepalived/keepalived.conf (192.168.24.35)
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh" #脚本位置,用来检测nginx服务是否正常,不正常则停掉keepalived
}
vrrp_instance VI_2 {
state MASTER
interface ens160
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.24.40 #上一篇控制平面高可用使用的vip是24.30,这里使用24.40
}
track_script {
check_nginx
}
}
vim /etc/keepalived/keepalived.conf (192.168.24.36)
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh"
}
vrrp_instance VI_2 {
state BACKUP
interface ens160
virtual_router_id 52
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.24.40
}
track_script {
check_nginx
}
}
# 重启keepalived
systemctl restart keepalived
# 查看VIP是否生效
ip a

5. 编写Nginx服务检测脚本(192.168.24.35~36)
用来检测 nginx 服务是否正常,不正常则停掉 keepalived
bash
vim /etc/nginx/check_nginx.sh
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
systemctl stop keepalived
fi
# 授予执行权限
chmod +x /etc/nginx/check_nginx.sh
四、验证HA
1. 创建demo
这里我们要测试的是,当我们在网页上访问 www.hwj.com 时,能否正常访问到这个 demo pod,以及当我们停掉 192.168.24.35 这台服务器时,192.168.24.36 这台服务器是否能看到虚拟 IP 漂移,以及访问页面是否依然正常
yaml
# 创建测试目录
mkdir -p /root/kubernetes/demo
# 编写deployment文件
vim /root/kubernetes/demo/demo-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 2
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: hashicorp/http-echo #这里拉不到镜像的话自行找台能上外网的服务器拉镜像传到harbor,不再赘述
args:
- "-text=Hello K8s HA!"
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: demo-svc
spec:
selector:
app: demo
ports:
- port: 80
targetPort: 5678
type: ClusterIP
# 编写demo-ingress规则文件
vim /root/kubernetes/demo/demo-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: www.hwj.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 80
# 运行demo pod
cd /root/kubernetes/demo && kubectl apply -f .
# 验证部署成功
kubectl get pod -n default
kubectl get svc -n default

2. 验证HA是否正常
这里先配置主机hosts,解析到 VIP 192.168.24.40,使用本机 ping 域名能通表示解析成功


接着打开浏览器访问 http://www.hwjnb.com/api,可以看到能正常访问到服务

接下来我们验证高可用,模拟 192.168.24.35 这台 nginx 服务器挂掉,是否还能正常访问服务
bash
# 模拟192.168.24.35 nignx 挂掉
#查看 keepalived 状态
systemctl status keepalived
#停掉 nginx
nginx -s stop
#再次查看 keepalived 状态
systemctl statut keepalived
#查看虚拟IP是否已经消失
ip a

经过测试可以看到,我们停掉了 192.168.24.35 这台服务器的 nginx,keepalived 也会随之关闭,然后我们再去 192.168.24.36 这台观察虚拟 IP 是否漂移,以及服务是否正常,经实验可以看到,虚拟 IP 漂移到了 24.36 这台服务器,业务访问依旧正常,至此,业务高可用测试完毕


总结
本文在已实现 Kubernetes 控制平面高可用的基础上,围绕业务访问入口,完整搭建了一套 Ingress 级别的业务高可用方案,通过 Ingress Controller 多副本 + Service 负载 + Nginx + Keepalived VIP 漂移,将业务访问入口从单点解耦出来,实现稳定、可切换、可扩展的访问链路
整体业务流量路径为:域名 → VIP → Nginx → Ingress → Service → Pod,在入口节点或 Ingress 实例发生故障时,业务流量可自动切换,访问不中断
该方案无需依赖云厂商负载均衡,适用于内网、私有化部署及生产环境,至此,集群已同时具备控制平面高可用 + 业务入口高可用的核心能力