{"id":2704,"date":"2020-04-14T17:53:54","date_gmt":"2020-04-14T12:23:54","guid":{"rendered":"https:\/\/opstree.com\/blog\/\/?p=2704"},"modified":"2020-04-21T13:05:19","modified_gmt":"2020-04-21T07:35:19","slug":"create-your-own-container-using-linux-namespaces-part-1","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2020\/04\/14\/create-your-own-container-using-linux-namespaces-part-1\/","title":{"rendered":"Create Your Own Container Using Linux Namespaces Part-1."},"content":{"rendered":"\r\n<p>In this lock-down, everyone has to maintain a social distance and in this trying time, we can learn from docker to isolate ourselves. So before that, we need to learn how docker does it? <br \/>The best approach to learn is to simulate it. For that, we&#8217;ll be creating our own container tool for the application to isolate itself.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/i.kym-cdn.com\/photos\/images\/newsfeed\/001\/789\/334\/c16.gif\" alt=\"Self isolation | SpongeBob SquarePants | Know Your Meme\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n<p><!--more--><\/p>\r\n<p><strong>Technology docker uses<\/strong><\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Linux Namespaces:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>The namespace is technology is behind most of the modern-day container\u2019s tools like docker, rkt, LXC. For providing isolation for the process.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>7 namespace we use to create container.:-\u00a0<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container\">\r\n<div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\r\n<ul>\r\n<li>Mount &#8211; isolate filesystem mount points<\/li>\r\n<li>UTS &#8211; isolate hostname and domainname<\/li>\r\n<li>IPC &#8211; isolate interprocess communication (IPC) resources<\/li>\r\n<li>PID &#8211; isolate the PID number space<\/li>\r\n<li>Network &#8211; isolate network interfaces<\/li>\r\n<li>User &#8211; isolate UID\/GID number spaces<\/li>\r\n<li>Cgroup &#8211; limit a resource usage (CPU, memory, disk I\/O, network, etc.).<\/li>\r\n<\/ul>\r\n<\/div>\r\n<\/div><\/div>\r\n<p>\r\n\r\n<\/p>\r\n<p>Above namespace is to provide a high level of Isolation.\u00a0<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<figure class=\"wp-block-image is-resized is-style-rounded\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/cdn.dribbble.com\/users\/1712260\/screenshots\/5823662\/comp_3.gif\" alt=\"Isolation by Kinsmen Collective on Dribbble\" width=\"422\" height=\"316\" \/><\/figure>\r\n<p>\r\n\r\n<\/p>\r\n<p>In This blog I&#8217;m trying to cover namespace to create a container in golang.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Why Golang ?<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>I pick golang because of the fact that Docker has written in golang and it provides low-level interface.\u00a0 <a href=\"https:\/\/www.slideshare.net\/jpetazzo\/docker-and-go-why-did-we-decide-to-write-docker-in-go\/22-Why_Go3_it_has_what\" target=\"_blank\" rel=\"noopener\">Why docker go with Golang?<\/a> Check there.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Namespace System calls.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>So we will use 3 system call: &#8211;<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container\">\r\n<div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\r\n<p>1. Clone:- creates a new process\u00a0<\/p>\r\n\r\n\r\n\r\n<p>2. Setns:- allows the calling process to join an existing namespace\u00a0<\/p>\r\n\r\n\r\n\r\n<p>3. Unshare:- moves the calling process to a new namespace<\/p>\r\n\r\n\r\n\r\n<p>Golang code for creating container.<\/p>\r\n<\/div>\r\n<\/div><\/div>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-syntaxhighlighter-code\">package main\r\n\r\nimport (\r\n\t\"path\/filepath\"\r\n\t\"fmt\"\r\n\t\"os\"\r\n\t\"os\/exec\"\r\n\t\"syscall\"\r\n\t\"github.com\/docker\/docker\/pkg\/reexec\"\r\n)\r\nfunc main() {\r\n\ttype SysProcIDMap struct {\r\n\t\tContainerID int \r\n\t\tHostID      int \r\n\t\tSize        int \r\n\t}\r\n\tvar rootfsPath string\r\n\r\n\tcmd := reexec.Command(\"nsInitialisation\", rootfsPath)\r\n\tcmd = exec.Command(\"\/bin\/bash\")\r\n\tcmd.Stdout = os.Stdout\r\n\tcmd.Stdin = os.Stdin\r\n\tcmd.Stderr = os.Stderr\r\n\r\n\tcmd.Env = []string{\"PS1=-[ns-process]- # \"}\r\n\tcmd.SysProcAttr = &amp;syscall.SysProcAttr{\r\n\t\tCloneflags: syscall.CLONE_NEWUTS |\r\n\t\t\tsyscall.CLONE_NEWNS |\r\n\t\t\tsyscall.CLONE_NEWIPC |\r\n\t\t\tsyscall.CLONE_NEWNET |\r\n\t\t\tsyscall.CLONE_NEWPID |\r\n\t\t\tsyscall.CLONE_NEWUSER,\r\n\t\tUidMappings: []syscall.SysProcIDMap{\r\n\t\t\t{\r\n\t\t\t\tContainerID: 0,\r\n\t\t\t\tHostID:      os.Getuid(),\r\n\t\t\t\tSize:        1,\r\n\t\t\t},\r\n\t\t},\r\n\t\tGidMappings: []syscall.SysProcIDMap{\r\n\t\t\t{\r\n\t\t\t\tContainerID: 0,\r\n\t\t\t\tHostID:      os.Getgid(),\r\n\t\t\t\tSize:        1,\r\n\t\t\t},\r\n\t\t},\r\n\t}\r\n\r\n\tif err := cmd.Run(); err != nil {\r\n\t\tfmt.Printf(\"Error running the \/bin\/bash command %s\\n\", err)\r\n\t\tos.Exit(1)\r\n\t}\r\n}<\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\r\n<div class=\"wp-block-group__inner-container\">\u00a0<\/div>\r\n<\/div><\/div>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWUTS syscall:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWUTS is set, then create the process in a new UTS namespace. it create new hostname UTS namespaces only has Only a privileged process (CAP_SYS_ADMIN).<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWNS syscall:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWNS is started in a new mount namespace. we have to mount file system. For that we will use pivot_root I.e. it allows you to change what \/.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-syntaxhighlighter-code\">func pivotRoot(newroot string) error {\r\n\tputold := filepath.Join(newroot, \"\/.pivot_root\")\r\n\tif err := syscall.Mount(\r\n\t\tnewroot,\r\n\t\tnewroot,\r\n\t\t\"\",\r\n\t\tsyscall.MS_BIND|syscall.MS_REC,\r\n\t\t\"\",\r\n\t); err != nil {\r\n\t\treturn err\r\n\t}\r\n\t\/\/ Create old put Directory\r\n\tif err := os.MkdirAll(putold, 0700); err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\tif err := syscall.PivotRoot(newroot, putold); err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\tif err := os.Chdir(\"\/\"); err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\tputold = \"\/.pivot_root\"\r\n\tif err := syscall.Unmount(\r\n\t\tputold,\r\n\t\tsyscall.MNT_DETACH,\r\n\t); err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\tif err := os.RemoveAll(putold); err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\treturn nil\r\n}<\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWUSER syscall:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWUSER is set, then create the process in a new user namespace. The User namespace provides isolation of UIDs and GIDs.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWIPC syscall:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWIPC is set, then create the process in a new IPC namespace.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>CLONE_NEWPID syscall:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Mounting new \/proc, running process inside the namespace. This is because ps relies on \/proc to detect running processes and we were still referencing the host\u2019s \/proc.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<pre class=\"wp-block-syntaxhighlighter-code\">func mountProc(newroot string) error {\r\n\tsource := \"proc\"\r\n\ttarget := filepath.Join(newroot, \"\/proc\")\r\n\tfstype := \"proc\"\r\n\tflag := 0\r\n\tdata := \"\"\r\n\r\n\tos.MkdirAll(target, 0755)\r\n\tif err := syscall.Mount(\r\n\t\tsource,\r\n\t\ttarget,\r\n\t\tfstype,\r\n\t\tuintptr(flag),\r\n\t\tdata,\r\n\t); err != nil {\r\n\t\treturn err\r\n\t}\r\n\treturn nil\r\n}<\/pre>\r\n<p>\r\n\r\n<\/p>\r\n<p>You can go with code: https:\/\/github.com\/Deveshs23\/mycontainer\/<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>In the Next part, We will focus on the Namespace network and create some basic functions of docker and also talk about reexec.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Summary:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>In this blog we have some basic containerize tool.<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>Reference:-<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>https:\/\/knowyourmeme.com\/photos\/1789334-spongebob-squarepants<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<p>https:\/\/dribbble.com\/shots\/5823662-Isolation<\/p>\r\n<p>\r\n\r\n medium.com\/@teddyking\/linux-namespaces-850489d3ccf<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\r\n<div class=\"wp-block-button\">\r\n<p>Opstree is an End to End DevOps solution provider<\/p>\r\n<p>\r\n\r\n<\/p>\r\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\r\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link\" title=\"https:\/\/www.opstree.com\/contact-us\" href=\"https:\/\/www.opstree.com\/contact-us\" target=\"_blank\" rel=\"noopener\">contact us<\/a><\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>In this lock-down, everyone has to maintain a social distance and in this trying time, we can learn from docker to isolate ourselves. So before that, we need to learn how docker does it? The best approach to learn is to simulate it. For that, we&#8217;ll be creating our own container tool for the application &hellip; <a href=\"https:\/\/opstree.com\/blog\/2020\/04\/14\/create-your-own-container-using-linux-namespaces-part-1\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Create Your Own Container Using Linux Namespaces Part-1.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":167208048,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_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":[242358,768739305,27540178,768739285,102206,3385],"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-HC","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/2704"}],"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\/167208048"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=2704"}],"version-history":[{"count":24,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/2704\/revisions"}],"predecessor-version":[{"id":3329,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/2704\/revisions\/3329"}],"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=2704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=2704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=2704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}