实现docker run命令

基于宿主机来创建容器

执行命令

《自己动手写Docker》code-3.1

./mydocker run -ti /bin/bash

代码流程

1. 解析参数。
2. 通过clone来fork一个Namespace隔离的容器进程。
3. 调用自己/proc/self/exe初始化容器(挂载proc文件系统),容器内1号进程就是这个init进程。
4. 调用syscall.Exec来把init进程替换成用户指定的进程。

unshare:已有进程加入到新的namespace中。
setns:已有进程加入到已经存在的namespace中。
clone:创建新进程,该进程加入到新的namespace中。

效果

基于容器镜像来创建容器

没有使用容器镜像时,容器进程继承了父进程的所有挂载点,与宿主机共用rootfs。mount namespace没有隔离,会把宿主机上的proc挂载到容器里面,导致宿主机上的ps -ef命令无法执行。

获取容器快照镜像

docker pull busybox
docker run -d busybox top
docker export -o busybox.tar 容器ID
tar -xvf busybox.tar -C busybox/

修改关键流程

《自己动手写Docker》code-4.1
把pivotRoot函数修改成如下内容(通过chroot来切换根目录,而不是pivot_root,避免报错;Docker优先使用pivot_root,失败后使用chroot)

func pivotRoot(root string) error {
    return syscall.Chroot("/root/busybox")
}

执行命令

./mydocker run -ti /bin/sh

效果

容器内的挂载点已经与宿主机不同,不存在宿主机上执行ps -ef报错的问题。

posted on 2023-02-25 17:08  王景迁  阅读(76)  评论(0编辑  收藏  举报

导航