这里不多赘述Ingress的安装部署,重点记录下ingress在生产中有哪些常用的配置,所有配置都是针对yaml中的annotation。
具体可以参考kubernetes官方ingress文档:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
1.Ingress Nginx入门
k create ns study-ingress
k create deploy nginx --image=nginx:1.15.12 -n study-ingress
k expose deploy nginx --port 80 -n study-ingress
# 配置
cat web-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
2.Ingress Nginx域名重定向Redirect
# 配置
cat redirect.yaml
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:
ingressClassName: nginx
rules:
- host: nginx.redirect.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
# 验证
curl -I nginx.redirect.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 24 May 2023 03:18:47 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.baidu.com
3.Ingress Nginx前后端分离Rewrite
k create deploy backend-api --image=registry.cn-beijing.aliyuncs.com/dotbalo/nginx:backend-api -n study-ingress
k expose deploy backend-api --port 80 -n study-ingress
# 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: backend-api
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /api-a(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: backend-api
port:
number: 80
访问/api-a会被重写为"/",访问/api-a/xxx会被重写为/xxx
即访问nginx.test.com/api-a会访问到后端服务
# 验证
[root@k8s-master-node1 ~/ingress-test]# curl 10.96.254.35
<h1> backend for ingress rewrite </h1>
<h2> Path: /api-a </h2>
<a href="http://gaoxin.kubeasy.com"> Kubeasy </a>
[root@k8s-master-node1 ~/ingress-test]# curl nginx.test.com/api-a
<h1> backend for ingress rewrite </h1>
<h2> Path: /api-a </h2>
<a href="http://gaoxin.kubeasy.com"> Kubeasy </a>
4.Ingress Nginx错误代码重定向
这个配置有些问题,待验证。
需要更改default-backend的configmap custom-http-errors
cat error-redirect.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-error-redirct
namespace: study-ingress
annotations:
#nginx.ingress.kubernetes.io/error-pages: "400=/errors/400.html, 401=/errors/401.html, 403=/errors/403.html, 404=/errors/404.html, 500 502 503 504 /errors/5xx.html"
nginx.ingress.kubernetes.io/custom-http-errors: "400,404,415"
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
5.Ingress Nginx SSL
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginx.test.com"
k create secret tls ca-secret --cert=tls.crt --key=tls.key -n study-ingress
# 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
tls:
- hosts:
- nginx.test.com
secretName: ca-secret
# 验证
curl -I http://nginx.test.com
HTTP/1.1 308 Permanent Redirect
Date: Thu, 25 May 2023 06:32:59 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://nginx.test.com
6.Ingress Nginx匹配请求头
# 部署移动端
k create deploy phone --image=registry.cn-beijing.aliyuncs.com/dotbalo/nginx:phone -n study-ingress
k expose deploy phone --port 80 -n study-ingress
k create ingress phone --rule=m.test.com/*=phone:80 --class=nginx -n study-ingress
curl m.test.com
<h1> Access From Android|iPhone|Windows Phone|UC|Kindle </h1>
# 部署PC端
k create deploy laptop --image=registry.cn-beijing.aliyuncs.com/dotbalo/nginx:laptop -n study-ingress
k expose deploy laptop --port 80 -n study-ingress
# 配置
cat laptop-ingress.yaml
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.example.com;
}
name: laptop
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: laptop
port:
number: 80手机和PC访问到的页面不同,会将来自移动段的访问重定向到移动端服务,PC端访问保持默认。
通过访问浏览器,开发者工具项进行验证。
7.Ingress Nginx基本认证
# 生成foo用户的密码
htpasswd -c auth foo
# 基于之前创建的密码文件创建secret
k create secret generic basic-auth --from-file=auth -n study-ingress
secret不可以跨namespace使用
# 配置
cat ingress-with-auth.yaml
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
nginx.ingress.kubernetes.io/auth-type: basic
name: ingress-with-auth
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: auth.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
# 通过浏览器访问验证,需要输入设定的用户名密码,否则访问401。
8.Ingress Nginx黑/白名单
# 黑名单配置
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
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/denylist-source-range: 192.168.73.101
name: ingress-with-auth
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: auth.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
# 配置白名单
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
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.73.101
name: ingress-with-auth
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: auth.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
9.Ingress Nginx速率限制
# 速率限制,只能有1个连接
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
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/limit-connections: "1"
name: ingress-with-auth
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: auth.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
# 其他参数
# 限制每秒的连接,单个IP
nginx.ingress.kubernetes.io/limit-rps
# 限制每分钟的连接,单个IP
nginx.ingress.kubernetes.io/limit-rpm
# 限制客户端每秒传输的字节数,单位为KB,需要开启proxy-buffering
nginx.ingress.kubernetes.io/limit-rate
# 速率限制白名单
nginx.ingress.kubernetes.io/limit-whitelist
10.Ingress配置灰度/金丝雀发布
这里ruby脚本执行有误,通过curl一样可以看出来配置效果
# 生产环境v1版本
k create ns production
k create deploy canary-v1 --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v1 -n production
k expose deploy canary-v1 --port 8080 -n production
k create ingress canary-v1 --rule=canary.com/*=canary-v1:8080 --class=nginx -n production
curl canary.com
<h1>Canary v1</h1>
# 创建v2版本
k create ns canary
k create deploy canary-v2 --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v2 -n canary
k expose deploy canary-v2 --port 8080 -n canary
k get svc -n canary
curl 10.96.163.55:8080
<h1>Canary v2</h1>
# canary版本切入部分流量
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# 灰度环境
nginx.ingress.kubernetes.io/canary: "true"
# 分配10%流量到该环境,v1:v2=9:1
nginx.ingress.kubernetes.io/canary-weight: "10"
name: canary-v2
namespace: canary
spec:
ingressClassName: nginx
rules:
- host: canary.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-v2
port:
number: 8080
# 测试灰度发布ruby脚本
cat test-canary.rb
counts = Hash.new(0)
100.times do
output = 'curl -s canary.com | grep 'Canary' | awk '{print $2}' | awk -F"<" '{print $1}''
counts[output.strip.split.last] += 1
end
puts counts
# 执行
ruby test-canary.rb
{"$1}'"=>100}
# 应该是有两个结果,v1和v2