https://yryz.net/post/golang-docker-alpine-start-panic.html
用docker基於alpine微型鏡像部署go的項目,啟動時報錯 panic: standard_init_linux.go:175: exec user process caused "no such file or directory"
,去年測試docker時遇到過,沒去深入研究,這次項目遇又到了,深入分析了一下。
詳細錯誤記錄:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
➜ xxx git:(master) ✗ docker run --rm -it xxxx.com/xxx_webapp:prod panic: standard_init_linux.go:175: exec user process caused "no such file or directory" [recovered] panic: standard_init_linux.go:175: exec user process caused "no such file or directory" goroutine 1 [running, locked to thread]: panic(0x88f8a0, 0xc82011bb20) /usr/local/go/src/runtime/panic.go:481 +0x3e6 github.com/urfave/cli.HandleAction.func1(0xc8200e72e8) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:478 +0x38e panic(0x88f8a0, 0xc82011bb20) /usr/local/go/src/runtime/panic.go:443 +0x4e9 github.com/opencontainers/runc/libcontainer.(*LinuxFactory).StartInitialization.func1(0xc8200e6bf8, 0xc82001a0c8, 0xc8200e6d08) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go:259 +0x136 github.com/opencontainers/runc/libcontainer.(*LinuxFactory).StartInitialization(0xc820051630, 0x7fc3c9efc728, 0xc82011bb20) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go:277 +0x5b1 main.glob.func8(0xc82006ea00, 0x0, 0x0) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/main_unix.go:26 +0x68 reflect.Value.call(0x7f45a0, 0x9a4d88, 0x13, 0x8ebac8, 0x4, 0xc8200e7268, 0x1, 0x1, 0x0, 0x0, ...) /usr/local/go/src/reflect/value.go:435 +0x120d reflect.Value.Call(0x7f45a0, 0x9a4d88, 0x13, 0xc8200e7268, 0x1, 0x1, 0x0, 0x0, 0x0) /usr/local/go/src/reflect/value.go:303 +0xb1 github.com/urfave/cli.HandleAction(0x7f45a0, 0x9a4d88, 0xc82006ea00, 0x0, 0x0) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:487 +0x2ee github.com/urfave/cli.Command.Run(0x8ee970, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x984240, 0x51, 0x0, ...) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/command.go:191 +0xfec github.com/urfave/cli.(*App).Run(0xc820001500, 0xc82000a100, 0x2, 0x2, 0x0, 0x0) /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:240 +0xaa4 main.main() /tmp/tmp.UkUQ4KXBPZ/src/github.com/opencontainers/runc/main.go:137 +0xe24 |
首先確認被執行的程序都是存在的,經過一番搜索測試也沒解決。
之前用GOOS=linux GOARCH=amd64 go build
是可以的,這次是通過golang的docker鏡像編譯的確不行,對比編譯后的文件發現有貓膩。
1 2 3 |
> GOOS=linux GOARCH=amd64 go build > file xxx xxx: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped |
vs docker build:
1 2 3 |
> docker run --rm -it -v $GOPATH:/go golang:1.7 bash -c 'cd $GOPATH/src/xxx && go build > file xxx xxx: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped |
問題找到了,一個是靜態鏈接,一個是動態鏈接,動態鏈接的在微型鏡像alpine上不支持。
總結
- 默認go使用靜態鏈接,在docker的golang環境中默認是使用動態編譯。
- 如果想使用docker編譯+alpine部署,可以通過禁用cgo
CGO_ENABLED=0
來解決。 - 如果要使用cgo可以通過
go build --ldflags "-extldflags -static"
來讓gcc使用靜態編譯。