Example application – Container Orchestration with Kubernetes

The Flask application queries a Redis sidecar for the secret and sends that as a response. That is not ideal, as you won’t send secrets back as a response, but for this demo, let’s go ahead with that.

So, first, let’s design our sidecar so that it pre-populates data within the container after it starts.

We need to create a secret named secret with a value of foobar. Now, base64-encode the Redis command to set the secret into the cache by running the following command:

$ echo ‘SET secret foobar’ | base64

U0VUIHNlY3JldCBmb29iYXIK

Now that we have the base64-encoded secret, we can create a redis-secret.yaml manifest with the string as follows:

apiVersion: v1

kind: Secret

metadata:

name: redis-secret

data:

redis-secret: U0VUIHNlY3JldCBmb29iYXIK

Then, we need to build the Redis container so that this secret is created at startup. To access the files for this section, go to the following directory:

$ cd ~/modern-devops/ch5/multi-container-pod/sidecar/redis/

Create an entrypoint.sh file, as follows:

redis-server –daemonize yes && sleep 5

redis-cli < /redis-master/init.redis

redis-cli save

redis-cli shutdown

redis-server

The shell script looks for a file, init.redis, within the /redis-master directory and runs the redis-cli command on it. This means the cache will be pre-populated with the values defined in our secret, provided we mount the secret as /redis-master/init.redis.

Then, we must create a Dockerfile that will use this entrypoint.sh script, as follows:

FROM redis

COPY entrypoint.sh /tmp/

CMD [“sh”, “/tmp/entrypoint.sh”]

Now that we are ready, we can build and push the code to Docker Hub:

$ docker build -t <your_dockerhub_user>/redis-secret .

$ docker push <your_dockerhub_user>/redis-secret

Now that we are ready with the Redis image, we must build the Flask application image. To access the files for this section, cd into the following directory:

$ cd ~/modern-devops/ch5/multi-container-pod/sidecar/flask

Let’s look at the app.py file first:

cache = redis.Redis(host=’localhost’, port=6379)

def get_secret():

try:

secret = cache.get(‘secret’)

return secret

def index():

secret = str(get_secret().decode(‘utf-8’))

return ‘Hi there! The secret is {}.\n’.format(secret)

The code is simple – it gets the secret from the cache and returns that in the response.

We also created the same Dockerfile that we did in the previous section.

So, let’s build and push the container image to Docker Hub:

$ docker build -t <your_dockerhub_user>/flask-redis-secret .

$ docker push <your_dockerhub_user>/flask-redis-secret

Now that our images are ready, let’s look at the pod manifest, flask-sidecar.yaml, which is present in the ~/modern-devops/ch5/multi-container-pod/sidecar/ directory:

spec:

containers:

  • name: flask-app

image: <your_dockerhub_user>/flask-redis-secret

  • name: redis-sidecar

image: <your_dockerhub_user>/redis-secret

volumeMounts:

  • mountPath: /redis-master

name: secret

volumes:

  • name: secret secret:

secretName: redis-secret items:

  • key: redis-secret

path: init.redis

The pod defines two containers – flask-app and redis-sidecar. The flask-app container runs the Flask application that will interact with redis-sidecar for the secret. The redis-sidecar container has mounted the secret volume on /redis-master. The pod definition also contains a single volume called secret, and the volume points to the redis-secret secret and mounts that as a file, init.redis.

So, in the end, we have a file, /redis-master/init.redis, and, as we know, the entrypoint. sh script looks for this file and runs the redis-cli command to pre-populate the Redis cache with the secret data.

Let’s apply the secret first using the following command:

$ kubectl apply -f redis-secret.yaml

Then, we can apply the flask-sidecar.yaml file using the following command:

$ kubectl apply -f flask-sidecar.yaml

Now, let’s get the pods using the following command:

$ kubectl get pod flask-sidecar

NAME

READY

STATUS

RESTARTS     AGE

flask-sidecar

2/2

Running

0

11s

As the pod is running, it’s time to port-forward it to the host using the following command:

$ kubectl port-forward flask-sidecar 5000:5000

Now, let’s open a duplicate Terminal, run the curl localhost:5000 command, and see what we get:

$ curl localhost:5000

Hi there! The secret is foobar.

As we can see, we get the secret, foobar, in the response. The sidecar is working correctly! Now, let’s look at another popular multi-container pod pattern – the adapter pattern.

Related Posts

Static provisioning – Managing Advanced Kubernetes Resources-2

As the Service resource is created, we can create a StatefulSet resource that uses the created PersistentVolume and Service resources. The StatefulSet resource manifest, nginx-manual-statefulset.yaml, looks like…

Static provisioning – Managing Advanced Kubernetes Resources-1

Static provisioning is the traditional method of provisioning volumes. It requires someone (typically an administrator) to manually provision a disk and create a PersistentVolume resource using the…

StatefulSet resources – Managing Advanced Kubernetes Resources

StatefulSet resources help manage stateful applications. They are similar to Deployment resources, but unlike a Deployment resource, they also keep track of state and require Volume and…

Managing stateful applications – Managing Advanced Kubernetes Resources

Imagine you’re a librarian in a magical library. You have a bunch of enchanted books that store valuable knowledge. Each book has a unique story and is…

Horizontal Pod autoscaling – Managing Advanced Kubernetes Resources-2

Now, let’s autoscale this deployment. The Deployment resource needs at least 1 pod replica and can have a maximum of 5 pod replicas while maintaining an average…

Horizontal Pod autoscaling – Managing Advanced Kubernetes Resources-1

Imagine you’re the manager of a snack bar at a park. On a sunny day, lots of people come to enjoy the park, and they all want…

Leave a Reply

Your email address will not be published. Required fields are marked *