Kubernetes Ingress 是集群流量的“守门员”,它提供了一种声明式的方式来管理外部用户对集群内部服务的访问。本文将聚焦于如何利用 Ingress Controller(以主流的 NGINX Ingress Controller 为例),通过七层(HTTP/HTTPS)路由规则,将来自不同域名的流量准确地导向集群内的不同服务。
1. Ingress 与七层负载均衡简介
传统的四层负载均衡(如 Service Type=LoadBalancer)仅基于 IP 和端口进行转发。而七层负载均衡(如 Ingress)则可以基于 HTTP 请求头中的信息(如 Host 字段、URL 路径等)进行更智能的路由决策。
当我们需要在同一个公网 IP 或端口上托管多个域名时(例如 api.domainA.com 和 web.domainB.com),Ingress 就是最理想的解决方案。
2. 准备工作
您需要一个运行中的 Kubernetes 集群,并且已经安装了 Ingress Controller。如果尚未安装,可以使用 Helm 快速部署 NGINX Ingress Controller:
# 假设您已配置好 Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install nginx-ingress ingress-nginx/ingress-nginx
# 确认 Ingress Controller 获得了外部 IP
kubectl get svc nginx-ingress-controller
# 记下EXTERNAL-IP,后续将用于DNS或/etc/hosts配置
3. 定义后端服务
我们创建两个简单的 Deployment 和配套 Service 来模拟两个不同的应用:app-a 和 app-b。
示例配置:services.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-a-deployment
spec:
selector:
matchLabels:
app: app-a
replicas: 1
template:
metadata:
labels:
app: app-a
spec:
containers:
- name: app-a
image: nginxdemos/hello:plain-text
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: service-a
spec:
selector:
app: app-a
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-b-deployment
spec:
selector:
matchLabels:
app: app-b
replicas: 1
template:
metadata:
labels:
app: app-b
spec:
containers:
- name: app-b
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: service-b
spec:
selector:
app: app-b
ports:
- port: 80
targetPort: 80
应用配置:
kubectl apply -f services.yaml
4. 创建 Ingress 资源实现多域名路由
现在,我们定义一个 Ingress 资源,它将负责将流量根据 Host 头部信息路由到对应的 Service。
路由规划:
* site-a.example.com -> service-a
* site-b.example.com -> service-b
示例配置:ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-ingress
annotations:
# 告诉 NGINX Ingress Controller 使用标准 HTTP 路由
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: site-a.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-a
port:
number: 80
- host: site-b.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-b
port:
number: 80
应用 Ingress 配置:
kubectl apply -f ingress.yaml
5. 验证配置
首先,确认 Ingress 资源已经成功创建,并关联到 Ingress Controller 的地址:
kubectl get ingress multi-domain-ingress
# ADDRESS 列应该显示 Ingress Controller 的外部 IP
假设 Ingress Controller 的 IP 是 192.168.1.100。
本地验证(推荐): 修改本地计算机的 /etc/hosts 文件(Windows 对应 C:\Windows\System32\drivers\etc\hosts),将 IP 映射到定义的域名:
# /etc/hosts 文件内容
192.168.1.100 site-a.example.com
192.168.1.100 site-b.example.com
测试结果:
- 访问 http://site-a.example.com:应该看到 service-a (nginxdemos/hello) 服务的响应,显示请求信息。
- 访问 http://site-b.example.com:应该看到 service-b (nginx:latest) 的默认欢迎页面。
通过上述配置,我们成功地利用同一个外部 IP 和 Ingress 资源,根据请求的域名(Host Header)实现了高效且灵活的七层负载均衡和流量分发。
汤不热吧