Applications are often written to connect to a database to read and write information. Hardcoding database connection details, port, username and password is the most insecure way and hard to manage at scale. So, Kubernetes solves this problem via ConfigMaps and Secrets.
Two ways to store data
-
ConfigMap: Used to store insensitive data such as
db-portvia anEnvironment variableor aFileorVolume Mounts. -
Secret: Used to store and encrypt sensitive data at rest such as
database usernameordatabase password
etcd is a
data storein Kubernetes which is used to store all created resources as objects. Resources such aPod,Deployment,Service,Ingress,ConfigMapare stored inectcdas plain objects. however, withsecrets,etcdstored the information andencryptsthe data at rest inbase64encoded.
1. Deploying ConfigMap in Kubernetes
- 1.a) ConfigMap via Env Variable
- 1.b) ConfigMap via File - Volume Mount
1.a) Deploy ConfigMap via Env Variable
- create
configmap.ymlfile as below
apiVersion: v1
kind: ConfigMap
metadata:
name: py-app-configmap
data:
db-port: "3306"
- Login to OpenShift Kubernetes cluster
oc login --token=sha256~asf9879SDAF987sd987sdf --server=https://api.sandbox-m3.1530.p1.openshiftapps.com:6443
- Deploy
Configmap
$ kubectl apply -f configmap.yml
configmap/py-app-configmap created
- verify
ConfigMap-$ kubectl get cm|kubectl get configmap
$ kubectl get configmap
NAME DATA AGE
config-service-cabundle 1 2d15h
config-trusted-cabundle 1 2d15h
kube-root-ca.crt 1 2d15h
openshift-service-ca.crt 1 2d15h
py-app-configmap 1 37s
- Kubectl Describe ConfigMap -
$kubectl describe cm py-app-configmap
$kubectl describe cm py-app-configmap
Name: py-app-configmap
Namespace: jasper475-dev
Labels: <none>
Annotations: <none>
Data
====
db-port:
----
3306
BinaryData
====
Events: <none>
- Deploy
Podsand appendingconfigMapusingdeployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-python-deployment
labels:
app: sample-python-app
spec:
replicas: 5
selector:
matchLabels:
app: sample-python-app
template:
metadata:
labels:
app: sample-python-app
spec:
containers:
- name: python-app
image: jasper475/d37-k8s-services-py-django-app:v2
env:
- name: DB-PORT
valueFrom:
configMapKeyRef:
name: py-app-configmap
key: db-port
ports:
- containerPort: 8000
- deployed Pods
kubectl apply -f deploy.yaml
deployment.apps/sample-python-deployment created
- get Pods and ssh into it to get env variable
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
sample-python-deployment-5787bd6b9f-5n779 1/1 Running 0 69s
sample-python-deployment-5787bd6b9f-h6th2 1/1 Running 0 69s
sample-python-deployment-5787bd6b9f-sft22 1/1 Running 0 69s
sample-python-deployment-5787bd6b9f-w7s56 1/1 Running 0 69s
sample-python-deployment-5787bd6b9f-xncfd 1/1 Running 0 69s
- SSH into a pod
- Command:
kubectl exec -it sample-python-deployment-5787bd6b9f-5n779 -- /bin/bashand Search(grep) for Env variableDB-PORT - Dev inside python app can retrieve via:
OS.env("DB-PORT")
$ kubectl exec -it sample-python-deployment-c57769684-749ct -- /bin/bash
groups: cannot find name for group ID 1011150000
1011150000@sample-python-deployment-c57769684-749ct:/app$ ls
db.sqlite3 demo devops manage.py requirements.txt
1011150000@sample-python-deployment-c57769684-749ct:/app$ env | grep DB
DB-PORT=3306
NSS_SDB_USE_CACHE=no
- Edit DB-PORT via configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: py-app-configmap
data:
db-port: "3307"
- Apply changes
kubectl apply -f configmap.yml
$ kubectl apply -f configmap.yml
configmap/py-app-configmap configured
- Notice config map Port changed to 3307
- SSH into the POD to get Environment variable value. Notice it is still having OLD Value.
DB-PORT=3306
1011150000@sample-python-deployment-c57769684-749ct:/app$ env | grep DB
DB-PORT=3306
NSS_SDB_USE_CACHE=no
1011150000@sample-python-deployment-c57769684-749ct:/app$
We cannot afford to restart pod in production - to Fix this issue we use Volume Mounts and persist config values and decouple it from pod application restarts and config changes.
1.b) Deploy ConfigMap via File - Volume Mount
deploy_volume_Mount.yamlfilecreate volume under
container
spec:
containers:
|
|
volumes:
- name: db-connection
configMap:
name: py-app-configmap
- Mount volume: provide
volume nameandvolume path
spec:
containers:
- name: python-app
image: jasper475/d37-k8s-services-py-django-app:v2
volumeMounts:
- name: db-connection
mountPath: /opt
- apply deployment changes
$ kubectl apply -f deploy_volume_mount.yaml
deployment.apps/sample-python-deployment configured
- Get Pods
kubectl get pods
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
sample-python-deployment-7b67d95fdc-56p4g 1/1 Running 0 37s
sample-python-deployment-7b67d95fdc-5sdcx 1/1 Running 0 37s
sample-python-deployment-7b67d95fdc-5v2r8 1/1 Running 0 35s
sample-python-deployment-7b67d95fdc-74sb8 1/1 Running 0 35s
sample-python-deployment-7b67d95fdc-cs9px 1/1 Running 0 37s
- SSH into pod as see ENV variable:
- Notice: There is no environment variable - because
deploy_volume_mount.yamlfile, since we removed it.
$ kubectl exec -it sample-python-deployment-7b67d95fdc-56p4g -- /bin/bash
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$ env | grep DB
NSS_SDB_USE_CACHE=no
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$
- Notice : volume is mounted on
/optpath andport: 3307
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$ ls /opt
db-port
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$ cat /opt/db-port | more
3307
- Change Port to
3308inconfigmap.ymland apply
apiVersion: v1
kind: ConfigMap
metadata:
name: py-app-configmap
data:
db-port: "3308"
- apply changes:
Kubectl apply -f configmap.yml - describe configmap :
$ kubectl describe cm py-app-configmap
$ kubectl describe cm py-app-configmap
Name: py-app-configmap
Namespace: jasper475-dev
Labels: <none>
Annotations: <none>
Data
====
db-port:
----
3308
BinaryData
====
Events: <none>
-
- SSH into POD and get Port info -
kubectl exec -it sample-python-deployment-7b67d95fdc-56p4g -- /bin/bash
$ kubectl exec -it sample-python-deployment-7b67d95fdc-56p4g -- /bin/bash
groups: cannot find name for group ID 1011150000
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$ env | grep DB
NSS_SDB_USE_CACHE=no
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$ ls /opt
db-port
1011150000@sample-python-deployment-7b67d95fdc-56p4g:/app$ cat /opt/db-port | more
3308
2. Deploying ConfigMap in Kubernetes
- create a
Secretvia CLI command kubectl create secret generic - to store passwords-
kubectl create secret tls - to store certificates
$ kubectl create secret generic empty-secret
secret/empty-secret created
$ kubectl get secret empty-secret
NAME TYPE DATA AGE
empty-secret Opaque 0 19s
or
$ kubectl create secret genericmy-db-secret --from-literal=db-port="3308"
or
- Create secret via
basic_secret.yamlfile
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
username: admin # required field for kubernetes.io/basic-auth
password: t0p-Secret # required field for kubernetes.io/basic-auth
- apply :
kubectl apply -f basicsecret.yaml
$ kubectl apply -f basic_secret.yaml
secret/secret-basic-auth created
$ kubectl get secret secret-basic-auth
NAME TYPE DATA AGE
secret-basic-auth kubernetes.io/basic-auth 2 17s
PS C:\Users\Jasper\OneDrive\Documents\CodeRepo\kubernetes\d41_ConfigMaps_Secrets>
- Verify Secrets
- Describe
Secret
kubectl describe secret secret-basic-auth
Name: secret-basic-auth
Namespace: jasper475-dev
Labels: <none>
Annotations: <none>
Type: kubernetes.io/basic-auth
Data
====
password: 10 bytes
username: 5 bytes
- Edit secret:
kubectl edit secret secret-basic-auth
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
password: dDBwLVNlY3JldA==
username: YWRtaW4=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"secret-basic-auth","namespace":"jasper475-dev"},"stringData":{"password":"t0p-Secret","username":"admin"},"type":"kubernetes.io/basic-auth"}
creationTimestamp: "2024-01-17T20:02:39Z"
name: secret-basic-auth
namespace: jasper475-dev
resourceVersion: "1769551165"
uid: 46bf94fa-c060-4f6b-83d6-9e08a4637b25
type: kubernetes.io/basic-auth
- Verify Secrets: By default, they are encoded
Base64
Jasper@JASPERS-PC MINGW64 ~/OneDrive/Documents/CodeRepo/kubernetes/d41_ConfigMaps_Secrets
$ echo dDBwLVNlY3JldA== | base64 --decode
t0p-Secret
Jasper@JASPERS-PC MINGW64 ~/OneDrive/Documents/CodeRepo/kubernetes/d41_ConfigMaps_Secrets
$ echo YWRtaW4= | base64 --decode
admin
Credits:-
Thanks to Abhishek Veeramalla



Top comments (0)