How to inject kubernetes secret into configuration file

5/24/2019

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>
-- zjffdu
kubernetes

3 Answers

5/24/2019

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
-- P Ekambaram
Source: StackOverflow

10/1/2019

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:

  1. Create Secret
  2. Reference Secret in the Depoyment environment variables
  3. Inject them as System Properties in a JAVA_OPT variable
  4. System properties get expanded

Example

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

-- Urosh T.
Source: StackOverflow

5/24/2019

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.

-- Thomas
Source: StackOverflow