엔터프라이즈용 어플리케이션 서버 배포 분투기

상황

얼마전 모 기업(이하 A기업)을 위한 어플리케이션&앱서버 제작을 하는 회사에서 해당 서버의 디플로이 작업 보조를 의뢰받은 일이 있었다. 일반적인 경우라면 AWS를 통해 개발&서비스 서버를 돌렸겠지만 이번 작업은 기업의 정책상 A기업의 내부 전산망에 설치된 서버에 서버를 배포해야 하는 상황이었다.

작업 시작 전 알고 있던 사전정보는 다음과 같았다.

  • 서버 OS: CentOS 6.x
  • 어플리케이션 서버 프레임워크: NodeJS + ExpressJS + nginx
  • DB: MongoDB 3.X
  • 특정 서비스 포트(80, 443)를 제외한 해당 서버로의 접근은 A기업 내부망에서만 가능
  • 서비스까지 남은 기간은 약 2주 정도
  • A기업은 9to6를 철저히 지키며 이 시간 이외에는 서버에 접근할 수 없다.

Challenges

Day 1 - yum & npm

예상대로 첫날부터 난관에 봉착했다. yum, npm등 패키지매니저가 제대로 동작하지 않았다. 내부망의 정책탓인지 혹은 전산팀의 실수인지, dns설정의 문제로 패키지를 가져오기 위한 도메인 이름들의 IP주소를 찾지 못해 깃은 물론 어떤 패키지도 설치할 수 없었다. 이때부터 우리 팀은 "인터넷 접속은 없다"라는 생각을 가지고 모든 것을 오프라인으로 준비하기로 결정했다. 주변의 조언을 받아 여러가지 준비를 할 수 있었는데 이는 다음과 같다.

Docker

A기업은 퇴근이 6시 이기에 시행착오에 시간을 할애하기 힘든 상황이다. 가능한 많은 것들을 환경에 구애받지 않도록 준비하기에 도커가 알맞은 툴이라 판단했다. 도커에 대한 자세한 설명은 생략하고 오프라인 설치&배포에 필요한 내용만 간단히 정리해보겠다.

  • 도커 또한 yum을 통해 설치해야 하기 때문에 static binary를 준비한다. 1
  • 도커 이미지 빌드에도 인터넷 연결이 필요하기에 인터넷 사용에 문제가 없는 환경에서 이미지를 준비, 파일로 보존 후 내부망에서 scp로 서버에 옮겨 이미지로 복원한다. 2
- host-with-internet:~$ docker save -o ARCHIVE.tar IMAGE_NAME:TAG
- host-with-internet:~$ scp /path/to/ARCHIVE.tar USER_NAME@HOST_URL:/path/to/copied/ARCHIVE.tar
...
- host-without-internet:~$ docker load < /path/to/copied/ARCHIVE.tar

Plan B

혹시 모를 상황에 대비해 도커를 사용하지 않는 오프라인 서버 설치 방법도 준비해 보았다. 도커 설치에 성공했기에 이 방법은 결국 사용되지 않았지만 기록을 위해 남긴다.

Day 2 - System Requirement for Docker

예상대로 둘째 날도 문제가 발생했다. 서버에 설치된 CentOS 버전이 도커의 최소 시스템 요구조건을 만족하지 않아 도커를 실행할 수 없는 문제가 발생했다. 3 간략히 이야기하면, 도커를 설치하기 위해서는 리눅스 커널 버전 3.10 이상을 사용하는 리눅스 distribution이 필요한데 CentOS 6.x 버전은 2.6버전대 커널을 사용하기 때문에 발생한 문제였다. 커널만 업데이트 한다는 옵션도 있었지만 어떤 문제가 발생할지 모르는 상황이라 가능한 안전한 방향으로 가고자 A기업 전산팀에 CentOS 7.4버전으로 업데이트를 요청했다.

이 후: Many Parties on Same Machine

서버 OS 업데이트로 주요한 문제들은 대부분 해결되었고 도커로 이미지를 돌리는데에 성공했다. 다음 문제는 A기업과 계약한 보안업체에서 발생했다.

이 보안업체가 보안 툴(?)을 설치한 이후 부터 eth0 인터페이스와 docker0 인터페이스간의 연결을 막아 기존의 bridge 네트워크 모드를 사용하던 서버 컨테이너가 먹통이 된 것이다. 문제를 이해하고 해결하기 위해 firewall-cmd 등으로 방화벽 세팅을 확인해봤지만 데몬이 돌아가고 있지 않았다. 만일의 경우를 생각에 CentOS 6버전의 iptables 세팅도 확인해 봤지만 전부 기본 설정으로 돌아가 있었다.

이상의 정황으로 미루어 본 결과 '커스텀 보안 툴을 사용하고 있을 것이다' 라는 결론에 이르렀다. 우선 서비스 정상화기 급했기 때문에 (최선의 방법은 아니지만) 각 컨테이너의 네트워크 모드를 host로 바꾸는 것으로 일단 문제를 해결할 수 있었다.

서버 보안업체와 같이 작업할 상황이 생긴다면 아래와 같은 사항을 숙지하자

  • 서비스가 돌아가는 상황에서 보안툴을 설치하지 말 것. 점검시간을 공지하고 서버를 내린 후 모든 작업을 하지 않으면 수 많은 유저들이 장애를 겪는다.
  • 서버에서 사용하는 모든 host names, ip addresses, ports 정보를 잘 체크해 보안업체에 전달하자.
  • 만약 도커를 사용하는 경우라면 eth0/docker0 인터페이스간 ip 포워딩을 요청하자.

Miscellaneous

  • 사용중인 노트북에 랜 포트가 없는 경우 꼭 이더넷 어뎁터를 준비하도록 하자.
  • 엔터프라이즈는 API 사용을 위해 jar파일을 주는 경우가 많다. 이러한 경우 기본적으로 jar은 블랙박스이기 때문에 문제가 생긴 경우 내부에 대한 지식이 없는 측이 책임을 떠맡기 쉬워진다. 불합리한 책임전가를 피하기 위해 자바 디컴파일러 3, IntelliJ IDEA 등으로 jar의 내부를 파악해 두자.

참조

https://docs.docker.com/install/linux/docker-ce/binaries/

https://docs.docker.com/engine/reference/commandline/save/#examples https://docs.docker.com/engine/reference/commandline/load/#examples

https://access.redhat.com/articles/3078 https://en.wikipedia.org/wiki/CentOS#CentOS_releases

https://github.com/kwart/jd-cmd/releases/tag/jd-cmd-0.9.2.Final

댓글

이 블로그의 인기 게시물

Unity에서 모델의 폴리곤의 반대편이 랜더링 되지 않는 문제 해결 방법

Docker 컨테이너 네트워크 설정시 ifconfig로 docker0를 찾을 수 없는 문제에 대해

Use FFMPEG in XCode(for MacOS)