【问题标题】:how to pass environment variable in kubectl deployment?如何在 kubectl 部署中传递环境变量?
【发布时间】:2019-09-24 00:07:51
【问题描述】:

我正在为 django webapp 设置 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

创建部署时出现上述错误的原因是什么?

【问题讨论】:

    标签: kubernetes kubectl


    【解决方案1】:

    我的解决方案是

    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
    

    【讨论】:

      【解决方案2】:

      我选择了yq,因为它可以识别 yaml 并且可以精确控制文本替换发生的位置。

      从 bash env var 设置图像:

      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

      【讨论】:

        【解决方案3】:

        请尝试关注

        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"
        

        【讨论】:

          【解决方案4】:

          文件:./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 ."
          

          【讨论】:

            【解决方案5】:

            这不是使用部署的正确方法,您不能在 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
            

            上面的命令将创建一个带有副本1和环境变量var1=val1的部署nginx

            【讨论】:

            • 如果您使用某种 CI/CD 怎么办?你会怎么说要部署的图像的女巫版本或标签??
            • 根据k8s docs示例:kubectl run hazelcast --image=hazelcast/hazelcast --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default"
            【解决方案6】:

            我为此使用了 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 
            

            【讨论】:

            【解决方案7】:

            按照以下步骤进行

            创建 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 也是我使用的,它在(可能?)每个发行版中。
            • 是的,请参阅unix.stackexchange.com/a/145229 并且对于动态变量替换这样做:export MYVAR=1234 then sed 's/wantReplaced/'"${MYVAR}"'/'.... etc
            【解决方案8】:

            您不能将变量传递给“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
            • 再次,使用“kubectl create -f”是不可能的。而是使用带有参数的“kubectl run”或使用 Helm 图表。
            • 如何使用 Helm 实现?@Vasily Angapov
            • 这个话题太宽泛了,没法讨论。你可以在这里阅读更多:helm.sh/docs/chart_template_guide/…
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-27
            • 1970-01-01
            • 2021-10-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多