I have one configuration file which as following. This file is a configmap and will be mounted and read by my app. The problem here is that this configuration file has one property with my db password. And I don't want to it to be exposed. So is there anyway to inject kubernetes secret into such configuration file. Thanks
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>my_db_password</value>
</property>
try below steps
1. add the password as an environment variable
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>${my_db_password}</value>
</property>
2. include the password in secret object
3. load the env variable from secret object. you need to define env from secret object ref in pod definition
The issue is that XML will not expand that variable. Not sure if it fits your use case but we had a JVM application with some XML configuration and did the following in order to make it work:
Secret
Secret
in the Depoyment
environment variablesSystem Properties
in a JAVA_OPT
variableExample
Deployment file:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myimage
ports:
- containerPort: 8080
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: my-secret-credentials
key: user
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret-credentials
key: password
- name: JAVA_OPTS
value: "-db.user=$(DB_USER) -Ddb.password=$(DB_PASSWORD)"
Your XML config file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>"#{systemProperties['db.user']}"</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>"#{systemProperties['db.password']}"</value>
</property>
This way your secret gets injected safely. Just pay attention when referencing environment variables from another environment variable in the deployment yaml, it uses parenthesis instead of curly braces.
Hope that helps
You can use a combination of an init container an a shared volume for this, if you don't want to expose the secret to the application container directly.
The init container uses the secret to create the configuration file from a template (f.e. sed
replacing a placeholder) and place the file in a shared volume. The application container uses the volume to retrieve the file. (Given that you can configure the path where the application expects the configuration file.)
The other option is to simply use the secret as an environment variable for your application and retrieve it separately from the general configuration.