本文介绍关于Nginx Ingress异常问题的诊断流程、排查思路、常见检查方法和解决方案。
本文目录
类别 | 内容 |
---|---|
诊断流程 | 诊断流程 |
排查思路 | 排查思路 |
常见排查方法 | |
常见问题及解决方案 |
|
背景信息
当前Kubernetes官方维护的是Nginx Ingress Controller,ACK基于社区版的Nginx Ingress Controller进行了优化。ACK的Nginx Ingress Controller与社区Nginx Ingress Controller完全兼容,支持社区所有的Annonation。当在创建ACK集群时,您选择安装的Nginx Ingress Controller组件即为ACK定制版的Nginx Ingress Controller组件。
- Service是后端真实服务的抽象,一个Service可以代表多个相同的后端服务。
- Nginx Ingress是反向代理规则,用来规定HTTP/HTTPS请求应该被转发到哪个Service所对应的Pod上。例如根据请求中不同的Host和URL路径,让请求落到不同Service所对应的Pod上。
- Nginx Ingress Controller是一个反向代理程序,负责解析Nginx Ingress的反向代理规则。如果Nginx Ingress有增删改的变动,Nginx Ingress Controller会及时更新自己相应的转发规则,当Nginx Ingress Controller收到请求后就会根据这些规则将请求转发到对应Service的Pod上。
nginx -s load
重新加载Nginx)来生成新的路由转发规则。

诊断流程

-
按照以下步骤,检查是否是由于Ingress所导致的问题,确保Ingress Controller的配置正确。
- 在Controller Pod中确认访问是否符合预期。具体操作,请参见 在Controller Pod中手动访问Ingress和后端Pod 。
- 确认Nginx Ingress Controller使用方法正确。具体操作,请参见 Nginx Ingress社区使用文档 。
- 使用Ingress诊断功能检查Ingress和组件配置,并且根据相关提示进行修改。关于Ingress诊断功能具体操作,请参见 使用Ingress诊断功能 。
- 按照 排查思路 ,确认相关问题及解决方案。
-
如果以上排查无果,请按照以下步骤排查:
-
针对HTTPS证书问题:
-
检查域名上是否启用了WAF接入或WAF透明接入。
- 如果启用了,请确认WAF或透明WAF没有设置TLS证书。
- 如果没启用,请执行下一步。
-
检查SLB是否为七层监听。
- 如果是,请确认SLB七层监听上没有设置TLS证书。
- 如果不是,请执行下一步。
-
检查域名上是否启用了WAF接入或WAF透明接入。
- 非HTTPS证书问题,检查Controller Pod中错误日志。具体操作,请参见 检查Controller Pod中错误日志 。
-
针对HTTPS证书问题:
- 如果以上排查无果,请在Controller Pod和对应后端的业务Pod中进行抓包,确认问题。具体操作,请参见 抓包 。
- 如果以上排查无果,请 提交工单 排查。
排查思路
排查思路 | 问题现象 | 解决方案 |
---|---|---|
访问不通 | 集群内部Pod到Ingress访问不通 | 集群内访问集群LoadBalancer暴露的SLB地址不通 |
Ingress访问自己不通 | 无法访问Ingress Controller自己 | |
测试域名解析不到 | 通过控制台提供的测试域名无法访问到Ingress | |
无法访问TCP、UDP服务 | 添加TCP、UDP服务 | |
HTTPS访问出现问题 | 证书未更新或返回默认证书 | 集群中添加或修改了TLS证书,但是访问时还是默认证书或旧的证书 |
返回
RX_RECORD_TOO_LONG/wrong version number
|
HTTPS访问报SSL_ERROR_RX_RECORD_TOO_LONG错误 | |
添加Ingress资源时出现问题 | 报错failed calling webhook... | 创建Ingress资源时报错 "failed calling webhook" |
添加了Ingress,但是没有生效 | Ingress规则没有生效 | |
访问不符合预期 | 无法获得客户端源IP | Ingress Pod中无法保留源IP |
IP白名单不生效或不按预期生效 | ||
无法连接到通过Ingress暴露的gRPC服务 | 无法连接到通过Ingress暴露的gRPC服务 | |
灰度不生效 | 灰度规则不生效 | |
灰度规则错误或影响到别的流量 | 流量分发与灰度规则不一致或其它流量进入灰度服务 | |
出现
The plain HTTP request was sent to HTTPS port
|
无法连接到后端HTTPS服务 | |
出现502、503、413、499等错误 | 出现常见HTTP错误码 | |
加载页面时部分资源加载不出来 |
配置了
rewrite-target
,资源访问时出现404
|
重写到根目录后部分资源无法加载或白屏 |
资源访问时出现
net::ERR_FAILED
或
net::ERR_HTTP2_SERVER_REFUSED_STREAM
|
出现net::ERR_HTTP2_SERVER_REFUSED_STREAM错误 |
常见检查方法
使用Ingress诊断功能
- 登录 容器服务管理控制台 。
- 在控制台左侧导航栏,单击 集群 。
- 在 集群列表 页面,选择目标集群,并在目标集群右侧的 操作 列,选择 。
- 在容器智能运维控制台左侧导航栏,选择 。
- 在 故障诊断 页面,单击 Ingress诊断 。
-
在
Ingress诊断
面板,输入出现问题的URL,例如
https://www.example.com
。选中
我已知晓并同意
,然后单击
发起诊断
。
诊断完成后,根据诊断结果解决问题。
通过日志服务SLS的Controller Pod查看访问日志
Ingress Controller访问日志格式可以在ConfigMap中看到(默认ConfigMap为kube-system命名空间下的nginx-configuration)。
$remote_addr - [$remote_addr] - $remote_user [$time_local]
"$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length
$request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length
$upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name]
日志服务控制台 的Ingress Controller日志如下图所示。具体操作,请参见 步骤四:查看日志 。

字段 | 说明 |
---|---|
remote_addr/client_ip
|
客户端的真实IP。 |
request/(method+url+version)
|
请求的信息。包括请求的方法、URL以及HTTP版本。 |
request_time
|
本次请求的时间。从接收客户端请求起,到发送完响应数据的总时间。该值可能会受到客户端网络条件等因素的影响,无法代表请求真实的处理速度。 |
upstream_addr
|
后端upstream的地址,如果该请求没有到后端,则该值为空。当后端因为失败请求多个upstream时,该值为半角逗号(,)分隔列表。 |
upstream_status
|
后端upstream返回的http code。如果该值为正常http status code,代表该值由后端upstream返回。当没有后端可以访问时,该值为502。有多个值时由半角逗号(,)分开。 |
upstream_response_time
|
后端upstream的响应时间,单位为秒。 |
proxy_upstream_name
|
后端upstream的名称。命名规则为
<命名空间>-<服务名称>-<端口号>
。
|
proxy_alternative_upstream_name
|
后端alternative upstream的名称。当该请求转发到alternative upstream(例如使用Canary设置的灰度服务)时,该值不为空。 |
kubectl logs <controller pod name> -n <namespace> | less
42.11.**.** - [42.11.**.**]--[25/Nov/2021:11:40:30 +0800]"GET / HTTP/1.1" 200 615 "_" "curl/7.64.1" 76 0.001 [default-nginx-svc-80] 172.16.254.208:80 615 0.000 200 46b79dkahflhakjhdhfkah**** 47.11.**.**[]
42.11.**.** - [42.11.**.**]--[25/Nov/2021:11:40:31 +0800]"GET / HTTP/1.1" 200 615 "_" "curl/7.64.1" 76 0.001 [default-nginx-svc-80] 172.16.254.208:80 615 0.000 200 fadgrerthflhakjhdhfkah**** 47.11.**.**[]
检查Controller Pod中错误日志
您可以根据Ingress Controller Pod中的日志,进一步缩小问题范围。Controller Pod中错误日志分为以下两种:
-
Controller错误日志:一般在Ingress配置错误时产生,可以执行以下命令过滤出Controller错误日志。
kubectl logs <controller pod name> -n <namespace> | grep -E ^[WE]
说明 Ingress Controller在启动时会产生若干条W(Warning)等级错误,属于正常现象。例如未指定kubeConfig或未指定Ingress Class等Warning信息,这些Warning信息不影响Ingress Controller的正常运行,因此可以忽略。 -
Nginx错误日志:一般在处理请求出现错误时产生,可以执行以下命令过滤出Nginx错误日志。
kubectl logs <controller pod name> -n <namespace> | grep error
在Controller Pod中手动访问Ingress和后端Pod
-
执行以下命令,进入Controller Pod。
kubectl exec <controller pod name> -n <namespace> -it -- bash
-
Pod中已预装好了curl、OpenSSL等工具,您可以通过该工具测试连通性、证书配置的正确性等。
-
执行以下命令,测试能否通过Ingress访问到后端。
# 请将your.domain.com替换为实际要测试的域名。 curl -H "Host: your.domain.com" http://127.0.**.**/ # for http curl --resolve your.domain.com:443:127.0.0.1 https://127.0.0.1/ # for https
-
执行以下命令,验证证书信息。
openssl s_client -servername your.domain.com -connect 127.0.0.1:443
-
访问后端Pod测试的正确性。
说明 Ingress Controller不会通过Service Cluster IP的形式来访问后端Pod,而是直接访问后端Pod IP。
-
执行以下命令,通过kubectl获得后端Pod IP。
kubectl get pod -n <namespace> <pod name> -o wide
预期输出:NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-dp-7f5fcc7f-**** 1/1 Running 0 23h 10.71.0.146 cn-beijing.192.168.**.** <none> <none>
由预期输出获得,后端Pod IP为10.71.0.146。
-
执行以下命令,在Controller Pod中访问该Pod,确认Controller Pod到后端Pod能够正常连通。
curl http://<your pod ip>:<port>/path
-
执行以下命令,通过kubectl获得后端Pod IP。
-
执行以下命令,测试能否通过Ingress访问到后端。
当无法定位问题时,需要抓包进行辅助诊断。
- 根据初步问题定位结果,简单判断网络问题出现在Ingress Pod还是业务Pod。如果信息不足,可以两方的包都进行抓取。
- 登录出现异常的业务Pod或Ingress Pod所在节点。
-
在ECS(非容器内)执行以下命令,可以将Ingress流量信息抓取到文件中。
tcpdump -i any host <业务Pod IP或Ingress Pod IP> -C 20 -W 200 -w /tmp/ingress.pcap
- 观察日志,当出现预期错误时,结束抓包。
-
结合业务日志的报错,定位到精准的报错时间的报文信息。
说明
- 在正常情况下,抓包对业务无影响,仅会增加小部分的CPU负载和磁盘写入。
- 以上命令会对抓取到的包进行rotate,最多可以写200个20 MB的 .pcap 文件。
集群内访问集群LoadBalancer暴露的SLB地址不通
问题现象
在Kubernetes集群中有部分节点能访问集群暴露出去的Local类型SLB,但是也有部分节点不能访问。
问题原因
SLB设置了
externalTrafficPolicy: Local
类型,这种类型的SLB地址只有在Node中部署了对应的后端Pod,才能被访问。因为SLB的地址是集群外使用,如果集群节点和Pod不能直接访问,请求不会到SLB,会被当作Service的扩展IP地址,被kube-proxy的iptables或ipvs转发。
如果刚好集群节点或者Pod所在的节点上没有相应的后端服务Pod,就会发生网络不通的问题,而如果有相应的后端服务Pod,是可以正常访问。有关external-lb的更多信息,请参见 kube-proxy将external-lb的地址添加到节点本地iptables规则 。
解决方案
-
(推荐)在Kubernetes集群内通过ClusterIP或者Ingress的服务名去访问。
其中Ingress的服务名为
nginx-ingress-lb.kube-system
。 -
执行
kubectl edit svc nginx-ingress-lb -n kube-system
命令,修改Ingress的服务。将LoadBalancer的Service中externalTrafficPolicy
修改为Cluster
,但应用中会丢失源IP。 -
如果是Terway的ENI或者ENI多IP的集群,将LoadBalancer的Service中
externalTrafficPolicy
修改为Cluster
,并且添加ENI直通的Annotation,可以保留源IP,并且集群内访问也没有问题。示例如下:apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/backend-type: eni #直通ENI。 labels: app: nginx-ingress-lb name: nginx-ingress-lb namespace: kube-system spec: externalTrafficPolicy: Cluster
关于Service的Annotation的更多信息,请参见 通过Annotation配置负载均衡 。
无法访问Ingress Controller自己
问题现象
对于Flannel集群,在Ingress Pod中通过域名、SLB IP、Cluster IP访问Ingress自己时,出现部分请求或全部请求不成功的情况。
问题原因
Flannel目前的默认配置不允许回环访问。
解决方案
- (推荐)如果条件允许,建议您重建集群,并使用Terway的网络插件,将现有集群业务迁移至Terway模式集群中。
-
如果没有重建集群的条件,可以通过修改Flannel配置,开启
hairpinMode
解决。配置修改完成后,重建Flannel Pod使修改生效。-
执行以下命令,编辑Flannel。
kubectl edit cm kube-flannel-cfg -n kube-system
-
在返回结果
cni-config.json
中的
delegate
增加"hairpinMode": true
。示例如下:cni-conf.json: | "name": "cb0", "cniVersion":"0.3.1", "type": "flannel", "delegate": { "isDefaultGateway": true, "hairpinMode": true }
-
执行以下命令,重启Flannel。
kubectl delete pod -n kube-system -l app=flannel
- 删除并重新创建Pod。
-
执行以下命令,编辑Flannel。
集群中添加或修改了TLS证书,但是访问时还是默认证书或旧的证书
问题现象
您已经在集群中添加或修改Secret并在Ingress中指定secretName后,访问集群仍使用了默认的证书(Kubernetes Ingress Controller Fake Certificate)或旧的证书。
问题原因
- 证书不是由集群内Ingress Controller返回的。
- 证书无效,未能被Controller正确加载。
- Ingress Controller根据SNI来返回对应证书,TLS握手时可能未携带SNI。
解决方案
-
通过以下任一方式,确认建立TLS连接时是否携带了SNI字段:
- 使用支持SNI的较新版本浏览器。
-
使用
openssl s_client
命令测试证书时,携带-servername
参数。 -
使用
curl
命令时,添加hosts或使用--resolve
参数映射域名,而不是使用IP+Host请求头的方式。
- 确认WAF、WAF透明接入或SLB七层监听上没有设置TLS证书,TLS证书应该由集群内Ingress Controller返回的。
- 在智能运维控制台进行Ingress诊断,观察是否存在配置错误和错误日志。具体操作,请参见 使用Ingress诊断功能 。
-
执行以下命令,手动查看Ingress Pod错误日志,根据错误日志中相关提示进行修改。
kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]
通过控制台提供的测试域名无法访问到Ingress
问题现象
通过容器服务控制台提供的测试域名(*.cxxxxxxxxxxx.xxx.alicontainer.com)无法访问到Ingress。
问题原因
域名未正确解析到Ingress服务,可能原因如下:
- 服务不是kube-system命名空间下的nginx-ingress-lb。
- 服务的外部IP在创建Ingress后出现变动。
解决方案
- 将正确的IP绑定在kube-system命名空间下的nginx-ingress-lb服务上。
-
在
容器服务管理控制台
对应集群的集群信息页面,单击
基本信息
页签,然后单击
重新绑定域名
。
无法连接到通过Ingress暴露的gRPC服务
问题现象
通过Ingress无法访问到其后的gRPC服务。
问题原因
- 未在Ingress资源中设置Annotation,指定后端协议类型。
- gRPC服务只能通过TLS端口进行访问。
解决方案
-
在对应Ingress资源中设置Annotation:
nginx.ingress.kubernetes.io/backend-protocol:"GRPC"
。 - 确认客户端发送请求时使用的是TLS端口,并且将流量加密。
无法连接到后端HTTPS服务
问题现象
- 通过Ingress无法访问到其后的HTTPS服务。
-
访问时回复可能为400,并提示
The plain HTTP request was sent to HTTPS port
。
问题原因
Ingress Controller到后端Pod请求使用了默认的HTTP请求。
解决方案
在Ingress资源中设置Annotation:
nginx.ingress.kubernetes.io/backend-protocol:"HTTPS"
。
Ingress Pod中无法保留源IP
问题现象
Ingress Pod中无法保留真实客户端IP,显示为节点IP或100.XX.XX.XX网段或其它地址。
问题原因
-
Ingress所使用的Service中
externalTrafficPolicy
设为了Cluster
。 - SLB上使用了七层代理。
- 使用了WAF接入或WAF透明接入服务。
解决方案
-
对于设置
externalTrafficPolicy
为Cluster
,且前端使用了四层SLB的情况。可以将
externalTrafficPolicy
改为Local
。但可能会导致集群内部使用SLB IP访问Ingress不通,具体解决方案,请参见 集群内访问集群LoadBalancer暴露的SLB地址不通 。 -
对于使用了七层代理(七层SLB、WAF、透明WAF)的情况,可以按以下步骤解决:
- 确保使用的七层代理且开启了X-Forwarded-For请求头。
-
在Ingress Controller的ConfigMap中(默认为kube-system命名空间下的nginx-configuration)添加
enable-real-ip: "true"
。 - 观察日志,验证是否可以获取到源IP。
-
对于链路较长,存在多次转发的情况(例如在Ingress Controller前额外配置了反向代理服务),可以在开启
enable-real-ip
时通过观察日志中remote_addr
的值,来确定真实IP是否是以X-Forwarded-For请求头传递到Ingress容器中。若不是,请在请求到达Ingress Controller之前利用X-Forwarded-For等方式携带客户端真实IP。
灰度规则不生效
问题现象
在集群内设置了灰度,但是灰度规则不生效。
问题原因
可能原因有两种:
-
在使用
canary-*
相关Annotation时,未设置nginx.ingress.kubernetes.io/canary: "true"
。 -
在使用
canary-*
相关Annotation时,0.47.0版本前的Nginx Ingress Controller,需要在Ingress规则里的Host字段中填写您的业务域名,不能为空。
解决方案
-
根据上述原因,修改
nginx.ingress.kubernetes.io/canary: "true"
或Ingress规则里的Host字段。详细信息,请参见 路由规则 。 - 如果上述情况不符合,请参见 流量分发与灰度规则不一致或其它流量进入灰度服务 。
流量分发与灰度规则不一致或其它流量进入灰度服务
问题现象
设置了灰度规则,但是流量没有按照灰度规则进行分发,或者有其它正常Ingress的流量进入灰度服务。
问题原因
Nginx Ingress Controller中,灰度规则不是应用单个Ingress上,而是会应用在所有使用同一个Service的Ingress上。
关于产生该问题的详情,请参见 带有灰度规则的Ingress将影响所有具有相同Service的Ingress 。
解决方案
针对需要开启灰度的Ingress(包括使用service-match和
canary-*
相关Annotation),创建独立的Service(包括正式和灰度两个Service)指向原有的Pod,然后再针对该Ingress启用灰度。
创建Ingress资源时报错 "failed calling webhook"
问题现象
添加Ingress资源时显示"Internal error occurred: failed calling webhook...",如下图所示。

问题原因
在添加Ingress资源时,需要通过服务(默认为ingress-nginx-controller-admission)验证Ingress资源的合法性。如果链路出现问题,(例如服务被删除,Ingress controller被删除时),会导致验证失败,拒绝添加Ingress资源。
解决方案
- 按照Webhook链路检查资源是否均存在且正常工作,链路为ValidatingWebhookConfiguration->Service->Pod。
- 确认Ingress Controller Pod的admission功能已打开,且能够正常从外部访问到该Pod。
- 如果Ingress Controller已被删除或不需要Webhook功能,可以直接将ValidatingWebhookConfiguration资源删除。
HTTPS访问报SSL_ERROR_RX_RECORD_TOO_LONG错误
问题现象
访问HTTPS时报错
SSL_ERROR_RX_RECORD_TOO_LONG
或
routines:CONNECT_CR_SRVR_HELLO:wrong version number
。
问题原因
HTTPS请求访问到了非HTTPS端口,例如HTTP端口。
- SLB的443端口绑定了Ingress Pod的80端口。
- Ingress Controller所对应服务的Service 443端口映射到了Ingress Pod的80端口。
解决方案
根据实际情况修改SLB设置或Service设置,使得HTTPS能够访问到正确的端口。
出现常见HTTP错误码
问题现象
请求出现非2xx、非3xx错误,例如502、503、413、499等错误。
问题原因及解决方案
查看日志,判断是否为Ingress Controller返回的错误。具体方法,请参见 通过日志服务SLS的Controller Pod查看访问日志 。若是,请参考以下解决方案:
-
413错误
- 问题原因:请求大小超过了最大限制。
- 解决方案:在ConfigMap中调大proxy-body-size的值(组件默认为1 M,ACK Ingress Controller中默认设置了20 M)
-
499错误
- 问题原因:客户端由于某些原因提前断开了连接,不一定是组件或者后端业务问题。
-
解决方案:
- 有少量499错误时,取决于业务,可能为正常现象,可以忽略。
- 有大量499错误时,请检查后端业务处理时间和前端请求超时时间是否符合预期。
-
502错误
- 问题原因:Ingress Controller无法正常连接到后端。
-
解决方案:
-
偶发情况
- 检查后端业务负载是否正常,若负载过高,尝试对后端业务进行扩容。
- Ingress Controller默认使用HTTP1.1请求访问后端服务,且keepalive默认开启,确认配置的后端keepalive的连接超时时间大于Ingress Controller的连接超时时间(默认60s)。
-
必现情况
检查后端Service端口配置是否正确,能否在Controller Pod中手动访问到。
- 以上方法都无法确定问题的情况下,请进行抓包分析,并 提交工单 处理。
-
偶发情况
-
503错误
- 问题原因:Ingress Controller没有找到后端Pod,或所有Pod均无法访问。
-
解决方案:
-
偶发情况
- 查看502错误解决方案。
- 检查后端业务就绪状态,配置合理健康检查。
-
必现情况
检查后端Service配置是否正确,是否存在Endpoint。
- 以上方法都无法确定问题的情况下,请 提交工单 处理。
-
偶发情况
出现net::ERR_HTTP2_SERVER_REFUSED_STREAM错误
问题现象
访问网页时,部分资源无法正确加载,控制台中有
net::ERR_HTTP2_SERVER_REFUSED_STREAM
或
net::ERR_FAILED
报错。
问题原因
资源并行请求数较多,达到HTTP2最大流数限制。
解决方案
-
(推荐)在ConfigMap中根据实际需要,调整
http2-max-concurrent-streams
至更大值(默认128)。具体操作,请参见 http2-max-concurrent-streams 。 -
在ConfigMap中直接关闭HTTP2支持,设置
use-http2
为false
。具体操作,请参见 use-http2 。
出现报错“The param of ServerGroupName is illegal”
问题原因
ServerGroupName的生成格式是
namespace+svcName+port
。服务器组名称为长度为2~128个字符,必须以大小写字母或中文开头,可包含数字、半角句号(.)、下划线(_)和短划线(-)。
解决方案
按照服务器组名称的格式要求修改。
创建Ingress时报错“certificate signed by unknown authority”

问题原因
创建Ingress时,出现上图报错,原因是布置了多套Ingress,而各Ingress之间使用了相同的资源 (可能包括Secret、服务、Webhook配置等),导致Webhook执行时与后端服务通信时使用的SSL证书不一致,从而出现错误。
解决方案
重新部署两套Ingress,两套Ingress包含的资源不能重复。关于Ingress中包含的资源信息,请参见 在ACK组件管理中升级Nginx Ingress Controller组件时,系统所做的更新是什么? 。
Ingress Pod健康检查失败导致重启
问题现象
Controller Pod出现健康检查失败导致Pod重启。
问题原因
- Ingress Pod或所在节点负载较高,导致健康检查失败。
-
集群节点上设置了
tcp_tw_reuse
或tcp_tw_timestamps
内核参数,可能会导致健康检查失败。
解决方案
- 对Ingress Pod进行扩容,观察是否还有该现象。具体操作,请参见 部署高可靠的Ingress接入层 。
-
关闭
tcp_tw_reuse
或设置为2,且同时关闭tcp_tw_timestamps
,观察是否还有该现象。
添加TCP、UDP服务
-
在对应ConfigMap中(默认为kube-system命名空间下的tcp-services和udp-services)添加对应条目。
例如default空间下example-go的8080端口映射到9000端口,示例如下。
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: ingress-nginx data: 9000: "default/example-go:8080" #8080端口映射到9000端口。
- 在Ingress Deployment中(默认为kube-system命名空间下的nginx-ingress-controller)添加所映射的端口。
-
在Ingress对应的Service中添加所映射的端口。
示例如下:
apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: type: LoadBalancer ports: - name: http port: 80 targetPort: 80 protocol: TCP - name: https port: 443 targetPort: 443 protocol: TCP - name: proxied-tcp-9000 port: 9000 targetPort: 9000 protocol: TCP selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx
关于添加TCP和UDP服务的更多信息,请参见 暴露TCP和UDP服务 。
Ingress规则没有生效
问题现象
添加或修改了Ingress规则,但是没有生效。
问题原因
- Ingress配置出现错误,导致新的Ingress规则无法被正确加载。
- Ingress资源配置错误,与预期配置不相符。
- Ingress Controller的权限出现问题,导致无法正常监视Ingress资源变动。
-
旧的Ingress使用了
server-alias
配置了域名,与新的Ingress冲突,导致规则被忽略。
- 使用智能运维控制台的Ingress诊断工具进行诊断,并按照提示进行操作。具体操作,请参见 使用Ingress诊断功能 。
-
检查旧的Ingress有无配置错误或配置冲突问题:
-
针对非
rewrite-target
,且路径中使用了正则表达式的情况,确认Annotation中配置了nginx.ingress.kubernetes.io/use-regex: "true"
。 -
检查PathType是否与预期相符(
ImplementationSpecific
默认与Prefix
作用相同)。
-
针对非
- 确认与Ingress Controller相关联的ClusterRole、ClusterRoleBinding、Role、RoleBinding、ServiceAccount都存在。默认名称均为ingress-nginx。
- 进入Controller Pod容器,查看 nginx.conf 文件中已添加了规则。
-
执行以下命令,手动查看容器日志,确定问题。
kubectl logs <ingress pod name> -n <pod namespace> | grep -E ^[EW]
重写到根目录后部分资源无法加载或白屏
问题现象
通过Ingress
rewrite-target
annotation重写访问后,页面部分资源无法加载,或出现白屏。
问题原因
-
rewrite-target
可能没有使用正则表达式进行配置。 - 业务中请求资源路径写死在根目录。
解决方案
-
检查
rewrite-target
是否配合正则表达式以及捕获组一起使用。具体操作,请参见 Rewrite 。 - 检查前端请求是否访问到了正确的路径。
当版本升级后SLS解析日志不正常怎样修复
问题现象
ingress-nginx-controller组件当前主要有0.20和0.30两个版本,当通过控制台的 组件管理 从0.20升级到0.30版本后 ,在使用Ingress的灰度或蓝绿发布功能时,Ingress Dashboard会出现无法正确展示实际后端服务访问的情况。
问题原因
由于0.20和0.30默认输出格式不同,在使用Ingress的灰度或蓝绿发布功能时,Ingress Dashboard会出现无法正确展示实际后端服务访问的情况。
解决方案
执行以下操作步骤进行修复,更新
nginx-configuration configmap
和
k8s-nginx-ingress
配置。
-
更新
nginx-configuration configmap
。-
如果您没有修改过
nginx-configuration configmap
,保存以下内容为nginx-configuration.yaml
, 然后执行kubectl apply -f nginx-configuration.yaml
命令进行部署。apiVersion: v1 kind: ConfigMap data: allow-backend-server-header: "true" enable-underscores-in-headers: "true" generate-request-id: "true" ignore-invalid-headers: "true" log-format-upstream: $remote_addr - [$remote_addr] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name] max-worker-connections: "65536" proxy-body-size: 20m proxy-connect-timeout: "10" reuse-port: "true" server-tokens: "false" ssl-redirect: "false" upstream-keepalive-timeout: "900" worker-cpu-affinity: auto metadata: labels: app: ingress-nginx name: nginx-configuration namespace: kube-system
-
如果您修改过
nginx-configuration configmap
,为了避免覆盖您的配置,执行以下命令进行修复:kubectl edit configmap nginx-configuration -n kube-system
在
log-format-upstream
字段末尾,添加[$proxy_alternative_upstream_name]
, 然后保存退出。 -
如果您没有修改过
-
更新
k8s-nginx-ingress
配置。将以下内容保存为k8s-nginx-ingress.yaml
文件,然后执行kubectl apply -f k8s-nginx-ingress.yaml
命令进行部署。apiVersion: log.alibabacloud.com/v1alpha1 kind: AliyunLogConfig metadata: namespace: kube-system # your config name, must be unique in you k8s cluster name: k8s-nginx-ingress spec: # logstore name to upload log logstore: nginx-ingress # product code, only for k8s nginx ingress productCode: k8s-nginx-ingress # logtail config detail logtailConfig: inputType: plugin # logtail config name, should be same with [metadata.name] configName: k8s-nginx-ingress inputDetail: plugin: inputs: - type: service_docker_stdout detail: IncludeLabel: io.kubernetes.container.name: nginx-ingress-controller Stderr: false Stdout: true processors: - type: processor_regex detail: KeepSource: false Keys: - client_ip - x_forward_for - remote_user - time - method - url - version - status - body_bytes_sent - http_referer - http_user_agent - request_length - request_time - proxy_upstream_name - upstream_addr - upstream_response_length - upstream_response_time - upstream_status - req_id - host - proxy_alternative_upstream_name NoKeyError: true NoMatchError: true Regex: ^(\S+)\s-\s\[([^]]+)]\s-\s(\S+)\s\[(\S+)\s\S+\s"(\w+)\s(\S+)\s([^"]+)"\s(\d+)\s(\d+)\s"([^"]*)"\s"([^"]*)"\s(\S+)\s(\S+)+\s\[([^]]*)]\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s*(\S*)\s*\[*([^]]*)\]*.* SourceKey: content
常见Controller错误日志
问题现象
User "system:serviceaccount:kube-system:ingress-nginx" cannot list/get/update resource "xxx" in API group "xxx" at the cluster scope/ in the namespace "kube-system"
问题原因
Nginx Ingress Controller缺少对应权限更新对应资源。
解决方案
-
根据日志确认问题是由于ClusteRole还是Role产生的。
-
日志中包含
at the cluster scope
,问题则产生自ClusterRole(ingress-nginx)。 -
日志中包含
in the namespace "kube-system"
,问题则产生自Role(kube-system/ingrerss-nginx)。
-
日志中包含
-
确认对应权限以及权限绑定是否完整。
-
对于ClusterRole:
-
确保ClusterRole
ingress-nginx
以及ClusterRoleBindingingress-nginx
存在。若不存在,可以考虑自行新建恢复、卸载组件重装或者 提交工单 寻求帮助。 -
确保ClusterRole
ingress-nginx
中包含日志中所对应的权限(图例中为networking.k8s.io/ingresses的List权限)。若权限不存在,可以手动添加至ClusterRole中。
-
确保ClusterRole
-
对于Role:
-
确认Role
kube-system/ingress-nginx
以及RoleBindingkube-system/ingress-nginx
存在。若不存在,可以考虑自行新建恢复、卸载组件重装或者 提交工单 寻求帮助。 -
确认Role
ingress-nginx
中包含日志中所对应权限(图例中为ConfigMapingress-controller-leader-nginx
的Update权限)。若权限不存在,可以手动添加至Role中。
-
确认Role
-
对于ClusterRole:
问题现象
requeuing……nginx: configuration file xxx test failed(多行内容)
问题原因
配置错误,导致Nginx配置reload失败,一般为Ingress规则或ConfigMap中插入的Snippet语法错误导致的。
解决方案
-
查看日志中错误提示(warn等级的提示可忽略),大体定位问题位置。若错误提示不够清晰,可以根据错误提示中文件的行数,进入Pod中查看对应文件。以下图为例,文件为/tmp/nginx/nginx-cfg2825306115的第449行。
执行如下命令,查看对应行附近的配置有无错误。
# 进入Pod执行命令。 kubectl exec -n <namespace> <controller pod name> -it -- bash # 带行数信息查看出错的文件,在输出中查看对应行附近的配置有无错误。 cat -n /tmp/nginx/nginx-cfg2825306115
- 根据错误提示和配置文件,根据自身实际配置,定位错误原因并修复。
问题现象
Unexpected error validating SSL certificate "xxx" for server "xxx"

问题原因
证书配置错误,常见的原因有证书所包含域名与Ingress中配置域名不一致。部分Warning等级日志不会影响到证书的正常使用(如证书中未携带SAN扩展等),请根据实际情况判断是否出现问题。
解决方案
- 证书的cert和key格式和内容是否正确。
- 证书所包含域名与Ingress中所配置域名是否一致。
- 证书有无过期。