【问题标题】:Set values in a knative service.yaml file using environment variables使用环境变量在 knative service.yaml 文件中设置值
【发布时间】:2025-12-21 03:50:11
【问题描述】:

有没有办法使用环境变量设置 Knative service.yaml 文件中某些键的值?


更多细节

我正在尝试使用 GitLab CI 将 Knative 服务部署到 Kubernetes 集群。我的service.yaml 文件中的一些变量取决于 GitLab CI 管道的项目和环境。有没有办法可以将这些值无缝插入到我的service.yaml 文件中,而无需诉诸sed -i ... 之类的黑客手段?

例如,给定以下脚本,我希望将 $(KUBE_NAMESPACE)$(CI_ENVIRONMENT_SLUG)$(CI_PROJECT_PATH_SLUG) 值替换为相应命名的环境变量。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: design
  namespace: "$(KUBE_NAMESPACE)"
spec:
  template:
    metadata:
      name: design-v1
      annotations:
        app.gitlab.com/env: "$(CI_ENVIRONMENT_SLUG)"
        app.gitlab.com/app: "$(CI_PROJECT_PATH_SLUG)"
    spec:
      containers:
        - name: user-container
          image: ...
      timeoutSeconds: 600
      containerConcurrency: 8

【问题讨论】:

    标签: kubernetes gitlab-ci knative


    【解决方案1】:

    我不认为在现有 yaml 中扩展环境变量的好方法,但如果您不想使用 sed,您也许可以使用envsubst

    envsubst < original.yaml > modified.yaml
    

    您只需在使用 yaml 扩展其中包含的环境变量之前运行此命令。

    另外我认为你需要你的变量使用花括号,而不是括号,像这样:${KUBE_NAMESPACE}

    编辑:您也可以像这样使用这个内联:kubectl apply -f &lt;(envsubst &lt; service.yaml)

    【讨论】:

      【解决方案2】:

      这不仅仅是一个 Knative 问题,这更多的是 Kubernetes 的限制。 Kubernetes 允许一些扩展,但不允许在注释或命名空间定义中。例如,您可以在容器 env 定义中执行此操作:

      containers:
      - env:
        - name: PODID
          valueFrom: ...
        - name: LOG_PATH
          value: /var/log/$(PODID)
      

      如果这是一个像 Gitlab 这样的 CI/CD 系统,环境变量应该在 shell 环境中,所以一个简单的 shell 扩展就可以了。例如。

      #!/bin/bash
      
      echo -e "
      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: design
        namespace: "${KUBE_NAMESPACE}"
      spec:
        template:
          metadata:
            name: design-v1
            annotations:
              app.gitlab.com/env: "${CI_ENVIRONMENT_SLUG}"
              app.gitlab.com/app: "${CI_PROJECT_PATH_SLUG}"
          spec:
            containers:
              - name: user-container
                image: ...
            timeoutSeconds: 600
            containerConcurrency: 8
      " | kubectl apply -f -
      

      您也可以使用envsubst 作为其他答案中提到的助手。

      【讨论】:

      • 感谢您解释容器环境部分!我在文档中看到了env 部分,这让我认为可以从调用进程中提取环境变量。