Redirecting traffic to Tomcat context path in Kubernetes service

8/26/2019

In a scenario where I set the context path of the Tomcat server by changing the server.xml file like this:

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">

    <Context path="${catalinaContextPath}" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true">
        <Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction"
            factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>
        <Manager pathname=""/>
        <JarScanner scanManifest="false"/>
        <Valve className="org.apache.catalina.valves.StuckThreadDetectionValve" threshold="120" />
    </Context>

</Host>

If catalinaContextPath is set to /my/new/context The server will start up in the Pod with the URL: localhost:8080/my/new/context. How do I change the service so that it sends all traffic arriving on service port 80 to container path <pod_ip>:8080/my/new/context

This is my current service:

apiVersion: v1
kind: Service
metadata:
namespace: jira
name: jira
spec:
selector:
    app: jira
    component: jira
ports:
- protocol: TCP
  name: serverport
  port: 80
  targetPort: 8080

My use case is, I am deploying this this JIRA docker image in a Pod and I set the context path using the environment variable CATALINA_CONTEXT_PATH as specified in this documentation. When I try to access it, it results in a 404. I assume this is because traffic is being redirected to <pod_ip>:8080 and nothing is running on <pod_ip>:8080 since tomcat has started up on <pod_ip>:8080/my/new/context

EDIT: This is the ingress.yaml I am using:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: {{ .Values.global.app }}
  name: jira-ingress
  annotations: 
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: myhost
    http:
      paths:
      - path: /dev/jira(/|$)(.*)
        backend:
          serviceName: jira
          servicePort: 80
      - path: /prod/jira(/|$)(.*)
        backend:
          serviceName: jira
          servicePort: 80

Whenever I visit myhost/dev/jira I need it to go to my JIRA instance.

-- user9492428
docker
jira
kubernetes
nginx-ingress

2 Answers

8/26/2019

This is not possible with services... I would strongly suggest using Ingress paths.

see here: Can a host be redirected to a service path in Kubernetes?

-- Raja
Source: StackOverflow

8/27/2019

Since your application "real" root is /my/new/context, you can rewrite every incoming request matching the /dev/jira URI using Nginx's AppRoot:

If the Application Root is exposed in a different path and needs to be redirected, set the annotation nginx.ingress.kubernetes.io/app-root to redirect requests for /.

If you're using this approach, there is no need to use capture groups with rewrite-target.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: {{ .Values.global.app }}
  name: jira-ingress
  annotations: 
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/app-root: /my/new/context
spec:
  rules:
  - host: myhost
    http:
      paths:
      - path: /dev/jira(/|$)(.*)
        backend:
          serviceName: jira
          servicePort: 80
      - path: /prod/jira(/|$)(.*)
        backend:
          serviceName: jira
          servicePort: 80
-- yyyyahir
Source: StackOverflow