[Github, MLOps] ML 모델 CI/CD 를 위한 Jenkins 테스트 자동화 [3]
이번 포스팅에서는 앞서 다뤘던 Jenkins 의 Unit Test 방법을 Blue Ocean이라는 plug in을 사용해서 Pipeline을 구축하는 방법에 대해서 설명해보려고 합니다. 사실 앞에 있던 포스팅들은 Jenkins의 기본을 이해하는데 중점적으로 생각하시면 좋을 것 같습니다. BlueOcean이라는 Plug-in이 훨씬 효율적으로 좋은 Unit Test를 만들 수 있어서 사용해보시면 좋을 것 같아서 포스팅을 쓰게 되었습니다.
Blue Ocean
먼저 Blue Ocean에 대해서 간단히 알아보겠습니다. Jenkins의 파이프라인을 구성하는 방법은 다양하게 존재합니다. 그 중 가장 흔하게 사용되는 방법은 groovy언어를 통해 Jenkinsfile 구성하는 방법과 Snippet Generator 을 사용해서 script를 구성하는 방법입니다. 저는 groovy를 통해서 구현을 해본 경험은 있지만 Snippet Generator를 사용한 적은 없습니다. 하지만, 처음 groovy 언어를 접하면 생각보다 많이 복잡하기도 하고 주 업무가 Groovy 언어를 쓰는게 아니다보니 공부하기에는 시간도 부족해서 원하는 구성의 파이프라인을 구성하기 까다롭습니다.
Blue Ocean은 Jenkins의 plug in으로 유저 친화적인 UI를 통해서 파이프라인을 간편하게 구성할 수 있게 해줍니다. Blue Ocean을 사용하기 위해서는 추가적으로 설치를 해줘야 사용할 수 있기 때문에 다음과 같이 Jenkins Dashboard에서 Jenkins 관리 -> 플러그인 관리로 이동합니다.
그리고 나오는 화면에서 '설치 가능' 탭을 선택한 뒤 위의 search 에 Blue Ocean이라고 검색을 합니다. 그러면 엄청 많은 Blue Ocean 관련된 플러그인들이 존재하지만 한가지만 설치하면 됩니다.
사진처럼 Blue Ocean 'Blue Ocean Aggregator' 를 선택하여 다운로드하면 나머지들 중 필요한 dependency plug in 들은 모두 자동으로 설치가 됩니다.
설치가 완료된 뒤에 Jenkins의 대쉬보드에 돌아오면 다음과 같이 '블루 오션 열기' 탭이 생성된 것을 볼 수 있습니다.
이제 블루오션을 클릭하고 들어가주세요. 그러면 파란색의 기본 Jenkins 대쉬보드의 어수선한 분위기와는 다른 깔끔한 UI를 가진 화면이 등장합니다. 그러면 바로 우측에 상단의 '파이프라인 생성'을 눌러서 다음과 같은 화면으로 들어와주세요.
이제 파이프라인을 생성할텐데, 저는 Github 의 레포지토리의 PR이 생겼을 때 Unit Test를 진행할 수 있도록 하는 파이프라인을 구성할 것이기 때문에 Github을 클릭해주세요. 그러고 나면 아래 몇가지 선택사항이 존재하는데, 선택하고자 하는 repository가 개인 or 등록된 회사의 것인지를 선택해주면 아래의 repository 선택에서 해당 ID에 등록된 repository들이 등장하고 원하는 repository를 선택한 뒤 파이프라인 생성을 눌러줍니다.
그러면 아래의 사진과 같이 아무것도 없는 DAG 형태의 그래프가 'start' 라고 적힌 노드와 함께 존재합니다.
여기서 '+' 모양의 원을 눌러서 처음 jenkins가 작동하면 수행하게 될 행동을 만들어 줍니다. 저같은 경우에는 앞선 포스팅의 내용을 그대로 구현해보고자 '스탭 추가'를 누른 뒤 'Shell Script'를 눌러서 docker container를 조건에 따라 생성하는 script를 넣어주었습니다. 어떤 내용인지 모르시는 분은 https://mjshin.tistory.com/4 포스팅을 참조해주세요.
### RUN TEST CONTAINER ###
if docker ps | grep jenkins_test
then
echo "Jenkins container for Test is already exists."
else
echo "Creating new one"
docker build --tag engine:test .
docker run -dit --runtime=nvidia -v /home/<---->/jenkins_home/workspace/:/workspace/engine --name jenkins_test --shm-size 32G engine:test
fi
### END ###
docker rm -f engine:test
저는 시작에서는 Docker를 DooD로 만들고 End 에서는 Docker를 지워주는 방식을 사용하였습니다. 그리고 사이에는 확인하고자 하는 ML project들을 하나씩 순차적으로 돌려줄 예정입니다. 그러다 보니 사이사이에 Git이나 다른 많은 스탭들을 추가할 수 있지만 저는 Shell Script만을 사용해서 python 파일을 실행해주는 방식을 사용하였습니다.
여기에서 주의할 점은 제가 사용한 ${PWD##*/} 입니다. 파이프 라인들을 완성하고 PR을 날리게 되면 자동적으로 Jenkins에서 PR branch를 사용해서 테스트를 수행하게 됩니다.
이때, groovy 언어를 통해서 현재 test 하고자 하는 branch의 workspace 경로를 얻을 수 있습니다. 하지만, workspace의 full path는 /var/jenkins_home/workspace/<branch 이름> 이런식으로 경로가 등장하게 됩니다.
저는 좀 특이하게 docker container를 하나 띄워서 ML 프로젝트를 실행시켜야 했기 때문에 이전 코드에서 "-v" 옵션으로 연결한 container 내부의 /workspace/engine에 존재하는 현재 test하고자 하는 <branch 이름>의 폴더를 찾아서 프로젝트를 실행시킬 필요가 있습니다.
그래서, 현재 workspace 정보에서 <branch 이름> 만을 가져오기 위해서 ${PWD##*/}를 사용한 것입니다. 궁금하신 분들은 Shell Script에 "echo ${env.BRANCH_NAME}"과 같이 현재 브랜치가 무엇인지 등의 정보를 통해서 출력해보고 사용하고자 하는 값을 가져와서 사용하시면 됩니다.
docker exec jenkins_test bash -c "export PYTHONPATH=$PYTHONPATH:/workspace/engine/${PWD##*/}; export CUDA_VISIBLE_DEVICES=0; python3 /workspace/engine/${PWD##*/}/projects/dummy/main.py"
이렇게 구성을 하고 나서 PR을 날리게 되면 PR 화면에서 다음과 같이 'Some checks haven't completed yet' 이 나타나면서 Unit test가 진행되는 모습을 볼 수 있습니다.
오른쪽의 'Details'를 누르면 Jenkins의 Blue Ocean 화면으로 연결이 되고 다음과 같이 진행 상황을 볼 수 있습니다.
한가지만 더 보고 가셔야 할 게 있습니다. 위의 내용을 따라하면, PR을 수행하였을 때 PR-head와 master 브랜치까지 2개의 브랜치에 대해서 파이프라인을 진행하게 됩니다. 이걸 방지하기 위해서는 Jenkins 대쉬보드에서 보이는 생성된 파이프라인을 클릭한 후 Configuration으로 이동해야합니다.
다 이동하셨다면 'Behaviours' 섹션의 셋팅을 다음과 같이 바꿔주세요.
Strategy에 따라서 어떤 branch에 대해서 파이프라인을 수행할 지 결정하게 되는데 선택지는 다음과 같습니다.
- Exclude ...옵션은 일반 브랜치는 아래 사진(Blue Ocean의 대쉬보드)에서 "브랜치"쪽에 나타나게 하며 PR을 요청한 브랜치는 "풀 리퀘스트"쪽에 나타나게 합니다. 이때 차이는 PR한 브랜치에 대해서 빌드하고, 브랜치 목록에 있는 브랜치에서 push가 발생하면 push 할 때 마다 빌드를 하게 됩니다.
- Only ... 이 옵션을 선택하면 PR을 날린 브랜치에 대해서만 빌드를 하게 됩니다.
- All branches 옵션은 Jenkins가 볼 수 있는 모든 branch에 대해서 빌드를 하게 됩니다.
후기
추후에 Deploy와 Dockerfile을 만드는 CI/CD 과정을 종합적으로 수행하는 Jenkins 파이프라인 구성법도 다룰 예정이니 이번에는 Blue Ocean의 기본 사용방법에 대해서 알아보았습니다.
기본적인 Jenkins의 Create Job을 통해서 CI Job을 생성하거나 파이프라인을 생성할 수 있지만 생각보다 많이 복잡하지만 이렇게 Blue Ocean이라는 Plug-in을 통해서 파이프라인을 작성하게 되면 훨씬 편하게 CI/CD 과정을 구성할 수 있습니다.
References
https://medium.com/@jyson88/jenkins-blue-ocean-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95-579d8059a7b7
https://medium.com/@jyson88/jenkins2-agent-%EC%83%9D%EC%84%B1-647872c2a5c4