본문 바로가기
AyoProject/DevOps

[DevOps] 7. jenkins를 통한 GitHub 소스배포 및 Docker build, run 자동화(1) - 실패 및 Error에 관한 정리

by 청양호박이 2022. 4. 8.

이제 jenkins에서 동일서버에 있는 경우, GitHub에 위치한 소스에 대해서 Maven build한 jar파일을 다시 docker로 build하여 기존 image를 대체하여 자동으로 구동하는 단계를 진행해 보겠습니다. 이번에는 실제로 성공하기까지 발생한 실패상황 및 Error에 대한 내용을 정리해 보겠습니다.

 

Dockerfile 배포 자동화

실제로 GitHub에 위치한 소스를 jenkins로 Maven build하게되면 jar파일이 생성되게 됩니다. 이 jar를 docker container로 build하기 위해서는 Dockerfile이 필요합니다. 그래야 해당 위치에서 docker build 혹은 doker run이 가능합니다. 따라서 자동화를 위해서는 이 Dockerfile을 jar가 생성되는 target폴더에 위치시켜야 합니다.

 

1. SpringBoot Project 내 Dockerfile 생성 [실패]


현재 jenkins에서 빌드하는 구조를 살펴보면 , jenkins의 workspace에 build item이름으로 폴더가 구성되고 해당 폴더 아래에 src와 target이 위치하게 됩니다. 따라서 SpringBoot Project내 target 폴더를 생성하고 그 하위에 Dockerfile을 만들어서 GitHub에 commit해 놓으면, jenkins build시 해당 파일도 같이 이동하지 않을까 하는 추측으로 구성해 봅니다.

아래와 같이 target 폴더에 Dockerfile을 확장자 없이 만들고, Docker관련 내용을 넣어줍니다. 지난번에 한번 구성했지만 다음과 같이 넣어줍니다.

FROM openjdk:8-jdk-alpine
ARG jar_file = AyoteraLabDockerTest-0.0.1-SNAPSHOT.jar
COPY ${jar_file} ayotera.jar
ENTRYPOINT ["java","-jar","/ayotera.jar"]

그럼 이제 git으로 추가된 파일을 add하고 commit을 하겠습니다. 현재 GitHub와 clone을 맺지 않은 상태이기 때문에 eclipse에서 말고 git bash에서 진행합니다.

git add .
git commit -m "Dockerfile commit"

이렇게 하면 아래와 같이 commit할 수 있는게 없다고 나옵니다. 

$ git commit -m "Dockerfile commit"
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

그래서 git status를 해봐도 아무런 반응이 없어서, ls로 target/폴더로 이동해서 git add . 를 해보니 아래와 같이 target을 .gitignore files에 명기된 무시된 경로라고 알려줍니다.

The following paths are ignored by one of your .gitignore files:
target
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"

해당 방법으로는 안되는 것을 알게되었습니다.

 

2. jenkins workspace에 수동 업로드 [실패]


Dockerfile을 만들어서 강제로 Maven build가 된 jar가 있는 경로에 넣어줍니다. 금번 실험에서 해당되는 경로는 아래와 같습니다.

/APP/pkgs/jenkins/workspace/ayotera_docker_test/target

이제 jenkins로 다시한번 빌드를 해보고 해당 파일이 사라지나 확인해 보겠습니다. 

역시나 build는 성공적으로 진행되었습니다. 그럼 다시 그 경로로 가서 파일을 확인해 보겠습니다. 크흑... 그냥 사라져 버리네요. 역시 target을 폴더채로 날리고 다시 생성하는 로직으로 돌아가는 것으로 보입니다.

 

3. SpringBoot Project root 폴더에 Dockerfile 생성 [성공]


해당 방법으로 구현하면 되는데... 성공케이스에 대해서는 다음글에서 쭉 한번에 정리해서 구현해 보겠습니다.

 



 

 

jenkins Post Steps 에서 Shell Script 동작 Error

이제 Dockerfile이 정상적으로 자동으로 jenkins 빌드 배포가 되면 다음으로는 jenkins Post Steps를 통해서 Shell Script를 입력하고 자동으로 docker container build 및 run을 수행해야 합니다. 이 중에도 참 많은 Error가 발생했는데, 해당 내용을 따로 정리해 보겠습니다.

 

[Error cd: can't cd to]


아래와 같이 Dockerfile을 옮겨주려고 shell script를 작성했는데 오류가 발생했습니다. 

cd /APP/pkgs/jenkins/workspace/ayotera_docker_test
cp Dockerfile target/

18:16:42 [ayotera_docker_test] $ /bin/sh -xe /tmp/jenkins14646409352988300902.sh
18:16:42 + cd /APP/pkgs/jenkins/workspace/ayotera_docker_test
18:16:42 /tmp/jenkins14646409352988300902.sh: 2: cd: can't cd to /APP/pkgs/jenkins/workspace/ayotera_docker_test
18:16:42 Build step 'Execute shell' marked build as failure
18:16:42 Finished: FAILURE

이 에러는 jeckins를 docker로 띄웠을 때 발생하는 경우로, docker에서 실제 binding한 물리경로로 접근을 하려고 하면 발생하는 문제입니다. 아래의 -v 옵션에서 binding하기전 경로로 접근해야 합니다. 

$ docker run -d --name jenkins -p 8081:8080 -v /APP/pkgs/jenkins:/var/jenkins_home jenkins/jenkins:lts

위의 경우에는 다음과 같이 변경을 해줍니다.

AS-IS : cd /APP/pkgs/jenkins/workspace/ayotera_docker_test
To-Be : cd /var/jenkins_home/workspace/ayotera_docker_test

그렇게 되면 정상적으로 넘어가고 아래의 명령이 정상적으로 수행되어 Dockerfile이 지정된 target경로로 옮겨져 있음을 확인할 수 있습니다.

cd /var/jenkins_home/workspace/ayotera_docker_test
cp Dockerfile target/

Post Steps에는 아래와 같이 입력해주고 build를 해보면 정상적으로 Dockerfile이 target 폴더에 복사되어 있음을 확인할 수 있습니다.

 

[Error : docker: not found]


+ docker rm ayotest -f
/tmp/jenkins1768231590894292124.sh: 5: docker: not found
Build step 'Execute shell' marked build as failure

이 문제가 발생하는 원인을 찾아보니... 일단 docker로 jenkins를 구동할때 발생하고, 이때 docker.sock을 마운트 해줘야 합니다. docker.sock은 도커의 컨테이너 안에서 데몬과 서로 연동하여 작업을 할 수 있게 해주는 Unix socket이라고 합니다. 따라서 이 볼륨도 마운트 해줍니다.

Jenkins를 이렇게 실행해봅니다. 이제 점점 명령어가 길어져서 여러줄로 보기좋게 표현하기 위해서 (\)를 각 줄마다가 추가해 줍니다. 그럼 아래처럼 이쁘게 표현되죠??

 

[jenkins build 최종 명령어]

docker run -d --name jenkins -p 8081:8080 -p 50000:50000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/usr/bin/docker \
-v /APP/pkgs/jenkins:/var/jenkins_home \
jenkins/jenkins:lts

이를 위해서는 기존에 build한 docker container를 삭제하고 다시 만들어 줘야 합니다. 

docker ps -a 
docker rm jenkins -f
docker run -d (이하 작성)

이렇게 정상적으로 jenkins docker container가 실행되었습니다. 다시 jenkins web으로 들어가서 해당 item을 다시 build해줍니다. 그럼 또 아래와 같은 error가 발생합니다. 참으로 갈길이 멉니다.

 

[Error : dial unix /var/run/docker.sock: connect: permission denied]


Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Delete "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/ayotest?orce=1": dial unix /var/run/docker.sock: connect: permission denied

 

/var/run/docker.sock의 접근권한이 없어서 발생하는 문제입니다. 따라서 chmod로 권한을 추가해 줍니다. 

$ sudo chmod 666 /var/run/docker.sock

docker.sock이 srw-rw----에서 srw-rw-rw-로 변경되었습니다. 다시 jenkins web으로 들어가서 해당 item을 다시 build해주면 됩니다.

 

- Ayotera Lab -

댓글