目录
介绍
本次所有操作都是在K8S 1.26.14 上面操作,太老的版本不知道会不会有问题。
更多 Ingress 配置请查看ingress-nginx 官网
ingress 安装 基本使用请查看
域名重定向
配置成功以后再次访问会直接跳转到百度首页。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
annotations:
## 配置域名重定向,将百度的域名改成自己业务需要的即可
nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
tls:
- hosts:
- prometheus.monitoring.cn
secretName: prometheus.monitoring.cn
修改域名重定向的同时还可以修改状态码,默认是301,本次修改成308.
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
annotations:
## 配置域名重定向,将百度的域名改成自己业务需要的即可
nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
## 修改状态码
nginx.ingress.kubernetes.io/permanent-redirect-code: '308'
spec:
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
tls:
- hosts:
- prometheus.monitoring.cn
secretName: prometheus.monitoring.cn
再次访问的时候可以看到状态码已经修改了(在网页调试里面查看)
前后端分离配置
部署好以后用这个域名访问即可prometheus.monitoring.cn/test,在nginx上面这个配置就是地址重写。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
annotations:
nginx.ingress.kubernetes.io/use-regex: "true" ## 启用正则表达式匹配路径
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /test(/|$)(.*)
pathType: ImplementationSpecific
tls:
- hosts:
- prometheus.monitoring.cn
secretName: prometheus.monitoring.cn
默认证书配置
测试环境可以用openssl 生成一个证书即可,正常生产环境是需要购买的证书才可以的要不浏览器会提示不安全。
比如申请的域名是以 *.monitoring.cn 的证书 就可以设置默认域名。
在 K8S上面创建证书。
bash
## 创建证书
kubectl create secret tls monitoring.cn --key monitoring.cn.key --cert monitoring.cn_bundle.pem -n ingress-nginx
## 查看创建的证书
[root@master01 ~]# kubectl get secrets -n ingress-nginx
NAME TYPE DATA AGE
monitoring.cn kubernetes.io/tls 2 65s
修改 ingress-nginx 配置
bash
kubectl edit daemonsets.apps -n ingress-nginx ingress-nginx-controller
### 找到这一行
spec:
containers:
- args:
- /nginx-ingress-controller
### 在此处添加 "- --default-ssl-certificate=ingress-nginx/monitoring.cn" 等号后面写命名空间/后面加上名字 (不是非得创建到 'ingress-nginx'理论上那个命名空间都可以)
- --default-ssl-certificate=ingress-nginx/monitoring.cn
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
保存退出即可。
使用方法:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
NGINX 将提供默认证书,但不会强制 HTTPS 重定向。就是用HTTP访问也行HTTPS访问也行。
如果需要强制转换HTTPS访问 在后面添加 tls 即可
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
tls:
- hosts:
- prometheus.monitoring.cn
指定证书配置
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
tls:
- hosts:
- prometheus.monitoring.cn
secretName: prometheus.monitoring.cn ## 这行要是注释了就是用默认的证书,没注释就是使用指定证书。
白名单配置
白名单建议使用 annotations 配置,这个只对的单个Ingress生效。
添加 nginx.ingress.kubernetes.io/whitelist-source-range 注释以实现白名单。未授权的 IP 访问会提示 403。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
annotations: ## 多个IP 用逗号隔开。
nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.1.175
spec:
tls:
- hosts:
- prometheus.monitoring.cn
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
黑名单配置
黑名单建议使用 ConfigMap 配置,此配置对整个集群段 Ingress 都生效。
Annotations 配置
这个注释可以指定具体的IP地址也可以写IP段的地址以逗号分隔,举例:192.168.1.0/24,192.168.1.2
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
annotations: ## 添加这个注释以开启黑名单设置
nginx.ingress.kubernetes.io/denylist-source-range: 172.31.163.46
spec:
tls:
- hosts:
- prometheus.monitoring.cn
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
ConfigMap 配置
注意:此操作全局生效,修改完保存即可生效,老版本的 Ingress-nginx 可能需要重启pod。
bash
kubectl edit cm -n ingress-nginx ingress-nginx-controller
yaml
apiVersion: v1
data:
allow-snippet-annotations: "true"
## 添加如下配置即可,IP 段也可以添加用逗号隔开即可。
denylist-source-range: 172.31.163.46
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: ingress-nginx
meta.helm.sh/release-namespace: ingress-nginx
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.8.1
helm.sh/chart: ingress-nginx-4.7.1
name: ingress-nginx-controller
namespace: ingress-nginx
匹配请求头
当请求头匹配到是用手机访问段就跳转到百度。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ingress
namespace: monitoring
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
set $agentflag 0;
if ($http_user_agent ~* "(Mobile)" ){
set $agentflag 1;
}
if ( $agentflag = 1 ) {
return 301 https://www.baidu.com;
}
spec:
tls:
- hosts:
- prometheus.monitoring.cn
ingressClassName: nginx
rules:
- host: prometheus.monitoring.cn
http:
paths:
- backend:
service:
name: prometheus-k8s
port:
name: web
path: /
pathType: Prefix
速率限制
本次仅展示部分 Ingress 配置。
限制客户端的最大连接数
nginx.ingress.kubernetes.io/limit-connections 是用于限制每个客户端与后端服务的最大并发连接数。当前设置段同一客户端最大连接数是10,个这种限制可以帮助防止某些类型的 DoS攻击。超出这个限制的连接请求将被 NGINX 阻止,返回 HTTP 503 错误。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/limit-connections: "10"
spec:
限制每秒钟段并发连接数
nginx.ingress.kubernetes.io/limit-rps 是用于限制每秒钟每个客户端 IP 地址可以发送到后端服务的请求数量,当前设置为每秒并发五个连接。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/limit-rps: "5"
spec:
rules:
限制每分钟段并发请求
这个和每秒的那个限制基本一致。当前配置是每分钟允许同一个客户端并发100个请求。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/limit-rpm: "100"
spec:
突发访问限制
nginx.ingress.kubernetes.io/limit-burst-multiplier 是用于控制请求速率限制中的突发请求数。它在配置 limit-rps(每秒请求数限制)或 limit-rpm(每分钟请求数限制)时一起使用,以允许短时间内超过设定请求速率的突发请求。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "2"
spec:
工作原理:
- nginx.ingress.kubernetes.io/limit-rps: "10":每个客户端 IP 每秒最多允许 10 个请求。
- nginx.ingress.kubernetes.io/limit-burst-multiplier: "2":允许的突发请求数是 10 的两倍,即 20 个请求。
这意味着在一个短时间窗口内,最多可以处理 20 个请求(超过 limit-rps 限制的 10 个正常请求数),之后请求速率将受 limit-rps 的限制。
限制传输速度
nginx.ingress.kubernetes.io/limit-rate-after 是用于控制在限制速率(Rate Limiting)生效之前将以当前带宽的最大速率,这项设置与 nginx.ingress.kubernetes.io/limit-rate 配合使用,用于管理响应速率的上限。
注意:此功能必须在启用代理缓冲的情况下使用。如果需要全局配置修改ConfigMap即可。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/proxy-buffering: "on" # 启用代理缓冲(默认情况是禁用段的)
nginx.ingress.kubernetes.io/proxy-buffers: "8 16k" # 8 个 16KB 缓冲区
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" # 初始缓冲区大小 16KB
nginx.ingress.kubernetes.io/limit-rate: "1024" # 每秒最多传输 1024 字节(1KB)
nginx.ingress.kubernetes.io/limit-rate-after: "5120" # 传输超过 5120 字节后开始限速(5k)
spec:
也可以直接使用这条 "nginx.ingress.kubernetes.io/limit-rate: "1024",既每秒传输1Kb(必须启用代理缓冲)
工作原理:
- 客户端在请求前 5120 字节的数据时,数据会以网络能够支持的最高速率传输。
- 当传输的数据量超过 5120 字节后,速率限制生效,传输速率限制为 1024 字节/秒(1KB/秒)。
速率限制白名单
nginx.ingress.kubernetes.io/limit-whitelist 是用于指定不受速率限制(rate limiting)影响的客户端 IP 地址或 IP 地址范围。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/limit-rate: "1024" # 每秒传输限制 1KB
nginx.ingress.kubernetes.io/limit-whitelist: "192.168.1.0/24,10.0.0.1" # 白名单
spec:
白名单中的 IP 不受每秒传输1Kb速度的限制。
灰度发布
基于权重配置
nginx.ingress.kubernetes.io/canary-weight:基于整数百分比的随机请求应路由到金丝雀入口中指定的服务。权重为 0 表示此金丝雀规则不会将任何请求发送到金丝雀入口中的服务。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test01
name: test01
namespace: apps
annotations:
nginx.ingress.kubernetes.io/canary: "true"
## 有百分之10的流量回到这个服务,剩下百分之90的流量到下面的那个服务。
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test01
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test02
name: test02
namespace: apps
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test02
port:
number: 80
path: /
pathType: Prefix
基于 Header 控制流量走向
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test01
name: test01
namespace: apps
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "always"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test01
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test02
name: test02
namespace: apps
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test02
port:
number: 80
path: /
pathType: Prefix
测试方法
不添加请求头的时候是访问 test02 。
bash
[root@master01 ~]# curl example.com
test022222
添加请求头的时候是访问 test01(请求时候命令行里面的键值对必须和 Ingress 里面的对应上)。
yaml
[root@master01 ~]# curl -H "X-Canary: always" example.com
test0111111
基于 Cookie 控制流量走向
nginx.ingress.kubernetes.io/canary-by-cookie:用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的 cookie。当 cookie 值设置为 时always,它将被路由到 Canary。当 cookie 设置为 时never,它将永远不会被路由到 Canary。对于任何其他值,将忽略 cookie,并根据优先级将请求与其他 Canary 规则进行比较。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test01
name: test01
namespace: apps
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "canary-user"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test01
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test02
name: test02
namespace: apps
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test02
port:
number: 80
path: /
pathType: Prefix
测试方法
将 cookie 的值设置为always是将访问test01,将值设置为never将访问 test02.
bash
[root@master01 ~]# curl -b "canary-user=always" example.com
test0111111
或者(不写cookie 或者值乱写也是访问test02)
yaml
[root@master01 ~]# curl -b "canary-user=never" example.com
test022222
Canary 规则按优先顺序进行评估。优先顺序如下:canary-by-header -> canary-by-cookie -> canary-weight
自定义错误页面
定义服务托管页面后段程序(为了演示使用 nginx 部署)。
部署自定义页面 配置文件。
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-error-pages
namespace: apps
data:
404.html: |
<html>
<head><title>404 Not Found</title></head>
<body>
<h1>404 Not Found</h1>
<p>The page you are looking for was not found.</p>
</body>
</html>
502.html: |
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<h1>502 Bad Gateway</h1>
<p>There was a problem with the upstream server.</p>
</body>
</html>
503.html: |
<html>
<head><title>503 Service Unavailable</title></head>
<body>
<h1>503 Service Unavailable</h1>
<p>The service is currently unavailable. Please try again later.</p>
</body>
</html>
部署 nginx Deployment 服务
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: error-pages
namespace: apps
spec:
replicas: 1
selector:
matchLabels:
app: error-pages
template:
metadata:
labels:
app: error-pages
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: error-pages
mountPath: /usr/share/nginx/html
volumes:
- name: error-pages
configMap:
name: custom-error-pages
---
apiVersion: v1
kind: Service
metadata:
name: error-pages
namespace: apps
spec:
ports:
- port: 80
selector:
app: error-pages
部署 Ingress (同一个命名空间直接写SVC名字即可,要是不同的命名空间情网下看。)
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test02
name: test02
namespace: apps
annotations:
nginx.ingress.kubernetes.io/custom-http-errors: "404,500"
nginx.ingress.kubernetes.io/default-backend: 'error-pages'
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test02
port:
number: 80
path: /
pathType: Prefix
不同命名空间配置
yaml
apiVersion: v1
kind: Service
metadata:
name: error-pages
namespace: apps
spec:
type: ExternalName
externalName: error-pages.apps.svc.cluster.local
ports:
- port: 80
基本认证
创建用户名和密码
bash
htpasswd -c auth user
## 没有这个命令直接yum安装
yum install -y httpd-tools
创建 secret
bash
kubectl create secret generic auth-secret --from-file=auth -apps
创建Ingress
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
k8s.kuboard.cn/layer: web
k8s.kuboard.cn/name: test02
name: test02
namespace: apps
annotations:
nginx.ingress.kubernetes.io/auth-type: "basic" ## 指定使用基本身份验证
nginx.ingress.kubernetes.io/auth-secret: "auth-secret" ## 指定刚刚创建的 secret
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required" ## 对话框面熟文字(就是在网页弹出的那个输入密码那个对话框的面熟问题,写什么都可以。)
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: test02
port:
number: 80
path: /
pathType: Prefix
在页面访问会提示输入账号密码。
官网还有更多Ingress 配置,我这里只列出了经常能用到的。
Ingress-Nginx 官方文档