ingress-nginx多实例部署

由于业务需求希望一个项目一个ingress-nginx以方便后期管理。为此我把ingress-nginx的所有Yaml文件读了一遍了解了其中的创建过程以及权限设置。想要实现多实例我们需要对如下几个地方做出适当的修改。

此段主要是允许访问一个叫ingress-controller-leader-iov-iov的configmap(通过RoleBinding绑定从而限制针对某一个命名空间中定义的一个ConfigMap实例的访问)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  - apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "<election-id>-<ingress-class>"
# Here: "<ingress-controller-leader>-<nginx>"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-iov-iov"
verbs:
- get
- update

#注意:这里的名称是<election-id>-<ingress-class>拼接而成

在如下args段中我们新增了几个参数:

  • --ingress-class=iov 当设置这个参数后只会Watch Ingress class为 iov的
  • --election-id=ingress-controller-leader-iov 用于Ingress状态更新的选举ID。(默认ingress-controller-leader
  • --report-node-internal-ip-address 默认情况下是–publish-service但是在裸机部署的时候要使用kubectl get ingress无法显示ADDRESS,所以我们需要使用–report-node-internal-ip-address参数

删除删除:

  • --publish-service=$(POD_NAMESPACE)/ingress-nginx 非公有云情况下使用kubectl get ingress无法显示ADDRESS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
node: IOV
containers:
- name: nginx-ingress-iov-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.24.1
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
# - --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --report-node-internal-ip-address
- --annotations-prefix=nginx.ingress.kubernetes.io
- --ingress-class=iov
- --election-id=ingress-controller-leader-iov
- --v=2

在创建ingress时我们需要注意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-myapp
namespace: default
annotations:
kubernetes.io/ingress.class: "iov" # 指定class类不然无法被ingress所选取到
spec:
rules:
- host: nginx.testdomain.com
http:
paths:
- path:
backend:
serviceName: nginx-service
servicePort: 8080

Ingress-nginx使用:

有三种方法可以自定义NGINX:

  • ConfigMap:使用Configmap在NGINX中设置全局配置。
  • Annotations: 如果需要特定Ingress规则的特定配置,请使用此选项。
  • 自定义模板:当需要更具体的设置时,比如open_file_cache,将listen选项调整为rcvbuf,或者当无法通过ConfigMap更改配置时。

Annotations:

1
2
将配置添加到server作用域中:
nginx.ingress.kubernetes.io/server-snippet:
1
2
将配置添加到location作用域:
nginx.ingress.kubernetes.io/configuration-snippet:
1
2
指示Ingress上定义的路径是否使用正则表达式:
nginx.ingress.kubernetes.io/use-regex:
1
2
必须重定向流量的目标URI:
nginx.ingress.kubernetes.io/rewrite-target:
1
2
设置upstream server  proxy_set_header Host $host
nginx.ingress.kubernetes.io/upstream-vhost:

ConfigMaps:

使用ConfigMap配置NGINX将是对整个Nginx进行全局配置

1
2
3
4
5
6
[root@k8s-m-19201680111034 overlord]# kubectl get configmap -n ingress-nginx
NAME DATA AGE
ingress-controller-leader-nginx 0 22d
nginx-configuration 0 22d
tcp-services 0 22d
udp-services 0 22d

例如,如果我们想改变超时,我们需要创建一个ConfigMap:

1
2
3
4
5
6
7
8
9
10
11
[root@k8s-m-19201680111034 overlord]# cat configmap.yaml
apiVersion: v1
data:
proxy-connect-timeout: "10"
proxy-read-timeout: "120"
proxy-send-timeout: "120"
kind: ConfigMap
metadata:
name: nginx-configuration

[root@k8s-m-19201680111034 overlord]# kubectl apply -f configmap.yaml

自定义标题

本例演示了通过ConfigMap配置nginx ingress控制器,以便将自定义头列表传递给上游服务器。

首先我们在ingress-nginx名称空间创建一个ConfigMap其中包含几个自定义的 X-prefixed HTTP头部。内容如下:

1
2
3
4
5
6
7
8
9
apiVersion: v1
data:
X-Different-Name: "true"
X-Request-Start: t=${msec}
X-Using-Nginx-Controller: "true"
kind: ConfigMap
metadata:
name: custom-headers
namespace: ingress-nginx

第二步我们修改ingres-nginx名称空间中一个名为nginx-configuration的ConfigMap。它控制ingress-controller的全局配置。nginx-ingress控制器将读取ingres-nginx/nginx-configuration ConfigMap,找到proxy-set-headers键,然后从ingres-nginx/custom-headers ConfigMap读取HTTP头部,并将这些HTTP头部包含在从nginx流到后端所有请求中。

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
data:
proxy-set-headers: "ingress-nginx/custom-headers"
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx

设置日志格式:

设置nginx日志格式,以json格式输出:

1
2
3
4
5
6
7
8
[root@k8s-m1 ~]# cat log.yaml
apiVersion: v1
data:
log-format-upstream: '{ "time": "$time_iso8601", "remote_addr": "$proxy_protocol_addr","x-forward-for": "$proxy_add_x_forwarded_for", "request_id": "$req_id", "remote_user":"$remote_user", "bytes_sent": $bytes_sent, "request_time": $request_time, "status":$status, "vhost": "$host", "request_proto": "$server_protocol", "path": "$uri","request_query": "$args", "request_length": $request_length, "duration": $request_time,"method": "$request_method", "http_referrer": "$http_referer", "http_user_agent":"$http_user_agent" }'
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx

调整工作进程和内存设置:

Nginx 具有默认设置worker_processes auto,这意味着工作进程号与宿主机上的 CPU 核心数相同。 请注意,这里提到的是物理主机而不是容器资源!这是因为 Nginx 不是 cgroup-aware,而 Ingress 控制器将忽略以下 2 个约束:

1
2
resources.limits.cpu
resources.requests.cpu

当技术人员将集群中的宿主机节点从 4 个 vCPU 核心升级到 16 个 vCPU 核心时,Ingress 控制器的 Pod 在 Ingress 的更改期间会出现故障。这时,登录 Pod 并检查/etc/nginx/nginx.conf后,你会发现每个 Ingress 控制器中的 Pod 有 16 个工作进程而不是 4 个。
当频繁的进行 Ingress 更改时,Nginx 将继续为这 16 个工作进程重新加载配置并消耗 Pod 中的所有内存,让他们死于 OOM。

注意:当node节点既有ingress-nginx Pod,又有其他业务Pod时请限制ingress-nginx的资源利用CPU、mem


ingress-nginx多实例部署
https://system51.github.io/2019/08/26/ingress-nginx-Multi-instance/
作者
Mr.Ye
发布于
2019年8月26日
许可协议