Exercise
In this exercise, you will use a Secret to connect to an external database.
The image registry.gitlab.com/lucj/messages:v1.0.5 contains a simple application that listens on port 3000 and allows, via HTTP requests, to create messages or list existing messages in a MongoDB database. The connection URL of this database must be provided to the application so that it can connect to it. We can provide it via an environment variable MONGODB_URL or via a file that must be accessible from /app/db/mongodb_url.
We will use the Mongo database with the following connection URL:
mongodb+srv://k8sExercice:k8sExercice@techwhale.hg5mrf8.mongodb.net/
This database is hosted on MongoDB Atlas.
- Creating the Secret
Create a Secret named mongo, its data field must contain the key mongo_url with the connection string specified above as its value.
Choose one of the following options:
-
Option 1: using the
kubectl create secret generic
command with the--from-file
option -
Option 2: using the
kubectl create secret generic
command with the--from-literal
option -
Option 3: using a specification file
- Using the Secret in an environment variable
Define a Pod named messages-env whose single container has the following specification:
- image: registry.gitlab.com/lucj/messages:v1.0.5
- an environment variable MONGODB_URL having the value linked to the mongo_url key of the mongo Secret created previously
Then create this Pod and expose it using the kubectl port-forward
command by mapping port 3000 of your local machine to port 3000 of the messages-env Pod.
From another terminal, verify that you can create a message with the following command:
Note: make sure to replace YOUR_NAME with your first name
curl -H 'Content-Type: application/json' -XPOST -d '{"msg":"hello from YOUR_NAME"}' http://localhost:3000/messages
- Using the Secret in a volume
Define a Pod named messages-vol with the following specification:
- a volume named mongo-creds based on the mongo Secret
- a container with the following specification:
- image: registry.gitlab.com/lucj/messages:v1.0.5
- a volumeMounts instruction allowing to mount the mongo_url key of the mongo-creds volume in the /app/db/mongo_url file
Create the Pod and verify that you can create a message in the same way as in the previous point by exposing the Pod via a port-forward.
- Cleanup
Delete the various resources created.
Solution
- Creating the Secret
- Option 1: using the
kubectl create secret generic
command with the--from-file
option
Use the following command to create a mongo_url file containing the database connection string:
echo -n "mongodb+srv://k8sExercice:k8sExercice@techwhale.hg5mrf8.mongodb.net/" > mongo_url
Then we create the Secret from this file:
kubectl create secret generic mongo --from-file=mongo_url
- Option 2: using the
kubectl create secret generic
command with the--from-literal
option
The following command creates the Secret from literal values
kubectl create secret generic mongo --from-literal=mongo_url='mongodb+srv://k8sExercice:k8sExercice@techwhale.hg5mrf8.mongodb.net/'
- Option 3: using a specification file
The first step is to encrypt the connection string in base64
$ echo -n 'mongodb+srv://k8sExercice:k8sExercice@techwhale.hg5mrf8.mongodb.net/' | base64
bW9uZ29kYitzcnY6Ly9rOHNFeGVyY2ljZTprOHNFeGVyY2ljZUB0ZWNod2hhbGUuaGc1bXJmOC5tb25nb2RiLm5ldC8=
Then we can define the mongo-secret.yaml specification file:
apiVersion: v1
kind: Secret
metadata:
name: mongo
data:
mongo_url: bW9uZ29kYitzcnY6Ly9rOHNFeGVyY2ljZTprOHNFeGVyY2ljZUB0ZWNod2hhbGUuaGc1bXJmOC5tb25nb2RiLm5ldC8=
The last step is to create the Secret from this file
kubectl apply -f mongo-secret.yaml
- We define the following specification in the messages-env.yaml file
apiVersion: v1
kind: Pod
metadata:
name: messages-env
spec:
containers:
- name: messages
image: registry.gitlab.com/lucj/messages:v1.0.5
env:
- name: MONGODB_URL
valueFrom:
secretKeyRef:
name: mongo
key: mongo_url
We can then create the Pod:
kubectl apply -f messages-env.yaml
The following command exposes the API running in the Pod container locally:
kubectl port-forward messages-env 3000:3000
From another terminal on the local machine, we can then send a POST request to the API:
Note: make sure to replace YOUR_NAME with your first name
curl -H 'Content-Type: application/json' -XPOST -d '{"msg":"hello from YOUR_NAME"}' http://localhost:3000/messages
The returned response is similar to the one below:
{"msg":"hello from USER_NAME","created_at":"2023-08-02T11:37:29.796Z"}
We can then stop the port-forward.
- We define the following specification in the messages-vol.yaml file
apiVersion: v1
kind: Pod
metadata:
name: messages-vol
spec:
containers:
- name: messages
image: registry.gitlab.com/lucj/messages:v1.0.5
volumeMounts:
- name: mongo-creds
mountPath: "/app/db"
readOnly: true
volumes:
- name: mongo-creds
secret:
secretName: mongo
:warning: if you gave the Secret key a name other than mongo_url (you named it mongo for example), you can make this key available with the following configuration:
...
volumeMounts:
- name: mongo-creds
mountPath: "/app/db/mongo_url"
subPath: "mongo"
We can then create the Pod:
kubectl apply -f messages-vol.yaml
The following command exposes the API running in the Pod container locally:
kubectl port-forward messages-vol 3000:3000
From the local machine, we can then send a POST request to the API:
curl -H 'Content-Type: application/json' -XPOST -d '{"msg":"hello from USER_NAME"}' http://localhost:3000/messages
We then get a response similar to the following:
{"msg":"hello from USER_NAME","created_at":"2023-08-02T11:40:26.765Z"}
Then stop the port-forward.
- Delete the various resources created
k delete po messages-env messages-vol
k delete secret mongo