Helm Chart 部署时如何处理多个values.yaml 文件?

问题描述 投票:0回答:1

背景:

我正在尝试实现一个 Helm Chart 来部署 Python 应用程序。这个 python 应用程序在同一个 docker 镜像上有多个 Web 服务器。因此,使用相同的图像,我可以运行网络服务器 A、B、C 等。彼此之间唯一发生变化的是图像内部的路径。因此,对于 Web 服务器 A 来说,类似于 /path/to/web_server/A.py,而 B 则类似于 /path/to/web_server/B.py,依此类推。 我的想法是创建这个单一的 docker 镜像,并使用多个 value.yaml 使用 Helm Charts 将每个 Web 服务器部署到 Kubernetes 中。

问题:

我正在使用 helm CLI 为这些应用程序创建部署和服务:

helm install app -f ./path/to/webserver_A.yaml webserverA

部署后,它的状态为 CrashLoopBackOff,当我运行

kubectl describe pod
检查应用程序的详细信息时,我收到错误:
no such file or directory: unknown

我尝试过的:

我使用

docker run my_image /opt/my_app/path/to/webserverA.py --host 0.0.0.0 --port 8001
测试了 docker 镜像,它在网络服务器上运行良好。在此图中,我将工作目录定义为 /opt/my_app,将入口点定义为 "python"。所以图像正在按预期运行。在 Kubernetes 上,我尝试使用以下命令以交互模式运行图像:
kubectl run test --rm -i -tty --image my_image:1.0 -- /bin/bash
来检查可能出现的问题。使用交互模式,我能够运行
python /opt/my_app/path/to/webserverA.py
并且它按预期工作,与使用 docker 映像的行为相同。

我的 Helm Chart 代码:

部署.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-webserver
  labels:
    app: webserver
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      labels:
        app: webserver
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          command: {{ .Values.pod.cmd }}
          args: {{ .Values.pod.args }}
          ports:
            - name: http
              containerPort: {{ .Values.pod.port }}
              protocol: TCP

服务.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-service
spec:
  selector:
    app.kubernetes.io/instance: {{ .Release.Name }}
  type: {{ .Values.service.type }}
  ports:
    - protocol: {{ .Values.service.protocol | default "TCP" }}
      port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.targetPort }}

webserverA.yaml(这是“我在 helm CLI 上使用的 value.yaml”)

replicaCount: 1

image:
  repository: webserverImage
  tag: "1.0"
  pullPolicy: Never

service:
  name: webserver-service
  type: ClusterIP
  port: 8001
  targetPort: 8001

pod:
  port: 8001 
  cmd: ["python","/opt/my_app/path/to/webserverA.py", "--host", "0.0.0.0", "--port","8001"]

env:
  name: dev

到目前为止我发现了什么:

当我直接在 deployment.yaml 上编写 cmd 时,网络服务器按预期启动,但是当我从自定义 value.yaml 获取 cmd 时,它确实获取了参数,但没有运行。

所以这有效:

部署.yaml

command: ["python","/opt/my_app/path/to/webserverA.py", "--host", "0.0.0.0", "--port","8001"]

这不起作用:

部署.yaml

command: {{ .Values.pod.cmd }}

python docker kubernetes kubernetes-helm
1个回答
0
投票

您需要查看生成的清单才能发现问题。如果您从图表目录运行

helm template .
,您将看到:

.
.
.
        - name: webserver
          image: "webserverImage:1.0"
          imagePullPolicy: Never
          command: [python /opt/my_app/path/to/webserverA.py --host 0.0.0.0 --port 8001]
          args: 
          ports:
            - name: http
              containerPort: 8001
              protocol: TCP

请注意,

command
的值无效'它不再是具有多个值的列表;这是一个具有单个值
python /opt/my_app/path/to/webserverA.py --host 0.0.0.0 --port 8001
的列表。

您可以通过在模板中使用

toJson
过滤器来解决此问题:

.
.
.
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          command: {{ .Values.pod.cmd | toJson }}

这让你:

.
.
.
      containers:
        - name: webserver
          image: "webserverImage:1.0"
          imagePullPolicy: Never
          command: ["python","/opt/my_app/path/to/webserverA.py","--host","0.0.0.0","--port","8001"]

这就是你想要的。

© www.soinside.com 2019 - 2024. All rights reserved.