Amongst the buzzword soup of the modern IT industry you'll often find Kubernetes and
Docker getting mentioned alongside fellow buzzwords like Cloud and DevOps; but what
are these Kubernetes and Docker things all about, and how might they be useful? The short version is
they're about containers. Kubernetes is for orchestrating containers at scale. Docker is
a platform for creating and running containers. And what are these containers? The topic of this video!
Welcome back to The Pro Tech Show. This video is a high-level introduction to containerisation.
Docker is largely responsible for popularising the use of containers but Docker didn't invent
containerisation, nor is it the only platform for them. You can run Docker on both Linux and
Windows, so whilst most people probably think of Linux first when containers are mentioned they are by no
means limited to that. Containers can benefit both developers and sysadmins but the developers are
usually the ones banging on about them so let's look at them from the application perspective
first, then we'll talk about the infrastructure. A modern application isn't a self-contained blob. It
has a whole web of dependencies and libraries that it relies on. These libraries save a huge amount of
time when developing software because you don't have to keep constantly reinventing the wheel;
but it can also create a whole mess of problems when moving from one environment to another.
The classic scenario is that the developer hands over some code operations, they deploy it, and it
immediately crashes and destroys itself. What does the developer say? "Well it worked on my computer!"
Of course it did... but obviously your laptop and the server we're actually running it on
differ somehow. Maybe the operating system is similar, but not exactly the same. Maybe one of
those libraries is a different version. Or part of the application conflicts with something
else already on the production system. Or maybe you had it all working fine and then you updated the
underlying infrastructure and that caused a change which broke the application. Maybe it introduced a
bug, or maybe it fixed a bug and the application was relying on that bug. Sounds silly, but believe
me that happens. Containerisation attempts to solve this problem by taking the application and all of
its dependencies and then packaging them up into one self-contained box... or "container" if you will.
The idea is that this container contains everything the application needs to run and
you can deploy it as a single unit with whatever version of PHP or .NET or whatever it needs as part
of the same package. You just need an operating system that's capable of running the container.
As long as it can run the container everything should work predictably, regardless of where it's
deployed, because it has everything it needs inside the container with it. This is not just about
dependency resolution like you get with a package manager on Linux. The whole thing runs inside its
own little bubble. Because it exists in its own little bubble, different containers can run on the
same host and have completely contradictory and conflicting dependencies; but they don't interfere
with each other because those dependencies are walled off inside each application's container.
Because containerisation runs applications within their own isolated bubbles,
and many of these bubbles can run on a single host independently of each other, it often gets
compared to server virtualisation. Containers and virtual machines are fundamentally quite different
but you could think of containerisation as a type of virtualisation that occurs at a different level.
If virtual machines are virtualisation of the hardware then containers are virtualisation of the
operating system. It helps if you view a server as a series of layers built one on top of the other.
At the bottom you have the physical nuts and bolts hardware. Running on that hardware you
have an operating system like Windows or Linux. The operating system can be further subdivided
into the kernel and supporting applications. On top of that you install your own applications. Server
virtualisation puts a layer called a hypervisor in-between the hardware and the operating system.
This hypervisor pretends to be multiple copies of the hardware. These are your virtual machines. This
lets you install multiple operating systems - one in each virtual machine; letting your one piece of
real hardware host multiple independent servers, each with their own copy of Windows or Linux or
BSD or whatever you want, and each with their own applications installed. Containerisation happens
a layer above that. So rather than sitting between the hardware and operating system it sits between
the operating system's kernel and the applications. Instead of pretending one set of hardware is
actually multiple sets of hardware and letting you install multiple operating systems, it pretends
your operating system (or more specifically its kernel) is multiple operating systems; which allows
you to run multiple applications each thinking they've got an operating system all to themselves.
They're all sharing the same operating system kernel, but they don't know that. Because it's using
the same underlying host operating system's kernel the containers do need to be compatible with it,
but it still affords a fair level of flexibility. You can't simply run a Windows container on Linux
or vice-versa but you can mix containers from different Linux distributions. For example you
can run an Ubuntu container on Red Hat as long as the underlying Linux kernel and architecture is
compatible. Compared to server virtualisation, containerisation has some advantages at an
infrastructure level. The main one being that the container is much smaller than a virtual machine.
A virtual machine has to encapsulate the entire server including its operating system. Because
a container shares that with other containers on the host it only needs to include the application
layer. That means that containers take up less storage compared to virtual machines, and they
incur less resource overhead because you're not running multiple full operating systems. The end
result is that you can pack more applications onto the same hardware using containers than
you can with multiple virtual machines. This has cost and scalability benefits beyond what you
get with server virtualisation. Both technologies allow you to scale out very quickly by deploying
new instances, but containerisation can do it much faster because starting a new container
only takes a few seconds as it doesn't need to wait for an operating system to boot. Remember
how going from physical servers to virtual servers reduced the start time significantly?
Well this makes it faster again! In fact it's so fast that fault conditions are often dealt with by
just discarding the running container and starting a new one. These features make containerisation a
natural fit for applications deployed using a microservices architecture, where the application
is broken down into a number of smaller and simple components that can each be packaged into their
own container. Scalability and fault-tolerance are achieved through the ability to deploy, redeploy,
and move containers around different hosts. So why aren't all applications deployed using containers?
Well, not all applications are a good fit. You now how I said microservices were a natural pairing?
Well, the opposite of microservices being a large monolithic application, is usually a bad idea to
containerise. Some would argue you can containerise most applications if you try hard enough
but ideally you want to be developing the application with containerisation in mind;
and large, complex applications really need some level of rewrite if you want to move to containers.
If you're a developer working on your own software that might be an option,
but for most people using off-the-shelf products... well it's not like you can just
download SharePoint and install it in a container. They're also not well suited to applications with
graphical interfaces. There are some scenarios where this can be made to work but it's limiting
and it may require clunky workarounds, and it's just not what they were designed for. Containers are
more for back-end services that users don't interact with directly; or if they do it's via
some other application like a web browser. Whilst it's a different technology it is fair
to suggest that they've at least inspired ideas like Flatpak applications, though.
Security is also an area of concern when it comes to containers. Because they're sharing a single
operating system, that host operating system can see everything. If you run a process in a container
you're running it on the host operating system and anyone with access to that host can manipulate it.
It also increases the risk of lateral movement between applications should an attacker exploit
a vulnerability to escape from the container and gain access to the host. Remember that it's
actually the same operating system underneath. Containers aren't as self-contained as virtual
servers and thus don't benefit from the same security isolation as virtual machines do. This
might not be a big worry if you're running your own containers on your own hosts and containers
with different security levels are never allowed to mix; but it has very serious implications for
shared platforms like cloud providers where random people could be running their code
within the very same operating system instance as your sensitive data. Before you run away from the
cloud screaming in terror, there are solutions to this problem. The big names will be using such a
solution, but don't be afraid to ask the smaller providers how they guarantee isolation between
customers because there are some cowboys out there. We have in fact talked about a solution to this
security concern already: virtualisation. There is a middle ground between full-blown virtual
machines and containers which essentially wraps containers inside lightweight virtual machines.
This provides your container with the same security isolation that virtualisation provides
whilst maintaining the portability benefits of containers. Because the container is encapsulated inside
a virtual machine that VM doesn't need to match the host operating system, so you can even use
this approach to run Linux containers on Windows. Whilst this might sound like a best of both worlds
thing it's really a trade-off. You do lose some of the efficiency benefits of containers compared to
virtualisation once you deploy containers inside virtualisation. You don't lose all of it, though.
The virtual machines used to run containers are more specialised. You don't need to load a full
instance of Ubuntu if all you want to do is run a container in it. These virtual containers use more
lightweight, single-purpose virtual machines that start faster than a normal VM and incur
less overhead; but they're still a bit slower and more bloated compared to a traditional container.
It does give you more options, though. It allows your developers to build their applications in
containers for portability, and then your ops team can decide later if they'll be deployed
as native containers for better performance or virtualised containers for better security. Now
that I've mentioned both "dev" and "ops" in the same sentence this leads me to a bit of a cautionary
thought. I don't personally use containers very much but I think every IT professional should at
least understand what they can do and where they might be useful. DevOps is an example of where they
work really well. Where we can use their portability to streamline the journey from developer to
production. It's a great use case for them but it's not the only use case. I've heard people advocating
the use of containers because it means you can deploy complex applications without needing
to know anything about how they're put together. People with little or no infrastructure experience
use them to deploy services on their home NAS for example: stuff like Plex or Bitwarden. Whilst that
is very convenient it also worries me a little. Actually, not that use case... it's OK. I generally
like anything that gets people experimenting with tech; but when the same attitude makes its way to
production... when people are deploying business critical services with no idea how they work...
I consider that a problem. DevOps is fine, but take the "Ops" out of it and you've just got developers.
This isn't a dig at developers. Writing software and securing infrastructure are different skillsets.
Some of the developers I work with know more about IT infrastructure than a lot of IT pros,
but they're in the minority. I've spent far too much my professional life
puling vendors up for distributing their software with serious security vulnerabilities resulting
from third-party dependencies. The problem is the developers often don't understand how these work.
They just know that by including this library they can get their code working. The perfect
example of this is the Log4Shell vulnerability that probably ruined a few of your Christmases.
I use an application that was vulnerable to this. One of the ways that application can be deployed
is as a container. At the time of recording this video it is January 2022 and the containerised
version is still vulnerable. I didn't deploy it as a container so I was able to quickly remediate it
myself; but if I was running it in a container I would be reliant on the developer and that would
put me in a rather precarious position. If you're going to consume applications in the form of
containers that are being developed by a third party then make sure you do your due diligence
on that third party; because whilst in theory it makes the process of deploying updates much easier
this only counts if they're actually providing timely updates - including those packaged up
dependencies. If they're not doing that it could actually put you at higher risk. That's not a
problem with containers themselves, it's a problem with people using them badly. Just because you can
deploy something without understanding it doesn't absorb you of your duty to deploy it responsibly.
As I said I don't really have much for use case for containers myself at the moment.
I just like to know what my options are so I can pull them out of my toolkit when they're needed.
If you want to explore this topic further I do have an industry expert in containerisation
who's happy to come talk to you, so go down to the comments and let us know your questions and
we'll build some content around that if it's something you want. If that video has already gone
up you'll be able to click on it here, and if not I'll let YouTube's algorithm find something
interesting for you to watch instead. Hit "like" if this was useful and I'll see you next time!