如何在 kubectl 部署中传递环境变量?

59

我正在为Django Web应用程序设置Kubernetes环境。

创建部署时,我会像下面这样传递环境变量

kubectl create -f deployment.yml -l key1=value1 

我遇到了以下错误:

error: no objects passed to create
能够成功创建部署,即使我在创建部署时移除了环境变量 -l key1=value1。
以下是deployment.yaml。
#Deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata: 
 labels: 
   service: sigma-service
 name: $key1
创建部署时会导致以上错误的原因是什么?
9个回答

90

我在此使用了envsubst (https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html)。创建deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: $NAME
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

然后:

export NAME=my-test-nginx
envsubst < deployment.yaml | kubectl apply -f -

不确定你使用的操作系统是什么。在 macOS 上,安装 envsubst 的命令如下:

brew install gettext
brew link --force gettext 

1
如果您的镜像没有安装envsubst,您还可以使用sed命令,请参见https://dev59.com/MlMI5IYBdhLWcg3wir6J#56005832上的评论。 - Mike Bendorf
这个在shell脚本中不起作用,我如何注入在shell脚本中设置的变量? - Nathan McKaskle

13

您无法将变量传递给 "kubectl create -f"。YAML 文件应该是没有变量的完整清单。另外,您不能使用 "-l" 标志对 "kubectl create -f" 进行操作。

如果您想要将环境变量传递给 Pod,请按照以下方式进行:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        env:
        - name: MY_VAT
          value: MY_VALUE
        ports:
        - containerPort: 80

点击此处阅读更多:https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/


我需要动态更改部署的名称,因此需要将环境变量传递给部署@Vasily Angapov - rakeshh92
再次强调,使用"kubectl create -f"是不可能的。相反,您可以使用带参数的"kubectl run"或使用Helm图表。 - Vasili Angapov
我如何使用Helm实现?@Vasily Angapov - rakeshh92
1
这是一个太广泛的话题,无法在此讨论。您可以在此处阅读更多信息:https://helm.sh/docs/chart_template_guide/#the-chart-template-developer-s-guide - Vasili Angapov

13

这不是使用部署的正确方式,您不能在yaml中提供一半的细节并在kubectl命令中提供另一半。如果您想在部署中传递环境变量,您应该将这些详细信息添加到 deployment spec.template.spec 中:

您应该将以下块添加到您的deployment.yaml中。

spec:
  containers:
  - env:
    - name: var1
      value: val1

这将在容器内导出您的环境变量。

另一种导出环境变量的方式是使用kubectl run(不建议使用),因为它很快将被弃用。您可以使用以下命令:

 kubectl run nginx --image=nginx --restart=Always --replicas=1 --env=var1=val1

以上命令将创建一个名为nginx的部署(deployment),副本数为1,并设置环境变量var1=val1


如果您正在使用某种CI/CD,那该怎么办呢?您会如何指定要部署的镜像版本或标签? - Ivan Vilanculo
根据 k8s 文档示例: kubectl run hazelcast --image=hazelcast/hazelcast --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default" - Ravi

6

请按照以下步骤操作:

1. 创建 test-deploy.yaml 文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: MYAPP
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

使用sed命令,您可以在部署时更新部署名称。
sed -e 's|MYAPP|my-nginx|g' test-deploy.yaml | kubectl apply -f -

Sed 是我也使用的工具,它在(可能?)每个发行版中都有。 - zsolt
是的,可以看https://unix.stackexchange.com/a/145229。而对于动态变量替换,请执行以下操作: export MYVAR=1234然后sed 's/wantReplaced/'"${MYVAR}"'/'....等 - Mike Bendorf

0

文件:./deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: MYAPP
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
      ports:
      - containerPort: 80

文件:./service.yaml

apiVersion: v1
kind: Service
metadata:
  name: MYAPP
  labels:
    app: nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: nginx

文件:./kustomization.yaml

resources:
- deployment.yaml
- service.yaml

如果你正在使用https://kustomize.io/,你可以在CI中使用这个技巧:

sh '( echo "images:" ; echo "  - name: $IMAGE" ; echo "    newTag: $VERSION" ) >> ./kustomization.yaml'
sh "kubectl apply --kustomize ."

-1
我选择了yq,因为它具有yaml感知能力,并可以精确控制文本替换的位置。
要从bash环境变量中设置图像,请执行以下操作:
export IMAGE="your_image:latest"
yq eval '.spec.template.spec.containers[0].image = "'$IMAGE'"' manifests/daemonset.yaml | kubectl apply -f -

yq 可在 MacPorts 上获取(截至21年4月19日v4.4.1),使用 sudo port install yq 命令进行安装。


-2

我曾经面临过同样的问题。我创建了一个Python脚本,用于更改YAML文件中的简单/复杂值或添加值。在您描述的类似情况下,这非常方便。此外,切换到Python领域可以允许更复杂的场景。

代码和如何使用它都可以在此Gist上找到。 https://gist.github.com/washraf/f81153270c80b0b4ecf90a53872abde7


-2
请尝试以下内容。
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kdpd00201
  name: frontend
  labels:
    app: nginx
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: frontend
        image: ifccncf/nginx:1.14.2
        ports:
        - containerPort: 8001
        env:
           - name: NGINX_PORT
             value: "8001"

-3

我的解决方案是

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: frontend
  name: frontend
  namespace: kdpd00201
spec:
  replicas: 4
  selector:
    matchLabels:
      app: frontend
  strategy: {}
  template:
    metadata:
      creationTimestamp: null      
      labels:
        app: frontend
    spec:
      containers:
      - env: # modified level
        - name: NGINX_PORT
          value: "8080"
        image: lfccncf/nginx:1.13.7
        name: nginx
        ports:  
          - containerPort: 8080

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接