πŸš€ Migrating from Ingress to Gateway API with Conditional Routing

πŸ“Œ The Question

The task is to migrate an existing Ingress configuration to a Gateway API HTTPRoute. The old Ingress file is located at /opt/course/13/ingress.yaml.

Key requirements:

  1. Work in Namespace project-r500.
  2. Use the already existing Gateway (reachable at http://r500.gateway:30080).
  3. Create a new HTTPRoute named traffic-director.
  4. The HTTPRoute must replicate the old Ingress routes:

  5. /desktop β†’ forwards to service web-desktop

  6. /mobile β†’ forwards to service web-mobile
  7. Extend the HTTPRoute with a new rule for /auto:

  8. If User-Agent header is exactly mobile β†’ forward to web-mobile

  9. Otherwise (any other header or no header at all) β†’ forward to web-desktop

πŸ“Œ The Old Ingress

Here’s the original Ingress manifest we are migrating:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traffic-director
spec:
  ingressClassName: nginx
  rules:
    - host: r500.gateway
      http:
        paths:
          - backend:
              service:
                name: web-desktop
                port:
                  number: 80
            path: /desktop
            pathType: Prefix
          - backend:
              service:
                name: web-mobile
                port:
                  number: 80
            path: /mobile
            pathType: Prefix

πŸ‘‰ This simply maps /desktop β†’ web-desktop and /mobile β†’ web-mobile.


πŸ“Œ Migrating to Gateway API

Gateway API is the next-generation alternative to Ingress.

  • Instead of defining rules in Ingress, we use HTTPRoute.
  • HTTPRoute attaches to an existing Gateway via parentRefs.
  • We can match traffic based on hostname, path, headers, and more.

πŸ“Œ The New HTTPRoute (With Deep Comments)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: traffic-director                # Same name for clarity
  namespace: project-r500               # Always set the correct namespace
spec:
  parentRefs:
    - name: main                        # Attach to the existing Gateway
      namespace: project-r500
  hostnames:
    - r500.gateway                      # Same hostname as in old Ingress

  rules:
    # -------------------------------
    # Rule 1: /desktop β†’ web-desktop
    # -------------------------------
    - matches:
        - path:
            type: PathPrefix            # PathPrefix = matches /desktop and subpaths
            value: /desktop
      backendRefs:
        - name: web-desktop             # Service name
          port: 80                      # Service port

    # -------------------------------
    # Rule 2: /mobile β†’ web-mobile
    # -------------------------------
    - matches:
        - path:
            type: PathPrefix
            value: /mobile
      backendRefs:
        - name: web-mobile
          port: 80

    # -------------------------------
    # Rule 3a: /auto + User-Agent: mobile β†’ web-mobile
    # -------------------------------
    - matches:
        - path:
            type: PathPrefix
            value: /auto
          headers:                      # Match HTTP header conditions
            - type: Exact               # "Exact" = must match exactly
              name: User-Agent          # The header we are checking
              value: mobile             # Match only if User-Agent = "mobile"
      backendRefs:
        - name: web-mobile
          port: 80

    # -------------------------------
    # Rule 3b: /auto (fallback) β†’ web-desktop
    # -------------------------------
    - matches:
        - path:
            type: PathPrefix
            value: /auto
          # Note: no header match here β†’ this acts as a fallback rule
      backendRefs:
        - name: web-desktop
          port: 80

πŸ“Œ How the /auto Rule Works

  • Two separate rules are required:

  • Specific case: /auto + User-Agent: mobile β†’ web-mobile

  • General case: /auto (no header or any other header) β†’ web-desktop

  • Gateway API processes rules in order:

  • If the header matches mobile, the first rule wins.

  • If not, the fallback rule applies.

πŸ“Œ Testing the Setup

After applying the manifest:

# Desktop route
curl r500.gateway:30080/desktop

# Mobile route
curl r500.gateway:30080/mobile

# Auto route with User-Agent: mobile
curl r500.gateway:30080/auto -H "User-Agent: mobile"

# Auto route with no header (falls back to desktop)
curl r500.gateway:30080/auto

βœ… Expected Results:

  • /desktop β†’ response from web-desktop
  • /mobile β†’ response from web-mobile
  • /auto with User-Agent: mobile β†’ response from web-mobile
  • /auto without header (or any non-mobile header) β†’ response from web-desktop

πŸ“Œ Key Takeaways

  • Ingress β†’ Gateway API migration = mostly about moving path-based rules into HTTPRoute.
  • Gateway API provides much finer control, especially with header-based routing.
  • The /auto path demonstrates conditional routing: same path but different backend depending on request headers.
  • Always define a fallback rule when doing conditional routing.