레이어 관리

image

  • Dockerfile에 작성된 지시어 1개당 레이어가 1개가 추가된다.
  • 불필요한 레이어가 많아지면 이미지의 크기ㅣ가 늘어나 빌드 속도가 느려진다.
  • 따라서, 명령어의 수를 줄여 레이어의 개수를 최소한으로 만들어야한다.

  • image

  • 이와 같이 RUN 지시어는 &&를 활용하여 하나의 명령어 안에서 모든 명령문이 처리되도록 한다.

image

  • 애플리케이션의 크기를 가능한 작게 관리하여 이미지의 크기를 작게 만들어야한다.
  • alpine OS를 사용하여 베이스 이미지를 작은 이미지로 사용할 수 있다.



캐싱을 활용한 빌드

  • Dockerfile에 작성된 순서대로 결과 이미지의 레이어가 쌓인다.
  • Docker는 각 단계의 결과 레이어를 캐시 처리한다. 지시어가 변경되지 않는다면 다음 빌드에서 레이어를 재사용한다.
  • COPY, ADD 명령의 경우 빌드 컨텍스트의 파일 내용이 변경되어도 캐시를 사용하지 않는다.
  • 레이어가 변경되면 그 레이어와 이후의 모든 레이어는 캐시를 사용하지 않고 새로운 레이어가 만들어진다.
  • 따라서, 잘 변경되지 않는 파일들을 아래 레이어에 배치하면, 더 많은 레이어에 캐시를 적용할 수 있다.

image

  • package.json, package-lock.json파일은 외부 라이브러리 정보가 저장되어 있어 개발 시 자주 변경되지 않는다.
  • 따라서, 거의 변경되지 않는 레이어와 함께 두어 캐시를 활용할 수 있도록 할 수 있다.



Tier 아키텍처 구성

image

  • Nginx의 프록시 기술을 활용해 보안에 뛰어난 3Tier 아키텍처를 구성한다.
  • Nginx는 특정 경로로 온 요청(/api로 시작하는 경로)를 지정한 서버로 전달된다.
  • Nginx를 프록시 서버를 활용하여 보안 향상, 부하 관리 및 API 응답 캐싱을 활용할 수 있다.

image

  1. 클라이언트는 원하는 정보를 조회 및 저장하기 위해 웹서버에 접속한다.
  2. 웹서버는 요청 프록시를 WAS에 전달한다.
  3. WAS는 DB서버에서 데이터 저징 및 조회를 진행하고 결과 값을 반환받는다.
  4. WAS는 결과 값을 활용하여 데이터를 가공하여 웹서버에 결과 값을 응답해준다.
  5. 웹서버는 응답받은 데이터를 활용하여 동적화면을 구성하여 클라이언트에 결과를 전달한다. 만약, 클라리언트가 정적인 자료를 요청할 경우 웹서버는 결과 값을 바로 응답한다.

도커에서 Tier 아키텍처 구성하기

image

  • /api로 시작하는 요청은 프론트엔드 컨테이너로 프록시 되도록 설정한다. 따라서, 백엔드 컨테이너에 Host OS의 80포트의 /api경로로 접근을 시도하면 프론트엔드 컨테이너를 거쳐 접근이 가능하다.
  • Nginx서버에서 프록시 되어 있기 때문에 외부서버에선 프론트엔드 서버에만 접근이 가능하다.
  • 데이터베이스 컨테이너는 포트포워딩 자체가 안되어있기 때문에 외부에서 접근이 불가능하다.
  • 데이터베이스 컨테이너는 백엔드 컨테이너와 레코드를 통해 연결이 되어있기 때문에 백엔드 컨테이너를 통해서 접근이 가능하다.



동적 서버 설정

  • Nginx서버에서 WAS 주소를 고정해서 설정해야한다.
  • 그런데 환경 별로 Nginx가 프록시 해야하는 주소는 변할 수 있다.
  • 그래서 프록시 설정의 주소를 바꾸기 위해선 이미지 빌드를 다시 해야한다.
  • 이렇게 환경 별로 달라지는 프록시 해야하는 주소같은 정보는 시스템 환경 변수로 처리하면 컨테이너 실행시 결적할 수 있다.
  • 이러한 설정을 동적 서버 설정이라 한다.

동적 서버 설정 방법

image

  • 프론트엔드의 설정 파일을 수정하여 프록시 설정 주소를 변수로 지정하여 동적으로 값이 지정되도록 설정한다.

image

  • Dockerfile을 수정하여 소스코드의 nginx.conf파일을 template 파일로 복사하고, 동적으로 지정될 기본 환경 변수를 지정한다.



PostgreSQL 이중화 DB 구성

image

  • 만약, 단일 서버로 구성하면 하나의 서버에 장애 발생 시 전체 서비스의 장애로 이어지게된다.
  • 하나의 서버에 장애가 발생하더라도 동일한 다른 서버가 동일한 역할을 수행할 수 있도록 고가용성을 보장하기 위해서 서버를 이중화하여 구성한다.

image

  • 서버 이중화 DB를 구성하는 방법은 2가지이다.
  • 첫번째는 여러 DB서버가 하나의 볼륨을 사용하는 방법이다. 이 구성은 간단하지만 볼륨의 문제가 발생할 경우 대처가 어렵다.
  • 두번째는 여러 DB서버가 각각 하나씩의 볼륨을 사용하는 방법이다. 이 구성은 성능에 부하가 발생할 수 있고, 데이터의 싱크를 항상 맞추기 위해서 별도의 처리가 필요하다.

image

  • 프라이머리-스탠바이 복제 구조
    • 하나의 프라이머리 서버에서만 쓰기 작업이 수행되고, 스탠바이 서버는 읽기 전용으로 사용된다.
    • 프라이머리 서버의 상태가 변경되었을 경우 스탠바이 서버에 상태를 복제한다.
    • 읽기 전용 스탠바이 서버는 여러개의 서버로 사용가능하다.
  • 프라이머리-프라이머리 복제 구조
    • 모든 서버에 읽기/쓰기 작업이 수행된다.
    • 여러 서버에서 동시에 쓰기 작업이 일어나 동기화 구성 작업이 매우 복잡하다.

프라이머리-스탠바이 이중화 DB 구성

image

image image

  • 프라이머리와 스탠바이 노드를 같은 방식으로 실행한다.

image

  • 프라이머리 노트에는 테이블 생성 및 데이터 삽입과 같이 쓰기 작업을 수행하도록 한다.
  • 스탠바이 노드에 프라이머리의 데이터가 동기화되어 있는지 확인한다.



컨테이너 내부에서 개발

일반 서버에서 개발할 때 문제점

  • 개발자의 PC마다 설치된 언어 및 라이브러리 버전을 완전히 일치시키기 어려움
  • 개발 환경과 배포 환경이 다를 경우 배포 시 장애 발생
  • 새로운 개발자 합류 시 개발 환경 설버에 시간이 많이 필요하고, 개발 환경이 변화에도 많은 시간이 필요함
  • 한명이 여러 프로젝트를 담당할 경우 각 프로젝트의 환경이 모두 달라야 하는 경우 프로젝트들이 한 번에 하나의 PC에서 관리되기 힘듦

도커 컨테이너 내부에서 개발

image

  • 도커를 활용하면 같은 이미지를 활용하여 개발자의 PC들과 배포 서버의 환경을 완전히 일치시킬 수 있다.
  • IDE의 원격 개발 환경 기능을 통해 각 컨테이너별로 격리된 개발 환경을 구성할 수 있다.
  • 개발자의 PC에 프로젝트에 필요한 언어와 라이브러리의 설치가 필요가 없어 유지가 쉽다.

image

  • json파일을 통해서 일관된 개발환경을 구성할 수 있다.
  • forwardPosts로 오픈할 포트를 입력한다. 명령어 -p와 같은 역할을 한다.
  • postCreateCommand로 개발환경에 필요한 라이브러리를 설치하는 명령어를 입력하여 실행하도록 한다.
  • 다른 개발자와 같은 json 파일을 사용하여 개발환경을 일관되게 유지할 수 있다.

image

  • 실제로 개발을 수행할 컨테이너를 정의하는 도커파일을 생성한다.
  • FROM 지시어로 베이지 이미지로 노트 14버전을 사용한다.
  • RUN 지시어로 운영체제의 패키지를 업데이트하고 필요한 유틸들을 설치한다.
  • ARG 지시어를 사용하여 node라는 사용자에게 적절한 권한을 부여한다.
  • ENV 지시어를 사용하여 개발용컨테이너라는 것을 명시한다.