공공 프로젝트에 도커 활용하기
기사 평가 알고리즘 개발에 도커(Docker)를 써보았습니다
슬로워크 디지털 사업부는 한국언론진흥재단과 함께 ‘뉴스트러스트’ 프로젝트를 진행 중입니다. 최대한 간단히 요약하자면 ‘자연어 처리 및 딥러닝 기술을 활용한 뉴스 기사 평가 알고리즘 개발 프로젝트’라고 할 수 있습니다. 인터넷 뉴스 기사를 모으고 선별해서 제공하는 기준을 정하는 프로젝트입니다. 쉽게 답이 나오는 문제는 아니지만 적어도 포털 사이트보다는 검증된 기관에서 대안을 모색해보자는 취지로 시작됐습니다. 더 자세한 배경과 의미는 한국언론진흥재단의 선임연구위원 오세욱님의 기사 '언론진흥재단, 뉴스트러스트 알고리즘 개발과 공개 의미 : 정보 편향 막아줄 알고리즘, 소스 공개로 투명성도 확보'를 통해 확인하세요.
이 글에서는 배경 설명보다는 ‘아이디어를 구현하기 위해 어떤 기술을 활용할 수 있는가’에 초점을 맞춘 이야기를 해보려고 합니다. 즉 뉴스트러스트라는 아이디어를 실제로 구현하기 위해 도커 기술을 사용한 이유와 프로젝트 구성 예시 일부를 보여드리겠습니다.
도커는 피할 수 없는 선택?!
뉴스트러스트가 추구하는 가치는 공공성입니다. 모두가 더 좋은 뉴스를 소비하도록 돕는 프로젝트이며, 누구든 그 과정에 참여하고 기여할 수 있는 기반을 만들려고 합니다. 그래서 거의 모든 소스코드를 공개하고, 누구든 쉽게 받아서 실행할 수 있도록 최대한 간편한 구성으로 프로젝트를 꾸리고 있습니다.
이런 상황에서 도커를 사용하는 것은 거의 피할 수 없는 선택이었습니다. 아무리 소스가 공개돼 있어도 그걸 받아서 실행하기 위해 운영체제(OS)나 실행환경, 버전, 환경변수 등을 맞추는 과정은 모든 개발자에게 고난이기 때문입니다. 그런데 도커는 다양한 오픈소스 프로그램을 배포하고 관리할 때 쓸 수 있는 단순한 인터페이스를 제공하는 플랫폼으로써, 기존의 OS 가상화보다 가벼운 프로세스 격리 방식(컨테이너)으로 구동됩니다.
즉 ‘모두가 더 좋은 뉴스를 소비하도록 돕는’ 프로젝트의 공공성을 기술적으로 잘 뒷받침해줄 수 있다는 점에서, 또 개발편의성이 높은 가상화 기술이라는 점에서 도커가 유용했습니다.
프로젝트 설명글(README)에는 도커 실행 가이드가 적혀있습니다. 프로젝트를 내려받은 다음 도커 명령어 몇줄만 실행하면 뉴스트러스트의 전체 시스템을 각자의 PC에 배포할 수 있습니다. 다만 깃(git)과 도커는 설치해야 합니다. 아래 스크린샷은 제 PC에 뉴스트러스트를 배포하고 형태소분석 API를 테스트한 결과입니다.
도커 기반 프로젝트 구성 예시
앞서 명령어 몇 줄만 실행하면 뉴스트러스트를 배포할 수 있다고 했는데요, 그렇게 간단한 방법으로 프로그램을 배포할 수 있다는 건 결국 복잡한 일을 누군가 대신 해주고 있다는 의미입니다. 이번에는 도커로부터 도움을 받았습니다. 이제 도커를 어떤 식으로 활용했는지 간단히 살펴보도록 하겠습니다.
우선 뉴스트러스트를 배포하는 과정을 풀어서 설명해보면 이렇습니다.
1. 리눅스 환경을 기본으로 구성한다.
2. 웹 애플리케이션을 구동시키는데, 언어는 GO를 쓴다.
3. 웹 애플리케이션의 세션을 저장하기 위해 Redis를 연동한다.
4. 데이터 처리를 위해 Python을 쓰고, 자연어처리를 위한 관련 라이브러리도 설치한다.
5. MongoDB를 설치하고 위의 GO/Python 모듈과 연동한다.
6. RabbitMQ를 설치하고 위의 GO/Python 모듈간 메시지 큐잉을 관리한다.
현재 뉴스트러스트 프로젝트는 위 단위들을 하나로 묶어서 공개하고 한번에 배포할 수 있도록 개발 중입니다. 여섯 단계 과정은 모두 일종의 도커 명세서로 정리했기 때문에 개발자는 이 프로젝트를 받아서 다음 명령어로 실행할 수 있습니다.
docker-compose up -d --scale worker=5
아래 스크린샷은 현재 개발 중인 프로젝트의 docker-compose 명세 파일 중 일부를 옮긴 것입니다. 각 모듈이 어떻게 연결되고 실행되는지만 간단히 살펴보겠습니다.
(docker-compose.yml)
명세 파일을 살펴보면 총 5개의 서비스 - web, mongo, redis, mq, worker를 운영하고 있습니다. 모두 각각의 이미지에 의해 컨테이너로 구현되며, 배치 작업할 것을 고려해서 여러 개의 worker 컨테이너만 동시에 실행시키기도 합니다. mq는 그런 병렬작업을 염두에 둔 모듈입니다.
다시 docker-compose 명세로 돌아가서, 다섯 개의 서비스가 공통으로 가지는 속성부터 차례대로 살펴보겠습니다.
1. image, build
컨테이너를 구동시키기 위한 image에 언어 혹은 프로그램 이름과 버전이 명시돼 있는데, 이는 도커 측에서 관리하는 DockerHub라는 공개저장소에서 가져옵니다. 그러나 worker에서 명시하는 nt-worker라는 이미지는 DockerHub에 없습니다. 이는 뉴스트러스트 프로젝트가 자체적으로 구성한 이미지를 따로 사용했기 때문입니다. 따라서 25번째 라인에 있는 build를 함께 봐야 합니다. worker는 따로 작성한 Dockerfile을 빌드해서 사용합니다(Python 모듈).
2. working_dir, volumes
working_dir은 루트 경로 대신 직접 지정하는 워킹 디렉토리고, volumes는 도커 컨테이너 안과 밖이 서로 공유하는 디렉토리입니다(여기서 컨테이너 밖이란 제 PC환경 그 자체를 의미합니다). web의 경우엔 수정한 소스가 컨테이너에도 바로 반영돼 디버깅에 도움이 되고, mongoDB의 경우 DB 관련 파일들을 외부에도 저장하는 일종의 백업 용도로 썼습니다.
3. command
command는 web과 worker에만 명시돼 있습니다. DB나 큐는 설정에 맞게 구동만 하면 되지만, 애플리케이션 성격의 web과 worker는 컨테이너가 구동된 직후에 실행돼야 할만한 세밀한 작업이 있습니다. 그래서 셸 파일을 별도로 작성했고 도커에게 이 파일을 실행하라고 알려주는 부분입니다.
4. ports
아홉 번째 라인에 명시된 “60000:8091”은 외부의 60000번 포트로 접속하면 도커 환경의 8091에 연결한다는 뜻입니다. 첫번째 스크린샷의 주소창을 보면 “localhost:60000”으로 접속한 걸 알수 있습니다. 제 PC의 60000번 포트가 도커 내 8091번 포트로 포워딩된 것입니다. 보안을 위해 접속 경로의 외부 노출은 최소화하는게 좋습니다. 예시에선 불가피하게 웹서비스에 대한 노출만 한 상황이고, 개발하는 과정에선 편의상 다른 서비스들도 열어놓곤 합니다.
이상 자연어 처리 및 딥러닝 기술을 활용해 뉴스 기사 평가 알고리즘을 개발하는 ‘뉴스트러스트’ 프로젝트에 도커를 사용한 이유와 구성 예시 한 개를 함께 살펴봤습니다. 비개발자에게는 외계어로 들릴 수도 있고, 어떤 개발자에게는 허점 많은 프로젝트로 보일지도 모르겠습니다. 하지만 공공 프로젝트에 걸맞는 접근성과 유용성을 갖출 수 있도록 앞으로도 계속 개선해 나가려고 합니다. 미처 다루지 못한 자연어 처리나 기계학습 관련된 이야기도 기회가 닿으면 이어서 소개하겠습니다.
글, 이미지 | 슬로워크 디지털 사업부 개발자 벤
편집 | 슬로워크 오렌지랩 테크니컬 라이터 메이