在MacOS上使用Golang创建一个容器 – syscall.CLONE_NEWUTS不起作用

huangapple go评论94阅读模式
英文:

Create a container with Golang on MacOS - syscall.CLONE_NEWUTS not working

问题

学习如何在MacOS终端上使用Golang实现容器化,我正在尝试按照Docker上推荐的方式实现以下代码:

unc main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Bad Command")
	}
}

func run() {
	fmt.Printf("Running %v \n", os.Args[2:])
	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}
	cmd.Run()
}

然而,似乎syscall.CLONE_NEWUTS只适用于Linux。在Mac上如何实现这个功能呢?

英文:

Learning how to implement containers on Golang, using MacOS Terminal,
I'm trying to implement the following code as promoted on Docker:

unc main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Bad Command")
	}
}

func run() {
	fmt.Printf("Running %v \n", os.Args[2:])
	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}
	cmd.Run()
}

However it seems that syscall.CLONE_NEWUTS works only with Linux.
How could I implement this on Mac ?

答案1

得分: 3

我手头没有 macOS,但如果你在 linx(ubuntu)上遇到类似的问题,首先检查一下你是否以 root 用户身份运行 go run .

如果不是以 root 用户身份运行,你需要在 SysProcAttr 中传入一个额外的标志(syscall.CLONE_NEWUSER):

func run() {
  fmt.Printf("Running %v \n", os.Args[2:])
  cmd := exec.Command(os.Args[2], os.Args[3:]...)
  cmd.Stdin = os.Stdin
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWUSER,
  }
  cmd.Run()
}

我认为这里的问题是,如果没有 syscall.NEWUSER 标志,你将尝试以 root 用户身份克隆当前进程,而你没有权限这样做。

顺便说一下,OP 的代码片段来自于 https://www.youtube.com/watch?v=8fi7uSYlOdc(其中所有命令都以 root 用户身份运行)。

英文:

I don't have a macos at hand, but if you're running into a similar problem on linx (ubuntu), first check if you are running your go run . as root.

If you are not, you will need an extra flag (syscall.CLONE_NEWUSER) passed into SysProcAttr:

func run() {
  fmt.Printf("Running %v \n", os.Args[2:])
  cmd := exec.Command(os.Args[2], os.Args[3:]...)
  cmd.Stdin = os.Stdin
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWUSER,
}
cmd.Run()

What I think happens here is that without the syscall.NEWUSER flag, you will try to clone the current process as root, which you do not have permission to do so.

By the way OPs snippet is taken from https://www.youtube.com/watch?v=8fi7uSYlOdc (in which all commands are run as the root user).

答案2

得分: 2

感谢@guites的回答,它对我有用。但是添加额外的标志可能是一个不必要的解决方法。

要解决这个问题而不添加CLONE_NEWUSER标志,你需要以root身份运行你的脚本。但是默认情况下,go可执行文件以非root身份运行,所以你需要先构建你的脚本,然后用sudo运行它。

go build main.go
sudo ./main

这对我起作用了。

英文:

thanks for @guites answer it worked with me. but adding the extra flag may be an unneeded workaround.

to solve this without adding the CLONE_NEWUSER flag you need to run your script as root. but buy default go executable run as non-root so you will need to build your script first and then run it with sudo.

go build main.go
sudo ./main

That what worked for me.

huangapple
  • 本文由 发表于 2021年10月28日 14:55:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/69749508.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定