Ingress Nginx与Nginx Ingress的区别
Ingress-nginx:它是由Kubernetes社区基于Nginx Web服务器开发的,并补充了一组用于实现额外功能的Lua插件,作为“官方”默认控制器支持当然最优。
Ingress-nginx:项目地址
ingress-nginx:文档
Nginx-ingress:是Nginx官方社区开发产品,Nginx ingress具有很高的稳定性,持续的向后兼容性,没有任何第三方模块,并且由于消除了Lua代码而保证了较高的速度。
Nginx-ingress:项目地址
Nginx-ingress:文档
常用示例
基本使用
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
pathType说明:
Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。当前支持的路径类型有三种:
- ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。
- Exact:精确匹配 URL 路径,且区分大小写。
- Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。
域名重定向Redirect
常用重定向的类别:
- 301:
nginx.ingress.kubernetes.io/permanent-redirect
,永久性重定向:新网址完全继承旧网址,旧网址的SEO网络搜索引擎的排名等完全清零 - 302:
nginx.ingress.kubernetes.io/temporal-redirect:
,302临时性重定向:对旧网址没有影响,但新网址不会有排名 - 307:
nginx.ingress.kubernetes.io/permanent-redirect-code: '307'
,307 的定义实际上和 302 是一致的,唯一的区别在于,307 状态码不允许浏览器将原本为 POST 的请求重定向到 GET 请求上。
在 Nginx 作为代理服务器时,Redirect 可用于域名的重定向,比如访问 old.com 被重定向到new.com。Ingress 可以更简单的实现 Redirect 功能,接下来用 nginx.redirect.com 作为旧域名,baidu.com 作为新域名进行演示:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
name: nginx-redirect
namespace: study-ingress
spec:
rules:
- host: nginx.redirect.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
使用域名、IP、域名及IP三种方式进行访问
域名
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
IP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
rules:
- http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
域名及IP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
- http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
前后端分离Rewrite
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: backend-test
namespace: study-ingress
spec:
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: backend-test
port:
number: 80
path: /test(/|$)(.*)
pathType: ImplementationSpecific
SSL访问
生产环境对外提供服务时,一般需要配置https协议,使用Ingress也可以非常方便的添加https的证书。
创建测试证书:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginx.test.com"
创建secret保存证书:
kubectl create secret tls ca-secret --cert=tls.crt --key=tls.key -n study-ingress
创建Ingress资源:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: nginx-ingress
namespace: study-ingress
spec:
ingressClassName: nginx # for k8s >= 1.22+
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts: # 证书所授权的域名列表
- nginx.test.com # 证书锁授权的域名列表
secretName: ca-secret # 证书的secret名字
匹配请求头
在实际使用时,常会遇到来自于手机端的访问路由至手机端页面,电脑端的访问路由器至电脑端页面。可以通过请求头中的$http_user_agent
来进行匹配分配。
创建手机端应用:
kubectl create deploy phone --image=nginx:phone -n study-ingress
kubectl expose deploy phone --port 80 -n study-ingress
创建手机端应用的ingress:
kubectl create ingress phone --rule=m.test.com/*=phone:80 -n study-ingress
创建PC端应用:
kubectl create deploy pc --image=nginx:pc -n study-ingress
kubectl expose deploy pc --port 80 -n study-ingress
创建电脑端的ingress,通过ingress.annotations
的nginx.ingress.kubernetes.io/server-snippet
配置。此配置专门用于一些复杂的Nginx配置。
nginx.ingress.kubernetes.io/server-snippet
:在nginx.conf的“server”字段中添加自定义配置。nginx.ingress.kubernetes.io/configuration-snippet
:在nginx.conf的“location”字段中添加自定义配置。
此配置和Nginx的配置通用,匹配移动端的实例如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
set $agentflag 0;
if ($http_user_agent ~* "(Android|iPhone|Windows Phone|UC|Kindle)" ){
set $agentflag 1;
}
if ( $agentflag = 1 ) {
return 301 http://m.test.com;
}
name: pc
namespace: study-ingress
spec:
rules:
- host: test.com
http:
paths:
- backend:
service:
name: laptop
port:
number: 80
path: /
pathType: ImplementationSpecific
此时,如果用手机端访问test.com
,那么会跳转至m.test.com
基本认证
如果网络需要通过密码来进行验证访问,可以使用Nginx的basic-auth设置密码,配置密码时,需要使用htpasswd工具,此工具为httpd服务内置工具,所以需要安装httpd服务。
$ yum install httpd -y
# 生成某个用户的密码:
$ htpasswd -c auth test
New password:
Re-type new password:
Adding password for user test
$ cat auth
test:$apr1$okma2fa9$hdTJ.Kbmi4pY9T6a2MjeS1
基于生成的密码文件创建secret:
kubectl create secret generic basic-auth --from-file=auth -n study-ingress
创建包含密码认证的ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-realm: Please Input Your Username and Password # 密码认证时的提示信息
nginx.ingress.kubernetes.io/auth-secret: basic-auth # 认证密码文件的secret名称
nginx.ingress.kubernetes.io/auth-type: basic # 认证类型:basic、digest
name: ingress-with-auth
namespace: study-ingress
spec:
rules:
- host: auth.test.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
黑/白名单
配置黑名单
配置黑名单需要在Ingress Nginx的ConfigMap中进行配置,比如将1.1.1.1添加至黑名单
vim values.yaml
config:
block-cidrs: 1.1.1.1 # 如有多个通过逗号分隔
更新ingress nginx
helm upgrade ingress-nginx -n ingress-nginx .
配置白名单
通过添加metadata.annotations
的nginx.ingress.kubernetes.io/whitelist-source-range
来进行配置。
速率限制
通过添加注解来进行配置
nginx.ingress.kubernetes.io/limit-connections
:限制连接个数nginx.ingress.kubernetes.io/limit-rps
:限制每个IP每秒的连接数nginx.ingress.kubernetes.io/limit-rpm
:限制每个IP每分钟的连接数nginx.ingress.kubernetes.io/limit-rate
:限制客户端每秒传输的字节数,单位是K,需要开启proxy-buffering
nginx.ingress.kubernetes.io/limit-whitelist
:限制白名单的速率
灰度/金丝雀发布
关于发布方式的区别请参考:常见发布方式介绍
V1版本环境
kubectl create ns prod
kubectl create deploy canary-v1 --images=test:v1 -n prod
kubectl expose deploy canary-v1 --port 8080 -n prod
kubectl create ingress canary-v1 --rule=test.com/*=canary-v1:8080 -n prod
V2版本环境
kubectl create ns canary
kubectl create deploy canary-v2 --image=test:v2 -n canary
kubectl expose deploy canary-v2 --port 8080 -n canary
创建canary的ingress进行流量切入
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
name: canary-v2
namespace: canary
spec:
ingressClassName: nginx # for k8s >=1.22+
rules:
- host: canary.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: canary-v2
port:
number: 8080
创建v2版本的Ingress时,需要添加两个注释:
nginx.ingress.kubernetes.io/canary: true
:表示此为灰度环境nginx.ingress.kubernetes.io/canary-weight: "10"
:表示切入10%的流量
此时v2版本占10%的流量,v1版本占90%的流量。
跨域
通过如下注解进行配置:
nginx.ingress.kubernetes.io/cors-allow-credentials:
:控制在跨域配置中是否允许传递凭据,默认值:true
nginx.ingress.kubernetes.io/cors-max-age
:控制预检请求可以缓存多长时间。默认值:1728000
。一般配置为'600'
nginx.ingress.kubernetes.io/cors-allow-origin
:控制CORS的可接受来源,默认值:*
nginx.ingress.kubernetes.io/cors-expose-headers
:控制哪些标头暴露给响应,默认值:empty
。一般情况不配置。nginx.ingress.kubernetes.io/cors-allow-headers
:控制接受哪些标头,默认值:DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization
。配置时需根据程序请求头信息将所有涉及到的请求头key进行填写。nginx.ingress.kubernetes.io/cors-allow-methods
:控制可接受的方法。默认:GET, PUT, POST, DELETE, PATCH, OPTIONS
。根据需求填写需要的方法即可。nginx.ingress.kubernetes.io/enable-cors
:控制是否开启跨域配置。开启配置为:true
示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
annotations:
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,token,idcard"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET,POST,OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/cors-max-age: "600"
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific