Table of Contents
- Containers are packages of software which contain all of the necessary elements to run in any development/production environment.
- In this article, we will see why we use container, benefits of containerization, and architecture
- This is one of the article, part of the podman tutorial article series
Traditional Applications Approach
- For running any application on a system, we would need dependency binaries or libraries for the applications
- The libraries is usually provided by the operating system, where the application is running
- Due to operating system restrictions, it may not always be possible to modify library version.
- It is not possible to run or install multiple versions of same library ( with few exceptions)
- We will have to offer multiple variant of the same applications, to be supported on different operating systems
- If we want to install an applications on Linux, Windows and Mac OS, then we need to provide the libraries for each of this platform
- If we need to do an update to the application, then it will be difficult to maintain and manage for different platform
Container Approach
- With container approach, it is possible to run an application with all of its dependencies
- Containerizing an application, will help to isolate the application from the host operating system
- Libraries are included in the container, the problem of offering support for multiple library versions is no longer an issue
- Upgrading of application is no longer an issue, instead of upgrading application, a new version of the same can be run as a different container
- Difference between Linux, Windows or Mac OS will be an issue, as the containers run on container run time, which will eliminate specific operating system requirement
History of Containerization
- Containerization technology was introduced in Unix with chroot system in 1978
- In Chroot environment, we are restricting the application or process to a specific directory
- Jail which is almost similar to chroot was introduced by FreeBSD in March 2000
- Solaris introduced Solaris containers which created Solaris zones, which gives an application to access and work with in its zone, while giving full user and process access to the system hardware with in the zone
- Solaris containers was introduced in 2004
- Introduction of Cgroups in Linux Kernel on 2008, and which lead to the creation of LXC project (Linux containers)
- Introduction of LMCTFY (Let Me Contain That For You) on 2013
- Docker release on 2013 etc.
Benefits of Containerization
- Hardware utilization is efficient, when we use containers
- Application will be secure, as containers are isolated from the rest of the infrastructure.
- Deployment and maintenance of containers is fast and efficient
- Containers focus on specific granular functionality and can be easily coupled with other micro services
- Containers are highly standardized in the Open Container Initiative or OCI, which greatly reduces the risk of vendor lock-in
- In RedHat Enterprise Linux 8, where redhat announced the drop of docker, it was of no impact, since all containerized solution including Redhat's where OCI complaint
- Any application can be moved to container ( limited to application, that doesn't require host hardware interaction)
Container Architecture
- The lowest layer is provided by Linux kernel features like
- Namespaces : Namespaces provide isolation for different parts of the kernel like filesystem namespace, user namespace, network namespace etc.
- Cgroups: Cgroups provide restrictions to resource usage such as memory. CPU and disk that a container can use
- Seccomp: Used to secure a process. It is a security profile that defines which system calls can be used by a process
- SELinux: SELinux provides mandatory access control that isolates container processes. It make sure that each container can access only their own things.
- On top of the kernel Layer, we have container Layer which consist of RunC, CRI-o( container runtime), we have podman as the runtime for RHEL
- RunC: Light weight universal container runtime. Iti is the default runtime defined by OCI. Its main job is to interfere with underlying OS and create containers.
- The low-level runtime is called runc and is the reference implementation of Open Containers Initiative (OCI) runtime-spec. Its job is to interface with the underlying OS and start and stop containers. Every running container has a runc instance managing it.
- CRI-o: Default found on podman engine stack. It provides the mountpoint and communicate with kernel. It is the heart of containerization. It added features like lifecycle management and image management
- Container Engine runs a container, which from Linux kernel POV, it is just an another process running with restrictions
- On top of the container run time layer, we will have our containers running
- In the above arch diagram, we have nginx, nodejs, mariadb containers, which is running in isolated mode
- By default there will be no direct communication between these containers, as the containers uses namespaces, cgroups etc offered by the kernel layer
- If we need to build containers together in a microservices, additional modification need to be done. It can be achieved using environment variables etc.
- Foundation of any running container is the container image
- Images are provided by a public or private repository
- Different tools are available for running container images. podman is the default tool in RHEL. Another alternative is docker
Container Standardization
- Containers are highly standardized, because of the standardization RHEL have switched from Docker to podman
- Docker founded the Open Container Initiative (OCI)
- The OCI is a governance council responsible for standardizing the low-level fundamental components of container infrastructure. In particular it focusses on image format and container runtime
- The OCI has published two specifications (standards) for all major vendors to follow
- The image-spec
- The runtime-spec