单个 docker 映像,通过 Kubernetes 和 helm 部署为 2 个不同的服务.更改应用的上下文路径



我们有一个 docker 镜像,它通过 kubernetes 和 helm 部署为 2 个不同的服务,名称为 "ServiceA" 和 "ServiceB"。在部署发生时,需要将Tomcat的上下文路径设置为不同的路径,如/ServiceA和/ServiceB。怎么能做到这一点?有什么可以直接在 YAML 上设置的吗?

例如:如下所示

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
-

设置应用的上下文路径的方法很少。

  • 从应用程序本身:这取决于应用程序使用的语言/框架/运行时。例如,如果它是在 Tomcat 上运行的传统 Java Web 应用程序,则默认情况下,它将从您放入webapp目录中的.war文件名的上下文路径提供。或者,如果它是一个 Spring Boot 2.X 应用程序,您可以使用 Spring Boot 属性server.servlet.context-path进行设置,该属性也可以通过环境变量传递,特别是SERVER_SERVLET_CONTEXT_PATH。因此,举个例子,在部署 Pod 规范的容器中:
env:           
- name: SERVER_SERVLET_CONTEXT_PATH
value: "/ServiceB"

但是,这种特定于应用程序的设置在 Kubernetes 中大多数时候是不需要的,因为您可以在外层处理这些问题。

  • 使用入口对象:如果您正在运行并正确配置了入口控制器,则可以创建一个Ingress来管理路径前缀剥离和其他 HTTP Layer7 问题。这意味着,您可以保持应用程序本身不变(例如从根上下文/提供服务),但从入口配置上下文路径。下面是一个示例,假设您使用 Nginx 入口控制器
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

请注意,捕获组(.*)path中,$1重写目标中 - 它将重写请求路径,例如/ServiceA/something/something,然后再将数据包转发到后端。

请参阅此页面以了解有关入口的更多信息。

  • 您可以使用 HTTP 路由器软件(如 skipper)来处理群集中的所有此类 HTTP 流量配置。

  • 如果您使用 Istio 等服务网格解决方案,它们为您提供了许多方法来管理网格内的流量。

最新更新