With the increasing adoption of containers and microservices in the enterprises, there is a need now to focus on structuring the containers and other distributed building blocks so that we can solve some of the common design challenges. In this post, we take look at some of the key design principles that could be used in Docker, Kubernetes, and other container platforms.
These principles are based on SOLID (Single responsibility, Open/closed, Liskov substitution, Interface segregation, Dependency inversion) principles that were introduced by Robert C. Martin, which represent guidelines for writing better object-oriented software.
Following these principles would ensure that the resulting containers behave like a good cloud-native citizen in most container orchestration engines, allowing them to be scheduled, scaled, and monitored in an automated fashion.
#1. Single Containment Principle
Every container should address ONLY a single concern. This principle is more like the single responsibility principle (SRP), which advises that a class should have only one responsibility.
#2. Self-Containment Principle
A container should rely only on the presence of the Linux kernel and have any additional libraries added to it at the time the container is built.
Some applications are composed of multiple containerized components. For example, a containerized web application may also require a database container. This principle does not suggest merging both containers. Instead, it suggests that the database container contains everything needed to run the database, and the web application container contains everything needed to run the web application, such as the webserver. At runtime, the web application container will depend on and access the database container as needed.
#3.Image Immutability Principle
Containerized applications are meant to be immutable, and once built are not expected to change between different environments.
We should prevent the creation of similar container images for different environments but stick to one container image configured for each environment.
#4.High Observability Principle
Every container must implement all necessary APIs to help the platform observe and manage the application in the best way possible.
#5.Lifecycle Conformance Principle
A container should have a way to read the events coming from the platform and conform by reacting to those events.
#6.Process Disposability Principle
Containerized applications need to be as ephemeral as possible and ready to be replaced by another container instance at any point in time. This means that containerized applications must keep their state externalized or distributed and redundant.
#7.Runtime Confinement Principle
Every container should declare its resource requirements and it is also important that the application stay confined to the indicated resource requirements.
In addition to passing the resource requirements of the container, it is also important that the application stay confined to the indicated resource requirements.
In addition to the above principles, follow the common container-related best practices:
- Aim for small images – this reduces container size, build time, and networking time when copying container images.
- Support arbitrary user IDs – avoid using the
sudocommand or requiring a specific
useridto run your container.
- Mark important ports – specifying ports using the
EXPOSEcommand makes it easier for both humans and software to use your image.
- Use volumes for persistent data – the data that needs to be preserved after a container is destroyed must be written to a volume.
- Set image metadata – Image metadata in the form of tags, labels, and annotations makes your container images more discoverable.
- Synchronize host and image – some containerized applications require the container to be synchronized with the host on certain attributes such as time and machine ID.
- Log to STDOUT and STDERR – logging to these system streams rather than to a file will ensure container logs are picked up and aggregated properly.
- Automate testing and deployment using CI/CD pipeline.
- Use Container design patterns to make containers reusable, fault-tolerant, and reliable.
Like this post? Don’t forget to share it!
Additional Resources :
- Take a free course on Building Scalable Java Microservices with Spring Boot and Spring Cloud
- Kubernetes tutorial – Create simple cluster & Deploy app
- Kubernetes tutorial – Scale & perform updates to your app
- Kubernetes tutorial – Create deployments using YAML file