Single docker image thats being deployed as 2 different services thru kubernetes and helm. Change context path of app

7/26/2019

We have a single docker image thats being deployed as 2 different services thru kubernetes and helm with names like "ServiceA" and "ServiceB". At the point deploy happens need to set the context path of Tomcat to be something different like /ServiceA and /ServiceB. How can this be done ? is there anything that can be set directly on the yaml ?

ex: Looks like below

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "fullname" . }}-bg
  {{- include "labels" . }}

spec:
  replicas: {{ .replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "name" . }}-bg
      app.kubernetes.io/instance: {{ .Release.Name }}
  strategy:
    type: Recreate 
    rollingUpdate: null 
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "name" . }}-bg
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .image.repository }}:{{ .image.tag }}"
          imagePullPolicy: {{ .image.pullPolicy }}
          env:           
            - name: SERVICE_NAME
              value: "ServiceB"
            - name: background.jobs.enabled
              value: "true"
          envFrom:
            - configMapRef:
                name: {{ include "commmonBaseName" . }}-configmap
            -
-- Sundara J
deployment
java
kubernetes
tomcat

1 Answer

7/27/2019

There are few approaches into setting up the context path of an app.

  • From the app itself: This depends on the language/framework/runtime your application uses. For example, if it's a traditional Java web application that runs on Tomcat, it would be served by default from the context path of the name of the .war file you put in the webapp directory. Or, if it is a Spring Boot 2.X app, you could set it up with the Spring Boot property server.servlet.context-path, which can be also passed via an environment variable, specifically SERVER_SERVLET_CONTEXT_PATH. So, to give an example, in the container in your deployment pod spec:
env:           
  - name: SERVER_SERVLET_CONTEXT_PATH
    value: "/ServiceB"

However, this kind of app-specific settings are most of the times not needed in Kubernetes, since you can handle those concerns on the outer layers.

  • Using Ingress objects: If you have an Ingress controller running and properly configured, you can create an Ingress that will manage path prefix stripping, and other HTTP Layer7 concerns. This means, you can leave your application itself as-is (like serving from root context /) but configure the context path from the Ingress. An example is the following, assuming you use Nginx Ingress Controller
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: service-a-ingress
  annotations:
    ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: service-a.yourdomain.com
      http:
        paths:
          - path: /ServiceA/(.*)
            backend:
              serviceName: service-a
              servicePort: service-a-port

Note the capture group (.*) in the path, and $1 in the rewrite target - it will rewrite the request paths like /ServiceA/something to /something before forwarding the packet to your backend.

See this page to lear more about ingresses.

  • You can use an HTTP router software such as skipper to handle all this HTTP traffic configuration in-cluster.

  • If you use a service mesh solution such as Istio, they give you many ways to manage the traffic inside the mesh.

-- Utku Ă–zdemir
Source: StackOverflow