K8s进阶之初识Ingress
概述
Service对集群之外暴露服务的主要方式有两种:NotePort和LoadBalancer,但是这两种方式,都有一定的缺点:
- NodePort方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就愈发明显
- LB方式的缺点是每个service需要一个LB,浪费、麻烦,并且需要kubernetes之外设备的支持
基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个Service的需求。工作机制大致如下图表示:
实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:
- ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则
- ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy等等
Ingress的工作原理如下:
- 用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
- Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
- Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
- 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则
Ingress-nginx介绍
项目地址:https://github.com/kubernetes/ingress-nginx
文档教程:https://kubernetes.github.io/ingress-nginx/
ingress-nginx
是 Kubernetes
的 Ingress
控制器,使用NGINX
作为反向代理和负载均衡器。
部署MetalLB
参考这篇文章:K8s进阶之MetalLB实现LoadBalancer
部署Ingress-nginx
选择版本
我的k8s版本是1.26,所以我选择v1.11.6版本
部署方式
Ingress-nginx部署方式有三种,分别是Helm
、kubectl
以及使用第三方插件的方式进行安装。
基于kubectl
进行部署
# 下载配置文件
[root@master01 ~/ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.6/deploy/static/provider/cloud/deploy.yaml
# 将ingress-nginx-controller的类型修改为LoadBalancer(原来为LoadBalancer,以防万一)
[root@master01 ~/ingress]# sed -i s#NodePort#LoadBalancer#g deploy.yaml
# 开始部署应用
[root@master01 ~/ingress]# kubectl apply -f deploy.yaml
# 检查资源
[root@master01 ~/ingress]# kubectl get all -n ingress-nginx
# pod资源
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-p87gx 0/1 Completed 0 10m
pod/ingress-nginx-admission-patch-87g8d 0/1 Completed 2 10m
pod/ingress-nginx-controller-58554b9b99-x8gdr 1/1 Running 0 10m
# service资源
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.96.3.174 10.0.0.150 80:32543/TCP,443:32705/TCP 3m30s
service/ingress-nginx-controller-admission ClusterIP 10.96.1.131 <none> 443/TCP 3m30s
# deployment资源
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 10m
# replicaSet资源
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-58554b9b99 1 1 1 10m
# job资源
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 18s 10m
job.batch/ingress-nginx-admission-patch 1/1 28s 10m
上述资源解释
Pods
-
ingress-nginx-admission-create
类型:Job 创建的 Pod(已完成)
作用:初始化 Ingress Nginx 的准入控制器配置,例如创建验证 Webhook 所需的证书和配置。完成后自动退出(状态为 Completed)。 -
ingress-nginx-admission-patch
类型:Job 创建的 Pod(已完成)
作用:修补 Ingress Nginx 控制器的配置,确保它能正确与准入控制器通信。完成后自动退出。 -
ingress-nginx-controller
类型:Deployment 管理的 Pod(运行中)
核心作用:作为 Ingress 控制器,负责监听 Kubernetes Ingress 资源的变化,并根据规则将外部流量路由到集群内的服务。
工作方式:通过 NodePort 或 LoadBalancer 类型的 Service 暴露到集群外部。
service
ingress-nginx-controller
- 类型:NodePort(原为 LoadBalance)
- 作用:将 Ingress 控制器暴露到集群外部。
- 80:32055/TCP:HTTP 端口,外部请求通过节点的 32055 端口转发到控制器的 80 端口。
- 443:32405/TCP:HTTPS 端口,外部请求通过节点的 32405 端口转发到控制器的 443 端口。
- 注意:在裸机环境中,LoadBalancer 类型的 Service 无法自动分配外部 IP,需手动配置(如使用 MetalLB)或切换为 NodePort。
ingress-nginx-controller-admission
- 类型:ClusterIP
- 作用:作为准入控制器的内部通信端点,用于验证和校验 Ingress 资源的创建或更新请求(通过 Webhook)。
Jobs
ingress-nginx-admission-create
- 作用:创建准入控制器所需的证书和配置,确保 Ingress 资源验证的安全性。
- 状态:COMPLETIONS 1/1 表示任务已成功完成。
ingress-nginx-admission-patch
- 作用:修补 Ingress 控制器的配置,确保其与准入控制器正确集成。
- 状态:COMPLETIONS 1/1 表示任务已成功完成。
创建ingress的资源配置文件详解
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: comprehensive-ingress
namespace: default
annotations:
# 基础配置
kubernetes.io/ingress.class: "nginx" # 指定 Ingress 控制器
nginx.ingress.kubernetes.io/ssl-redirect: "true" # 强制 HTTPS 重定向
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # 即使无 TLS 也重定向
nginx.ingress.kubernetes.io/proxy-body-size: "50m" # 请求体大小限制
# 性能优化
nginx.ingress.kubernetes.io/proxy-read-timeout: "180" # 代理读取超时
nginx.ingress.kubernetes.io/proxy-send-timeout: "180" # 代理发送超时
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" # 代理缓冲区大小
# 安全配置
nginx.ingress.kubernetes.io/enable-cors: "true" # 启用 CORS
nginx.ingress.kubernetes.io/cors-allow-origin: "*" # CORS 允许源
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS" # CORS 允许方法
# 会话亲和性(Sticky Session)
nginx.ingress.kubernetes.io/affinity: "cookie" # 基于 Cookie 的会话亲和性
nginx.ingress.kubernetes.io/session-cookie-name: "route" # 会话 Cookie 名称
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1" # 会话 Cookie 哈希算法
# 负载均衡策略
nginx.ingress.kubernetes.io/load-balance: "round_robin" # 轮询负载均衡
# nginx.ingress.kubernetes.io/load-balance: "ip_hash" # IP 哈希负载均衡
# 自定义 Nginx 配置
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
spec:
ingressClassName: nginx # 指定 Ingress 类(与 annotation 作用相同)
# TLS 配置(HTTPS)
tls:
- hosts:
- www.example.com # 域名
- api.example.com
secretName: example-tls-secret # 存储 TLS 证书的 Secret 名称
# 路由规则
rules:
- host: www.example.com
http:
paths:
# 静态资源路径
- path: /static
pathType: Prefix
backend:
service:
name: static-service
port:
number: 80
# 应用主页路径
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 8080
- host: api.example.com
http:
paths:
# API 网关路径
- path: /v1
pathType: Prefix
backend:
service:
name: api-gateway-service
port:
number: 8081
# 特殊路径 - 重写配置
- path: /legacy(/|$)(.*)
pathType: Prefix
backend:
service:
name: legacy-service
port:
number: 8082
# 路径重写:移除 /legacy 前缀
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
# 特殊路径 - 自定义超时
- path: /long-running
pathType: Prefix
backend:
service:
name: batch-service
port:
number: 8083
# 为特定路径设置更长的超时时间
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
# 默认后端(当所有规则都不匹配时)
defaultBackend:
service:
name: default-service
port:
number: 80
pathType规则
在 Kubernetes Ingress
中,pathType
是一个关键配置项,用于定义路径匹配的方式。
path其中pathType
字段有三个值:
- Exact:精确匹配整个路径,区分大小写,不考虑查询参数。
- Prefix:前缀匹配路径,会递归检查子路径,但必须以指定路径开头。
- ImplementationSpecific:由 Ingress 控制器自行决定匹配方式,不同控制器可能有不同实现,Nginx Ingress 控制器将其视为 Prefix 类型
路径匹配优先级规则
- Exact 类型优先于 Prefix 类型:
如果存在/api(Prefix)
和/api/users(Exact)
,则/api/users
请求会匹配到Exact
规则。 - 较长的 Prefix 优先于较短的 Prefix:
/api/v2
优先于/api
,即使它们都是Prefix
类型。 - ImplementationSpecific 由控制器自行排序:通常作为 Prefix 处理,但具体取决于控制器实现。
Ingress初体验实战
创建deployment和service
[root@master01 ~/ingress]# cat nginx-deploy.yaml
# service
apiVersion: v1
kind: Service
metadata:
namespace: default
name: nginx-svc-clusterip
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: clusterip-nginx
port: 6789
targetPort: 80
protocol: TCP
---
# deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
name: pod-nginx
labels:
app: nginx
spec:
containers:
- name: container-nginx
image: nginx:1.14.1
restartPolicy: Always
创建ingress
# 定义资源文件
[root@master01 ~/ingress]# cat app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
# 和service在一个命名空间
namespace: default
spec:
ingressClassName: nginx
rules:
# 域名
- host: app.huangsir.com
# http配置
http:
paths:
# 指定连接后端的方式
- backend:
#指定service
service:
# 指定service的名称
name: nginx-svc-clusterip
# 指定端口,将流量转发到后端指定的端口,因为后端service的端口是80,所以这里是80,注意,这里不是访问的端口
port:
number: 80
# 指定匹配方式
pathType: Prefix
# 匹配路径
path: /
# 创建Ingress
[root@master01 ~/ingress]# kubectl apply -f app-ingress.yaml
ingress.networking.k8s.io/app-ingress created
查看创建的Ingress
# 获取ingress
[root@master01 ~/ingress]# kubectl get ing -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
app-ingress nginx app.huangsir.com 80 12s
# 查看详情
[root@master01 ~/ingress]# kubectl describe ing app-ingress
Name: app-ingress
Labels: <none>
Namespace: default
Address: 10.96.2.89
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
app.huangsir.com
/ nginx-svc-clusterip:80 ()
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 43s (x2 over 83s) nginx-ingress-controller Scheduled for sync
访问测试
使用浏览器访问
http://app.huangsir.com
进入ingress-controller查看对应的配置
从这里可以看到,当我们创建ingress时,其会自动将对应的配置映射到ingress-nginx-controller的nginx.conf配置文件中
# 进入ingress-controller容器内部
[root@node01 ~]# kubectl exec -it ingress-nginx-controller-58554b9b99-rdnhp -n ingress-nginx -- /bin/bash
# 查看对应的配置
ingress-nginx-controller-58554b9b99-rdnhp:/etc/nginx$ grep -A10 app.huangsir.com nginx.conf
## start server app.huangsir.com
server {
server_name app.huangsir.com ;
http2 on;
listen 80 ;
listen [::]:80 ;
listen 443 ssl;
listen [::]:443 ssl;
set $proxy_upstream_name "-";
--
未完结
本文来自博客园,作者:huangSir-devops,转载请注明原文链接:https://www.cnblogs.com/huangSir-devops/p/18869641,微信Vac666666,欢迎交流