두 가지 솔루션을 도커로 패키징하기
이번 주에는 두 개의 솔루션을 하나의 도커 환경에서 패키징하여 제공하는 업무를 진행했다.
요구사항
- 서버 재시작 시 자동으로 복구되어야 한다.
- 도커 내부에서 실행되도록 구성해야 한다.
- 고객사의 형상관리툴에서 제한하는 크기를 초과하지 않아야 한다.
고객사의 형상관리툴을 통해 직접 설치 및 운영하는 방식이기 때문에 네트워크 구성, 솔루션별 프로세스 분리 여부, 재시작 정책, 로그 관리 방식 등이 사전에 명확히 정해지지 않은 상태였다.
특히, 두 개의 솔루션을 각각 별도의 도커 컨테이너로 실행할지, 하나의 컨테이너에서 통합 관리할지에 대한 논의가 필요했다. 또한, 빠른 검증이 필요했기 때문에 일주일 내에 도커 구성을 완료하고 성능 테스트까지 진행해야 했다. (물론, 다른 업무도 병행하면서...)
네트워크 방식 테스트
도커 환경에서 네트워크를 구성하는 방식에 따라 성능 차이가 발생할 수 있기 때문에 아래 세 가지 방식으로 부하 테스트를 진행했다.
네트워크 구성 방식
- 슈퍼바이저 방식
- 도커 브릿지 네트워크
- 호스트 네트워크
일반적으로 성능은 슈퍼바이저 방식 > 호스트 네트워크 > 도커 브릿지 네트워크 순으로 좋다고 알려져 있다.
- 슈퍼바이저 방식은 같은 컨테이너 내에서 프로세스 간 통신이 이루어지므로 가장 빠를 것으로 예상했다. 다만, 개별 프로세스의 환경을 분리하는 장점을 잃는다는 단점이 있었다.
- 호스트 네트워크 방식은 가상화된 네트워크 인터페이스를 사용하지 않기 때문에 도커 브릿지보다 성능이 더 좋을 것이라 생각했다.
하지만 실제 부하 테스트 결과는 예상과 달랐다.
테스트 결과: 슈퍼바이저 방식 > 도커 브릿지 > 호스트 네트워크 순으로 성능이 나왔다.
특히, 두 개의 솔루션 중 하나가 부하 분산 기능을 제공하며 1:N 구성이 가능했기 때문에 개별 컨테이너를 띄우는 구조가 더 적합했다. 이에 따라 성능과 운영 편의성을 고려해 도커 브릿지 네트워크 방식으로 최종 결정했다.
호스트 네트워크 방식을 고려했던 이유는 맥주소 기반의 라이선스 인증 방식 때문이었다. 하지만 실제 테스트 결과 성능 차이가 크지 않았고, 포트 충돌 등의 문제가 발생할 수 있어 결국 라이선스 인증 방식을 변경해야 할 필요성을 공유했다. (중앙 라이선스 서버를 통한 인증 방식 구현 필요)
컨테이너 재시작 정책
컨테이너 실행 시 가장 먼저 실행되는 명령어(entrypoint)를 설정하는 방식에 대해 두 가지를 검토했다.
- 에이전트를 활용한 자동 재시작
- 컨테이너 내부에서 에이전트가 서버를 감시하고, 서버가 죽으면 자동으로 재시작하는 방식
- 도커 자체의 프로세스 감지를 활용한 재시작
- docker-compose의 entrypoint에 서버 바이너리를 직접 지정하여, 도커 프로세스가 비정상을 감지하면 자동 재시작하도록 설정
에이전트 방식의 경우, 각 서버마다 개별적으로 에이전트를 띄워야 하는 단점이 있었다. 반면, 도커 프로세스에서 직접 감지하여 재시작하도록 하면 불필요한 프로세스를 줄일 수 있었다. 따라서 도커 컴포즈의 entrypoint를 활용하는 방식이 더 적합하다고 판단했다.
마운팅 관련 이슈
고객사의 형상관리툴 제한 때문에 이미지 크기를 최소화해야 했고, 인식 모델 및 라이브러리를 이미지에 포함시키는 방식이 문제될 가능성이 있었다. 이를 해결하기 위해 로그, 설정 파일 외에도 일부 파일을 마운트하는 방식을 테스트했다.
하지만, 이 과정에서 호스트 서버의 SSH가 고장나는 문제가 발생했다.
원인 분석
서버실로 내려가서 로컬 시스템 로그를 확인한 결과, 마운팅 경로가 잘못 설정되어 서버 시작 시 Segmentation Fault(Segfault) 가 발생했다. 이로 인해 컨테이너가 계속 재시작되었고, 도커 네트워크가 사라졌다가 다시 생성되기를 반복하면서 호스트 서버의 NetworkManager가 등록/해제를 반복하다가 비정상 상태가 된 것이었다.
해결 방안
- 도커 네트워크가 호스트 서버의 NetworkManager에 영향을 주지 않도록 설정하고, 가용 리소스를 제한하여 호스트 서버에 미치는 영향을 최소화
- 에이전트 방식이 아닌 도커 프로세스 감지 기반의 재시작 정책을 적용하여 컨테이너가 비정상 종료되었을 때 자동으로 복구되도록 설정
회고
처음에는 단순한 작업이라고 생각했지만, 실제 구성하면서 예상치 못한 문제들이 많았다. 특히,
- 네트워크 방식에 따른 성능 차이
- 컨테이너 재시작 정책의 선택
- 재시작 및 마운팅 방식이 호스트 서버에 미치는 영향
등을 고민하면서 많은 것을 배울 수 있었다. 이번 경험을 바탕으로 앞으로 비슷한 업무를 할 때 더 효율적인 방향으로 접근할 수 있을 것 같다.