三、ingress全面详解: 实例配置及访问

说在开头:本文所 实例放在结尾,测试实验可先跳至文末提取。需要注意修改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
相关推荐
心无旁骛~2 小时前
Docker常见命令
运维·docker·容器
羑悻的小杀马特2 小时前
openGauss 数据库快速上手评测:从 Docker 安装到SQL 实战
数据库·sql·docker·opengauss
企鹅侠客2 小时前
Kubeconfig文件自动合并-K8S多集群切换
云原生·容器·kubernetes
victory04313 小时前
resource 和 K8S 对接部分 apifox
云原生·容器·kubernetes
炸裂狸花猫3 小时前
开源CI&CD工具-Drone
ci/cd·云原生·容器·kubernetes·开源·drone
刘一说4 小时前
Spring Boot 应用的云原生 Docker 化部署实践指南
spring boot·docker·云原生
❀͜͡傀儡师4 小时前
docker部署开源监控软件hertzbeat
docker·容器·开源·hertzbeat
demonre4 小时前
阿里云 Debian 13.1 安装 docker 并切换阿里云镜像源
后端·docker
故林丶4 小时前
【Linux】CentOS 7.8 Docker + Docker Compose 安装
linux·docker·centos