mydocker icon indicating copy to clipboard operation
mydocker copied to clipboard

本项目构建测试环境基于Ubuntu 14.04.4,kernel版本是3.13.x,请先确认环境再提交issue

Open BSWANG opened this issue 8 years ago • 14 comments

针对不同版本的系统或者kernel我们没做过兼容性的测试,可以提交PR一起来提高mydocker的兼容性。

known issue:

  1. 4.2+的内核中userns的使用方式变化导致operation not permitted: #3
  2. Centos 7.x中的内核不支持userns
  3. 4.4内核运行后会导致/proc挂载不释放,导致后续命令报错 #8
  4. Ubuntu 14.04.4之后的版本使用systemd去管理cgroup,会导致cgroup的限制失效

BSWANG avatar Aug 24 '17 05:08 BSWANG

Pls check following command output: dpkg -l | grep linux-image-extra If the command output is empty, Pls install the package by command apt-get update; apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual.

xianlubird avatar Aug 24 '17 09:08 xianlubird

O(∩_∩)O谢谢啊 你们的书让我受益匪浅。

看完想加入你们部门,但是看到封面折页上你们title才是高级,难道你们部门牛人挤成堆了么,有点吓人。我同学西欧小硕回来工作一年加入蚂蚁,第2年就P7了。

2qif49lt avatar Dec 26 '17 06:12 2qif49lt

@2qif49lt 欢迎给我邮箱发简历,我的邮箱是[email protected] 。 我们努力的招贤纳士中,期待新鲜血液加入 :)

xianlubird avatar Dec 26 '17 09:12 xianlubird

uname -a Linux vagrant-ubuntu-trusty-64 3.13.0-112-generic #159-Ubuntu SMP Fri Mar 3 15:26:07 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

go run main.go 2018/03/17 16:33:21 fork/exec /bin/sh: operation not permitted exit status 1

package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"
)

func main() {
	cmd := exec.Command("sh")
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
	}

	cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(1), Gid: uint32(1)}

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}

}

rhinoceros avatar Mar 17 '18 16:03 rhinoceros

@rhinoceros Pls run with root account or use sudo.

BSWANG avatar Mar 18 '18 14:03 BSWANG

@BSWANG 我是在mac上用vagrant启动的虚拟机。多谢答复。 修改成这样就好了。

package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"
)

func main() {
	cmd := exec.Command("sh")
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS |
			syscall.CLONE_NEWUSER |
			syscall.CLONE_NEWNET,
		UidMappings: []syscall.SysProcIDMap{
			{
				ContainerID: 1234,
				HostID:      0,
				Size:        1,
			},
		},
		GidMappings: []syscall.SysProcIDMap{
			{
				ContainerID: 1234,
				HostID:      0,
				Size:        1,
			},
		},
	}

	//cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(1), Gid: uint32(1)}

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}

}

rhinoceros avatar Mar 19 '18 03:03 rhinoceros

需要安装的包有:

环境相关

apt-get install git -y
apt-get install stress -y
apt-get install cgroup-bin cgroup-lite libcgroup1 -y

Go (我用了 go1.9.2,书里推荐 1.7.1 )

wget https://studygolang.com/dl/golang/go1.9.2.linux-amd64.tar.gz
tar -C /usr/local -xzf /vagrant/go1.9.2.linux-amd64.tar.gz 
vim /etc/profile
     export GOPATH="/root/go"
     export GOROOT="/usr/local/go"
     export GOBIN="${GOROOT}/bin"
     export PATH=$PATH:$GOBIN

source /etc/profile

# godep
go get github.com/tools/godep

第四章开始需要用到docker

install docker ce 17.03.1~ce-0~ubuntu-trusty

#!/bin/bash
set -e
type -f docker >/dev/null 2>&1 && { echo "docker is exists!"; exit 0; }
sudo apt-get update
sudo apt-get install  -y   linux-image-extra-$(uname -r)     linux-image-extra-virtual
sudo apt-get install  -y   apt-transport-https     ca-certificates     curl     software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
 $(lsb_release -cs) \
 stable"
sudo apt-get update
sudo apt-get install -y docker-ce=17.03.1~ce-0~ubuntu-trusty

# 配置一个国内docker镜像加速:
# 举例,镜像加速地址:https://aaaaaaaa.mirror.aliyuncs.com
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors" : [
    "https://aaaaaaaa.mirror.aliyuncs.com"
  ]
}
EOF

service docker restart
sudo docker run hello-world

rhinoceros avatar Mar 20 '18 05:03 rhinoceros

@rhinoceros 感谢

BSWANG avatar May 28 '18 07:05 BSWANG

@xianlubird centos7.4 code-2.1:

command-line-arguments

./main.go:19: undefined: initCommand ./main.go:20: undefined: runCommand

什么问题???

eric-chao avatar May 31 '18 05:05 eric-chao

netlink版本低

master 分支下,编译报错,vendor下的netlink版本低了,删了go get一个最新的编译可过

pivot_root报错

我的是ubuntu16,所以跑代码在pivot_root系统调用那里报错Invalid argument,然后程序退出后,/proc有问题,其他issue有提到,翻了下runc的代码,发现是因为/这个mount point的标记位是share, 所以pivot_root切换rootfs失败,加上后面重新mount /proc的时候,传递到host的/proc,使host的也有问题,在mount隔离下,是不应该有share的mount point的.

所以在pivotRoot函数开始加上

if err := syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("make parent mount private error: %v", err)
	}

func pivotRoot(root string) error {
	
	if err := syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("make parent mount private error: %v", err)
	}
	/**
	  为了使当前root的老 root 和新 root 不在同一个文件系统下,我们把root重新mount了一次
	  bind mount是把相同的内容换了一个挂载点的挂载方法
	*/
	if err := syscall.Mount(root, root, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("Mount rootfs to itself error: %v", err)
	}
	// 创建 rootfs/.pivot_root 存储 old_root
	pivotDir := filepath.Join(root, ".pivot_root")
	if err := os.Mkdir(pivotDir, 0777); err != nil {
		return err
	}
	// pivot_root 到新的rootfs, 现在老的 old_root 是挂载在rootfs/.pivot_root
	// 挂载点现在依然可以在mount命令中看到
	if err := syscall.PivotRoot(root, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %v", err)
	}
	// 修改当前的工作目录到根目录
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %v", err)
	}

	pivotDir = filepath.Join("/", ".pivot_root")
	// umount rootfs/.pivot_root
	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %v", err)
	}
	// 删除临时文件夹
	return os.Remove(pivotDir)
}

问题解决,host的/proc也没问题了

希望遇到问题的人能看到啦

ejunjsh avatar Jan 02 '19 15:01 ejunjsh

Ubuntu 14.04 没有cgroup on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory) 的可以试下安装docker,安装完成后就出现了. 但是指定docker版本,否则dockers run 报caused "process_linux.go:297: copying bootstrap data to pipe caused \"write init-p: broken pipe\"": unknown.

root@ubuntu:~# apt remove docker-ce docker-ce-cli
root@ubuntu:~# apt install docker-ce=18.06.1~ce~3-0~ubuntu

MalikCheng avatar Apr 27 '20 03:04 MalikCheng

urfave/cli 用的是什么版本呢?

./mydocker run -ti -m 100m stress -m 1

urfave用的是1.22.4版本,然后发现 后面的 -m 1 被处理没了

image

BPing avatar Sep 07 '20 14:09 BPing

@BSWANG 我是在mac上用vagrant启动的虚拟机。多谢答复。 修改成这样就好了。

package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"
)

func main() {
	cmd := exec.Command("sh")
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS |
			syscall.CLONE_NEWUSER |
			syscall.CLONE_NEWNET,
		UidMappings: []syscall.SysProcIDMap{
			{
				ContainerID: 1234,
				HostID:      0,
				Size:        1,
			},
		},
		GidMappings: []syscall.SysProcIDMap{
			{
				ContainerID: 1234,
				HostID:      0,
				Size:        1,
			},
		},
	}

	//cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(1), Gid: uint32(1)}

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}

}

谢谢我的问题和你一样,运行大半天出不来,把你的代码copy就好了,请问这是为什么?和虚拟机有声梦关系

Qjping avatar Sep 17 '20 09:09 Qjping

谢谢

内核版本问题,3.19

Gettingdone avatar Oct 18 '21 14:10 Gettingdone