---
# System prepended metadata

title: 自己動手寫 docker - 除錯手冊

---

#  自己動手寫 docker - 除錯手冊

這個地方是紀錄閱讀書本 自己動手寫 docker 跟實作的過程中，因為版本不同出現的問題或除錯的結果

github Repo https://github.com/fwfly/toy_docker

### p17 : User Namespace 錯誤
```
就算跑 sudo 指令，也會出現 permission error

fork/exec /usr/bin/sh: operation not permitted
```

答案:
kernel 版本不相容，網路上有提供相關解法

solution : 
https://github.com/xianlubird/mydocker/issues/3

簡單來說可以直接使用 syscall.CLONE_NEWUSER 然後不設定 gid 跟 uid, 系統會默認為 65535(nouser). 

如過要設定 gid 跟 uid 則需要用 UidMappings 跟 GidMappings, SysProcAttr.Credential 在很多版本會出現 error.

### p24: WARNING: Your kernel does not support swap limit

Solution : 
https://github.com/moby/moby/issues/4250

好用 config check script
https://github.com/moby/moby/blob/master/contrib/check-config.sh

### p27
在 docker 19版後, union file system 是使用 overlayFS (https://en.wikipedia.org/wiki/OverlayFS)

資料夾則是在 /var/snap/docker/common/var-lib-docker/overlay2
透過 ` docker inspect <image ID>` 可以找到相對應的資料夾
```
....
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/snap/docker/common/var-lib-docker/overlay2/2c09b65166b1fe7cd8df52f731d0c3eec010246ad1314f3b38f7eebfebd4aa64/diff:/var/snap/docker/common/var-lib-docker/overlay2/c3ac3a50e11956be0542cac1d311b26ab176dc11c36809b7727de7091714a54e/diff:/var/snap/docker/common/var-lib-docker/overlay2/5447f70fad76a2bb0b5afe9b6dfa01bda5ac6bed5b5606d0fe6e93a329e3372c/diff",
                "MergedDir": "/var/snap/docker/common/var-lib-docker/overlay2/98137f18bf2bc2b28b06d6444d5a766dc8f1c5e59d3e8b3dcf94b2af37a3dcb2/merged",
                "UpperDir": "/var/snap/docker/common/var-lib-docker/overlay2/98137f18bf2bc2b28b06d6444d5a766dc8f1c5e59d3e8b3dcf94b2af37a3dcb2/diff",
                "WorkDir": "/var/snap/docker/common/var-lib-docker/overlay2/98137f18bf2bc2b28b06d6444d5a766dc8f1c5e59d3e8b3dcf94b2af37a3dcb2/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:2ce3c188c38d7ad46d2df5e6af7e7aed846bc3321bdd89706d5262fefd6a3390",
                "sha256:ad44aa179b334bbf4aeb61ecef978c3c77a3bb27cb28bcb727f5566d7f085b31",
                "sha256:35a91a75d24be7ff9c68ce618dcc933f89fef502a59becac8510dbc3bf7a4a05",
                "sha256:a4399aeb9a0e1ddf9da712ef222fd66f707a8c7205ed2607c9c8aac0dbabe882"
            ]
        },         
```


### p40 ( Ch3.1.2 )
預設是缺少 package 的，所以需要先動手安裝
```
# 可能需要有 sudo access right
go get github.com/Sirupsen/logrus
go get github.com/urfave/cli
go get github.com/cpuguy83/go-md2man
```

### p41

在新版本的 cli.Command 的使用方式已經做改變，改成
```
    app.Commands = []*cli.Command{
        &initCommand,
        &runCommand,
    }
```

細節可以參考這邊
https://github.com/urfave/cli/blob/master/docs/v2/manual.md

在 Arg 長度也不是使用 len()，而是改成 NArg
```
context.NArg() < 1
```
https://github.com/urfave/cli/blob/master/context.go#L115

