Containers are taking the world by storm. This technology is helping enterprises to transform legacy application to cloud-native hence achieve scalability and manageability. The container adoption by enterprises is on the rise, and as per Gartner, it will be more than 50% by 2020 as compared to 20% today. More and more containerized workloads are running in production today. This rush to production may create non-optimal use of containers due to lack of best practices. The container is still an evolving technology and needs to be followed by correct guidelines to be effective. This paper highlights the 10 best practices for container usage and serves as a checklist for developers and operation engineers.
- Selective Containerization
The first rule of the game is not to aim for complete containerization of the systems. The value for containerizing the application should be determined before we take a jump. Not all applications that are containerized will give the expected benefits, hence sometimes it is best to leave them as traditional microservices.
- Base Images
Docker hub has several images available, ready to use for developers. Since the Docker hub is a public repository and not audited for image content security, it is always a good idea to build the base image by yourself. Having a private or trusted repository for your organization would help to ensure the authenticity of the base images.
- Ephemeral Storage
Microservices architecture is primarily based on stateless application. It is very important to design an application so as not to maintain any state or persistent storage within the container. If there is any need to store state beyond reboot or shutdown then it should be stored outside the container. Docker volumes are best way to have persistent storage outside containers.
- Multistage Builds
Docker containers are normally created as a part of a broad DevOps setup. It will involve code build stage before the final executable is packaged in docker container. In this case, use a separate development container for build stage and then copy over the compiled binary to production container. This way will help to keep the container size within a manageable limit. Latest Docker version supports multistage builds with a single docker file with no need to create two containers.
- No Default Root User
By default, the docker containers are created for root user. It’s always a good practice to create a normal user and login with it. This can be easily handled in docker build file. If required, this normal user be added to sudoer list so that it can be elevated to root explicitly whenever required.
- Process and Service in Container
The application transformation for converting it to a container begin with categorizing the application. The application can be a service that is typically running forever or process that is run on demand and short lived. In both cases, it is recommended to keep a service or process per container. This one to one mapping between process/service and container makes it easy to monitor the container for failure and take corrective action. Also, it makes the overall system scalable at process or service level.
- Sensitive Data
The sensitive data like password, the token string needs to be handled carefully and should never be stored in docker build file or in docker images. The sensitive data should always be passed on runtime as an environment variable when the docker image is run.
- Latest Tag
Avoid using the latest tag for the software in docker build file. The docker images are intended to be deterministic and exactly reproducible using docker build file. Using latest tag may change the software versions used to build the final image and may break it due to backward compatibility.
- Privileges and Capabilities
By default, docker runs with restricted access but this can be easily over-ridden. Docker container running with privileged mode has unrestricted access to the host. As far as possible avoid running containers running with elevated privileges. It is recommended to remove all the capabilities except the required ones.
- Resource Consumption
It’s always a good idea to limit the resources available to containers, no more no less.
The above is by no means a comprehensive checklist but a definitely a good head start.