
첫 글이다!
별 시덥찮은 소리도 많습니다.
초보자 주의
장대한 삽질기: 발단
발단은 진행중인 프로젝트에 CI/CD를 적용해보는 것은 어떨까 하는 내 소소한 의견 (이때는 이렇게까지 장대한 삽질기가 될 것이라 생각하지 못한 내 문제다. 무식하면 용감한 법이다.)에서 시작했다. 프로젝트를 지원하는 멘토님의 도움을 받아 서버를 빌려서 운용할 수 있게 된 덕분에 엄청나게 기분이 좋은 상태에서 (지금 생각해보면 이 쪽에 대해 1도 모르는 한 학생의 의견에 이렇게까지 전폭적인 지원을 해주신 멘토분께 그저 감사의 말씀을 드릴 따름이다...) 계획을 하기 시작했다.
지금 생각해보면 생각보다 작은 일이 아니었다. -> 계획을 잘 짜야만 했다.
과거의 나는 잘 몰랐겠지만, CI/CD 서버를 구축하는 것은 결코 작은 일이 아니다. Controller 서버 뿐만 아니라 Runner에 대한 고려도 충분히 이루어져야 했으며, 프로젝트가 어떤 프레임워크 혹은 엔진을 쓰는지도 고려해야 한다. 프로젝트에 따라 별도의 플러그인 등을 활용해야 하는 경우도 존재한다. 특히 Jenkins의 경우 후술하겠지만 수많은 플러그인을 이용해서 빌드와 배포를 자동화할 수 있어야 한다.
그러니까 설치하기 이전에 고려할 사항은 생각보다 많다. 아주 많다. 근데 난 이걸 알아볼 생각도 안했다. 과거의 나한테 '넌 무슨 깡으로 지른거냐'라고 무한히 쪼고 싶은 마음 한가득이다. 하지만... 이걸 깨달은 것은 이것보다 한참 이후였다...
서버 구축을 하려는 목표
당시의 내가 목표로 하는 것들과 구축하기로 마음먹은 서비스는 다음과 같다.
1. 자체 Git 서버
- 서비스 개발 과정에서 업데이트가 관리가 되는 환경에서 형상관리를 하기 위함.
- 서비스 개발 과정에서 프로젝트의 소스코드가 노출되는 경우를 최소화하기 위함.
2. CI/CD 서버
- 빌드와 (가능한) 테스트, 배포를 자동화해서 불필요한, 반복되는 작업을 줄이기 위함
장대한 삽질기의 시작 - 이거 어카지?
일단 필자의 프로젝트는 Unity를 활용한다. 그러다보니 생각보다 고려해 볼 사항이 많았다.
1. 테스트 자동화는 어떻게 할 것인가?
2. 빌드 자동화 단계에서 그래픽 카드의 조력은 필요하지 않은가?
3. 서버의 성능은 어느 정도여야 하는가?
특히 2번은 정말 많은 고민을 불러오는 문제였다. 유니티는 게임 엔진이고, 게임에는 그래픽 요소가 정말, 정말 많이 들어간다. 그러다보니 처음 구축할 때 정말 많은 고민을 했고 오랬동안 답을 알아내기 위해 열심히 검색해보았다.
검색하고보니 나만 그런 고민을 한 것은 당연히 아니었다.
https://forum.unity.com/threads/share-your-build-server-specs-and-setup.507060/
Share your build server specs and setup!
Hello, if you like us have decided to use your own build servers instead of relying on a third party service, you might want to contribute to this...
forum.unity.com
링크를 타고 가보니 그래픽 카드의 역할은 제한적이다. 라고 되어있었다. '제한적이다? 그럼 필요한거야 뭐야?' 라는 생각이 들어 더 찾아봤지만 필요 없다는 없고 제한적이다만 엄청 많았다. '아이씨 어쩌라는거야'라고 속으로 구시렁대면서 찾다 그냥 직접 돌려보기로 마음먹고 Unity 작업을 하던 동료에게 물어봤다. '빌드할 때 그래픽 카드 쓰는지 확인해줄 수 있어요?'
결과는 '제한적이다'라는 말 그대로였다. 마지막에 Global illumination (이게 맞나 싶긴 한데... 암튼 마지막 과정이었다) 에서만 그래픽 사용률이 툭 올라온 것 이외에 작업 관리자상에서 그래픽 카드를 썼다는 징후는 없었다. 이 결과를 보고서 나는 그래픽 카드는 필요가 없을 것 같다는 결론에 이르었다. 그리고 실제로 빌드 하는 과정에서 그래픽 카드는 필요 없었다. 다만 성능에 영향을 미칠까에 대해서는... 글쎄? 나중에 테스트해볼 가치는 충분할 것 같다.
삽질의 시작 - 일을 뻥튀기시키는 이상한 습관
서버를 활용하기 이전에 일단 내 개인 환경에서 먼저 테스트를 진행하고 나서 서비스를 가동하자는 생각에 집에서 안쓰던 데스크탑에 리눅스를 깔고 테스트 환경을 갖췄다. 여기서 일을 뻥튀기시키는 이상한 습관이 발동하기 시작한다. 도커를 써서 업데이트를 편하게 해야겠다는 생각에 실은 그냥 써보고 싶었다라는 개인적인 욕망일 뿐 도커를 활용하기로 마음먹었다. 근데 서비스를 2개 이상 활용해서 하려니 '하나하나 일일히 켜야 되나? 너무 귀찮은데?' 라는 생각이 또 났고, 찾아보니 역시 마법의 도커 답게 docker compose를 통해서 여러개의 docker container를 한 번에 관리가 가능하다는 것을 찾았다. 그래서 '와! 역시 도커!'를 말하며 docker compose를 사용해서 서비스를 활용하기로 결정했다. 이와중에 '저 친구들 서브 도메인으로 해서 같은 포트(80, 443)를 이용할 수 있게 해보자!'고 생각해서 nginx를 활용해서 서비스를 연결하기로 마음먹었다. 그리고 이 nginx는 속을 두고두고 썩이는 결정적인 계기가 된다.
장대한 삽질기: 전개
필자가 docker를 아예 안 써본 것은 아니었기 때문에 docker를 도입하는 데에는 별로 큰 문제가 들지는 않았다.
당시에 활용한 방식은 이와 같다.
1. docker pull을 통해서 필요한 이미지를 docker hub에서 다운받는다.
2. 다른 사이트들을 기반으로 docker-compsoe.yml을 작성한다.
3. 설정 파일 등을 저장할 디렉토리 등을 잡는다.
4. docker-compose를 돌려본다.
으아니 차! 왜 안되는거야!
왜 안되긴 너가 멍청하니까지...
안된 것들 위주로 빠르게 정리하자면...
1. docker를 sudo를 통해서 켜야되는 문제
- 이곳 저곳 찾아보니 컨테이너 탈출(container breakout) 등의 문제가 발생할 여지가 있기 때문에 user 에게 docker 사용 권한을 주는 것이 안전하다고 되어있었다. 그거 하기 위해서 내 계정에 권한을 추가했다. 근데 바로 적용 안되는 경우가 있어 재부팅하니 잘 됐다. 로그아웃 이후 다시 로그인 하는 것 만으로 되는 건지는 잘 모르겠다. 나중에 VM으로 테스트해봐야 할 듯
usermod -aG docker <username>
참고: 네이버 Deview 2020에서 나온 발표자료 컨테이너 활용간 보안 이야기가 담겨있다. [링크]
2. nginx
nginx를 통해서 연결하는 과정이 노가다 그 자체였다. 다만 이게 바보의 향연이었던 것이...
- docker-compose를 활용해서 container간 네트워크 연결이 가능하다고 되어 있었다. 그래서 아무것도 모르던 필자는 그냥 '오 역시 마법의 도커'를 외치며 별 설정도 안하고 연결을 시도했다. 그리고 당연하게도 안됐다. (이건 후술)
- '으아니 차'를 외치며 nginx 세팅을 봤는데 이상하게도 nginx에서 어떤 파일도 불러온 것이 없다는 것을 확인하고선 뭔가 이상함을 감지하고 nginx.conf를 확인하니 옛날에는 sites-availabled, sites-enabled를 활용하지 않고 conf.d라는 폴더에 몰빵되는 구조였다. 아뿔싸! 삽질 끝에 volume을 연결하니 설정은 이제 들어간다. 근데 이번엔 기본 페이지도 안뜬다...
- nginx 기본 페이지가 잘 뜨다가 안뜨니까 더 환장해서 docker container의 상태를 확인하니 status restarting이라는 대환장 파티가 열리고 있었다. 급하게 확인해보니 error를 내며 죽고 docker-compose 설정(restart: always)에 의해 다시 켜지고를 반복하고 있었던 것인데 우여곡절 끝에 로그를 확인하고 보니 문법이 안맞아서 계속 꺼지고 있었던 것이었고 파일을 보니 세미콜론을 왕창 빼먹고 conf 파일을 작성했던 것이었다. 덕분에 몇번의 바보짓을 하고난 이후 재부팅 문제 해결. 하지만 필자가 원했던 서비스는 보이지 않았다.
3. Docker-compose Network Setting
위의 nginx에서 이어지는 삽질로, 간단히 말하자면 docker-compose의 네트워크 연결 구조를 전혀 모르고 뻘짓하던 내 무지가 만들어낸 삽질이다. docker-compose 내의 container들은 연결을 하기 위해서는 두 가지중 하나를 해야 한다.
-1. link를 통해서 연결한다.
container의 속성에 links를 넣고 거기에 연결할 container를 입력한다.
nginx:
<생략>
links:
- Gitlab
- Jenkins
뭐 이런 방식으로 말이다.
-2. network를 통해서 연결한다.
위의 방식이 옛날 방식이고 요즘은 가장의 네트워크 인터페이스를 설정하는 식으로 한다고 한다.
# 필요한 부분만 작성, 전체 버전은 다음 글(예정) 참조
services:
nginx:
networks:
- web_service
gitlab:
networks:
- web_service
jenkins:
networks:
- web_service
networks:
- web_service:
이런식으로 한다고 한다. 다만 실제로 적용해본 적은 없으니 실제로 쓰려면 공식 문서를 통해서 설정을 꼭 확인해보고 쓰자.
참조: docker 공식 문서 [링크]
Networking in Compose
docs.docker.com
필자는 빨리빨리 테스트하려고 1번을 했지만 2번을 많이 추천하기도 하고, 사이즈가 커지면서 네트워크의 분리가 필요한 경우도 생길테니 2번 방식을 빨리 적용해볼 예정이다.
이렇게해서 대략 2~3일에 걸친 삽질 끝에 모든 테스트를 로컬에서 한 이후에 실제 서버에 설치하기 위해서 준비를 했다.
물론 실제 서버에 세팅을 하는 과정에서도 문제가 생겼다.
다만 이것도 얘기가 길어지기 때문에 다음에 따로 작성한다.
'프로그래밍 > DevOps' 카테고리의 다른 글
CI/CD 구축 삽질기 - Docker 기반으로 Gitlab, Jenkins 구축하기 (2) (0) | 2021.10.05 |
---|

변덕 심한, 쓸데없는 것 연구하는 것을 좋아하는 개발자입니다. 원하는 것 위주로만 공부하고 정리합니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!