0

I'm developing an simple Spring Boot application and trying to deploy it in cluster.

Controller looks like this:

@Controller
@RequestMapping("/")
@RequiredArgsConstructor
public class UiController {
    private final ScenarioRepository scenarioRepository;
    
    @GetMapping
    public String index() {
        return "redirect:/scenarios";
    }

    @GetMapping("/debug")
    public String debug(HttpServletRequest request) {
        log.info("RequestURI: {}", request.getRequestURI());
        log.info("Context path: {}", request.getContextPath());
        log.info("Servlet path: {}", request.getSession());
        log.info("Path translated: {}", request.getPathTranslated());
        log.info("Path info: {}", request.getPathInfo());
        return "redirect:/scenarios";
    }

    @GetMapping("/scenarios")
    public String scenarios() {
        List<Scenario> scenarios = scenarioRepository.findAll();
        model.addAttribute("scenarios", scenarios);
        return "scenarios";
    }
}

Ingress configuration:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myservice
  namespace: dev
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice
    app.kubernetes.io/version: "1.0"
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: dev.cluster
      http:
        paths:
          - path: /apps/myservice/(.*)
            backend:
              serviceName: myservice
              servicePort: http

No extra web/spring configuration.

With this configuration I expect following behaviour:

  • Locally: request to http://localhost/ redirects to http://localhost/scenarios
  • Cluster: request to http://dev.cluster/apps/myservice/ redirects to http://dev.cluster/apps/myservice/scenarios

Locally in my IDE it is work correctly. But when I deploy it into K8S index request redirects me to http://dev.cluster/scenarios with missing ingress path /apps/myservice/.

Access /debug in cluster produces following output:

12:43:21.338 Servlet path: org.apache.catalina.session.StandardSessionFacade@12da0eae
12:43:21.338 Path translated: null
12:43:21.338 Path info: null
12:43:21.236 RequestURI: /debug
12:43:21.236 Context path: 

And location header in response: http://dev.cluster/scenarios. Obviously, spring does not know anything about ingresses rewrite and generates illegal redirect URL.

So, question is: how do I fix this configuration issue?

Ivan
  • 490
  • 1
  • 7
  • 23
  • 1
    did you try to remove "rewrite-target" annotation? – Vasili Angapov Jan 24 '21 at 14:46
  • 2
    You need to use either path `/` in ingress or change your Spring Boot application to use `/apps/myservice/` as a basepath. Many services I saw allow for configurable basepath either through configfile or env variables. You should do this too, although I dont know spring boot and cannot help you with implementing it. Check this for reference: [how-to-set-base-url-for-rest-in-spring-boot](https://stackoverflow.com/questions/32927937/how-to-set-base-url-for-rest-in-spring-boot), maybe it will help you somehow – Matt Jan 25 '21 at 08:41
  • @VasiliAngapov, removing "rewrite-target" itself does not help - it's just starting to pass whole url into `myserive` instead extracted part. – Ivan Feb 04 '21 at 07:42
  • @Matt, thanks, that's it! Specifying `spring.servlet.context-path` property with ingress `path` value helps. Now service knows own URL context and correctly responds in cluster. – Ivan Feb 04 '21 at 07:47
  • @Matt, could you transform your comment to answer? – Ivan Nov 14 '22 at 19:43

1 Answers1

0

spring boot 3 & undertow web server configs.

I used the config for Spring MVC, SseEmitter in Kubernetes.

The SseEmitter uses the config for sending message to client.

ingress path : /

application config ->

  server:
    servlet:
      context-path: /
Turgay Can
  • 111
  • 1
  • 4