{"id":18427740,"url":"https://github.com/mugli/container-from-scratch-in-go","last_synced_at":"2025-04-07T16:33:57.874Z","repository":{"id":53548683,"uuid":"148038806","full_name":"mugli/container-from-scratch-in-go","owner":"mugli","description":"Toy container build from scratch in Go solely for learning purpose","archived":false,"fork":false,"pushed_at":"2018-09-10T14:33:49.000Z","size":65351,"stargazers_count":50,"open_issues_count":0,"forks_count":10,"subscribers_count":0,"default_branch":"master","last_synced_at":"2023-03-11T08:43:00.176Z","etag":null,"topics":["cgroups","chroot","containers","golang","namespaces"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mugli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-09T15:28:06.000Z","updated_at":"2023-01-18T22:19:54.000Z","dependencies_parsed_at":"2022-09-09T09:50:16.881Z","dependency_job_id":null,"html_url":"https://github.com/mugli/container-from-scratch-in-go","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Fcontainer-from-scratch-in-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Fcontainer-from-scratch-in-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Fcontainer-from-scratch-in-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Fcontainer-from-scratch-in-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mugli","download_url":"https://codeload.github.com/mugli/container-from-scratch-in-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223286383,"owners_count":17120000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cgroups","chroot","containers","golang","namespaces"],"created_at":"2024-11-06T05:11:41.391Z","updated_at":"2024-11-06T05:11:41.973Z","avatar_url":"https://github.com/mugli.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Building Containers from Scratch in Go\n\nThis is a toy container build from scratch in Go solely for learning purpose. It uses namespaces and cgroups, mount a tmpfs that's isolated from host filesystem.\n\n## What it does\n\n*Before starting, you'll have to unzip the content of `ubuntu_fs.zip` file. This will create a subdirectory called `ubuntu_fs` which will be mounted as our container's root directory.*\n\nYou'll have to be inside a Linux box (Ubuntu in my case) to try this.\n\nThis will start our container (needs root privilege for creating `cgroup`):\n```\nsudo su\ngo run main.go run /bin/bash\n``` \n\nIt will:\n- Fork itself with `CLONE_NEWUTS`, `CLONE_NEWPID`, `CLONE_NEWNS` flags with isolated hostname, processes and mounts\n- The forked process will create `cgroup` to limit memory usage of itself and any child process it creates\n- Mount `./ubuntu_fs` directory as root filesystem using `chroot` to limit access to host machine's filesystem\n- Mount `/mytemp` directory as tmpfs. Any change made to this directory will not be visible from host.\n- Mount proc (where `CLONE_NEWPID` namespace was already set) so that container can run `ps` and see only the processes running inside it.\n- Execute the supplied argument `/bin/bash` inside the isolated environment\n\n---\n\n## Sources of the inspiration and information\nBuilding Containers from Scratch with Go by Liz Rice\nhttps://www.safaribooksonline.com/videos/building-containers-from/9781491988404\n\nIf you don't have access to safaribooksonline.com, Liz Rice gave talk on the same topic in several conferences too.\nOne of them is \"GOTO 2018 • Containers From Scratch\": \nhttps://www.youtube.com/watch?v=8fi7uSYlOdc\n\nAlso, sysdevbd initiative by @appscode:\nhttps://sysdevbd.com/\n\n---\n\n## Further reading\n\n### Namespaces in Go\nPart 1: Linux Namespaces\nhttps://medium.com/@teddyking/linux-namespaces-850489d3ccf\n\nPart 2: Namespaces in Go - Basics\nhttps://medium.com/@teddyking/namespaces-in-go-basics-e3f0fc1ff69a\n\nPart 3: Namespaces in Go - User\nhttps://medium.com/@teddyking/namespaces-in-go-user-a54ef9476f2a\n\nPart 4: Namespaces in Go - reexec\nhttps://medium.com/@teddyking/namespaces-in-go-reexec-3d1295b91af8\n\nPart 5: Namespaces in Go - Mount\nhttps://medium.com/@teddyking/namespaces-in-go-mount-e4c04fe9fb29\n\nPart 6: Namespaces in Go - Network\nhttps://medium.com/@teddyking/namespaces-in-go-network-fdcf63e76100\n\nPart 7: Namespaces in Go - UTS\nhttps://medium.com/@teddyking/namespaces-in-go-uts-d47aebcdf00e\n\n---\n\n### Understand Container\nhttps://pierrchen.blogspot.com/2018/08/understand-container-index.html\n\n---\n\n## Bonus tip: Setting up VS Code for cross-platform development\n\nI have used OSX to develop the container from scratch and have run it inside Ubuntu in a virtualbox by sharing the development directory. While this setup is fine for running the code inside Linux, the development experience is not great because a lot of pieces of this application is Linux specific. For example, calls like `syscall.Sethostname` or the `Cloneflags` field in the `syscall.SysProcAttr{}` struct is not available in intellisense in VSCode when the dev environment is not Linux. VS Code will mark those lines as errors, because they are platform specific and declared in the standard library in Go for Linux only.\n\nFortunately the workaround is very simple. Search for `\"go.toolsEnvVars\"` in VS Code settings, copy it to User Settings and change it to:\n\n```\n    \"go.toolsEnvVars\": {\n        \"GOOS\": \"linux\"\n    }\n```\n\nRestarting VS Code after that will recognize all Linux specific declarations and will not see them as errors. Go-to-definition will work properly too.\n\n---\n\nPS: the contents of `ubuntu_fs.zip` file has been extracted from Ubuntu docker image (using `docker export...` command).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmugli%2Fcontainer-from-scratch-in-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmugli%2Fcontainer-from-scratch-in-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmugli%2Fcontainer-from-scratch-in-go/lists"}