通过Ingress将微服务关联到测试/开发/生产环境的问题咨询
Alright, let’s tackle your two main problems one by one, and walk through the best way to get your setup working as intended. First off, your core goal—letting the frontend call services via path-based routing without hardcoding domain names—is totally feasible, we just need to fix how the Ingress rules are structured.
Why Your Current Setup Isn’t Working
Rewrite Target Not Taking Effect: Chances are you’re using the NGINX Ingress Controller (the most common one), and you’re either using the deprecated annotation name or not leveraging capture groups to properly rewrite the path. The old
ingress.kubernetes.io/rewrite-targetis outdated for newer NGINX Ingress versions, and just settingrewrite-target: /won’t strip the/services/service1prefix unless you capture the remaining path segments.Route Order Misbehavior: Most Ingress Controllers (like NGINX) use longest path matching priority instead of the order you list rules in. When you use
/*, it’s a catch-all that can override shorter service paths if your rules aren’t structured to be more specific. Removing the*fixes order but breaks subpath access because you lose the ability to match routes like/services/service1/method1.
Fixed Ingress Configuration
Here’s a revised configuration tailored for NGINX Ingress Controller (the standard choice for Kubernetes) that addresses both issues:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: dev-environment-ingress annotations: # Use the modern NGINX rewrite annotation nginx.ingress.kubernetes.io/rewrite-target: /$2 # Optional: Force HTTPS if you're using TLS # nginx.ingress.kubernetes.io/force-ssl-redirect: "true" spec: # Specify your Ingress Controller class to avoid conflicts ingressClassName: nginx rules: - host: dev.website.com http: paths: # Matches /services/service1, /services/service1/, and all subpaths like /services/service1/method1 - path: /services/service1(/|$)(.*) pathType: Prefix backend: service: name: service1 port: number: 8080 # Same pattern for service2 - path: /services/service2(/|$)(.*) pathType: Prefix backend: service: name: service2 port: number: 8080 # Catch-all for webapp, handles /en, /, and any other paths not claimed by services - path: /(.*) pathType: Prefix backend: service: name: webapp port: number: 8080
How This Fixes Your Issues
- Proper Path Rewriting: The path pattern
/services/service1(/|$)(.*)uses two capture groups:- The first group
(/|$)matches either a trailing slash or the end of the URL (so it works for both/services/service1and/services/service1/). - The second group
(.*)captures everything after the base service path. - The
rewrite-target: /$2tells NGINX to replace the original path with whatever’s in the second capture group. So:/services/service1becomes//services/service1/method1becomes/method1
- The first group
- Correct Route Matching: With
pathType: Prefix, the controller uses longest-path priority. Since/services/service1/...is longer than the catch-all/..., requests to service paths will always be routed to the correct service instead of webapp.
Best Practices to Follow
- Separate Ingress Resources per Environment: Create distinct Ingresses for dev, test, and prod. This lets you tweak rules independently without affecting other environments.
- Explicitly Set
ingressClassName: This avoids confusion if you have multiple Ingress Controllers running in your cluster (like NGINX plus a cloud-specific one). - Test Routes Thoroughly: Use
curlto verify routing and rewriting:# Check if service1 gets the rewritten path curl -v dev.website.com/services/service1/method1 # Check if webapp handles /en correctly curl -v dev.website.com/en - Leverage TLS: Add a TLS section to your Ingress to encrypt traffic between clients and the controller if you haven’t already.
To answer your final question: Yes, this approach is absolutely feasible and aligns with Kubernetes Ingress best practices for path-based service routing.
内容的提问来源于stack exchange,提问作者Vojtěch

