When I was a child, the town where I lived had a dock where ships would be unloaded of loose cargo using a crane that scooped it up and deposited it into a row of waiting trucks. Shipping containers had not made it to our town.
A few years ago, I saw huge cranes unloading standardized containers from ships and autonomous vehicles moving the containers around the terminal to await collection. It is a whole different level of scale and efficiency.
Shipping containers’ strength lies in their durability and standardized size and shape, making them easily manageable with cranes and forklifts, loading them onto trucks and trains for further transportation. Their ability to be stacked and stored efficiently, coupled with their locked and sealed nature, ensures they are secure and tamper-proof. By abstracting the cargo from the infrastructure that transports it, they revolutionize shipping logistics.
Just as shipping containers were standardized by the International Organization for Standardization (ISO) in the 1960s, containers for applications were standardized by the Open Container Initiative (OCI). Although practitioners often talk about Docker containers, this is just one implementation of the OCI container standard.
A container encapsulates everything necessary for the application to run—the application code, libraries, dependencies, and runtime—into a lightweight, standalone, and executable package. This concisely addresses the second factor of the 12-factor application methodology (see “II. Dependencies: Explicitly Declare and Isolate Dependencies”).
The primary advantages of containers, much like their physical counterparts, lie in their packaging and portability. When run on a host, containers are isolated from others, mitigating the risk of conflicts between coexisting applications and services.
The thing to remember is that containers are both a packaging and an isolation mechanism, and by using them, you get both benefits. Sometimes, for example, in a Python application with many dependencies, there will be a great advantage in packaging it up as a container. Other times, such as packaging to a single Go binary, the packaging will be less useful. However, in both cases, the content will give isolation at runtime.
The containers can also be immutable, and like having a locked and sealed shipping container, the content is immutable. As containers are a standard, there is also a wide range of tools for working with them, from building to checking security.
There are arguments against the need to use containers for cloud native applications around complexity and overhead. However, Google Cloud services are container-centric, so using containers gives a lot of flexibility in where those containers can run. As you will see, Google Cloud also has tools that take away a lot of the complexity and overhead concerns.