说在开头:本文所 实例放在结尾,测试实验可先跳至文末提取。需要注意修改image源
访问流程图

步骤一:确认 Ingress 环境就绪
1.1 检查 Ingress Controller 状态
# 检查 ingress controller 的 Pod 是否运行
kubectl get pods -n ingress-nginx
# 检查 ingress controller 的 Service
kubectl get svc -n ingress-nginx
实例输出:
[root@k8s-m01 ~]# kubectl -n ingress-nginx get pods
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-f7c47664d-mtrt4 1/1 Running 6 (6m51s ago) 5h15m
[root@k8s-m01 ~]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.107.119.188 <none> 80:30458/TCP,443:30634/TCP 5h15m
ingress-nginx-controller-admission ClusterIP 10.102.128.196 <none> 443/TCP 5h15m
[root@k8s-m01 ~]#
1.2 检查应用和 Service
# 检查应用 Pod
kubectl get pods -l app=my-app
# 检查 Service
kubectl get svc my-app-service
实例输出:
[root@k8s-m01 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
apple-app-5955985997-4wc4b 1/1 Running 4 (9m1s ago) 5h51m app=apple,pod-template-hash=5955985997
apple-app-5955985997-5vxcp 1/1 Running 4 (8m59s ago) 5h51m app=apple,pod-template-hash=5955985997
banana-app-5fc5fb864b-bpfh8 1/1 Running 4 (8m59s ago) 5h51m app=banana,pod-template-hash=5fc5fb864b
banana-app-5fc5fb864b-h55ld 1/1 Running 4 (8m59s ago) 5h51m app=banana,pod-template-hash=5fc5fb864b
nginx-deployment-5c89bd966f-4979d 1/1 Running 4 (8m59s ago) 5h51m app=nginx,pod-template-hash=5c89bd966f
nginx-deployment-5c89bd966f-q72fm 1/1 Running 4 (8m59s ago) 5h51m app=nginx,pod-template-hash=5c89bd966f
nginx-deployment-5c89bd966f-x62b9 1/1 Running 4 (9m1s ago) 5h51m app=nginx,pod-template-hash=5c89bd966f
[root@k8s-m01 ~]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
apple-service ClusterIP 10.107.5.38 <none> 80/TCP 22h app=apple
banana-service ClusterIP 10.108.121.94 <none> 80/TCP 22h app=banana
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15d <none>
nginx-service ClusterIP 10.106.32.140 <none> 80/TCP 5d3h app=nginx
1.3 检查 Ingress 资源
# 查看已创建的 Ingress
kubectl get ingress
# 查看 Ingress 详细信息
kubectl describe ingress my-app-ingress
实例输出:
[root@k8s-m01 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx minikube.local 192.168.80.103 80 22h
minimal-ingress nginx example.ingress.com 192.168.80.103 80 5d3h
[root@k8s-m01 ~]# kubectl describe ingress example-ingress
Name: example-ingress
Labels: <none>
Namespace: default
Address: 192.168.80.103
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
minikube.local
/apple apple-service:80 (10.244.1.105:80,10.244.1.110:80)
/banana banana-service:80 (10.244.1.106:80,10.244.1.107:80)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 6h55m (x3 over 6h56m) nginx-ingress-controller Scheduled for sync
Normal Sync 5h1m (x2 over 5h2m) nginx-ingress-controller Scheduled for sync
Normal Sync 153m (x3 over 154m) nginx-ingress-controller Scheduled for sync
Normal Sync 50m (x3 over 51m) nginx-ingress-controller Scheduled for sync
Normal Sync 39m (x3 over 40m) nginx-ingress-controller Scheduled for sync
Normal Sync 7m13s (x3 over 8m13s) nginx-ingress-controller Scheduled for sync
步骤二:获取访问入口地址
根据你的环境选择相应的方法:
2.1 本地环境(Docker Desktop / Kind)
# 查看 Service 的 NodePort
kubectl get svc -n ingress-nginx ingress-nginx-controller
使用 localhost 或节点 IP + NodePort 访问
2.2 裸机环境
# 获取节点的 IP 地址
kubectl get nodes -o wide
# 获取 NodePort
kubectl get svc -n ingress-nginx ingress-nginx-controller
使用节点 IP + NodePort 访问
实例输出:
[root@k8s-m01 ~]# kubectl -n ingress-nginx get svc ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.107.119.188 <none> 80:30458/TCP,443:30634/TCP 5h24m
[root@k8s-m01 ~]# kubectl -n ingress-nginx get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-f7c47664d-mtrt4 1/1 Running 6 (16m ago) 5h24m 10.244.1.102 k8s-n02 <none> <none>
[root@k8s-m01 ~]# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-m01 Ready control-plane 15d v1.34.0 192.168.80.101 <none> CentOS Linux 7 (Core) 6.6.9-1.el7.elrepo.x86_64 docker://26.1.3
k8s-n01 Ready <none> 14d v1.34.0 192.168.80.102 <none> CentOS Linux 7 (Core) 6.6.9-1.el7.elrepo.x86_64 docker://26.1.4
k8s-n02 Ready <none> 14d v1.34.0 192.168.80.103 <none> CentOS Linux 7 (Core) 6.6.9-1.el7.elrepo.x86_64 docker://26.1.4
步骤三:配置域名解析
3.1 生产环境 - 配置真实 DNS
在域名服务商处添加 A 记录:
- 记录类型:
A - 主机记录:
my-app(或@表示根域名) - 记录值:
EXTERNAL-IP(步骤二获取的)
3.2 测试环境 - 配置本地 hosts 文件
注意: 解析的IP地址,是ingress-nginx-controller的POD后在的node节点的IP地址。
Windows 系统:
# 以管理员身份运行记事本或 PowerShell,编辑:
notepad C:\Windows\System32\drivers\etc\hosts
# 添加记录(将 IP 替换为你的实际 IP):
192.168.80.103 example.ingress.com
192.168.80.103 minikube.local
Linux/Mac 系统:
sudo vim /etc/hosts
# 添加记录:
192.168.80.103 example.ingress.com
192.168.80.103 minikube.local
实例输出:
[root@k8s-m01 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx minikube.local 192.168.80.103 80 23h
minimal-ingress nginx example.ingress.com 192.168.80.103 80 5d3h
[root@k8s-m01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.80.101 k8s-m01
192.168.80.102 k8s-n01
192.168.80.103 k8s-n02
192.168.80.104 k8s-n03
192.168.80.100 harbor.fq.com
192.168.80.103 example.ingress.com
192.168.80.103 minikube.local
步骤四:访问应用
使用节点 IP + NodePort 访问
[root@k8s-m01 ~]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.107.119.188 <none> 80:30458/TCP,443:30634/TCP 5h47m
4.1 使用浏览器访问
直接在浏览器地址栏输入:
http://my-app.example.com:30458
4.2 使用命令行测试
# 使用 curl 测试
curl http://my-app.example.com:NodePort
# 详细测试(显示响应头)
curl -v http://my-app.example.com
# 测试特定路径(如果配置了路径路由)
curl http://my-app.example.com/api/v1/users
实例输出:
[root@k8s-m01 ~]# curl http://example.ingress.com:30458
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-m01 ~]# curl http://minikube.local:30458/apple
<html><body><h1>I am a apple!</h1></body></html>
[root@k8s-m01 ~]# curl http://minikube.local:30458/banana
<html><body><h1>I am a banana!</h1></body></html>
4.3 测试不同域名(如果配置了多域名)
# 假设你还配置了 api.example.com
curl http://api.example.com
步骤五:验证和排查
如果无法访问,按以下顺序排查:
5.1 检查 DNS 解析
# 检查域名是否解析到正确 IP
nslookup my-app.example.com
# 或
ping my-app.example.com
5.2 检查网络连通性
# 测试是否能访问到入口 IP
telnet <EXTERNAL-IP> 80
# 或使用 curl 测试 IP(绕过 DNS)
curl http://<EXTERNAL-IP> -H "Host: my-app.example.com"
5.3 检查 Ingress 日志
# 查看 ingress controller 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller -f
# 查看具体的 ingress 资源事件
kubectl describe ingress my-app-ingress
5.4 检查后端应用
# 直接访问 Service 测试后端
kubectl port-forward svc/my-app-service 8080:80
# 然后在浏览器访问 http://localhost:8080
访问路径处理方案
实例一、应用部署文件(ingress-nginx-demo.yaml)
[root@k8s-m01 YAML]# cat ingress-nginx-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
#imagePullSecrets:
# - name: harbor-secret
containers:
- name: nginx
image: harbor.fq.com/public/nginx:1.27.3
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx-service
spec:
ports:
- port: 80
name: nginx-service
protocol: TCP
targetPort: 80
selector:
app: nginx
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: example.ingress.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
实例二 、 基于路径的路由:多path路径实例(fruits-ingress.yaml)
[root@k8s-m01 YAML]# cat apple.yaml
# apple.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apple-app
spec:
replicas: 2
selector:
matchLabels:
app: apple
template:
metadata:
labels:
app: apple
spec:
containers:
- name: apple-container
image: harbor.fq.com/public/nginx:1.27.3
ports:
- containerPort: 80
command:
- /bin/sh
- -c
- |
echo "<html><body><h1>I am a apple!</h1></body></html>" > /usr/share/nginx/html/index.html
nginx -g 'daemon off;'
---
apiVersion: v1
kind: Service
metadata:
name: apple-service
spec:
selector:
app: apple
ports:
- port: 80
targetPort: 80
[root@k8s-m01 YAML]# cat banana.yaml
#banana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: banana-app
spec:
replicas: 2
selector:
matchLabels:
app: banana
template:
metadata:
labels:
app: banana
spec:
containers:
- name: banana-container
image: harbor.fq.com/public/nginx:1.27.3
ports:
- containerPort: 80
command:
- /bin/sh
- -c
- |
echo "<html><body><h1>I am a banana!</h1></body></html>" > /usr/share/nginx/html/index.html
nginx -g 'daemon off;'
---
apiVersion: v1
kind: Service
metadata:
name: banana-service
spec:
selector:
app: banana
ports:
- port: 80
targetPort: 80
[root@k8s-m01 YAML]# cat fruits-ingress.yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fruits-ingress
annotations:
# 某些场景下可能需要注解,这里是一个通用示例
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # 指定使用 nginx ingress controller
rules:
- host: fruits.local # 假设的域名,在测试机上需要配置 hosts 文件
http:
paths:
- path: /apple
pathType: Prefix
backend:
service:
name: apple-service
port:
number: 80
- path: /banana
pathType: Prefix
backend:
service:
name: banana-service
port:
number: 80
访问验证
[root@k8s-m01 ~]# curl http://minikube.local:31913/apple
<html><body><h1>I am a apple!</h1></body></html>
[root@k8s-m01 ~]# curl http://minikube.local:31913/banana
<html><body><h1>I am a banana!</h1></body></html>
实例三、基于主机名的路由:多host实例(fruits-ingress-multi-host.yaml)
# fruits-ingress-multi-host.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fruits-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
# 访问 apple 服务
- host: apple.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apple-service
port:
number: 80
# 访问 banana 服务
- host: banana.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: banana-service
port:
number: 80
访问验证
[root@k8s-m01 YAML]# echo "192.168.80.102 apple.local" >> /etc/hosts
[root@k8s-m01 YAML]# echo "192.168.80.102 banana.local" >> /etc/hosts
[root@k8s-m01 YAML]# curl -k http://banana.local:30287
<html><body><h1>I am a banana!</h1></body></html>
[root@k8s-m01 YAML]# curl -k http://apple.local:30287
<html><body><h1>I am a apple!</h1></body></html>
实例四、 高级访问方式 HTTPS 访问
1、创建自签名证书
# 生成自签名证书(banana.local)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout banana.key -out banana.crt \
-subj "/CN=banana.local/O=banana"
# 创建 Kubernetes Secret(供容器和 Ingress 共用)
kubectl create secret tls banana-tls \
--cert=banana.crt \
--key=banana.key
2、检查 secrets
[root@k8s-m01 YAML]# kubectl get secrets
NAME TYPE DATA AGE
banana-tls kubernetes.io/tls 2 17h
harbor-secret kubernetes.io/dockerconfigjson 1 15d
3、修改banana的配置,添加tls认证,端口修改为443 banana-tls-deployment.yaml
# banana-tls-deployment.yaml(修正版)
apiVersion: apps/v1
kind: Deployment
metadata:
name: banana-app
spec:
replicas: 2
selector:
matchLabels:
app: banana
template:
metadata:
labels:
app: banana
spec:
containers:
- name: banana-container
image: harbor.fq.com/public/nginx:1.27.3
ports:
- containerPort: 443
volumeMounts:
- name: banana-cert
mountPath: /etc/nginx/ssl
command:
- /bin/sh
- -c
- |
cat <<EOF > /etc/nginx/conf.d/default.conf
server {
listen 443 ssl;
server_name banana.local;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
EOF
echo "<html><body><h1>I am a banana! 🍌 (Full HTTPS OK)</h1></body></html>" > /usr/share/nginx/html/index.html
nginx -g 'daemon off;'
volumes:
- name: banana-cert
secret:
secretName: banana-tls
---
apiVersion: v1
kind: Service
metadata:
name: banana-service
spec:
selector:
app: banana
ports:
- name: https
port: 443
targetPort: 443
5、修改ingress的配置文件fruits-ingress-tls.yaml
# fruits-ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fruits-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
rules:
- host: apple.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apple-service
port:
number: 80
- host: banana.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: banana-service
port:
number: 443
tls:
- hosts:
- banana.local
secretName: banana-tls
6、访问验证 通过下面信息,可以看出通过https能正常访问到banana文件,apple因使用的是80端口,不能正常访问
[root@k8s-m01 YAML]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.110.109.165 <none> 80:30287/TCP,443:31910/TCP 2d18h
ingress-nginx-controller-admission ClusterIP 10.109.240.117 <none> 443/TCP 2d18h
[root@k8s-m01 YAML]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
fruits-ingress nginx apple.local,banana.local 192.168.80.102 80, 443 16h
minimal-ingress nginx example.ingress.com 192.168.80.102 80 14d
[root@k8s-m01 YAML]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.80.101 k8s-m01
192.168.80.102 k8s-n01
192.168.80.103 k8s-n02
192.168.80.104 k8s-n03
192.168.80.100 harbor.fq.com
192.168.80.103 example.ingress.com
#192.168.80.103 fruits.local
192.168.80.102 service2.example.com
192.168.80.102 service1.example.com
192.168.80.102 example.ingress.com
192.168.80.102 fruits.local
192.168.80.103 service1.example.com
192.168.80.103 service2.example.com
192.168.80.102 apple.local
192.168.80.102 banana.local
[root@k8s-m01 YAML]# curl -k https://banana.local:31910
<html><body><h1>I am a banana! 🍌 (Full HTTPS OK)</h1></body></html> # 通https访问到了banana
[root@k8s-m01 YAML]# curl -k http://banana.local:31910
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>
[root@k8s-m01 YAML]# curl -k https://apple.local:31910
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@k8s-m01 YAML]# curl -k http://apple.local:31910
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>
# 查看 ingress controller 的实时访问日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller -f --tail=10 nginx
# 查看 ingress controller 的实时访问日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller -f --tail=10