{"id":2115,"date":"2020-01-21T12:43:13","date_gmt":"2020-01-21T07:13:13","guid":{"rendered":"https:\/\/opstree.com\/blog\/\/?p=2115"},"modified":"2025-11-28T11:55:47","modified_gmt":"2025-11-28T06:25:47","slug":"docker-inside-out-a-journey-to-the-running-container","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2020\/01\/21\/docker-inside-out-a-journey-to-the-running-container\/","title":{"rendered":"Docker Inside Out &#8211; A Journey to the Running Container"},"content":{"rendered":"\r\n<div class=\"wp-block-image\">\r\n<figure class=\"alignleft is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"\" src=\"https:\/\/lh6.googleusercontent.com\/FpVLhDhkGBq8FyQreUGKs_gHD34UavIwCRHVpnMC4_hY_n7XYTCgNwnJ2loGHIOSxbU61mBI5AfjgaRO_nwEF32J04_yKceq8HfmJsMNYC0C4GXFqOHjpMLa3JDJSvBMvZLYvHHz\" alt=\"\" width=\"286\" height=\"198\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-3286\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2020\/06\/containerd-e1450381335180-1.png?w=300\" alt=\"\" width=\"283\" height=\"186\" \/><\/p>\r\n<p>&nbsp;<\/p>\r\n<p>Necessity is the mother of invention, the same happens here in case of docker. With the pressure of splitting monolithic applications for the purpose of ease, we arrived at docker and it made our life much simpler. We all access docker with docker-cli command but I wonder what it does behind the scene, to run a container. Let\u2019s get deeper into it in this very blog.<!--more--><\/p>\r\n<p>There&#8217;s a saying that &#8220;Behind every successful man, there is a woman&#8221;. I would love to give my perspective on this. One of the things that I have actively observed from the life of successful people I know is that there is a lot of truth in this statement but it varies with different situations and in most of the cases these women are not directly helping men in their prime work but taking care of another important workaround so that they can concentrate on their prime work. Keeping this in my mind, I am expecting that there are other components as well which are behind docker-cli command that leads to the successful creation of containers. Whenever I talk about docker containers with developers who are new to docker in my organization the only thing I hear from them is &#8220;docker-cli command is used to invoke docker daemon to run container&#8221;<\/p>\r\n\r\n\r\n\r\n<p>\r\n\r\n<\/p>\r\n<p>But, Docker daemon is not the process that gets executed when a container is meant to be run &#8211; it delegates the action to containerd which then controls a list of runtimes (runc by default) which is then responsible for creating a new process (calling the defined runtime as specified in the configuration parameters) with some isolation and only then executing the entry point of that container.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<h1 class=\"wp-block-heading\">Components involved<\/h1>\r\n<p>\r\n\r\n<\/p>\r\n<ul>\r\n<li>Docker-cli<\/li>\r\n<li>Dockerd<\/li>\r\n<li>Containerd<\/li>\r\n<li>RunC<\/li>\r\n<li>Containerd-shim<\/li>\r\n<\/ul>\r\n<p>\r\n\r\n<\/p>\r\n<p><strong>Docker-cli: <\/strong>Used to make Docker API calls.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p><strong>Dockerd<\/strong>:\u00a0 dockerd listens for Docker API requests, dockerd can listen for Docker Engine API requests via three different types of Socket:\u00a0<strong>unix, tcp, and fd\u00a0<\/strong>and manages host&#8217;s container life-cycles with the help of containerd. Hence, actual container life-cycle management is outsourced to containerd.\u00a0<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p><strong>Containerd<\/strong>: Actually manages container life-cycle through the below-mentioned tasks:<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<ul>\r\n<li>Image push and pull<\/li>\r\n<li>Management of storage<\/li>\r\n<li>Of course, executing containers by calling <strong>runc<\/strong> with the right parameters to run containers.<\/li>\r\n<\/ul>\r\n<p>\r\n\r\n<\/p>\r\n<h4 class=\"wp-block-heading\"><strong>Let&#8217;s go through some subsystems of containerd :<\/strong><\/h4>\r\n<p>\r\n\r\n<\/p>\r\n<p><strong>Runc<\/strong>: Containerd uses <strong>RunC<\/strong> to run containers according to the OCI specification.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p><strong>Containerd shim<\/strong>: With the docker 1.11 version, this component has been added. This is the parent process of every container started and it also allows <strong>daemon-less<\/strong> containers. First, it allows the runtimes, i.e. runc, to exit after which it starts the container.\u00a0 This way we don&#8217;t have to have the long-running processes for containers.\u00a0 When you start nginx you should only see the nginx process and the shim.\u00a0\u00a0<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p><em>Daemon-less: When I say <\/em><strong><em>daemon-less<\/em><\/strong><em> containers in the above paragraph, it means there is an advantage of this. When containerd shim was not there, upgrading docker daemon without restarting all your containers was a big pain. Hence, containerd shim got introduced to solve this problem.<\/em><\/p>\r\n<p>\r\n\r\n<\/p>\r\n<h1 class=\"wp-block-heading\">The communication between Dockerd and ContainerD<\/h1>\r\n<p>\r\n\r\n<\/p>\r\n<p>We can see how docker delegates all the work of setting up the container to containerd. Regarding interactions between docker, containerd, and runc, we can understand that without even looking at the source code &#8211; plain strace and <strong>pstree<\/strong> can do the job.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/rQxxw_oPJmaBM2lGpA-pfHGM-Ktw9r37_wUSvbIMiNenHTnSj7xWhBsIGnVSxj6T8OULs2swt7zj8lTgfMeP7V0uKqTUFk0B4NqYWz9S5fEK85EYh_-ZrVHPjpNQGGgOKk6B0Tnj\" alt=\"\" width=\"710\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/MUNGA0GHqO_v21BX52mMET1pmqs0xopaNakxEc1OlKuIvnYkh6pY6SbiDca9IMrpftxyUnBXrREs2m26NfTCKAH_Q0f2aNJ5BbD3zAepRwcKOt9q2nq8no752Z3XmPBgkqMq1f7K\" alt=\"\" width=\"710\" height=\"150\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<h3 class=\"wp-block-heading\"><strong>Command:<\/strong><\/h3>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-preformatted\">when no containers running:\r\n\r\nps fxa | grep docker -A 3 <\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<p>Result:<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/7z3Xd5_XgpyeIlhZHY3bHSW2J6BTAl2wLywnpv-CTnjnfK7dEVOcKku97Q_c88CgXzjDjGg4XcDUy4Yb82xe6RwPnq-OjGB5aVDXO9G9XJIDRIgpjn5iTWYsWKh1mG3n08A1NKTU\" alt=\"\" width=\"710\" height=\"197\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<h1 class=\"wp-block-heading\">Working of all components together<\/h1>\r\n<p>\r\n\r\n<\/p>\r\n<p>Well, To see how all these components work together? We need to initialize a container i.e. Nginx in our case. We will be firing the same command after running an Nginx container.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>This shows us that we have two daemons running &#8211; the docker daemon and the docker-containerd daemon.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Given that dockerd interacts heavily with containerd all the time and the later is never exposed to the internet, it makes sense to bet that its interface is unix-socket based.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<h1 class=\"wp-block-heading\">High-Level overview of initializing container<\/h1>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/qb8JigZeH4_2gLPiPvstyXESytf-FO_PZP-QUlAW9MawD9Tv5Gnj4Wrd-t4YkAsrrx53UB8oIo5oSUr4hh3WrppC-3B_m-0oH6-lzWUrUfSZhfAXNFRe-2xf9L0M08z5MTIqzngI\" alt=\"\" width=\"585\" height=\"338\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<h1 class=\"wp-block-heading\">Initializing container to see the involvement of all components<\/h1>\r\n<p>\r\n\r\n<\/p>\r\n<h3 class=\"wp-block-heading\"><strong>Command:<\/strong><\/h3>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-preformatted\">docker run --name docker-nginx -p 80:80 -d nginx\r\ndocker ps<\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/_jwK1gjjS-Gpa9wPwKxQr83yIjhOA0dlNzBj4x-KYtchgneYO_hhGd6MV_3YREDZ3KA3I7MPLoYJk-oouqxUTzjupv5zZ2zy9UHlKD8k_yP180EWnp_1MpwIdjmIiEaNcM166Qrw\" alt=\"\" width=\"710\" height=\"150\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-preformatted\">pstree\u00a0 -pg | grep -e docker -e containerd\u00a0<\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/nJ4-g08C_hnmW0J8s2g2W_ETqCv6YEhszMtijA3SCrl5TUgvgj4gJT7RNAzgYQel2I8APk8G_9OLn-erv3Zuk0qA3SANceeHewfVqTXK44cXfLBc-Xp23HTJ5J6MBuna2w1rEKWq\" alt=\"\" width=\"709\" height=\"575\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-preformatted\">ps fxa | grep -i \u201cdocker\u201d -A 3 | grep -v \u201cjava\u201d<\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/bCej_miBV5R5z0cmJ2rbl1qH0YF4ap8EwLHJHnxJ-ews8iW0OqYxQn1TpAhsgtXcbZJlcc59X--B_HEabJuSxEcUfLanVCNGrLhbgtasv1rEbRJGLv-S8l2_ITnbjljZP3d175aV\" alt=\"\" width=\"710\" height=\"200\" \/><\/figure>\r\n<\/div>\r\n<p>\r\n\r\n<\/p>\r\n<h2 class=\"wp-block-heading\">Summary<\/h2>\r\n<p>\r\n\r\n<\/p>\r\n<p>By now, it might be clear that dockerd is not only a single component involved while running a container. We got to know what all components are backing a running container beside dockerd and how they work together to manage the lifecycle of a container.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>I hope we have a good understanding of the docker components involved. Now it\u2019s time to see things practically on your own with commands discussed in this blog without mugging up theoretical concepts.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>That\u2019s all till next time, thanks for reading, I\u2019d really appreciate your feedback, please leave your comment below if you guys have any feedback or any queries.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Happy <strong>Containerization !!<\/strong><\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Opstree is an End to End DevOps solution provider<\/p>\r\n<p><a class=\"wp-block-button__link\" href=\"https:\/\/www.opstree.com\/contact-us\">Contact<\/a><\/p>\r\n<div class=\"wp-block-buttons\">\r\n<p><\/p>\r\n<\/div>\r\n<p><!-- \/wp:buttons --><\/p>","protected":false},"excerpt":{"rendered":"<p>&nbsp; Necessity is the mother of invention, the same happens here in case of docker. With the pressure of splitting monolithic applications for the purpose of ease, we arrived at docker and it made our life much simpler. We all access docker with docker-cli command but I wonder what it does behind the scene, to &hellip; <a href=\"https:\/\/opstree.com\/blog\/2020\/01\/21\/docker-inside-out-a-journey-to-the-running-container\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Docker Inside Out &#8211; A Journey to the Running Container&#8221;<\/span><\/a><\/p>\n","protected":false},"author":175681501,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"{\"coblocks-hero-06164135490\":{\"padding\":{}}}","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[28070474,4504191],"tags":[483658163,692478033,768739305,220770493,634777967,85247986],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-y7","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/2115"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/175681501"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=2115"}],"version-history":[{"count":24,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/2115\/revisions"}],"predecessor-version":[{"id":30099,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/2115\/revisions\/30099"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=2115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=2115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=2115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}