Configuration Docker中env文件的Kubernetes等价物
背景: 目前,我们的服务使用Docker和Docker Compose。我们已经将不同环境的配置外部化为文件,这些文件定义了应用程序读取的环境变量。例如Configuration Docker中env文件的Kubernetes等价物,configuration,docker,environment-variables,configuration-files,kubernetes,Configuration,Docker,Environment Variables,Configuration Files,Kubernetes,背景: 目前,我们的服务使用Docker和Docker Compose。我们已经将不同环境的配置外部化为文件,这些文件定义了应用程序读取的环境变量。例如prod.env文件: ENV_VAR_ONE=Something Prod ENV_VAR_TWO=Something else Prod ENV_VAR_ONE=Something Test ENV_VAR_TWO=Something else Test 和test.env文件: ENV_VAR_ONE=Something Prod EN
prod.env
文件:
ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod
ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test
和test.env
文件:
ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod
ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test
因此,在启动容器时,我们可以简单地使用prod.env
或test.env
文件:
docker run --env-file prod.env <image>
当使用YAML文件为Kubernetes定义pod时,没有直接的方法为容器指定包含环境变量的不同文件。Kubernetes项目表示,他们将在未来改善这一领域(参见) 同时,我建议使用资源调配工具,并将pod YAML作为模板。例如,使用Ansible,您的pod YAML文件如下所示: 文件
my pod.yaml.template
:
apiVersion: v1
kind: Pod
...
spec:
containers:
...
env:
- name: MYSQL_ROOT_PASSWORD
value: {{ mysql_root_pasword }}
...
然后您的Ansible playbook可以在方便的地方指定变量mysql\u root\u password
,并在创建资源时替换它,例如:
ansible-playbook -e deploy=test my-playbook.yaml
文件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
mysql_root_password: supersecret
mysql_root_password: notsosecret
文件my-env-vars-prod.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
mysql_root_password: supersecret
mysql_root_password: notsosecret
文件my env vars test.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
mysql_root_password: supersecret
mysql_root_password: notsosecret
现在通过运行创建pod资源,例如:
ansible-playbook -e deploy=test my-playbook.yaml
您可以通过使用或来填充容器的环境变量。当您使用的数据是敏感数据(例如密码)时,请使用机密;当数据不是敏感数据时,请使用配置映射 在Pod定义中,指定容器应从机密文件中提取值:
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
(注意env
将数组作为值)
并为每个值重复
无论使用哪种方法,现在都可以定义两个不同的秘密,一个用于生产,一个用于开发
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
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
MYSQL_USER: am9obgo=
MYSQL_PASSWORD: c2VjdXJlCg==
MYSQL_DATABASE: cHJvZC1kYgo=
MYSQL_ROOT_PASSWORD: cm9vdHkK
prod-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
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启动时,它都会根据机密中指定的值填充其环境变量。Kubernetes(v1.6)的新更新允许您(几年前)要求的内容 您现在可以在yaml文件中这样使用
envFrom
:
containers:
- name: django
image: image/name
envFrom:
- secretRef:
name: prod-secrets
如果开发秘密是您的秘密,您可以通过以下方式创建它:
kubectl create secret generic prod-secrets --from-env-file=prod/env.txt`
其中txt文件内容是一个键值:
DB_USER=username_here
DB_PASSWORD=password_here
这些文档仍然是大量的示例,我不得不在这些地方非常努力地搜索:
- ,从文件中搜索<代码>--显示此选项可用
- 显示了如何使用它的示例
--与环境文件中的--之间存在差异。这对我很有用:
文件env secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: env-secret
type: Opaque
stringData:
.env: |-
APP_NAME=Laravel
APP_ENV=local
spec:
...
volumeMounts:
- name: foo
mountPath: "/var/www/html/.env"
subPath: .env
volumes:
- name: foo
secret:
secretName: env-secret
````
并进入deployment.yaml
或pod.yaml
apiVersion: v1
kind: Secret
metadata:
name: env-secret
type: Opaque
stringData:
.env: |-
APP_NAME=Laravel
APP_ENV=local
spec:
...
volumeMounts:
- name: foo
mountPath: "/var/www/html/.env"
subPath: .env
volumes:
- name: foo
secret:
secretName: env-secret
````
这是一个老问题,但它有很多观众,所以我添加我的答案。
将配置与K8s实现分离的最佳方法是使用Helm。每个Helm包可以有一个values.yaml
文件,我们可以在Helm图表中轻松使用这些值。如果我们有一个多组件拓扑,我们可以创建一个伞形头盔包,父值包也可以覆盖子值文件。这是一个老问题,但让我为未来的初学者描述我的答案
您可以使用kustomize configMapGenerator
configMapGenerator:
- name: example
env: dev.env
请参考pod定义中的这个配置图/示例我现在已经用两个小时的时间砸了头。我在文档中找到了一个非常简单的解决方案,可以最大限度地减少我(希望是你)的痛苦
- 将
env.prod
,env.dev
保留在现有状态
- 使用oneliner脚本将这些脚本导入yaml:
kubectl create configmap my dev config——从env file=env.dev
kubectl create configmap my prod config——从env file=env.prod
您可以看到结果(即时满足):
作为一个Ruby开发者,我个人认为这个解决方案是最枯燥的,因为您只需要维护一个点(ENV bash文件,它与Python/Ruby库兼容,…),然后在一次执行中对其进行YAMLize
请注意,您需要保持ENV文件的干净(我有很多注释阻止了它的工作,因此必须预先添加一个cat config.original | egrep-v“^#”| tee config.cleaned
),但这并没有实质性地改变复杂性
这些都有文档记录理想情况下,您应该能够定义一个秘密(或我们将拥有的最终配置对象),并将其作为env vars注入。不幸的是,这项工作还没有完成,所以我投了赞成票。如果您使用ansible,我们有一个共同的角色部署在kubernetes:。然后,准备新的应用程序就很容易了,请参见如何在其他repo中使用它的示例:我希望我们将在1.2版的env vars中使用secrets。注意,有一个模板建议:如果我想使用kubectl run
传递20个env变量,我应该怎么做???那么为什么不更简单一些呢?这是我目前的方法,但是我有3个不同的pod,它们使用与EnvVars相同的机密列表。有没有可能定义一次并将它们暴露在3个吊舱中?我不知道。那太好了。。。似乎是为了把环境变量放入容器而分配的样板文件@PixelElephant@jävi您是指复制控制器吗?无论如何,没有任何东西可以将secret/config映射绑定到单个pod/RC/Deployment。它只是在上面的清单中定义的,并且可以装载到您想要的任何东西上。我认为重要的一点是,在秘密的定义中,这些值必须是base64编码的。易居