Site icon Vinsguru

Kubernetes Init Container Pattern

Overview

Design Patterns serve as reusable and replicable solutions for common challenges in software and architectural design. They advocate for the development of highly cohesive and loosely coupled applications. In today’s era of microservices, these patterns extend beyond traditional software design and find application in infrastructure and deployment.

This article explores one such design pattern—the Kubernetes Init Container Pattern.

Goal

During development, developers may make assumptions about the presence of certain files or properties at specific paths for the application to function properly. For instance, database credentials might be stored in a property file. However, keeping these files as part of the project may not be ideal for reasons such as security. The challenge arises when deploying microservices in the cloud—these crucial configuration files, like DB credentials, must be injected into the container before it starts.

The goal is to ensure a secure and flexible way to inject property files at runtime for multiple microservices, promoting a generic and reusable solution.

We can easily argue that why can we not include that feature / add some piece of code in the application itself that is – to get those files programmatically from the AWS secrets manager. It can be done, but we need to update all the N microservices. Also, we might want to add the AWS specific dependencies in our application during local development. There is a much better and cleaner way to accomplish this goal using Kubernetes Init Container Pattern.

Init Container

Init Container is a docker container, an application, which runs before the main application starts. Kubernetes guarantees that main application does not even start unless the init container successfully exits.

Init container should be

Init container and main application container shares the disk space. So init container can prepare the required files and keep them ready for the app server to use it when it starts.

AWS Secrets Manager

Kubernetes Init Container Pattern

provider.sh

aws secretsmanager --region ca-central-1 get-secret-value --secret-id vinsguru/prod | jq -r .SecretString > app.properties
mkdir /secret
mv app.properties /secret/app.properties

Dockerfile:

FROM amazon/aws-cli

# install jq
RUN yum install jq -y

ADD provider.sh provider.sh

ENTRYPOINT sh provider.sh

Pod

apiVersion: v1
kind: Pod
metadata:
  name: vinsguru-init
  labels:
    app: vinsguru
spec:
  initContainers:
    - name: secrets-provider
      image: vinsdocker/secrets-provider
      volumeMounts:
        - name: secret
          mountPath: /secret
  containers:
    - name: microservice
      image: busybox
      command: [ 'sh', '-c', 'echo The app is running! && sleep 3600' ]
      volumeMounts:
        - name: secret
          mountPath: /app
  volumes:
    - name: secret
      emptyDir: {}
kubectl exec vinsguru-init -- cat app/app.properties

#prints below lines
api.username=prod-username
api.password=prod-password

Conclusion

By implementing the Kubernetes Init Container Pattern, I was able to successfully inject a property file from the Secrets Manager into my application docker container. Init containers provide a secure means of preparing the main app and setting up the required environment for seamless execution. While our example focused on accessing the Secrets Manager, this approach can be used to various tasks, such as interacting with external URLs, downloading files from S3, or GitHub. This approach ensures that the main application remains focused on its functionality without worrying about intricate setup procedures.

Happy Learning 🙂

 

 

Share This:

Exit mobile version