Containers are immutable. This means that each change to the application or microservice involves updating the container image and launching new containers. This type of environment is highly dynamic and requires continuous monitoring, observability, and security.
Container security is a continuous practice, which should be fully integrated into the entire development cycle. By implementing security as an integral part of your continuous deployment cycle, you can mitigate risk and reduce the number of vulnerabilities across a dynamic and complex attack surface.
To ensure efficiency, you should automate manual touch points. This includes not only development tasks, but also those related to the operation and maintenance of the underlying infrastructure. For example, you should protect your build pipeline container images as well as the runtime host, your chosen platform, and all application layers.
In this article:
Docker is a popular open source container engine. Docker popularized containerized infrastructure and took DevOps automation to the next level, but at the same time, it created new attack surfaces. To secure Docker, you must harden several layers of your environment:
Learn more in our detailed guide to Docker security
Kubernetes is an open-source container management platform that offers a rich set of capabilities. You can define a wide range of policies and then let the platform automatically enforce these operational and security baselines.
Together, the registry and orchestrator enable automated enforcement of a set of container security and quality standards. These standards are applied before and during any redeployment into the environment.
Kubernetes offers security features, but it is not secure by default. Standards like the Kubernetes CIS Benchmark can help you understand how to securely configure Kubernetes. You need to enforce secure configuration when deploying new clusters and on an ongoing basis.
Learn more in our detailed guide to Kubernetes security
The container stack usually consists of container images, containers, a container engine (Docker), container runtime (runC), registries, hosts, and orchestrators. The following are several potential risks affecting the stack, and techniques that can help you overcome them.
Container images are just as likely to have vulnerabilities as any legacy code. To ensure you are not introducing critical issues into the production environment, you should scan images for both vulnerabilities and compliance issues. Vulnerability scanning tools produce a software bill of materials (BOM), which can help identify out-of-date or unwanted software libraries, malicious software (malware), and embedded secrets. You can then correlate risk to individual image layers to ensure you are securely building your images.
Remember that configuration drift—gradual, unplanned changes in configuration over time—can be a huge issue for containers. A scanned image may pass a vulnerability and compliance check today, but may not remain secure in the future. This is because new threat data can identify vulnerabilities in a component that was previously thought to be secure. To prevent this issue, you need to continuously monitor all images and containers.
Related content: Read our guide to container security scanning
A container runtime is generally considered one of the most challenging components to secure. Traditional security technology was not designed to monitor running containers, so these tools cannot obtain visibility into containers or even establish solid baselines that model a secure container environment.
To secure containers, you need to establish behavioral baselines for your container environment in a normal and secure state. This can help detect and prevent anomalies and potential attacks. Runtime security requires you to focus on securing the application level, rather than relying mainly on network security tools.
The management stack helps coordinate containers. It includes at least two pieces of infrastructure—a privacy container registry, such as Amazon ECS, and a container orchestrator (Kubernetes).
Container registries simplify the sharing of containers. This helps teams build on each other’s work. However, these containers must be secured, typically through the use of automated scanners that ensure all containers meet development and security baselines.
Automated scanners check each container for known malware, vulnerabilities, and exposed secrets. To reduce issues downstream, the check should run before making the container available in the registry.
To ensure your registry is protected, you need to run it on a secure cloud service or a hardened system. When using a cloud service, you must factor in the shared responsibility model of the cloud and implement your own strong role-based access control (RBAC) for the registry.
Here are several practices that can help you secure container host machines:
Once a container runs in production, it starts interacting with resources and other containers. You should monitor and secure this type of internal traffic by ensuring all network traffic from containers passes through an IPS. However, do not try to implement a small number of large traditional IPS engines on the perimeter. Instead, you should implement the IPS on each host. This allows effective monitoring of all traffic without significantly impacting performance.
While it is critical to scan images, that alone is not enough. You should aim to shift image security left, avoid using unsafe images in the first place, and take care not to add vulnerable components to new images you create. Here are a few steps you can use to improve the security of your container images early in the development process.
Containers are intended to run software applications. Typically, these applications will consist of a combination of proprietary code and open source components. It is important to realize that a critical part of securing images is ensuring the code packaged within them is secure.
A variety of automated tools are available that can help you scan your code for vulnerabilities:
It is important to have these or similar tools as a mandatory step in your CI/CD pipeline, to ensure that all code you add to a container image is known to be safe.
Almost all container images are derived from a base image (this is the FROM
line in the Dockerfile). There are a huge number of public images to choose from when selecting your base image. Compare all the images that meet your needs and select the minimal image—the one with the smallest footprint and fewest features, components, and dependencies.
Selecting a minimal image will reduce your attack surface from the outset. It will also make your containers more lightweight and improve resource utilization. Remember that a base image can run in hundreds or even thousands of containers and the overhead adds up.
Never use container images from unknown publishers in public repositories. There are a few sources of trusted images where there is some assurance that the image does not contain vulnerabilities and has not been tampered with by attackers. For example:
In a Dockerfile, you start from a base image and then add additional components needed for your containers to function. You do this using RUN
, COPY
, and ADD
commands. Technically, each of these commands adds another layer to the container image, and each layer creates a new attack surface.
It is important to be aware of the layers you are adding to your containers, and reduce security risks using these guidelines:
Related content: Read our guide to container security best practices
In the past few years, dedicated security solutions have emerged that can help secure containerized environments. Here are some of the commonly used types of container security solutions:
Related content: Read our guide to container security tools
Here are several common container security pitfalls to avoid:
Calico Cloud offers active build, deploy and runtime security for containers and Kubernetes.
Visit our container security solutions page to learn more about Calico Cloud’s container security features.
Next Steps