一个计算机技术爱好者与学习者

0%

好好学K8S:Ingress常用配置

1. 前言

本文记录Ingress的常用配置,备忘。

关于Ingress更基础的内容,请参考《K8S中安装使用Ingress》

2. 支持websocket

推荐方法:

1
2
3
4
5
6
7
8
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"

参考文档:

历史方法:

1
2
3
4
5
6
7
8
9
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";

3. 域名证书配置

3.1. 普通域名配置证书

1、创建secret

1
2
3
4
5
kubectl create secret tls cert \
--cert=/etc/letsencrypt/live/voidking.com/fullchain.pem \
--key=/etc/letsencrypt/live/voidking.com/privkey.pem \
--dry-run=client \
-oyaml > secret.yaml

secret.yaml 结构如下:

1
2
3
4
5
6
7
8
apiVersion: v1
data:
tls.crt: xxx
tls.key: yyy
kind: Secret
metadata:
name: cert
type: Opaque

其中,tls.crt是base64加密后的证书,tls.key是base64加密后的key。

2、ingress添加tls定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
spec:
ingressClassName: nginx
rules:
- host: test.voidking.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 80
tls:
- hosts:
- test.voidking.com
secretName: cert

3.2. 泛域名配置证书

泛域名的证书配置方法,和普通域名的证书配置方法完全一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
spec:
ingressClassName: nginx
rules:
- host: *.voidking.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 80
tls:
- hosts:
- '*.voidking.com'
secretName: cert

参考文档:

3.3. 多个域名配置泛域名证书

多个域名使用同一个泛域名证书,建议集中配置泛域名证书。

1、域名证书配置

1
2
3
4
5
6
7
8
9
10
spec:
ingressClassName: nginx
rules:
- host: test0.voidking.com
- host: test1.voidking.com
tls:
- hosts:
- 'test0.voidking.com'
- 'test1.voidking.com'
secretName: cert

2、路由配置

1
2
3
4
5
6
7
8
9
10
11
12
13
spec:
ingressClassName: nginx
rules:
- host: test0.voidking.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 80

3.4. 批量修改域名证书

已知条件:

  • k8s集群中,使用ingress配置了很多四级域名,例如 test0.intl.voidking.com 和 test1.intl.voidking.com
  • 除了四级域名,还有五级域名,例如 web.core.intl.voidking.com 和 api.core.intl.voidking.com
  • 每个域名都有一个自己的ingress配置文件,包含tls配置
  • ingress位于不同的namespace

需求:*.intl.voidking.com域名证书过期,需要批量修改k8s中对应的四级域名证书,不要影响五级域名证书。

脚本实现:patch-ingress-tls

4. 前后端分离

需求描述:前端后端是两个服务,位于两个namespace,要配置ingress,使发往路由/的流量打到前端服务,发往/api的流量打到后端服务。

方法一:
在一个namespace中,创建一个ingress和一个externalname类型的service。在ingress中配置两个path。

方法二:
在两个namespace中,分别创建一个ingress。host相同,配置不同的path,ingress-controller会自动合并这两个配置。

5. 设置max_client_body_size

ingress-nginx-controller有一个全局配置文件(configmap),类似于nginx中的nginx.conf,通过它可以配置一些通用配置,例如max_client_body_size。

1、编辑配置文件

1
kubectl edit cm ingress-nginx-controller -n ingress-nginx

修改data部分的配置:

1
2
data:
proxy-body-size: "1000m"

2、重启ingress-nginx-controller

1
kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx

6. 修改日志格式

1、编辑配置文件

1
kubectl edit cm ingress-nginx-controller -n ingress-nginx

修改data部分的配置:

1
2
3
4
data:
log-format-upstream: '$remote_addr - $remote_port [$time_local] "$http_user_agent" "$http_x_forwarded_for" $host $http_host $scheme "$http_referer" "$request" "$request_uri" "$request_method" $request_time $request_length $status $bytes_sent $body_bytes_sent $upstream_addr $upstream_response_time'
access-log-path: "/var/log/nginx/access.log"
error-log-path: "/var/log/nginx/error.log"

这里的日志格式参考《Nginx入门篇》

2、重启ingress-nginx-controller

1
kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx

7. 路径重写

参考文档:

需求:发往 /api/* 的流量,变成 /* 转发到 api-service ;发往 /cms/* 的流量,变成 /* 转发到 cms-service;其余流量发往 frontend-service。

配置方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: true
spec:
ingressClassName: nginx
rules:
- host: test0.voidking.com
http:
paths:
- path: /(.*)
backend:
serviceName: frontend-service
servicePort: 80
- path: /api/(.*)
backend:
serviceName: api-service
servicePort: 8080
- path: /cms/(.*)
backend:
serviceName: cms-service
servicePort: 8080

其中,path中的(.*)是第一个匹配,与rewrite-target中的$1对应。

需求:发往 /api/* 的流量,变成 /api/v1/* 转发到 api-service ;发往 /api-v2/* 的流量,变成 /api/v2/* 转发到 api-service。

配置方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fe
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/api/(.*)$ /api/v1/$1 redirect;
rewrite ^/api-v2/(.*)$ /api/v2/$1 redirect;
spec:
ingressClassName: nginx
rules:
- host: test0.voidking.com
http:
paths:
- path: /api
backend:
serviceName: api-service
servicePort: 8080

需求:发往 /tea/* 的流量,变成 /* 转发到 tea-svc ;发往 /coffee/* 的流量,变成 /beans/* 转发到 api-service。

配置方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.org/rewrites: "serviceName=tea-svc rewrite=/;serviceName=coffee-svc rewrite=/beans/"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea/
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80
- path: /coffee/
pathType: Prefix
backend:
service:
name: coffee-svc
port:
number: 80

8. 域名重定向

需求:访问 voidking.com 域名的请求,自动跳转到 www.voidking.com

配置方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: voidking-com-redirect
namespace: voidking
annotations:
nginx.ingress.kubernetes.io/rewrite-target: 'https://www.voidking.com'
spec:
ingressClassName: nginx
tls:
- hosts:
- voidking.com
secretName: voidking-com
rules:
- host: voidking.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: fake-service
port:
number: 80

注意:虽然 voidking.com 配置了重定向,但是这个域名依然需要证书,哪怕配置了 nginx.ingress.kubernetes.io/force-ssl-redirect,也需要证书,这是比较坑的一点。

其实,更简单的方法是使用dnspod的显性URL记录类型解析。但是,并不是所有的DNS服务器都支持这种显性URL记录类型,所以很多情况下还是需要用到ingress的域名重定向。

参考文档:Ingress-Nginx Controller Rewrite

9. 404重定向到首页

需求:访问URL test.voidking.com/x/y/z 时,如果路径不存在出现404,那么自定义404页面或者跳转到首页。

配置方法:开启custom-http-errors,创建一个自定义backend,出现404等错误时都重定向到这个backend。

1、创建自定义backend,包括deployment和svc,资源清单为custom-default-backend.yaml

1
kubectl create -f custom-default-backend.yaml -n ingress-nginx

2、修改ingress-nginx的配置

1
kubectl edit cm ingress-nginx-controller -n ingress-nginx

添加配置:

1
2
data:
custom-http-errors: 404,503

3、修改ingress-nginx启动参数

1
2
kubectl edit deployment ingress-nginx-controller -n ingress-nginx
#kubectl edit daemonset ingress-nginx-controller -n ingress-nginx

启动命令的参数中添加:

1
--default-backend-service=ingress-nginx/nginx-errors

注意这里的 ingress-nginx/nginx-errors 对应的格式为 namespace/name

ingress-nginx重启后,报错404时会提示The page you're looking for could not be found.

如果想要自定义404页面,那么可以添加一个configmap.yaml,然后挂载到custom-default-backend.yaml

如果想要404重定向到首页,那么可以在该域名的ingress的annotations配置中,添加配置:

1
2
3
4
5
6
7
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
error_page 404 = /404.html;
location = /404.html {
return 301 https://test.voidking.com;
}

参考文档:Ingress-Nginx Custom Errors

10. 404重定向到不同路径

需求:访问URL test.voidking.com/x/y/z 时,如果路径不存在出现404,那么跳转到 test.voidking.com/x。其中 xyz 都代表一个字符串。

结论:单纯使用ingress,是无法实现这个配置的。
对于静态页面,可以借助Nginx进行配置,参考文档:《好好学Nginx:Nginx入门篇》
对于动态页面,可以在后端服务代码中自行处理404的跳转。

11. 查看最终的nginx配置

我们编写的ingress,实际上最终会生成nginx.conf,可以在ingress-nginx-controller中查看是否符合预期。

1
2
3
kubectl exec -it ingress-nginx-controller-xxx -- /bin/bash
cd /etc/nginx
cat nginx.conf
  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-ingress-config/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~