작년 DDos공격으로 인한 서버 다운시 대규모 트래픽이 와도 서버가 버틸수 있도록 무중단 서비스에 대해 고민을 하게 되었다.
올해초 2년간 작업을 한 Koin_Renewal_Deploy에서 무중단배포, 그리고 추후의 Auto-Scaling을 위해 DB/WAS의 분리가 필요했다.
위와같이 DB를 분리하면서 docker를 도입하게 되었다.
도입을 하게 된 이유는 코인 마이그레이션을 하면서 여러 버젼의 데이터베이스가 필요했기 때문이다.

왜냐하면 현재 레가시 코인(Spring3) mysql버전은 5.7을 사용중이고 코인 마이그레이션(SpringBoot3)은 8.0.29를 사용중이기 때문이다.
이후 데이터베이스만 컨테이너 방식으로 관리해야 하나 고민하던 차 XZ_Utils의 문제가 발생하였다. 그리하여 현재 사용하는 리눅스 커널에만 종속되는 서비스를 운영해서는 안되겠다는 생각을 하였다.
또한 최근에 지원이 종료된 Ubuntu 16.0.4를 사용하고 있던 프로덕션 서버의 OS에 대한생각, 레드햇 계열 리눅스에서 가장 많이 사용중인 CentOS의 지원 종료든 하나의 OS에 지속적으로 종속되는 것은 좋지 않다고 판단하였다.
이러한 이슈로 인해 갑자기 OS를 옮겨야 할 경우 컨테이너 화가 정말 중요하다고 생각을 하였다.
이전에 인프라를 관리할때 무중단 배포에만 생각을 많이 하였던것 같다. 무중단 배포는 사실 EC2, AMI, ELB, Jenkins를 활용해서 언제든지 배포를 할수 있다는 생각을 한 것이다.
또한 DB서버를 분리하였기 때문에 현재도 was이관 혹은 ec2이관에는 충분히 무중단으로 배포를 진행할수 있고 Auto-scaling도 충분히 가능한 상황이 되었다.

추후 완성하지 못했던 AutoScaling을 적용한다면 Scaling을 통해 좀더 유연하게 대처를 할 수도 있겠지만 현재 서비스의 특성상 특정시간대의 대규모 접속할 일은 많이 없다보니 불필요하다고 느꼈다. 왜냐하면 스케일링을 하는 과정에서 비용이 발생되기 때문이고, 대규모 트래픽에 대비해 다중적인 스케일 아웃을 한다고 하여도 성능이 제대로 나오지도 않기 때문이다. 데이터독을 살펴보면 급작스럽게 트래픽이 튀는 경우를 제외하고는 일정하게 트래픽이 발생하는 것을 알 수 있다.(추후 논의된 이벤트 기능이 나오면 인프라를 손볼 필요는 있겠다고 생각한다)

대신 추후 도커스웜까지 사용한다면 유휴 자원, 특히 한정된 메모리를 좀더 효율적으로 이용할 수 있을 것으로 보인다.(오케스트레이션 활용가능)
일단 현재 가용가능한 서버의 자원을 살펴보자.(쩝쩝박사는 올해 여름 서비스 종료 예정이므로 제외를 하였다.)
1. Koin_Production

Koin_Stage

Koin_DataBase

BCSD_Internal

이전의 대응책으로 t3a.small서버 기준 2g로 할당된 메모리에 2g의 스왑을 추가로 주었다.
전체적으로 CPU사용률은 크게 문제가 되지 않지만 메모리 사용량은 트래픽이 급증하거나 외부 공격이 들어올시, 문제가 될수도 있다. 그리하여 고려하였던 것이 AutoScaling이나 사실 Scale up할 일이 자주 없을 뿐더러 인스턴스의 비용이 발생하기에 오케스트레이션 도구를 활용하여 좀더 효율적으로 자원을 이용하는 방향으로 바꾸었다.
마음 같아서는 오케스트레이션의 레퍼런스가 된 쿠버네티스를 도입하고 싶지만 도커라이즈를 한다고 하여도 컨테이너의 개수가 20개 남짓 이기에 도커스웜으로도 충분히 컨트롤이 가능하다고 판단을 하였다.
도커를 알기전에 컨테이너라는 개념을 알아야 한다.
컨테이너는 앱이 들어있는 박스로서 자체의 이름,IP,주소,디스크 등이 있다. 이들은 도커가 만든 가상 리소스 이며 애플리케이션이 실행한 환경과 함께 하는 논리적 객체들이다.

컨테이너 내부의 앱은 외부를 볼 수 없지만 컨테이너는 한 컴퓨터에서 실행하며 컴퓨터는 여러개의 컨테이너를 실행할 수 있다.


dockerfile은 애플리케이션을 패키징하는 스크립트 파일로서 이미지를 만든다.
FROM diamol/node
ENV TARGET="blog.sixeyed.com"
ENV METHOD="HEAD"
ENV INTERVAL="3000"
WORKDIR /web-ping
COPY app.js .
CMD ["node", "/web-ping/app.js"]
예시는 다음과 같으며 이 용어들에 대해 알아보자
컨테이너를 이미지로 만드는 작업은 commit명령어로 쉽게 수행할 수 있다. 그러나 이미지가 어떻게 빌드되는지에 대한 개념을 알아야 한다.
docker inspect 이미지 이름
으로 이미지를 살펴보면

위와 같이 Layer가 있음을 알 수 있으며 해시 형태로 저장이 되어있음을 확인할 수 있다.
또한 commit이 쌓이면 이미지가 적층되는 구조임을 알 수 있다.
docker images에서 이미지 크기가 1GB라고 출력돼도 1GB크기의 이미지가 존재하는 것은 아니다. 이미지를 커밋할때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 그 레이어를 포함해 새로운 이미지를 생성하기 때문에 전체 이미지의 실체 크기는 1GB+ 커밋 파일....+커밋파일의 파일크기가 된다.
ifconfig를 통해 네트워크 인터페이스를 확인하면 다음과 같은 결과가 나오는 것을 볼 수 있다.

위와 같이 docker0와 veth0d66e11등 veth이 존재하는데 이는 컨테이너가 생성시 도커에서 자동으로 만들어 준다.
즉 호스트의 eth0를 docker0라는 브리지가 veth과 연결을 해주는 구조이다.

이전에는 Jenkins와 AMI를 활용해도 충분히 유연한 배포가 가능하다고 생각해왔었고 이와 같이 유지를 해왔다.
하지만 컨테이너가 정말 필요한 순간이 와서 도입을 하니, 사람들이 왜 컨테이너를 활용해서 배포를 하는지 알게 되었다.
출처:
https://velog.io/@iuliet716/Docker%EC%9D%98-%EC%97%AD%ED%95%A0%EA%B3%BC-%EC%9E%A5%EC%A0%90
https://velog.io/@springer/Docker#34-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A0%88%EC%9D%B4%EC%96%B4-%EC%BA%90%EC%8B%9C%EB%A1%9C-dockerfile-%EC%B5%9C%EC%A0%81%ED%99%94
시작하세요! 도커/쿠버네티스
이제야 좀 이해가 간다. 도커 네트워크는 조금만 더 공부해야할듯. +) gpt한테 물어보며 조금 이해했다