跳转至

ingress 对象应用案例

ingress-http 案例

基于名称的负载均衡

1. 创建 deployment 控制器类型应用

1. 编辑 nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: c1
        image: nginx:1.15-alpine
        imagePullPolicy: IfNotPresent
2. 应用 nginx.yml 文件
[root@k8smaster001 ingress]# kubectl apply -f nginx.yaml 
deployment.apps/nginx created
3. 验证 pod
[root@k8smaster001 ingress]# kubectl get pods -n ingress-nginx
NAME                                       READY   STATUS      RESTARTS       AGE
ingress-nginx-admission-create-rj2rv       0/1     Completed   0              14d
ingress-nginx-admission-patch-84zl9        0/1     Completed   0              14d
ingress-nginx-controller-5458dd5f6-r4k9m   1/1     Running     1 (7d2h ago)   14d
nginx-6555d45fcd-27t8k                     1/1     Running     0              15s
nginx-6555d45fcd-5j8jf                     1/1     Running     0              15s

2. 创建 service

1. 创建 nginx-service.yml 文件
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: ingress-nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
2. 应用 nginx-service.yml 文件
[root@k8smaster001 ingress]# kubectl apply -f nginx-service.yml 
service/nginx-service created
3. 验证 service
[root@k8smaster001 ingress]# kubectl get svc nginx-service -n ingress-nginx 
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   10.99.117.76   <none>        80/TCP    69s

3. 创建 ingress 对象

1. 编写 ingress 规则 资源清单 ingress-nginx.yaml
# 编写 ingress-nginx 规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: ingress-nginx
           # saas 前缀区分自己服务与客户服务的区别,jenkins 服务名
spec:
  ingressClassName: nginx
  rules:
    - host: "uri.example.com"
           # jenkins 服务名
      http:
        paths:
          - backend:
              service:
                name: nginx-service
           # 需要暴漏的 web服务的 server 名称
                port:
                  number: 80
            path: /
            pathType: Prefix
2. 创建并查看 ingress 规则
[root@k8smaster001 ingress]# kubectl apply -f ingress-nginx.yaml 
ingress.networking.k8s.io/ingress-nginx created

[root@k8smaster001 ingress]# kubectl get ingress -n ingress-nginx
NAME      CLASS   HOSTS                        ADDRESS         PORTS   AGE
ingress   nginx   uri.example.com   192.168.3.204   80      117s

4. 模拟客户端访问

1. 准备 pod 内容器运行的 web 主页
[root@k8smaster001 ingress]# kubectl get pods  -n ingress-nginx |grep nginx-65
nginx-6555d45fcd-27t8k                     1/1     Running     0              128m
nginx-6555d45fcd-5j8jf                     1/1     Running     0              128m

[root@k8smaster001 ingress]# kubectl exec -it  nginx-6555d45fcd-27t8k -n ingress-nginx  --  /bin/sh
/ # echo "ingress web1" > /usr/share/nginx/html/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-6555d45fcd-5j8jf -n ingress-nginx  --  /bin/sh
/ # echo "ingress web2" > /usr/share/nginx/html/index.html
2. 确认 nginx-ingress-controller 的 pod IP, 下面命令查询的结果为 10.109.138.153
[root@k8smaster002 ~]# kubectl get svc -n ingress-nginx  |grep ingress
ingress-nginx-controller             NodePort    10.109.138.153   <none>        80:30212/TCP,443:32105/TCP   15d
3. 在集群之外任一主机中添加上述域名与 IP 地址解析(模拟公网DNS)
[root@k8smaster002 ~]# echo "10.109.138.153 uri.example.com" >> /etc/hosts
4. 访问及结果展示
❯ curl uri.example.com
ingress web2

❯ curl uri.example.com
ingress web1

基于 url 的负载均衡

image-20240402134601434

1. 创建 web1 应用

1. 编写 web1 的 **Deployment** 资源的资源清单 nginx-uri-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-uri-1
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-uri-1
  template:
    metadata:
      labels:
        app: nginx-uri-1
    spec:
      containers:
      - name: c1
        image: nginx:1.15-alpine
        imagePullPolicy: IfNotPresent
2. 编写 web1 service 资源的资源清单 nginx-service-uri-1.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service-uri-1
  namespace: ingress-nginx
  labels:
    app: nginx-uri-1
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx-uri-1
3. 创建 deployment 与 service
[root@k8smaster001 ingress]# kubectl apply -f nginx-uri-1.yaml 
deployment.apps/nginx-uri-1 created

[root@k8smaster001 ingress]# kubectl apply -f nginx-service-uri-1.yaml
service/nginx-service-uri-1 created
4. 查看 deployment 与 service 是否创建成功
[root@k8smaster001 ingress]# kubectl get pod -n ingress-nginx -owide |grep ur
nginx-uri-1-566bc894c-8pp2h                1/1     Running     0              116s   10.244.87.213   k8sworker001   <none>           <none>
nginx-uri-1-566bc894c-bb7pv                1/1     Running     0              116s   10.244.35.54    k8sworker002   <none>           <none>

[root@k8smaster001 ingress]# kubectl get svc -n ingress-nginx -owide |grep ur
nginx-service-uri-1                  ClusterIP   10.105.135.111   <none>        80/TCP                       103s   app=nginx-uri-1

2. 创建 web2 应用

1. 编写 web2 的 **Deployment** 资源的资源清单 nginx-uri-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-uri-2
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-uri-2
  template:
    metadata:
      labels:
        app: nginx-uri-2
    spec:
      containers:
      - name: c2
        image: nginx:1.15-alpine
        imagePullPolicy: IfNotPresent
2. 编写 web2 service 资源的资源清单 nginx-service-uri-2.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service-uri-2
  namespace: ingress-nginx
  labels:
    app: nginx-uri-2
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx-uri-2
3. 创建 deployment 与 service
[root@k8smaster001 ingress]# kubectl apply -f nginx-uri-2.yaml 
deployment.apps/nginx-uri-2 created

[root@k8smaster001 ingress]# kubectl apply -f nginx-service-uri-2.yaml
service/nginx-service-uri-2 created
4. 查看 deployment 与 service 是否创建成功
[root@k8smaster001 ingress]# kubectl get pod -n ingress-nginx -owide |grep uri-2
nginx-uri-2-6fcd746f85-7lwb7               1/1     Running     0              28s     10.244.35.29    k8sworker002   <none>           <none>
nginx-uri-2-6fcd746f85-fskbs               1/1     Running     0              28s     10.244.87.214   k8sworker001   <none>           <none>

[root@k8smaster001 ingress]# kubectl get svc -n ingress-nginx -owide |grep uri-2
nginx-service-uri-2                  ClusterIP   10.96.97.105     <none>        80/TCP                       35s     app=nginx-uri-2

3. 创建 ingress 对象

1. 编写 ingress 规则 资源清单 ingress-nginx-uri.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-uri
  namespace: ingress-nginx
spec:
  ingressClassName: nginx
  rules:
  - host: uri.example.com
    http:
      paths:
      - path: /hello/svc1/
        pathType: Prefix
        backend:
          service:
            name: nginx-service-uri-1
            port:
              number: 80
      - path: /hello/svc2/
        pathType: Prefix
        backend:
          service:
            name: nginx-service-uri-2
            port:
              number: 80           
2. 应用 YAML 资源清单 ingress-nginx-uri.yaml
[root@k8smaster001 ingress]# kubectl apply -f ingress-nginx-uri.yaml
ingress.networking.k8s.io/ingress-uri created
3. 查看 pod 资源
[root@k8smaster001 ingress]#  kubectl get pods -o wide -n ingress-nginx|grep nginx-uri
nginx-uri-1-566bc894c-8pp2h                1/1     Running     0              18m    10.244.87.213   k8sworker001   <none>           <none>
nginx-uri-1-566bc894c-bb7pv                1/1     Running     0              18m    10.244.35.54    k8sworker002   <none>           <none>
nginx-uri-2-6fcd746f85-7lwb7               1/1     Running     0              14m    10.244.35.29    k8sworker002   <none>           <none>
nginx-uri-2-6fcd746f85-fskbs               1/1     Running     0              14m    10.244.87.214   k8sworker001   <none>           <none>
4. 验证 ingress
[root@k8smaster001 ingress]# kubectl get ingress -n ingress-nginx
NAME          CLASS   HOSTS                        ADDRESS         PORTS   AGE
ingress-uri   nginx   uri.example.com              192.168.3.204   80      124m
5. 描述查看 ingress 信息
[root@k8smaster001 ingress]#  kubectl describe ingress ingress-uri -n ingress-nginx
Name:             ingress-uri
Labels:           <none>
Namespace:        ingress-nginx
Address:          192.168.3.204
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host             Path  Backends
  ----             ----  --------
  uri.example.com  
                   /hello/svc1/   nginx-service-uri-1:80 (10.244.35.54:80,10.244.87.213:80)
                   /hello/svc2/   nginx-service-uri-2:80 (10.244.35.29:80,10.244.87.214:80)
Annotations:       <none>
Events:            <none>

4. 模拟客户端访问

1. 确认 nginx-ingress-controller 的 pod IP, 下面命令查询的结果为 10.109.138.153
[root@k8smaster002 ~]# kubectl get svc -n ingress-nginx  |grep ingress
ingress-nginx-controller             NodePort    10.109.138.153   <none>        80:30212/TCP,443:32105/TCP   15d
2. 在集群之外任一主机中添加上述域名与 IP 地址解析(模拟公网DNS)
[root@k8smaster002 ~]# echo "10.109.138.153 uri.example.com" >> /etc/hosts
3. 查看所有创建的 pod
[root@k8smaster001 ingress]# kubectl get pods  -n ingress-nginx |grep nginx-uri
nginx-uri-1-566bc894c-8pp2h                1/1     Running     0              21m
nginx-uri-1-566bc894c-bb7pv                1/1     Running     0              21m
nginx-uri-2-6fcd746f85-7lwb7               1/1     Running     0              16m
nginx-uri-2-6fcd746f85-fskbs               1/1     Running     0              16m
4. 准备 pod 内容器运行的 web 主页
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-8pp2h -n ingress-nginx -- /bin/sh
/ # mkdir /usr/share/nginx/html/hello/svc1 -p
/ # echo "我是 svc1 Pod1" > /usr/share/nginx/html/hello/svc1/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-bb7pv -n ingress-nginx -- /bin/sh 
/ # mkdir /usr/share/nginx/html/hello/svc1 -p
/ # echo "我是 svc1 Pod2" > /usr/share/nginx/html/hello/svc1/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-7lwb7 -n ingress-nginx -- /bin/sh 
/ # mkdir /usr/share/nginx/html/hello/svc2 -p
/ # echo "我是 svc2 Pod1" > /usr/share/nginx/html/hello/svc2/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-fskbs -n ingress-nginx -- /bin/sh 
/ # mkdir /usr/share/nginx/html/hello/svc2 -p
/ # echo "我是 svc2 Pod2" > /usr/share/nginx/html/hello/svc2/index.html
5. 访问及结果展示
[root@k8smaster002 ~]# curl uri.example.com/hello/svc1/index.html
我是 svc1 Pod1

[root@k8smaster002 ~]# curl uri.example.com/hello/svc1/index.html
我是 svc1 Pod2

[root@k8smaster002 ~]# curl uri.example.com/hello/svc2/index.html
我是 svc2 Pod2

[root@k8smaster002 ~]# curl uri.example.com/hello/svc2/index.html
我是 svc2 Pod1

ingress URL Rewrite

rewrite 主要用于地址重写。

名称 描述
nginx.ingress.kubernetes.io/rewrite-target 必须重定向的目标URL String
nginx.ingress.kubernetes.io/ssl-redirect 指示位置部分是否只能由SSL访问(当Ingress包含证书时,默认为True) Bool
nginx.ingress.kubernetes.io/force-ssl-redirect 即使Ingress没有启用TLS,也强制重定向到HTTPS Bool
nginx.ingress.kubernetes.io/app-root 定义应用程序根目录,Controller在“/”上下文中必须重定向该根目录 String
nginx.ingress.kubernetes.io/use-regex 指示Ingress上定义的路径是否使用正则表达式 Bool

1. 编写 ingress 规则

rewrite.example.com/foo-svc1 -> nginx-service-uri-1:80 -> endpoint(pod1 , pod2 ip) -> web1(pod1 , pod2)。 rewrite.example.com/foo-svc2 -> nginx-service-uri-2:80 -> endpoint(pod1 , pod2 ip) -> web2(pod1 , pod2)。

1. 编写 ingress-nginx-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx-rewrite
  namespace: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
  ingressClassName: nginx
  rules:
  - host: rewrite.example.com
    http:
      paths:
      # ? 表示前面的斜杠字符 / 是可选的。请求路径可以是 /foo-svc1 或者 /foo-svc1/ 后面可以跟任意字符
      - path: /foo-svc1/?(.*)  
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx-service-uri-1
            port:
              number: 80
      - path: /foo-svc2/?(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx-service-uri-2
            port:
              number: 80
2. 应用 YAML 资源清单 ingress-nginx-rewrite.yaml
[root@k8smaster002 rewrite]# kubectl apply -f ingress-nginx-rewrite.yaml 
ingress.networking.k8s.io/ingress-nginx-rewrite created
3. 验证 ingress
[root@k8smaster002 rewrite]# kubectl get ingress -n ingress-nginx
NAME                    CLASS   HOSTS                 ADDRESS         PORTS   AGE
ingress-nginx-rewrite   nginx   rewrite.example.com   192.168.3.204   80      73s
4. 描述查看 ingress 信息
[root@k8smaster002 rewrite]# kubectl describe ingress ingress-nginx-rewrite -n ingress-nginx
Name:             ingress-nginx-rewrite
Labels:           <none>
Namespace:        ingress-nginx
Address:          192.168.3.204
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host                 Path  Backends
  ----                 ----  --------
  rewrite.example.com  
                       /foo-svc1/?(.*)   nginx-service-uri-1:80 (10.244.35.54:80,10.244.87.213:80)
                       /foo-svc2/?(.*)   nginx-service-uri-2:80 (10.244.35.29:80,10.244.87.214:80)
Annotations:           nginx.ingress.kubernetes.io/rewrite-target: /$1
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    39s (x2 over 97s)  nginx-ingress-controller  Scheduled for sync

2. 模拟客户端访问

2. 模拟客户端访问

1. 确认 nginx-ingress-controller 的 pod IP, 下面命令查询的结果为 10.109.138.153
[root@k8smaster002 ~]# kubectl get svc -n ingress-nginx  |grep ingress
ingress-nginx-controller             NodePort    10.109.138.153   <none>        80:30212/TCP,443:32105/TCP   15d
2. 在集群之外任一主机中添加上述域名与 IP 地址解析(模拟公网DNS)
[root@k8smaster002 ~]# echo "10.109.138.153 rewrite.example.com" >> /etc/hosts
3. 准备 pod 内容器运行的 web 主页
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-8pp2h -n ingress-nginx -- /bin/sh
/ # echo "我是 svc1 Pod1 的主页" > /usr/share/nginx/html/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-bb7pv -n ingress-nginx -- /bin/sh 
/ # echo "我是 svc1 Pod2 的主页" > /usr/share/nginx/html/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-7lwb7 -n ingress-nginx -- /bin/sh 
/ # echo "我是 svc2 Pod1 的主页" > /usr/share/nginx/html/index.html

[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-fskbs -n ingress-nginx -- /bin/sh 
/ # echo "我是 svc2 Pod2 的主页" > /usr/share/nginx/html/index.html
4. 访问及结果展示
[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc1
我是 svc1 Pod1 的主页

[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc1
我是 svc1 Pod2 的主页

[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc2
我是 svc2 Pod1 的主页

[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc2
我是 svc2 Pod2 的主页

ingress 匹配请求头

1. 编写 ingress 规则

开启 server-snippet 功能
1. 发现报错没开放 nginx.ingress.kubernetes.io/contfiguration-snippet 配置
[root@k8smaster002 header]# kubectl apply -f ingress-nginx-header.yaml 
\Error from server (BadRequest): error when creating "ingress-nginx-header.yaml": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request: nginx.ingress.kubernetes.io/server-snippet annotation cannot be used. Snippet directives are disabled by the Ingress administrator
2. 修改 ingress-nginx-controller 配置为 true
[root@k8smaster002 header]# kubectl edit cm  -n ingress-nginx ingress-nginx-controller 
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"allow-snippet-annotations":"false"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"controller","app.kubernetes.io/instance":"ingress-nginx","app.kubernetes.io/name":"ingress-nginx","app.kubernetes.io/part-of":"ingress-nginx","app.kubernetes.io/version":"1.10.0"},"name":"ingress-nginx-controller","namespace":"ingress-nginx"}}
  creationTimestamp: "2024-03-18T03:04:26Z"
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.0
  name: ingress-nginx-controller
  namespace: ingress-nginx
  resourceVersion: "1763166"
  uid: 58ef348d-3e35-4e88-ada2-0f9e78f1e7bd

匹配请求头,主要用于根据请求头信息将用户请求转发到不同的应用,比如根据不同的客户端转发请求。

1. 编写 ingress-nginx-header.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx-header
  namespace: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
        set $agentflag 0;

        if ($http_user_agent ~* "(iPhone)" ){
          set $agentflag 1;
        }

        if ( $agentflag = 1 ) {
          return 301 https://iphone-header.k8s.example.com:60000;
        }
spec:
  ingressClassName: nginx
  rules:
  - host: header.k8s.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service-uri-1
            port:
              number: 80
2. 创建一个 iphone.header.example.com 的 ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx-iphoneheader
  namespace: ingress-nginx
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  ingressClassName: nginx
  rules:
  - host: iphone-header.k8s.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service-uri-2
            port:
              number: 80