Configure Secrets In Applications
- Example Python application: ``` import os from flash import Flask
app = Flash(name)
@app.route(“/”) def main():
mysql.connector.connect(host='mysql', database='mysql', user='root', password='passwrd')
return render_template('hello.html', color=fetchacolor())
if name == “main”: app.run(host=”0.0.0.0”, port=”8080”)
* Secrets store sensitive information such as passwords or keys.
* Example secret:
DB_Host: mysql DB_User: root DB_Password: passwrd
* Two steps are the the following for creating secrets:
1. Create the Secret.
2. Inject it into a pod.
* Imperative way of creating a secret:
kubectl create secret generic
* Declarative way of creating a secret:
kubectl create -f
* Imperative way allows you to specify the key-value pairs:
kubectl create secret generic
kubectl create secret generic app-secret –from-literal=DB_Host=mysql
* To specify multiple key-value pairs, add the `--from-literal` option multiple times like so:
kubectl create secret generic
app-secret –from-liberal=DB_Host=mysql
–from-literal=DB=User=root
–from-literal=DB_Password=passwrd
* However, if there are multiple secrets, the above method is difficult.
* Add multiple secrets using a file:
kubectl create secret generic
kubectl create secret generic
app-secret –from-file=app_secret.properties
* The declarative approach is:
* A secret is again created:
DB_Host: mysql DB_User: root DB_Password: passwrd
* The definition file looks like:
apiVersion: kind: Secret metadata: name: app-secret data: DB_Host: mysql DB_User: root DB_Password: passwrd
kubectl create -f
* The above version is unsafe, due to the secret being in plain text.
* Must encode the data. This can be done on a Linux host using `echo -n 'mysql' | base64`
Example output
bXlzcWw=
* From that, you can then place the encoded data instead of the plain text:
apiVersion: v1 kind: Secret metadata: name: app-secret data: DB_Host: bXlzcWw= DB_User: VH6L DB_Password: Y0Y0Y0
* View secrets with the following:
kubectl get secrets
* Kubernetes also creates its own internal secret, which is shown during the `kubectl get secrets` command.
* The secret looks like `default-token-<string> kubernetes.io/service-account-token`
* You can also `describe` secrets as well with `kubectl describe secrets`
* This shows the attributes in the command, but not the secrets themselves.
* To show the values as well, run the command `kubectl get secrets <secret> -o yaml` and that will output the `secrets` and their values.
* How do you decode, encoded values? Run:
echo -n ‘
* To inject the secret into a pod, we firstly have the secret definition file:
apiVersion: v1 kind: Secret metadata: name: app-secret data: DB_Host: bXlzcWw= DB_User: VH6L DB_Password: Y0Y0Y0
* The pod definition file then looks like this:
apiVersion: v1 kind: Pod metadata: name: simple-websapp-color labels: name: simple-webapp-color spec: containers:
- name: simple-webapp-color
image: simple-webapp-color
ports:
- containerPort: 8080 envFrom:
- secretRef: name: app-secret ```
- The
envFromproperty is a list and it contains as many environment variables as required. - In the above case,
app-secrethas to be in both definition files. - Then creating the pod definition file with
kubectl create -f <pod_definition_name>then creates the pod and it can then refer to the secret file. - There are other ways to inject environment variables, these can be single variables like so into the pod definition file:
```
env:
- name: DB_Password valueFrom: secretKeyRef: name: app-secret key: DB_Password ```
- The whole secret can be injected as a file via a
volume: ``` volumes: - name: app-secret-volume secret: secretName: app-secret ```
- Expanding more on
secretsand volumes, inside the container, the secrets are created under/opt/app-secret-volumes(whichever name was specified in the- namesection) as individual files:ls /opt/app-secret-volumes DB_Host DB_Password DB_User - Each of the above files will show the contents of each password.
- Secrets are not encrypted, they are only encoded!
- When uploading to GitHub, don’t push up any
secretfiles, as those contain un-encrypted credentials essentially. - The
secretsare not encrypted inetcdeither. - Consider enabling encryption at rest.
- Good documentation on that: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
- Anyone able to deploy pods / deployments in the same namespace can access the same secrets!
- Consider Role-based Access Control (RBAC) for least-privilege access.
- Consider a third-party
secretsstore providers- AWS Provider, Azure Provider, GCP Provider, Vault Provider
secretsare stored then not inETCDand then via an external provider