💻
Application Security Cheat Sheet
  • Application Security Cheat Sheet
  • Android Application
    • Overview
      • Application Data & Files
      • Application Package
      • Application Sandbox
      • Application Signing
      • Deployment
      • Package Manager
    • Intent Vulnerabilities
      • Deep Linking Vulnerabilities
    • WebView Vulnerabilities
      • WebResourceResponse Vulnerabilities
      • WebSettings Vulnerabilities
  • CI/CD
    • Dependency
      • Dependency Confusion
      • Dependency Hijaking
      • Typosquatting
    • GitHub
      • GitHub Actions
      • Code owners
      • Dependabot
      • Redirect
      • Releases
  • Cloud
    • AWS
      • Amazon API Gateway
      • Amazon Cognito
      • Amazon S3
  • Container
    • Overview
      • Container Basics
      • Docker Engine
    • Escaping
      • CVE List
      • Exposed Docker Socket
      • Excessive Capabilities
      • Host Networking Driver
      • PID Namespace Sharing
      • Sensitive Mounts
    • Container Analysis Tools
  • Framework
    • Spring
      • Overview
      • Mass Assignment
      • Routing Abuse
      • SpEL Injection
      • Spring Boot Actuators
      • Spring Data Redis Insecure Deserialization
      • Spring View Manipulation
    • React
      • Overview
      • Security Issues
  • Linux
    • Overview
      • Philosophy
      • File
      • File Descriptor
      • I/O Redirection
      • Process
      • Inter Process Communication
      • Shell
      • Signals
      • Socket
      • User Space vs Kernel Space
    • Bash Tips
  • iOS Application
    • Overview
      • Application Data & Files
      • Application Package
      • Application Sandbox
      • Application Signing
      • Deployment
    • Getting Started
      • IPA Patching
      • Source Code Patching
      • Testing with Objection
  • Resources
    • Lists
      • Payloads
      • Wordlists
    • Researching
      • Web Application
      • Write-ups
    • Software
      • AWS Tools
      • Azure Tools
      • Component Analysis
      • Docker Analysis
      • Dynamic Analysis
      • Fuzzing
      • GCP Tools
      • Reverse Engineering
      • Static Analysis
      • Vulnerability Scanning
    • Training
      • Secure Development
  • Web Application
    • Abusing HTTP hop-by-hop Request Headers
    • Broken Authentication
      • Two-Factor Authentication Vulnerabilities
    • Command Injection
      • Argument Injection
    • Content Security Policy
    • Cookie Security
      • Cookie Bomb
      • Cookie Jar Overflow
      • Cookie Tossing
    • CORS Misconfiguration
    • File Upload Vulnerabilities
    • GraphQL Vulnerabilities
    • HTML Injection
      • base
      • iframe
      • link
      • meta
      • target attribute
    • HTTP Header Security
    • HTTP Request Smuggling
    • Improper Rate Limits
    • JavaScript Prototype Pollution
    • JSON Web Token Vulnerabilities
    • OAuth 2.0 Vulnerabilities
      • OpenID Connect Vulnerabilities
    • Race Condition
    • Server Side Request Forgery
      • Post Exploitation
    • SVG Abuse
    • Weak Random Generation
    • Web Cache Poisoning
Powered by GitBook
On this page
  • runc
  • containerd
  • containerd-shim
  • dockerd
  • docker CLI
  • Running container
  • References
  1. Container
  2. Overview

Docker Engine

PreviousContainer BasicsNextEscaping

Last updated 3 years ago

Docker Engine is the heart of the container and what makes the container to run. Docker has a modular design, which means you can swap/customize some of its components.

Docker architecture has five components:

  • docker CLI

  • dockerd

  • containerd

  • containerd-shim

  • runc

runc

You can run your containers without Docker using the CLI only. To do this, you must have a bundle aligned with the OCI standards. A bundle for a container is a directory that includes a specification file named config.json and a root filesystem. config.json is used to create a container in a particular state.

An example of config.json

{  
  "ociVersion": "0.6.0-dev",  
  "platform": {     
    "os": "linux",     
    "arch": "amd64"   
  },   
  "process": {   
    "terminal": true,   
    "args": ["sh"],   
    "env": ["PATH=/usr/local/sbin:/usr/local/bin:/bin", ...]
  ...
}

Given the bundle, you can simply run the container with runc

# Creates an empty folder
mkdir ~/mycontainer
cd ~/mycontainer
# Creates rootfs, one way of doing so is to export it re-using docker
mkdir rootfs
docker export $(docker create busybox) | tar -C rootfs -xvf -
# Creates the new specification file named "config.json" for the bundle
runc spec
# Runs the container
runc run mycontainerid

containerd

containerd is one of the layers in the Docker's modular architecture. When you make a request to dockerd, containerd manages processes related to image distribution such as pushing/pulling them to/from registries. With the images containerd generates an OCI bundle for the container.

containerd manages the container lifecycle: it starts, stops, pauses, or deletes it. It also manages image distribution: pushes/pulls the images to/from registry.

containerd-shim

containerd-shim allows you to have daemonless containers. How this is achieved:

  • containerd forks an instance of runc for each new container

  • runc process exits after the container is created

  • once a container is created by runc, containerd-shim becomes the new parent for the container process

You can see this by creating a docker container and checking the processes.

$ docker run -d alpine sleep 30
$ ps fxa | grep dockerd -A 3  
 2239 ?        Ssl    0:28 /usr/bin/dockerd -H fd://
 2397 ?        Ssl    0:19  \_ docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock ...
15476 ?        Sl     0:00      \_ docker-containerd-shim 3de8... /var/run/docker/libcontainerd/3da7.. docker-runc  
15494 ?        Ss     0:00          \_ sleep 30

That there is no runc used as it was replaced by containerd-shim.

containerd-shim is responsible for STDIN/STDOUT and for reporting exit status to the Docker daemon.

dockerd

dockerd is a daemon and a server that processes the Docker API requests and then utilizes containerd functionality to manage life-cycle of the containers.

docker CLI

Docker CLI is an one of the ways to talk to Docker server dockerd. You can use it to run the docker commands like docker run or docker build.

Running container

  1. A user uses the docker CLI to execute a command:

    docker container run -it --name <NAME> <IMAGE>:<TAG>
  2. Docker client sends POST request to daemon's API

  3. Docker daemon receives instructions and calls containerd to start a new container

  4. containerd creates an OCI bundle from the Docker image

  5. containerd tells runc to create a container using the OCI bundle

  6. runc interfaces with the OS kernel to create a container

  7. Container process starts as a child process

  8. runc exits after starting the container

  9. containerd-shim takes over the child process and becomes its parent

  10. Container is running!

References

is a lightweight CLI wrapper for the libcontainer and it is used to spawn and run containers.

Docker is a higher level abstraction over runc and runc is a CLI for libcontainer. Moreover, it is also possible to set the docker to your own runtime dockerd daemon .

So what do you actually get using containerd? You get push and pull functionality as well as image management. You get container lifecycle APIs to create, execute, and manage containers and their tasks. An entire API dedicated to snapshot management. Basically everything that you need to build a container platform without having to deal with the underlying OS details. more see

runc
--add-runtime
Docker containerd integration
Docker Engine Architecture Under the Hood
docker-engine-arch
running-container