Featured image of post K8s 集群流量入口:Ingress-nginx 七层与 TCP/UDP 四层代理实战

K8s 集群流量入口:Ingress-nginx 七层与 TCP/UDP 四层代理实战

Pod IP 与 Service IP 只能在集群内访问,要从集群外访问 K8s 服务有 NodePort / LoadBalancer / Ingress 等方式。本文系统讲清 ingress-nginx 的七层 HTTP 反向代理、四层 TCP/UDP 转发、hostNetwork 模式、TLS 终端、Nacos 反代以及常见排错,是生产级二进制 K8s 集群流量入口的一站式笔记。

K8s 集群流量入口:Ingress-nginx 七层与 TCP/UDP 四层代理实战

TL;DR:在 K8s 里 Pod IP / ClusterIP 只能在集群内访问。要把服务暴露到集群外,常见链路是 ingress-nginx(七层 HTTP)→ Service(ClusterIP)→ Pod;非 HTTP 的 TCP/UDP 流量(数据库、MQTT、WebSocket、SSH)走 ingress-nginx 的 四层 stream-snippet / ConfigMaphostNetwork + DaemonSet 模式。本文是一份基于生产二进制集群踩坑的实战笔记。

一、为什么需要 Ingress(When to use)

K8s 提供了 4 种把集群内服务暴露到外部的方式:

方式适用场景优点缺点
NodePort开发测试、单端口临时调试简单,配置最少端口范围受限(30000-32767),要逐个开防火墙
LoadBalancer云厂商环境自动化分配公网 IP依赖云厂商 LB,每个 Service 一个 LB 贵
IngressHTTP/HTTPS 七层路由,多域名多路径一台 LB 服务多套系统,支持 TLS 终止、灰度只能代理 HTTP/HTTPS
hostNetwork四层流量 + 极致性能走宿主机网络,无 kube-proxy 转发损耗一个 Node 只能跑一个 Pod,要配 nodeSelector

核心架构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
外网 (Client)
[ NodePort / LoadBalancer / hostNetwork ]
[ ingress-nginx-controller ]   ← 七层:解析 Host / Path
[ Service (ClusterIP) ]         ← 集群内虚拟 IP
[ Pod (业务容器) ]

原则:ingress 代理 service,service 代理 pod。Ingress 本身不直接连 Pod,一定要过 Service 这一层(service mesh 也是同理)。

API 版本注意:本文示例全部使用 apiVersion: networking.k8s.io/v1(K8s 1.19 GA,1.22 起 extensions/v1beta1 被彻底移除)。kubernetes.io/ingress.class 注解在 1.18 后也已被 spec.ingressClassName 取代,请直接使用新写法。

二、安装 ingress-nginx

2.1 部署清单来源

⚠️ 版本匹配:K8s 1.19+ 务必使用 ingress-nginx v0.46+(首个 networking.k8s.io/v1 稳定支持的 controller),2020 年下半年该分支已 GA。

2.2 应用与查看

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 部署
kubectl apply -f /etc/k8s/ingress-nginx/deploy.yaml

# 删除
kubectl delete -f /etc/k8s/ingress-nginx/deploy.yaml

# 部署后产生的核心资源
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

2.3 资源清单

1
kubectl get all -n ingress-nginx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-cf9w5        0/1     Completed   0          7m36s
pod/ingress-nginx-admission-patch-zm7m5         0/1     Completed   0          7m36s
pod/ingress-nginx-controller-766bcbf897-fhvrb   1/1     Running     0          7m36s

NAME                                         TYPE        CLUSTER-IP       PORT(S)
service/ingress-nginx-controller             NodePort    10.x.x.x         80:30080/TCP,443:30443/TCP
service/ingress-nginx-controller-admission   ClusterIP   10.x.x.x         443/TCP

NAME                                       READY   UP-TO-DATE   AVAILABLE
deployment.apps/ingress-nginx-controller   1/1     1            1

这里的 ingressclass.networking.k8s.io/nginx 是 v1 引入的 IngressClass 对象,下游 Ingress 资源靠 spec.ingressClassName: nginx 引用它。

三、最简七层反代测试

3.1 测试 Deployment / Service / Ingress

 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
26
27
28
29
30
31
32
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: test
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# ingress.yaml(networking.k8s.io/v1)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: test
spec:
  ingressClassName: nginx
  rules:
    - host: nginx.example.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
1
2
3
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

3.2 查看 Ingress 解析结果

1
kubectl describe ingress test-ingress -n test
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Name:             test-ingress
Namespace:        test
Address:          10.x.x.x
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host             Path  Backends
  ----             ----  --------
  nginx.example.com
                   /    nginx-service:80 (10.244.1.10:80, 10.244.2.71:80, 10.244.3.8:80)
Events:
  Type    Reason  Age                   From                      Message
  ----    ------  ----                  ----                      -------
  Normal  Sync    110s (x2 over 2m22s)  nginx-ingress-controller  Scheduled for sync

3.3 本地 hosts + curl 测试

1
2
3
4
5
6
7
8
# /etc/hosts(开发机)
# 内网IP-A nginx.example.com tomcat.example.com

# 直接访问 NodePort
curl -H "Host: nginx.example.com" http://内网IP-A:30080/

# 或先 ping 测连通
ping 内网IP-A

v1 与 v1beta1 的关键差异(写错会 apply 失败):

字段extensions/v1beta1(已弃用)networking.k8s.io/v1(本文用)
apiVersionextensions/v1beta1networking.k8s.io/v1
路径匹配path: /foo(隐式 Prefix)path: /foo + pathType: Prefix | Exact | ImplementationSpecific(必填)
后端backend.serviceName + servicePortbackend.service.name + backend.service.port.number/name
Ingress 类注解 kubernetes.io/ingress.class: nginxspec.ingressClassName: nginx

四、关键注解(Annotations)速查

完整注解列表:https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md

4.1 不配置 host,用路径区分服务(Nacos 场景)

把 Nacos 控制台通过 /nacos 路径前缀反代出去,不绑定 host

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nacos-ingress
  namespace: example-corp
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - pathType: Prefix
            path: /nacos
            backend:
              service:
                name: nacos-headless
                port:
                  name: server

访问地址:http://内网IP-A/nacos

注意:当 host 字段省略,Ingress 会响应所有到达 controller 的请求,生产环境强烈建议绑定 host 防止冲突。如果一定要多服务复用 host,请用 pathType: Prefix 拆分路径。

4.2 app-root:访问根路径自动重定向

1
2
3
metadata:
  annotations:
    nginx.ingress.kubernetes.io/app-root: /corp

访问 https://example-corp.com/ 会 302 到 https://example-corp.com/corp,适合老门户的默认页迁移。

五、hostNetwork 模式:性能 + 四层必备

默认 ingress-nginx-controller 是 Deployment + Service(NodePort),但生产环境有两类需求让它不够用:

  1. 直接监听 80/443 端口——不想用 30080/30443 这种高位端口
  2. 代理 TCP/UDP 四层流量——NodePort 不支持 stream

解决方案:hostNetwork: true + DaemonSet + nodeSelector,让 controller 在每个打了 ingress=true 标签的 Node 上独占监听宿主机网络

5.1 修改清单的关键点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
spec:
  # 1. 改成 DaemonSet:一个 Node 只能跑一个 controller
  kind: DaemonSet

  template:
    spec:
      # 2. 与宿主机共享网络栈
      hostNetwork: true

      # 3. 节点选择器
      nodeSelector:
        kubernetes.io/os: linux
        ingress: "true"

      # 4. hostNetwork 模式下要保留 K8s DNS
      dnsPolicy: ClusterFirstWithHostNet

删除 replicasstrategy.rollingUpdate 等 Deployment 专属字段。

5.2 给 Node 打标签

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 打标签
kubectl label node k8s-master-1 ingress=true
kubectl label node k8s-master-2 ingress=true
kubectl label node k8s-master-3 ingress=true

# 移除标签
kubectl label node k8s-master-3 ingress=true-

# 容忍 NoSchedule 污点(master 节点常有)
kubectl taint nodes k8s-master-1 node-role.kubernetes.io/control-plane:NoSchedule-

# 查看所有节点标签
kubectl get node --show-labels

5.3 部署与验证

1
2
3
4
5
6
7
8
# 先删旧 Deployment
kubectl delete -f /etc/k8s/ingress-nginx/deploy.yaml

# 部署新清单
kubectl apply -f /etc/k8s/ingress-nginx/hostNetwork.yaml

# 查看 controller 是否在每个 Node 跑一个
kubectl get pods -n ingress-nginx -o wide
1
2
3
4
NAME                             READY   STATUS    IP                NODE
ingress-nginx-controller-cd58b   1/1     Running   内网IP-B          k8s-master-2
ingress-nginx-controller-cgzk7   1/1     Running   内网IP-C          k8s-master-1
ingress-nginx-controller-p2fdt   1/1     Running   内网IP-D          k8s-master-3

5.4 验证四层与七层

1
2
3
4
5
# 七层:80 端口直接访问
curl http://nginx.example.com

# 四层:可以走 NodePort 也可以走宿主机 IP 直连
curl -H "Host: nginx.example.com" http://内网IP-A

六、四层代理:代理集群外的 TCP / WS / UDP

ingress-nginx 默认只代理 HTTP / HTTPS。要让 ingress-nginx 转发 TCP / UDP 流量(如 MySQL 3306、MQTT 1883、自定义 WebSocket),有三种方案:

6.1 方案对比

方案适用场景优点缺点
stream-snippet 注解单个 Ingress 临时使用配置最简单不易复用
ConfigMap 集中管理多服务、需统一管理一个 CM 管多个端口要修改 DaemonSet args
ExternalName + Service集群内 Pod 访问集群外应用侧零配置集群外无法反向访问

6.2 方案一:使用 Endpoints + Service + Ingress + stream-snippet

核心思路:用 Endpoints 直接指向集群外的 IP:PORT,再通过 Ingress 的 stream-snippet 注解把流量引过去。

⚠️ Endpoints.name 必须和 Service.name 完全一致——这是手写四层 Service 的铁律,写错 Service 永远 no endpoints available

 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
# tcp-outside-3306.yaml
apiVersion: v1
kind: Endpoints
metadata:
  name: external-mysql
  namespace: example-corp
subsets:
  - addresses:
      - ip: 内网IP-E       # 集群外的 MySQL 真实地址
    ports:
      - port: 3306
        protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: external-mysql
  namespace: example-corp
spec:
  clusterIP: None          # Headless Service,由 Endpoints 决定后端
  type: ClusterIP
  ports:
    - port: 7306           # 集群内访问用的端口
      protocol: TCP
      targetPort: 3306     # 转发到 Endpoints 里的 3306
 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
# tcp-outside-3306-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: external-mysql-ingress
  namespace: example-corp
  annotations:
    nginx.ingress.kubernetes.io/stream-snippet: |
      server {
        listen 8000;
        proxy_pass 内网IP-E:3306;
      }
spec:
  ingressClassName: nginx
  rules:
    - host: mysql.example-corp.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: external-mysql
                port:
                  number: 7306

TCP 流量不要用 HTTP 测:四层流量没有 Host 头,curl http://内网IP-A:8000 会一直 400。正确姿势:nc -vz 内网IP-A 8000telnet 内网IP-A 8000

6.3 方案二:ConfigMap 集中管理(推荐生产用)

第一步:创建 ConfigMap 占位

1
kubectl -n ingress-nginx create configmap tcp-services

第二步:编辑 ConfigMap

1
kubectl edit -n ingress-nginx cm tcp-services
1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  # 格式:"<对外端口>": "<namespace>/<service>:<service-port>"
  "7306": "example-corp/external-mysql:7306"
  "1883": "example-corp/mqtt-service:1883"

第三步:让 controller 加载 ConfigMap

1
kubectl edit -n ingress-nginx DaemonSet/ingress-nginx-controller
1
2
3
4
5
6
7
8
spec:
  template:
    spec:
      containers:
        - args:
            - /nginx-ingress-controller
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services

重要:$(POD_NAMESPACE) 是 controller 自带的 downward API 变量,会自动展开为 ingress-nginx,不要手写死。

第四步:补充 Service 端口暴露

1
kubectl edit -n ingress-nginx Service/ingress-nginx-controller
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
    - name: external-mysql
      port: 7306
      targetPort: 7306
      protocol: TCP

第五步:调整 Service 类型与 externalIPs

1
2
3
# 类型改为 LoadBalancer(云厂商自动分配 IP)
kubectl patch svc ingress-nginx-controller -n ingress-nginx \
  -p '{"spec": {"type": "LoadBalancer", "externalIPs":["内网IP-A"]}}'

6.4 集群内测试连通

 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
26
# 用 busybox 测连通
kubectl exec -it busybox -- sh
ping external-mysql.example-corp.svc.cluster.local
telnet external-mysql.example-corp.svc.cluster.local 3306

# 用 ubuntu + mycli 工具测
cat << "EOF" > ubuntu.yml
apiVersion: v1
kind: Pod
metadata:
  name: diag-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:22.04
      command: [ "/bin/bash", "-c", "--" ]
      args: [ "while true; do sleep 3600; done;" ]
EOF

kubectl apply -f ubuntu.yml
kubectl exec -it diag-pod -- bash
apt update && apt install -y python3-pip
pip3 install mycli

# 用 K8s Service DNS 名连接(注意改密码)
mycli -h external-mysql.example-corp.svc.cluster.local -uroot -p'<REDACTED-MYSQL-PWD>'

七、TLS 终端

7.1 创建 Secret

1
2
3
4
5
6
7
8
# 先建命名空间
kubectl create namespace example-corp

# 从证书文件创建 TLS Secret
kubectl create secret generic www-example-corp-secret \
  --from-file=tls.key=<CERT_ID>__example-corp.com.key \
  --from-file=tls.crt=<CERT_ID>__example-corp.com.pem \
  -n example-corp

7.2 开启 configuration-snippet

ingress-nginx v0.46+ 默认禁用 configuration-snippet(安全考量),要自定义 nginx 片段必须先开:

1
kubectl edit -n ingress-nginx configmap/ingress-nginx-controller
1
2
data:
  allow-snippet-annotations: "true"   # 允许使用 configuration-snippet 注解

7.3 启用 TLS 的 Ingress

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
apiVersion: v1
kind: Endpoints
metadata:
  name: www-service
  namespace: example-corp
subsets:
  - addresses:
      - ip: 内网IP-F
    ports:
      - port: 81
        protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: www-service
  namespace: example-corp
spec:
  ports:
    - port: 81
      targetPort: 81
      protocol: TCP
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: www-ingress
  namespace: example-corp
  annotations:
    nginx.ingress.kubernetes.io/app-root: /corp
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      access_log /var/log/nginx/www.example-corp.com.access.log upstreaminfo if=$loggable;
      error_log  /var/log/nginx/www.example-corp.com.error.log;
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example-corp.com
        - www.example-corp.com
      secretName: www-example-corp-secret
  rules:
    - host: www.example-corp.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: www-service
                port:
                  number: 81
    - host: example-corp.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: www-service
                port:
                  number: 81
1
kubectl apply -f /etc/k8s/ingress/www-ingress.yaml

访问:https://example-corp.com https://www.example-corp.com

八、WebSocket 代理

ingress-nginx 默认支持 WebSocket,但要在 location 里显式设置:

1
2
3
4
5
6
7
8
9
location / {
    proxy_pass         http://backend;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade    $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_set_header   Host       $host;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_read_timeout 3600s;            # 长连接超时
}

在 ingress-nginx 里用注解实现:

1
2
3
4
5
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    # WebSocket 自动识别 Connection: Upgrade

默认 60s 不发包就断,WebSocket / 长轮询场景必须把 read/send timeout 拉到 3600s 以上,否则客户端会频繁断连。

九、Nacos 反代实战

Nacos Headless Service(clusterIP: None)+ Ingress 是社区最常见的"在 K8s 外面访问 Nacos 控制台"姿势:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 假设 Nacos 已经用 Helm 或 Operator 部署好
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nacos-console
  namespace: nacos
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
spec:
  ingressClassName: nginx
  rules:
    - host: nacos.example-corp.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: nacos-headless
                port:
                  name: server   # 8848,对应 service.port.name

同样适用 Apollo、Consul、Sentinel Dashboard 等"控制台类服务"。use-regex: "true" 是因为 Nacos 前端路由里有 /#/xxx 这种 hash 路径,不开 regex 会被当成物理路径处理。

十、常见 8 个坑

#现象解决
1用了 extensions/v1beta1K8s 1.22+ 直接 apply 失败 no matches for kind改用 networking.k8s.io/v1pathType 必填
2忘写 pathTypenetworking.k8s.io/v1 apply 报 pathType Required value路径下必须显式 pathType: Prefix | Exact | ImplementationSpecific
3Windows 能 ping 通但浏览器打不开hosts 配了域名,ping 通,浏览器 502关代理、关防火墙;netsh winsock reset 重启
4客户端开了代理工具后无法访问 Ingress浏览器挂了科学上网工具,所有流量走代理,Ingress 不通代理工具"Bypass Domain/IP"里加业务域名;或选"全球直连"
5Endpoints.name 与 Service.name 不一致Service 一直无 Endpoints,curl 报 no endpoints available严格保持两个 name 一致;这是 K8s 老坑
6hostNetwork 模式下 DNS 解析错乱Pod 用宿主机 /etc/resolv.conf,找不到集群内服务dnsPolicy: ClusterFirstWithHostNet
7DaemonSet 配了 replicas 字段apply 时报 validation error删掉 replicasstrategy.rollingUpdate
8configuration-snippet 不生效自定义 nginx 片段被忽略ConfigMap 里设 allow-snippet-annotations: "true"
9TCP 走 8000 端口但用 HTTP 测telnet 通,curl 失败四层不能用 HTTP 探测;用 nc -vztelnet

十一、核心 6 点速记

  1. 链路:外网 → NodePort/hostNetwork → ingress-nginx → Service → Pod
  2. 七层(HTTP)用 Ingress四层(TCP/UDP)用 stream-snippetConfigMap + DaemonSet args
  3. 生产必开 hostNetwork:直连 80/443 + 支持四层;必须配 DaemonSet + nodeSelector + dnsPolicy: ClusterFirstWithHostNet
  4. Endpoints.name == Service.name 是手写四层 Service 的铁律
  5. TLS 终端走 Ingress tls.hosts + secretName;自定义 nginx 片段需先开 allow-snippet-annotations
  6. Ingress 不直接连 Pod:中间一定要过 Service(service mesh 同样),不要图省事

十二、排错命令速查

 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
26
27
# 查看 controller 配置
kubectl exec -it <pod> -n ingress-nginx -- cat /etc/nginx/nginx.conf

# 实时日志
kubectl logs -f -n ingress-nginx <pod>

# 集群内连通性
kubectl exec -it busybox -- sh
ping <svc>.<ns>.svc.cluster.local

# Service 详情
kubectl describe svc <svc-name> -n <ns>
kubectl describe endpoints <svc-name> -n <ns>

# Ingress 状态
kubectl get ingress -A
kubectl describe ingress <name> -n <ns>

# IngressClass 引用关系
kubectl get ingressclass
kubectl get ingress -A -o jsonpath='{range .items[?(@.spec.ingressClassName)]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'

# hostNetwork 模式查看端口监听
ss -tlnp | grep -E ":(80|443|3306|1883)"

# 检查 controller 加载的 TCP/UDP ConfigMap
kubectl logs -n ingress-nginx <pod> | grep -E "tcp-services|stream-snippet"

十三、参考资料

使用 Hugo 构建
主题 StackJimmy 设计