将多个 k8s 秘密组合成一个环境变量
Combining multiple k8s secrets into an env variable
我的 k8s 命名空间包含一个 Secret
,它是在部署时创建的(由 svcat
),因此这些值是事先不知道的。
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-database-credentials
data:
hostname: ...
port: ...
database: ...
username: ...
password: ...
A Deployment
需要以稍微不同的格式注入这些值:
...
containers:
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: my-database-credentials
key: jdbc:postgresql:<hostname>:<port>/<database> // ??
- name: DATABASE_USERNAME
valueFrom:
secretKeyRef:
name: my-database-credentials
key: username
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: my-database-credentials
key: password
DATABASE_URL
需要由先前定义的秘密中的 hostname
、port
、“数据库”组成。
这个作文有什么办法吗?
有几种方法(按复杂程度递增的顺序):
在将参数放入 Secret 之前对其进行处理(扩展您用来在此处插入信息的任何内容)。
将脚本添加到您的 Pod/Container 中以将传入参数(环境变量或命令参数)分解为所需的内容。如果您不能或不想拥有自己的容器镜像,您可以将额外的脚本作为卷添加到容器中,并且 set the Container's command
field to override the container image start command.
向您的 Kubernetes 添加一个工具来进行自动处理 "behind the scenes":您可以添加一个 Dynamic Admission Controller to do your mangling, or you can create a Kubernetes Operator and add a Custom Resource Definition(CRD 会告诉操作员要监视哪些 Secrets更改,操作员将读取这些值并生成您想要的任何其他条目)。
你可以做一些我能想到的事情:
使用 secrets volume 并制作一个启动脚本,从卷中读取机密,然后使用 DATABASE_URL
环境变量启动您的应用程序。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: your_db_container
command: [ "yourscript.sh" ]
volumeMounts:
- name: mycreds
mountPath: "/etc/credentials"
volumes:
- name: mycreds
secret:
secretName: my-database-credentials
defaultMode: 256
在容器规范的 command
键中传递环境变量:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: your_db_container
command: [ "/bin/sh", "-c", "DATABASE_URL=jdbc:postgresql:<hostname>:<port>/<database>/$(DATABASE_USERNAME):$(DATABASE_PASSWORD) /start/yourdb" ]
env:
- name: DATABASE_USERNAME
valueFrom:
secretKeyRef:
name: my-database-credentials
key: username
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: my-database-credentials
key: password
Kubernetes 允许您在配置的其他地方使用先前定义的环境变量作为后续环境变量的一部分。来自 Kubernetes API reference docs:
Variable references $(VAR_NAME) are expanded using the previous defined environment variables in the container and any service environment variables.
此 $(...)
语法为容器定义 interdependent environment variables。
因此,您可以先将所需的秘密值提取到环境变量中,然后用这些变量组成DATABASE_URL
。
...
containers:
env:
- name: DB_URL_HOSTNAME // part 1
valueFrom:
secretKeyRef:
name: my-database-credentials
key: hostname
- name: DB_URL_PORT // part 2
valueFrom:
secretKeyRef:
name: my-database-credentials
key: port
- name: DB_URL_DBNAME // part 3
valueFrom:
secretKeyRef:
name: my-database-credentials
key: database
- name: DATABASE_URL // combine
value: jdbc:postgresql:$(DB_URL_HOSTNAME):$(DB_URL_PORT)/$(DB_URL_DBNAME)
...
如果所有前置变量都定义为环境变量:
- { name: DATABASE_URL, value: '{{ printf "jdbc:postgresql:$(DATABASE_HOST):$(DATABASE_PORT)/$(DB_URL_DBNAME)" }}'}
使用此语句,您还可以从 values.yaml 文件中引入值:
例如:
如果您可能已经在值文件中定义了 DB_URL_DBNAME:
- { name: DATABASE_URL, value: '{{ printf "jdbc:postgresql:$(DATABASE_HOST):$(DATABASE_PORT)/%s" .Values.database.DB_URL_DBNAME }}'}
我的 k8s 命名空间包含一个 Secret
,它是在部署时创建的(由 svcat
),因此这些值是事先不知道的。
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-database-credentials
data:
hostname: ...
port: ...
database: ...
username: ...
password: ...
A Deployment
需要以稍微不同的格式注入这些值:
...
containers:
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: my-database-credentials
key: jdbc:postgresql:<hostname>:<port>/<database> // ??
- name: DATABASE_USERNAME
valueFrom:
secretKeyRef:
name: my-database-credentials
key: username
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: my-database-credentials
key: password
DATABASE_URL
需要由先前定义的秘密中的 hostname
、port
、“数据库”组成。
这个作文有什么办法吗?
有几种方法(按复杂程度递增的顺序):
在将参数放入 Secret 之前对其进行处理(扩展您用来在此处插入信息的任何内容)。
将脚本添加到您的 Pod/Container 中以将传入参数(环境变量或命令参数)分解为所需的内容。如果您不能或不想拥有自己的容器镜像,您可以将额外的脚本作为卷添加到容器中,并且 set the Container's
command
field to override the container image start command.向您的 Kubernetes 添加一个工具来进行自动处理 "behind the scenes":您可以添加一个 Dynamic Admission Controller to do your mangling, or you can create a Kubernetes Operator and add a Custom Resource Definition(CRD 会告诉操作员要监视哪些 Secrets更改,操作员将读取这些值并生成您想要的任何其他条目)。
你可以做一些我能想到的事情:
使用 secrets volume 并制作一个启动脚本,从卷中读取机密,然后使用
DATABASE_URL
环境变量启动您的应用程序。apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: your_db_container command: [ "yourscript.sh" ] volumeMounts: - name: mycreds mountPath: "/etc/credentials" volumes: - name: mycreds secret: secretName: my-database-credentials defaultMode: 256
在容器规范的
command
键中传递环境变量:apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: your_db_container command: [ "/bin/sh", "-c", "DATABASE_URL=jdbc:postgresql:<hostname>:<port>/<database>/$(DATABASE_USERNAME):$(DATABASE_PASSWORD) /start/yourdb" ] env: - name: DATABASE_USERNAME valueFrom: secretKeyRef: name: my-database-credentials key: username - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: my-database-credentials key: password
Kubernetes 允许您在配置的其他地方使用先前定义的环境变量作为后续环境变量的一部分。来自 Kubernetes API reference docs:
Variable references $(VAR_NAME) are expanded using the previous defined environment variables in the container and any service environment variables.
此 $(...)
语法为容器定义 interdependent environment variables。
因此,您可以先将所需的秘密值提取到环境变量中,然后用这些变量组成DATABASE_URL
。
...
containers:
env:
- name: DB_URL_HOSTNAME // part 1
valueFrom:
secretKeyRef:
name: my-database-credentials
key: hostname
- name: DB_URL_PORT // part 2
valueFrom:
secretKeyRef:
name: my-database-credentials
key: port
- name: DB_URL_DBNAME // part 3
valueFrom:
secretKeyRef:
name: my-database-credentials
key: database
- name: DATABASE_URL // combine
value: jdbc:postgresql:$(DB_URL_HOSTNAME):$(DB_URL_PORT)/$(DB_URL_DBNAME)
...
如果所有前置变量都定义为环境变量:
- { name: DATABASE_URL, value: '{{ printf "jdbc:postgresql:$(DATABASE_HOST):$(DATABASE_PORT)/$(DB_URL_DBNAME)" }}'}
使用此语句,您还可以从 values.yaml 文件中引入值:
例如:
如果您可能已经在值文件中定义了 DB_URL_DBNAME:
- { name: DATABASE_URL, value: '{{ printf "jdbc:postgresql:$(DATABASE_HOST):$(DATABASE_PORT)/%s" .Values.database.DB_URL_DBNAME }}'}