Joh*_*han 70 configuration environment-variables configuration-files docker kubernetes
背景:
目前我们正在使用Docker和Docker Compose来提供服务.我们已将不同环境的配置外部化为定义应用程序读取的环境变量的文件.例如一个prod.env
文件:
ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod
Run Code Online (Sandbox Code Playgroud)
和一个test.env
文件:
ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test
Run Code Online (Sandbox Code Playgroud)
因此,我们可以在启动容器时简单地使用prod.env
or test.env
文件:
docker run --env-file prod.env <image>
Run Code Online (Sandbox Code Playgroud)
然后,我们的应用程序根据中定义的环境变量获取其配置prod.env
.
问题:
apiVersion: v1 kind: Pod metadata: labels: context: docker-k8s-lab name: mysql-pod name: mysql-pod spec: containers: - env: - name: MYSQL_USER value: mysql - name: MYSQL_PASSWORD value: mysql - name: MYSQL_DATABASE value: sample - name: MYSQL_ROOT_PASSWORD value: supersecret image: "mysql:latest" name: mysql ports: - containerPort: 3306
Pix*_*ant 90
您可以通过使用Secrets或ConfigMaps填充容器的环境变量.当您使用的数据敏感(例如密码)时使用Secrets,而不使用ConfigMaps时使用Secrets.
在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
Run Code Online (Sandbox Code Playgroud)
请注意,此语法仅适用于Kubernetes 1.6或更高版本.在早期版本的Kubernetes上,您必须手动指定每个值,例如:
env:
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-secret
key: MYSQL_USER
Run Code Online (Sandbox Code Playgroud)
并重复每一个价值观.
无论使用哪种方法,您现在可以定义两个不同的秘密,一个用于生产,一个用于开发.
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
并将正确的秘密部署到正确的Kubernetes集群:
kubectl config use-context dev
kubectl create -f dev-secret.yaml
kubectl config use-context prod
kubectl create -f prod-secret.yaml
Run Code Online (Sandbox Code Playgroud)
现在每当Pod启动时,它将从Secret中指定的值填充其环境变量.
Or *_*uan 25
Kubernetes(v1.6)的新更新允许您(多年前)提出要求.
您现在可以envFrom
在yaml文件中使用这样的:
containers:
- name: django
image: image/name
envFrom:
- secretRef:
name: prod-secrets
Run Code Online (Sandbox Code Playgroud)
如果开发秘密是您的秘密,您可以通过以下方式创建:
kubectl create secret generic prod-secrets --from-file=prod/env.txt`
Run Code Online (Sandbox Code Playgroud)
txt文件内容是键值的位置:
DB_USER=username_here
DB_PASSWORD=password_here
Run Code Online (Sandbox Code Playgroud)
文档仍然是例子的湖泊,我必须在那些地方非常努力地搜索:
envFrom
- 显示此选项可用.ConfigMap
文档显示了如何使用它的示例.小智 10
使用YAML文件为Kubernetes定义pod时,没有直接的方法来指定包含容器的环境变量的不同文件.Kubernetes项目表示他们将来会改进这个领域(参见Kubernetes docs).
与此同时,我建议使用配置工具并将pod YAML作为模板.例如,使用Ansible,您的pod YAML文件将如下所示:
档案my-pod.yaml.template
:
apiVersion: v1
kind: Pod
...
spec:
containers:
...
env:
- name: MYSQL_ROOT_PASSWORD
value: {{ mysql_root_pasword }}
...
Run Code Online (Sandbox Code Playgroud)
然后你的Ansible playbook可以在mysql_root_password
方便的地方指定变量,并在创建资源时替换它,例如:
档案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
Run Code Online (Sandbox Code Playgroud)
档案my-env-vars-prod.yaml
:
mysql_root_password: supersecret
Run Code Online (Sandbox Code Playgroud)
档案my-env-vars-test.yaml
:
mysql_root_password: notsosecret
Run Code Online (Sandbox Code Playgroud)
现在,您可以通过运行来创建pod资源,例如:
ansible-playbook -e deploy=test my-playbook.yaml
Run Code Online (Sandbox Code Playgroud)
这对我有用:
文件 env-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: env-secret
type: Opaque
stringData:
.env: |-
APP_NAME=Laravel
APP_ENV=local
Run Code Online (Sandbox Code Playgroud)
并进入deployment.yaml
或pod.yaml
spec:
...
volumeMounts:
- name: foo
mountPath: "/var/www/html/.env"
subPath: .env
volumes:
- name: foo
secret:
secretName: env-secret
````
Run Code Online (Sandbox Code Playgroud)
我的头被撞了两个小时了。我在文档中找到了一个非常简单的解决方案,可以最大限度地减少我(也希望是您)的痛苦。
保留env.prod
,env.dev
因为你有它们。
使用 oneliner 脚本将它们导入 yaml:
kubectl create configmap my-dev-config --from-env-file=env.dev
kubectl create configmap my-prod-config --from-env-file=env.prod
你可以看到结果(为了即时满足):
# You can also save this to disk
kubectl get configmap my-dev-config -o yaml
Run Code Online (Sandbox Code Playgroud)
作为一名 Ruby 专家,我个人认为这个解决方案是最干燥的,因为您需要维护一个点(ENV bash 文件,与 Python/Ruby 库兼容,..),然后您在一次执行中对其进行 YAMLize。
请注意,您需要保持 ENV 文件干净(我有很多评论阻止了它的工作,因此必须在前面添加一个cat config.original | egrep -v "^#" | tee config.cleaned
),但这并不会显着改变复杂性。
一切都记录在这里
归档时间: |
|
查看次数: |
33425 次 |
最近记录: |