Linux(Centos or RHEL)/docker

처음 실행하는 컨테이너에서 실행시키는 스크립트에서 발생할 수 있는 에러...?

최소양 2020. 5. 13. 16:48

컨테이너를 실행시킬 때, 미리 만들어둔 스크립트를 실행시키고 싶은 경우가 있습니다. 이 경우에는 보통 Dockerfile을 만들어서 그 안에 만들어둔 스크립트를 컨테이너에 복사(ADDCOPY를 이용), 스크립트에 실행 권한 부여(”RUN chmod +u”를 이용), 컨테이너에서 스크립트를 실행(CMDENTRYPOINT를 이용)합니다.

 

하지만 컨테이너에서 다음과 같은 에러가 발생하는 경우가 있습니다.

 

standard_init_linux.go:211: exec user process caused "exec format error“

 

코드의 줄 번호를 나타내는 211은 도커 버전에 따라서 다르게 나타날 수 있습니다.

 

해당 에러는 컨테이너에서 지정된 파일을 어떤 프로그램을 이용하여 실행해야 하는지 모를 경우 발생할 수 있는 에러입니다. 구체적인 예시로는, 쉘 스크립트 파일을 실행하는 데에, 어떠한 쉘로 실행하는지 모를 경우가 있습니다. 때문에 스크립트 파일에 shebang을 지정해 주든지, Dockerfile에서 어떤 쉘을 이용하여 해당 스크립트를 실행해야 되는지를 지정해 주면 됩니다.

여기서 중요한 것은 바탕이 되는 도커 이미지에 해당 스크립트를 실행 시키는 프로그램이 들어있어야 된다는 것입니다. 예를 들면, alpine에는 bash가 없기 때문에 bash를 설정하면 에러가 발생합니다.

 

여기서는 그에 대한 테스트를 해 보겠습니다.

 

 

사전지식

https://blog.gaerae.com/2015/10/what-is-the-preferred-bash-shebang.html (shebang이란?)

https://docs.docker.com/engine/reference/builder/ (Dockerfile에 대한 설명)

 


1. 스크립트에 shebang을 넣은 것과 넣지 않은 것으로 테스트

 

step 1. 스크립트와 Dockerfile을 만듭니다.

(1) shebang을 넣은 스크립트 파일과, 그 파일을 이용하여 Dockerfile을 만듭니다.

[root@centos77 passTest]# cat hello1.sh

#!/bin/bash

echo hello test1!

[root@centos77 passTest]# cat Dockerfile1

FROM ubuntu

ADD ./hello1.sh /tmp/hello1.sh

RUN chmod +x /tmp/hello1.sh

ENTRYPOINT [ "/tmp/hello1.sh" ]

[root@centos77 passTest]#

 

 

(2) shebang을 넣지 않은 스크립트 파일과, 그 파일을 이용하여 Dockerfile을 만듭니다.

[root@centos77 passTest]# cat hello2.sh

echo hello test2!

[root@centos77 passTest]# cat Dockerfile2

FROM ubuntu

ADD ./hello2.sh /tmp/hello2.sh

RUN chmod +x /tmp/hello2.sh

ENTRYPOINT [ "/tmp/hello2.sh" ]

[root@centos77 passTest]#

 

 

step 2. Dockerfile들을 빌드 시킵니다.

[root@centos77 passTest]# docker build -t test1 -f Dockerfile1 .

Sending build context to Docker daemon 5.12kB

Step 1/4 : FROM ubuntu

---> 1d622ef86b13

Step 2/4 : ADD ./hello1.sh /tmp/hello1.sh

---> 2c6be12f8c9d

Step 3/4 : RUN chmod +x /tmp/hello1.sh

---> Running in 9ae65a2864c5

Removing intermediate container 9ae65a2864c5

---> 9d1b794ef2d3

Step 4/4 : ENTRYPOINT [ "/tmp/hello1.sh" ]

---> Running in 6b0778d8c781

Removing intermediate container 6b0778d8c781

---> 842289f55cff

Successfully built 842289f55cff

Successfully tagged test1:latest

[root@centos77 passTest]# docker build -t test2 -f Dockerfile2 .

Sending build context to Docker daemon 5.12kB

Step 1/4 : FROM ubuntu

---> 1d622ef86b13

Step 2/4 : ADD ./hello2.sh /tmp/hello2.sh

---> 143756c3930c

Step 3/4 : RUN chmod +x /tmp/hello2.sh

---> Running in 506b6cfb1072

Removing intermediate container 506b6cfb1072

---> f86dc3294e15

Step 4/4 : ENTRYPOINT [ "/tmp/hello2.sh" ]

---> Running in 896f63900b89

Removing intermediate container 896f63900b89

---> 9e86009fad13

Successfully built 9e86009fad13

Successfully tagged test2:latest

[root@centos77 passTest]#

 

 

step 3. 빌드시킨 이미지를 이용하여 컨테이너를 실행시킵니다.

[root@centos77 passTest]# docker run --rm test1

hello test1!

[root@centos77 passTest]# docker run --rm test2

standard_init_linux.go:211: exec user process caused "exec format error"

[root@centos77 passTest]#

 

shebang을 넣지 않은 스크립트를 실행시키는 이미지에서는 에러가 발생한 것을 확인할 수 있습니다.

 


2. Dockerfile에 해당 스크립트를 실행시킬 프로그램을 지정해서 스크립트에 shebang을 넣은 것과 넣지 않은 것으로 테스트

 

step 0. 위에서 만든 이미지는 제거합니다.

[root@centos77 passTest]# docker rmi test1 test2

Untagged: test1:latest

Deleted: sha256:842289f55cff258a75dea6a8f463762df96a95f78ce55b5a0552c59b2b50559c

Deleted: sha256:9d1b794ef2d329ab12e3c69cf18ba21100be596cb42244fb4706beaed6b6e342

Deleted: sha256:025e51f1c14a68a13928e113a290930afc30d4bc69c978aca30b59f94d2c57dc

Deleted: sha256:2c6be12f8c9df5be89498000ce719cdda0e5463f47970e5764660b0f2704a419

Deleted: sha256:146876ac114558eaeee6739184b4b506e0351d33d205240ffea255898e0e80ae

Untagged: test2:latest

Deleted: sha256:9e86009fad137ec34d1b3dee689a2d6f934f0974cbdb9d13ce52349ba7accc88

Deleted: sha256:f86dc3294e1532ca9b34714ac119415f77bd596f75096588674669f4c219f31f

Deleted: sha256:2e4fc52c8c7e9787552f8ee869caeacf9b0af88537fb2874a30c06d2011b63d3

Deleted: sha256:143756c3930c7994e37c3144d65534bad6a84f02048d8e9bf94544ae94fc3ec0

Deleted: sha256:6b6fc274bd82bdef673692361f154e6db9a33fd61aad83ca75ce0f62cc817e5b

[root@centos77 passTest]#

 

 

step 1. 위에서 만든 Dockerfile을 수정합니다.

[root@centos77 passTest]# cat Dockerfile1

FROM ubuntu

ADD ./hello1.sh /tmp/hello1.sh

RUN chmod +x /tmp/hello1.sh

ENTRYPOINT ["sh", "/tmp/hello1.sh" ] # 이부분 수정

[root@centos77 passTest]# cat Dockerfile2

FROM ubuntu

ADD ./hello2.sh /tmp/hello2.sh

RUN chmod +x /tmp/hello2.sh

ENTRYPOINT ["sh", "/tmp/hello2.sh" ] # 이부분 수정

[root@centos77 passTest]#

 

 

 

step 2. 이미지를 빌드합니다.

[root@centos77 passTest]# docker build -t test1 -f Dockerfile1 .

Sending build context to Docker daemon 5.12kB

Step 1/4 : FROM ubuntu

---> 1d622ef86b13

Step 2/4 : ADD ./hello1.sh /tmp/hello1.sh

---> 0f6d1e5af296

Step 3/4 : RUN chmod +x /tmp/hello1.sh

---> Running in 97c158a0d547

Removing intermediate container 97c158a0d547

---> cfaf42284c72

Step 4/4 : ENTRYPOINT ["sh", "/tmp/hello1.sh" ]

---> Running in e37053b9c0d3

Removing intermediate container e37053b9c0d3

---> a4719185de37

Successfully built a4719185de37

Successfully tagged test1:latest

[root@centos77 passTest]# docker build -t test2 -f Dockerfile2 .

Sending build context to Docker daemon 5.12kB

Step 1/4 : FROM ubuntu

---> 1d622ef86b13

Step 2/4 : ADD ./hello2.sh /tmp/hello2.sh

---> b9ddd0d173c1

Step 3/4 : RUN chmod +x /tmp/hello2.sh

---> Running in 1535b9cd3075

Removing intermediate container 1535b9cd3075

---> 44a417a36f67

Step 4/4 : ENTRYPOINT ["sh", "/tmp/hello2.sh" ]

---> Running in c0f3008516a5

Removing intermediate container c0f3008516a5

---> 5f776c498849

Successfully built 5f776c498849

Successfully tagged test2:latest

[root@centos77 passTest]#

 

 

step 3. 빌드한 이미지를 이용하여 컨테이너를 실행시킵니다.

[root@centos77 passTest]# docker run --rm test1

hello test1!

[root@centos77 passTest]# docker run --rm test2

hello test2!

[root@centos77 passTest]#

 

shebang이 없는 스크립트도 실행이 잘 되는 것을 확인할 수 있습니다.

 

 

위와 같은 쉘 스크립트 파일 뿐만 아니라, js파일, python파일 에서도 해당 문제가 발생할 경우가 있습니다.

또한, 윈도우에서 만든 쉘 스크립트를 리눅스에서 실행시키려고 할 경우에, 윈도우와 리눅스의 라인의 마지막을 나타내는 문자 코드가 달라서도 이러한 문제가 발생할 수도 있다고 합니다.

 

 

참조

https://github.com/containers/buildah/issues/475

https://stackoverflow.com/questions/42494853/standard-init-linux-go178-exec-user-process-caused-exec-format-error

https://www.lewuathe.com/exec-format-error-in-docker-container.html