在Docker中相当于env-file的Kubernetes

背景:

目前我们正在使用Docker和Docker Compose来处理我们的服务。 我们将不同环境的configuration外化为定义由应用程序读取的环境variables的文件。 例如prod.env文件:

 ENV_VAR_ONE=Something Prod ENV_VAR_TWO=Something else Prod 

和一个test.env文件:

 ENV_VAR_ONE=Something Test ENV_VAR_TWO=Something else Test 

因此,我们可以简单地在启动容器时使用prod.envtest.env文件:

 docker run --env-file prod.env <image> 

然后,我们的应用程序将根据prod.env定义的环境variables来select其configuration。

问题:

  1. 有没有办法从Kubernetes中的文件提供环境variables(例如定义一个pod时),而不是像这样硬编码它们:
 apiVersion:v1
类:Pod
元数据: 
  标签: 
    上下文:docker-k8s-lab
    名称:mysql-pod
  名称:mysql-pod
规格: 
  容器: 
     -  
       ENV: 
         -  
          名称:MYSQL_USER
          值:mysql
         -  
          名称:MYSQL_PASSWORD
          值:mysql
         -  
          名称:MYSQL_DATABASE
          值:样本
         -  
          名称:MYSQL_ROOT_PASSWORD
          价值:supersecret
       image:“mysql:latest”
      名字:mysql
      端口: 
         -  
           containerPort:3306
  1. 如果这是不可能的,那么build议的方法是什么?

您可以通过使用Secrets或ConfigMaps来填充容器的环境variables。 当你正在使用的数据是敏感的(例如密码)时使用秘密,当不是时则使用ConfigMaps。

在您的Pod定义中指定容器应该从Secret中提取值:

 apiVersion: v1 kind: Pod metadata: labels: context: docker-k8s-lab name: mysql-pod name: mysql-pod spec: containers: - image: "mysql:latest" name: mysql ports: - containerPort: 3306 envFrom: secretRef: name: mysql-secret 

请注意,此语法仅在Kubernetes 1.6或更高版本中可用。 在较早版本的Kubernetes中,您将不得不手动指定每个值,例如:

 env: - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-secret key: MYSQL_USER 

并重复每一个价值。

无论您使用哪种方法,现在都可以定义两个不同的秘密,一个用于生产,另一个用于开发。

DEV-secret.yaml:

 apiVersion: v1 kind: Secret metadata: name: mysql-secret type: Opaque data: MYSQL_USER: bXlzcWwK MYSQL_PASSWORD: bXlzcWwK MYSQL_DATABASE: c2FtcGxlCg== MYSQL_ROOT_PASSWORD: c3VwZXJzZWNyZXQK 

PROD-secret.yaml:

 apiVersion: v1 kind: Secret metadata: name: mysql-secret type: Opaque data: MYSQL_USER: am9obgo= MYSQL_PASSWORD: c2VjdXJlCg== MYSQL_DATABASE: cHJvZC1kYgo= MYSQL_ROOT_PASSWORD: cm9vdHkK 

并将正确的秘密部署到正确的Kubernetes集群:

 kubectl config use-context dev kubectl create -f dev-secret.yaml kubectl config use-context prod kubectl create -f prod-secret.yaml 

现在,每当Pod启动时,它将从Secret中指定的值中填充其环境variables。

当使用YAML文件为Kubernetes定义一个窗格时,没有直接的方法来指定一个包含容器环境variables的不同文件。 Kubernetes项目说,他们将在未来改善这一领域(见Kubernetes文件 )。

同时,我build议使用configuration工具并将YAML吊舱作为模板。 例如,使用Ansible你的pod YAML文件看起来像这样:

文件my-pod.yaml.template

 apiVersion: v1 kind: Pod ... spec: containers: ... env: - name: MYSQL_ROOT_PASSWORD value: {{ mysql_root_pasword }} ... 

然后,您的Ansible手册可以方便地指定variablesmysql_root_password ,并在创build资源时replace它,例如:

文件my-playbook.yaml

 - hosts: my_hosts vars_files: - my-env-vars-{{ deploy_to }}.yaml tasks: - name: create pod YAML from template template: src=my-pod.yaml.template dst=my-pod.yaml - name: create pod in Kubernetes command: kubectl create -f my-pod.yaml 

文件my-env-vars-prod.yaml

 mysql_root_password: supersecret 

文件my-env-vars-test.yaml

 mysql_root_password: notsosecret 

现在通过运行来创buildpod资源,例如:

 ansible-playbook -e deploy=test my-playbook.yaml 

Kubernetes(v1.6)的一个新的更新允许你问(几年前)。

你现在可以在yaml文件中像这样使用envFrom

  containers: - name: django image: image/name envFrom: - secretRef: name: prod-secrets 

在哪里发展秘密是你的秘密,你可以通过以下方式创build它:

 kubectl create secret generic prod-secrets --from-file=prod/env.txt` 

在txt文件内容是一个键值的地方:

 DB_USER=username_here DB_PASSWORD=password_here 

文件仍然是湖的例子,我不得不在这些地方努力search:

  • 秘密文档 ,searchenvFrom – 显示此选项可用。
  • 等效的ConfigMap文档显示了如何使用它的例子。

这个注释显示了如何做到这一点,而不必更新环境variables列表时更新kubernetesconfiguration。

从本质上说:1)与env.sh秘密2)将秘密映射到容器作为卷3)容器的启动脚本运行env.sh然后应用程序。