728x90

라이브  DB DDL 작업을 하게 될때는 항상 주의를 해야 한다.   보통 회사들의 경우에는  master ->  slave 구조를 채택하고 있는데 이때 복제 지연이 생길 수 있기 떄문에 항상 주의를 기울여야 한다.

 


1. 복제 지연의 원인
DDL 작업(특히 `ALTER TABLE`을 통한 컬럼 추가)은 데이터베이스 복제 환경에서 지연을 유발할 수 있습니다. `NOT NULL` 또는 `DEFAULT` 값을 추가할 때 복제 지연이 발생하는 주요 원인은 다음과 같습니다:

테이블 재구성(Table Rewrite): MySQL과 같은 일부 데이터베이스에서는 `NOT NULL` 또는 `DEFAULT` 값을 가진 컬럼을 추가할 때 테이블을 재구성해야 합니다. 이 과정에서 기존 데이터에 대해 새로운 컬럼 값을 채우거나 업데이트하는 작업이 필요하며, 이로 인해 대량의 데이터 복사 및 디스크 I/O가 발생합니다. 복제 노드에서도 동일한 작업이 반복되므로 지연이 발생할 수 있습니다.


잠금(Locking): `NOT NULL` 제약 조건을 추가하거나 `DEFAULT` 값을 설정하면 테이블에 잠금이 걸릴 수 있습니다. 이는 주로 MySQL의 InnoDB와 같은 엔진에서 테이블 전체를 스캔하거나 업데이트할 때 발생하며, 잠금으로 인해 복제 노드에서 트랜잭션이 지연될 수 있습니다.


메타데이터 동기화: PostgreSQL 11 이전 버전이나 Oracle 11g 이전 버전에서는 `NOT NULL`과 `DEFAULT` 값을 추가할 때 모든 로우에 대해 값을 삽입하거나 업데이트해야 했습니다. 이 과정은 복제 노드에서도 동일하게 수행되며, 대규모 테이블에서는 시간이 오래 걸립니다.


복제 방식에 따른 지연: 비동기 복제 환경(예: MySQL의 기본 복제)에서는 마스터에서 실행된 DDL이 슬레이브에 순차적으로 적용됩니다. 대량의 데이터가 포함된 테이블에서 DDL 작업이 느리게 처리되면 복제 지연이 발생합니다.

 

 


2. 데이터베이스별 동작 및 개선 사항
MySQL
문제: MySQL에서 `NOT NULL` 또는 `DEFAULT` 값을 가진 컬럼을 추가하면 테이블 재구성이 필요하며, 이는 테이블 크기에 따라 시간이 오래 걸립니다. Online DDL(예: `ALGORITHM=INPLACE`)를 사용하더라도 `NOT NULL` 제약 조건 추가는 잠금을 유발할 수 있습니다.


해결 방안:
Online DDL 활용: MySQL 5.6 이상에서는 `ALGORITHM=INPLACE`와 `LOCK=NONE`을 사용해 잠금을 최소화할 수 있습니다. 

ALTER TABLE table_name ADD COLUMN new_column VARCHAR(50) NOT NULL DEFAULT 'value', ALGORITHM=INPLACE, LOCK=NONE;

 



두 단계로 나누기: 컬럼을 먼저 `NULL` 허용으로 추가한 뒤, `DEFAULT` 값을 설정하고 마지막에 `NOT NULL` 제약 조건을 추가하면 잠금 시간을 줄일 수 있습니다.

 

ALTER TABLE table_name ADD COLUMN new_column VARCHAR(50);
ALTER TABLE table_name MODIFY COLUMN new_column VARCHAR(50) DEFAULT 'value';
ALTER TABLE table_name MODIFY COLUMN new_column VARCHAR(50) NOT NULL;


  

  pt-online-schema-change 사용: Percona Toolkit의 `pt-online-schema-change`를 사용하면 테이블을 복사해 DDL을 적용하고, 데이터를 점진적으로 동기화해 복제 지연을 최소화할 수 있습니다.

PostgreSQL
문제: PostgreSQL 11 이전에서는 `NOT NULL`과 `DEFAULT` 값을 가진 컬럼 추가 시 모든 로우를 업데이트해야 했습니다. 이는 대규모 테이블에서 복제 지연을 유발합니다.

 


개선 사항: PostgreSQL 11부터는 `NOT NULL`과 `DEFAULT` 값을 추가할 때 메타데이터만 업데이트하고 실제 데이터는 필요 시 점진적으로 채워집니다. 이는 복제 지연을 크게 줄입니다.

ALTER TABLE table_name ADD COLUMN new_column VARCHAR(50) NOT NULL DEFAULT 'value';

  이 작업은 메타데이터에 기본값을 저장하고, 로우 액세스 시 기본값을 동적으로 적용합니다.


해결 방안:
  - PostgreSQL 11 이상을 사용해 메타데이터 기반 컬럼 추가를 활용.
  - 대규모 테이블에서는 트랜잭션을 작은 단위로 나누거나, 백그라운드 작업으로 데이터를 채우는 스크립트를 작성.


Oracle
문제: Oracle 11g 이전에서는 `NOT NULL`과 `DEFAULT` 값을 가진 컬럼 추가 시 모든 로우에 대해 업데이트가 발생해 복제 지연이 발생했습니다.
개선 사항: Oracle 11g부터는 `NOT NULL` 컬럼 추가 시 메타데이터에 기본값을 저장하고, 실제 데이터는 로우가 업데이트/삽입될 때 적용됩니다. 이는 복제 지연을 줄입니다.


해결 방안:
  - Oracle 11g 이상을 사용.
  - 컬럼 추가와 `DEFAULT` 값 설정을 별도로 수행해 잠금을 최소화:

ALTER TABLE table_name ADD (new_column VARCHAR2(50));
    ALTER TABLE table_name MODIFY (new_column DEFAULT 'value');
    ALTER TABLE table_name MODIFY (new_column NOT NULL);




3. 복제 지연 최소화 전략
1. 사전 테스트: 개발 환경에서 동일한 데이터 크기와 복제 설정으로 DDL 작업을 테스트해 예상 소요 시간을 확인합니다.
2. 점진적 적용:
   - 컬럼을 `NULL` 허용으로 추가한 뒤, 배치 작업으로 기존 데이터를 채우고 마지막에 `NOT NULL` 제약 조건을 추가합니다.
   - 예: MySQL에서 배치 업데이트 스크립트:

UPDATE table_name SET new_column = 'default_value' WHERE new_column IS NULL LIMIT 1000;

 


     이를 반복 실행해 부하를 분산.
3. 복제 지연 모니터링: MySQL의 `SHOW SLAVE STATUS` 또는 PostgreSQL의 `pg_stat_replication`을 사용해 복제 지연을 실시간으로 모니터링합니다.


4. 유지보수 시간대 활용: 트래픽이 낮은 시간대에 DDL 작업을 수행해 복제 지연의 영향을 최소화합니다.


5. 도구 활용:
   - MySQL: `pt-online-schema-change` 또는 `gh-ost`를 사용.
   - PostgreSQL: 최신 버전(11 이상) 사용.
   - Oracle: 메타데이터 기반 DDL 활용.


6. 복제 방식 변경: 가능하면 비동기 복제 대신 반동기(semi-synchronous) 복제나 동기 복제를 고려해 지연을 줄입니다.


4. 주의사항
기존 데이터 확인: `NOT NULL` 제약 조건을 추가하기 전에 기존 데이터가 모두 유효한 값으로 채워져 있는지 확인합니다. 그렇지 않으면 에러가 발생할 수 있습니다.
트랜잭션 로그 크기: 대규모 테이블에서 DDL 작업은 트랜잭션 로그를 많이 사용할 수 있으므로, 디스크 공간과 로그 설정을 확인합니다.


복제 환경 테스트: 복제 지연은 복제 노드의 하드웨어 성능, 네트워크 대역폭, 복제 설정에 따라 달라질 수 있으므로 실제 환경에서 테스트가 중요합니다.



5. 예제: MySQL에서 복제 지연 최소화

 

1. 컬럼 추가 (NULL 허용)

ALTER TABLE table_name ADD COLUMN new_column VARCHAR(50), ALGORITHM=INPLACE, LOCK=NONE;



ALTER TABLE table_name ADD COLUMN new_column VARCHAR(50), ALGORITHM=INPLACE, LOCK=NONE;

2. 기존 데이터에 기본값 채우기 (배치로 실행)

UPDATE table_name SET new_column = 'default_value' WHERE new_column IS NULL LIMIT 1000;

 


3. DEFAULT 값 설정

ALTER TABLE table_name MODIFY COLUMN new_column VARCHAR(50) DEFAULT 'default_value', ALGORITHM=INPLACE, LOCK=NONE;

 

4. NOT NULL 제약 조건 추가

ALTER TABLE table_name MODIFY COLUMN new_column VARCHAR(50) NOT NULL, ALGORITHM=INPLACE, LOCK=NONE;

 

 

6. 결론
`NOT NULL` 또는 `DEFAULT` 값을 포함한 컬럼 추가는 데이터베이스 종류와 버전에 따라 복제 지연에 미치는 영향이 다릅니다. MySQL에서는 Online DDL과 단계적 적용, PostgreSQL 11 이상과 Oracle 11g 이상에서는 메타데이터 기반 작업을 활용해 지연을 최소화할 수 있습니다. 작업 전 충분한 테스트와 모니터링, 트래픽이 낮은 시간대를 활용하는 것이 중요합니다.

728x90

'코드 > dev' 카테고리의 다른 글

도커(Docker) 명령어  (0) 2025.04.22
도커(Docker) 컨테이너(Container)  (1) 2025.04.21
Bastion  (0) 2025.04.13
처리율 제한 알고리즘  (0) 2025.04.04
Nginx  (0) 2025.04.04
728x90

명령어 사용법 

* docker 를 사용을 위해  설치 부터 시작 해야한다

1. 우분투 시스템 패키지 업데이트
sudo apt-get update
2. 필요한 패키지 설치
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
 
3. Docker의 공식 GPG키를 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
 
4. Docker의 공식 apt 저장소를 추가
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
 
5. 시스템 패키지 업데이트
sudo apt-get update
6. Docker 설치
sudo apt-get install docker-ce docker-ce-cli containerd.io
 
7. Docker가 설치 확인
7-1 도커 실행상태 확인
sudo systemctl status docker
7-2 도커 실행
sudo docker run hello-world

 

 

 

1. Docker 이미지 (Image) 관리

  • docker images: 로컬 시스템에 저장된 Docker 이미지 목록을 보여줍니다.
    • 옵션:
      • -a 또는 --all: 중간 레이어 이미지까지 모두 표시합니다.
      • -q 또는 --quiet: 이미지 ID만 표시합니다.
      • --filter <key>=<value>: 특정 조건에 맞는 이미지만 필터링합니다 (예: --filter "label=com.example.version=1.0").
      • --format <template>: 원하는 형식으로 출력합니다 (Go template 사용).
  • docker search <term>: Docker Hub에서 특정 키워드로 이미지를 검색합니다.
    • 옵션:
      • --limit <count>: 검색 결과 개수를 제한합니다.
      • --filter <key>=<value>: 검색 결과를 필터링합니다 (예: --filter is-official=true).
  • docker pull <image_name>[:<tag>]: Docker Hub 또는 설정된 레지스트리에서 이미지를 다운로드합니다. 태그를 지정하지 않으면 latest 태그가 기본으로 사용됩니다.
  • docker push <image_name>[:<tag>]: 로컬 이미지를 Docker Hub 또는 설정된 레지스트리에 업로드합니다.
  • docker rmi <image_id_or_name> [...]: 로컬 이미지를 삭제합니다. 실행 중인 컨테이너에서 사용 중인 이미지는 삭제할 수 없습니다.
    • 옵션:
      • -f 또는 --force: 실행 중인 컨테이너가 있더라도 강제로 삭제합니다 (주의해서 사용).
      • --no-prune: 태그가 없는 (dangling) 이미지는 삭제하지 않습니다.

2. Docker 컨테이너 (Container) 관리

  • docker ps: 현재 실행 중인 컨테이너 목록을 보여줍니다.
    • 옵션:
      • -a 또는 --all: 모든 컨테이너 (실행 중, 중지됨)를 표시합니다.
      • -q 또는 --quiet: 컨테이너 ID만 표시합니다.
      • --filter <key>=<value>: 특정 조건에 맞는 컨테이너만 필터링합니다 (예: --filter "status=running").
      • --format <template>: 원하는 형식으로 출력합니다.
      • -n <last>: 최근 생성된 n개의 컨테이너만 표시합니다.
  • docker run [OPTIONS] <image_name>[:<tag>] [COMMAND] [ARG...]: 새로운 컨테이너를 생성하고 실행합니다.
    • 주요 옵션:
      • -d 또는 --detach: 백그라운드에서 컨테이너를 실행합니다.
      • --name <container_name>: 컨테이너 이름을 지정합니다.
      • -p <host_port>:<container_port>: 호스트와 컨테이너의 포트를 연결합니다 (포트 포워딩).
      • -v <host_path>:<container_path>[:<options>]: 호스트 디렉토리 또는 명명된 볼륨을 컨테이너에 마운트합니다 (데이터 영속성). 옵션으로는 ro (읽기 전용), rw (읽기/쓰기) 등이 있습니다.
      • -e <VARIABLE>=<value>: 컨테이너 내 환경 변수를 설정합니다.
      • --env-file <path>: 환경 변수 파일에서 환경 변수를 설정합니다.
      • --link <container_name>[:<alias>]: 다른 컨테이너와 링크합니다 (레거시 기능, 네트워크 사용 권장).
      • --network <network_name>: 컨테이너를 특정 네트워크에 연결합니다.
      • --rm: 컨테이너가 종료되면 자동으로 삭제합니다.
      • --restart <policy>: 컨테이너 종료 시 재시작 정책을 설정합니다 (no, on-failure, always, unless-stopped).
  • docker start <container_id_or_name> [...]: 중지된 컨테이너를 다시 시작합니다.
  • docker stop <container_id_or_name> [...]: 실행 중인 컨테이너를 정상적으로 종료합니다 (SIGTERM 후 유예 시간 후 SIGKILL).
  • docker kill <container_id_or_name> [...]: 실행 중인 컨테이너를 강제로 종료합니다 (SIGKILL).
  • docker restart <container_id_or_name> [...]: 실행 중인 컨테이너를 재시작합니다 (stop 후 start).
  • docker rm <container_id_or_name> [...]: 중지된 컨테이너를 삭제합니다. 실행 중인 컨테이너는 삭제할 수 없습니다.
    • 옵션:
      • -f 또는 --force: 실행 중인 컨테이너를 강제로 종료 후 삭제합니다 (주의해서 사용).
  • docker logs <container_id_or_name>: 컨테이너의 로그를 확인합니다.
    • 옵션:
      • -f 또는 --follow: 실시간으로 로그를 따라갑니다.
      • --since <time>: 특정 시간 이후의 로그만 표시합니다.
      • --until <time>: 특정 시간 이전의 로그만 표시합니다.
      • --tail <n>: 마지막 n개의 로그 라인만 표시합니다.
  • docker exec [OPTIONS] <container_id_or_name> <COMMAND> [ARG...]: 실행 중인 컨테이너 내부에서 명령을 실행합니다.
    • 옵션:
      • -it: 터미널을 할당하고 상호 작용 모드로 실행합니다 (쉘 접속 시 유용).
      • -u <user>: 특정 사용자로 명령을 실행합니다.
  • docker stats [<container_id_or_name>...]: 실행 중인 컨테이너의 자원 사용량 (CPU, 메모리, 네트워크 I/O 등)을 실시간으로 보여줍니다.
    • 옵션:
      • --no-stream: 한 번만 통계를 표시하고 종료합니다.
  • docker top <container_id_or_name>: 실행 중인 컨테이너 내부의 프로세스를 보여줍니다.
  • docker diff <container_id_or_name>: 컨테이너의 파일 시스템 변경 사항을 보여줍니다.

3. Docker 네트워크 (Network) 관리

  • docker network ls: Docker 네트워크 목록을 보여줍니다.
  • docker network create [OPTIONS] <network_name>: 새로운 Docker 네트워크를 생성합니다.
    • 주요 옵션:
      • -d 또는 --driver <driver>: 네트워크 드라이버를 지정합니다 (bridge, host, overlay 등). 기본은 bridge입니다.
      • --subnet <subnet>: 서브넷을 지정합니다.
      • --gateway <gateway>: 게이트웨이를 지정합니다.
  • docker network connect <network_name> <container_id_or_name>: 실행 중인 컨테이너를 네트워크에 연결합니다.
  • docker network disconnect <network_name> <container_id_or_name>: 컨테이너를 네트워크에서 분리합니다.
  • docker network inspect <network_id_or_name>: Docker 네트워크의 상세 정보를 확인합니다.
  • docker network rm <network_id_or_name> [...]: Docker 네트워크를 삭제합니다. 사용 중인 네트워크는 삭제할 수 없습니다.

4. Docker 볼륨 (Volume) 관리

  • docker volume ls: Docker 볼륨 목록을 보여줍니다.
  • docker volume create [OPTIONS] [<volume_name>]: 새로운 Docker 볼륨을 생성합니다.
    • 주요 옵션:
      • -d 또는 --driver <driver>: 볼륨 드라이버를 지정합니다 (local 등).
      • --opt <key>=<value>: 드라이버별 옵션을 설정합니다.
  • docker volume inspect <volume_name>: Docker 볼륨의 상세 정보를 확인합니다.
  • docker volume rm <volume_name> [...]: Docker 볼륨을 삭제합니다. 사용 중인 볼륨은 삭제할 수 없습니다.
  • docker volume prune: 사용하지 않는 로컬 볼륨을 모두 삭제합니다.

5. Docker Compose (Compose) 관련 명령어

Docker Compose는 여러 컨테이너로 이루어진 애플리케이션을 정의하고 실행하는 도구입니다. docker-compose.yml 파일을 기반으로 동작합니다. (별도 설치 필요)

  • docker-compose up [OPTIONS] [--scale <service>=<num>...] [SERVICE...]: Compose 파일을 기반으로 서비스를 생성하고 시작합니다.
    • 옵션:
      • -d 또는 --detach: 백그라운드에서 실행합니다.
      • --build: Dockerfile이 변경되었거나 이미지가 없는 경우 이미지를 빌드합니다.
      • --force-recreate: 컨테이너를 강제로 다시 생성합니다.
      • --scale <service>=<num>: 특정 서비스의 컨테이너 개수를 조정합니다.
  • docker-compose down [OPTIONS]: Compose 파일에 정의된 모든 서비스를 중지하고 삭제합니다.
    • 옵션:
      • --rmi <type>: 관련 이미지를 삭제합니다 (all, local).
      • -v 또는 --volumes: 명명된 볼륨까지 삭제합니다.
  • docker-compose ps [OPTIONS] [SERVICE...]: Compose 파일에 정의된 서비스의 상태를 보여줍니다.
  • docker-compose logs [OPTIONS] [SERVICE...]: 서비스의 로그를 확인합니다.
    • 옵션은 docker logs와 유사합니다 (-f, --since, --tail 등).
  • docker-compose exec [OPTIONS] <service> <command> [ARGS...]: 실행 중인 서비스의 컨테이너 내부에서 명령을 실행합니다.
    • 옵션은 docker exec와 유사합니다 (-it, -u).
  • docker-compose stop [SERVICE...]: 특정 서비스 또는 모든 서비스를 중지합니다.
  • docker-compose start [SERVICE...]: 중지된 특정 서비스 또는 모든 서비스를 시작합니다.
  • docker-compose restart [SERVICE...]: 특정 서비스 또는 모든 서비스를 재시작합니다.
  • docker-compose build [OPTIONS] [SERVICE...]: Compose 파일에 정의된 이미지를 빌드합니다.
  • docker-compose pull [SERVICE...]: 서비스가 사용하는 이미지를 다운로드합니다.
  • docker-compose config [OPTIONS]: Compose 파일의 유효성을 검사하고 설정 내용을 보여줍니다.

6. 기타 유용한 명령어

  • docker info: Docker 시스템의 전반적인 정보를 보여줍니다 (컨테이너 수, 이미지 수, 커널 버전 등).
  • docker version: Docker 클라이언트 및 서버 버전을 보여줍니다.
  • docker system df: Docker 관련 디스크 사용량을 보여줍니다 (이미지, 컨테이너, 볼륨, 빌드 캐시).
  • docker system prune [OPTIONS]: 사용하지 않는 Docker 리소스 (중지된 컨테이너, 사용하지 않는 네트워크, dangling 이미지, 빌드 캐시)를 삭제하여 디스크 공간을 확보합니다.
    • 옵션:
      • -a 또는 --all: 사용하지 않는 이미지뿐만 아니라 사용하지 않는 모든 이미지를 삭제합니다.
      • --volumes: 사용하지 않는 익명 볼륨도 삭제합니다.

이 명령어들은 Docker를 사용하는 데 있어 가장 기본적인 부분이며, 익숙해질수록 Docker를 더욱 효율적으로 관리하고 활용할 수 있습니다. 필요에 따라 각 명령어의 옵션을 참고하여 사용하시면 됩니다.

 
 
 
728x90

'코드 > dev' 카테고리의 다른 글

DDL 작업 중 복제지연 원인과 해결 방안  (3) 2025.05.22
도커(Docker) 컨테이너(Container)  (1) 2025.04.21
Bastion  (0) 2025.04.13
처리율 제한 알고리즘  (0) 2025.04.04
Nginx  (0) 2025.04.04
728x90

Docker Container는 애플리케이션과 그 실행에 필요한 모든 것(코드, 라이브러리, 설정 등)을 담고 있는, 격리된 실행 환경이다.

 

도커 컨테이너는 프로세스의 라이프 사이클을 관리한다.

프로세스가 생성되고 운영되고 제거되기까지 생애주기를 관리를 하기 위해 필요한 것이 격리이다.

 

 

컨테이너 안의 프로세스는 제한된 자원내에서 제한된 사용자만 접근 가능하다. 

컨테이너는 Host OS 시스템 커널을 사용한다.

 

가상머신과 컨테이너의 차이

 

Hypervisor란 단일 물리적 머신에서 여러개의 가산 머신을 실행할 수 있게 해주는 소프트웨어이다.

 

HostOS 에서는 직접 실행하거나 컨테이너 안에서 실행되나 동일한 시스템으로 인식된다.

 

위와 같이 독립적인 파일시스템이 생성된다.

 

 

 

특징

 

 

  • 독립적인 실행 환경: 컨테이너 안에는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 라이브러리, 시스템 도구, 런타임 등)이 담겨 있습니다. 마치 캡슐처럼 외부 환경과는 완전히 분리되어 있어서, 어떤 환경에서든 동일하게 실행될 수 있습니다.
  • 가볍고 빠름: 가상 머신(VM)과는 달리, 컨테이너는 운영체제(OS) 커널을 공유하기 때문에 훨씬 가볍고 빠르게 실행됩니다. 새로운 컨테이너를 시작하거나 중지하는 데 몇 초밖에 걸리지 않아요.
  • 이식성: 개발 환경에서 만든 컨테이너 이미지를 그대로 테스트 환경, 운영 환경 등 어떤 Docker 환경에서도 실행할 수 있습니다. 마치 포장된 제품처럼 어디든 쉽게 옮겨갈 수 있죠.
  • 확장성: 필요에 따라 컨테이너를 쉽게 복제하고 확장할 수 있습니다. 트래픽이 증가하면 컨테이너 수를 늘리고, 줄어들면 줄이는 방식으로 유연하게 대처할 수 있습니다.
  • 자원 효율성: 하나의 호스트 OS 위에서 여러 개의 컨테이너가 독립적으로 실행되므로, 시스템 자원을 효율적으로 사용할 수 있습니다.

 

 

사용하는 이유 

  • 개발과 배포의 일관성 유지: 개발 환경과 운영 환경의 차이로 인해 발생하는 문제를 줄여줍니다.
  • 빠른 배포 및 롤백: 애플리케이션 배포와 이전 버전으로의 롤백이 간편하고 빠르게 이루어집니다.
  • 애플리케이션 격리 및 보안 강화: 각 컨테이너는 독립적으로 실행되므로, 하나의 컨테이너에 문제가 발생해도 다른 컨테이너에 영향을 주지 않습니다.
  • 마이크로서비스 아키텍처 구현 용이: 작은 기능 단위로 분리된 마이크로서비스들을 각각의 컨테이너로 관리하고 배포하기에 용이합니다.

 

도커 컨테이너 네트워크

컨테이너 생성시 독자적인 파일시스템이 생성되는데  컨테이너 안에 맥 주소와 IP 주소가 할당된다. 

 

도커 컨테이너 실행 시 파일시스템

 

 

 

1.컨테이너를 생성하면, veth가 생성되고 컨테이너 내의 eth0과 연결됩니다.

2.컨테이너들의 veth들은 docker0를 통해 컨테이너들간에 통신이 가능합니다.

3.컨테이너는 gateway인 docker0를 거쳐 외부와 통신합니다.

 

 

컨테이너 IP를 일일이 확인하기 어렵고, 외부로 오는 요청은 Host NIC로 온다 이 2문제를 해결하기 위해 포트포워딩을 활용.

 

Host OS의 80 포트번호를 사용하는 소켓 파일과 컨테이너 내의 80 포트번호를 사용하는 소켓 파일을 연결.

728x90

'코드 > dev' 카테고리의 다른 글

DDL 작업 중 복제지연 원인과 해결 방안  (3) 2025.05.22
도커(Docker) 명령어  (0) 2025.04.22
Bastion  (0) 2025.04.13
처리율 제한 알고리즘  (0) 2025.04.04
Nginx  (0) 2025.04.04
728x90

Bastion이란?

 

성형 요새에서 돌출 지점마다 건설된 포루를 의미한다. 이때에는 능보, 치성이라고도 흔히 번역된다. 요새나 보루로 잘못아는 경우가 많은데 그렇게 큰 전체를 의미하지는 않는다. 딱 돌출부만 칭하는 단어다.

 

Bastion 서버는 보안 강화를 위해 설계된 특별한 서버로, 외부 네트워크(예: 인터넷)와 내부 네트워크(예: 사설망) 사이에 위치하여 내부 네트워크로의 접근을 제어하고 보호하는 역할을 한다. 마치 중세 시대 성곽의 '보루'와 같은 역할을 수행하기 때문에 Bastion이라는 이름이 붙었다.

 

 

주요 목적과 기능

 

 

  • 단일 접근 지점 제공: 외부 네트워크에서 내부 네트워크의 여러 서버에 직접 접근하는 것을 차단하고, Bastion 서버를 통해서만 접근을 허용. 이는 내부 네트워크의 보안을 크게 강화한다.
  • 접근 제어 및 인증: 누가 언제 내부 네트워크에 접근하려고 하는지 Bastion 서버에서 관리하고 인증한다. 이를 통해 허가된 사용자만 내부 자원에 접근할 수 있도록 통제한다.
  • 보안 감사 및 로깅: Bastion 서버를 통한 모든 접근 시도 및 활동을 기록하고 감사할 수 있습니다. 이는 보안 사고 발생 시 원인을 분석하고 추적하는 데 중요한 정보를 제공합니다.
  • 보안 강화: Bastion 서버 자체에 강력한 보안 설정을 적용하여 외부 공격으로부터 보호합니다. 불필요한 서비스 제거, 최신 보안 패치 적용, 다단계 인증(MFA) 적용 등이 일반적인 보안 강화 방법입니다.
  • 프록시 역할: Bastion 서버는 내부 네트워크로 연결을 중계하는 프록시 서버 역할을 수행하여, 내부 서버의 실제 IP 주소를 외부에 노출시키지 않아 추가적인 보안 이점을 제공합니다.

 

 

활용 및 사용 

  • 클라우드 환경: AWS, Azure, GCP 등의 클라우드 환경에서 외부에서 가상 네트워크(VPC) 내부의 인스턴스에 안전하게 접근하기 위해 사용된다.
  • 기업 내부 네트워크: 외부 협력업체나 재택근무자가 사내 네트워크의 특정 서버에 접근해야 할 경우, Bastion 서버를 통해 보안을 유지하면서 접근 권한을 부여할 수 있다.
  • 원격 관리: 시스템 관리자가 외부에서 서버를 관리해야 할 때, Bastion 서버를 통해 안전하게 접속하여 작업을 수행할 수 있다.

요약하자면, Bastion 서버는 외부의 잠재적인 위협으로부터 내부 네트워크와 중요한 자산을 보호하기 위한 핵심적인 보안 구성 요소이다.

728x90

'코드 > dev' 카테고리의 다른 글

도커(Docker) 명령어  (0) 2025.04.22
도커(Docker) 컨테이너(Container)  (1) 2025.04.21
처리율 제한 알고리즘  (0) 2025.04.04
Nginx  (0) 2025.04.04
네트워크 연결 확인 방법: ping, telnet, curl 활용  (0) 2025.04.04
728x90

토큰 버킷(Token Bucket)

토큰 버킷(Token Bucket)은 네트워크 트래픽이나 시스템 자원을 관리하기 위해  사용되는 속도 제한(Rate Lmiting) 알고리즘이다.

주로 요청 처리 속도를 일정하게 유지하거나 과도한 사용을 방지하는 데 활용 된다. 

 

 

 

 

 

동작원리

bucket 이라는 토큰을 담는 컨테이너

토큰 공급기는 주기적으로 bucket에 토큰을 채워줌 

토큰이 꽉찬 버킷에는 토큰 추가되지 않고 버려진다.

각 요청마다 하나의 토큰 사용(토큰이 있는 경우 버킷에서 토큰을 할당, 충분한 토큰이 없는 경우 해당 요청 drop)

 

장/단점

  • 간단함, 유연성(버스트 허용시), 평균 속도 유지.
  • 버스트로 인한 부하, 세밀한 제어 부족, 설정의 복잡함

 

누출 버킷 알고리즘(leaky bucket)

토큰 버킷과 비슷하게 트래픽제어나 속도제한(Rate Limiting)에 사용되는 알고리즘이지만, 동작 방식과 특징에서 차이가 있다.

누출 버킷은 물이 담긴 양동이에 비유할 수 있다. 양동잉 바닥에 작은 구멍이 있어 물이 일정한 속도로 새어 나가고, 물(데이터)이 양동이에 너무 빨리 들어오면 넘치게 된다.

동작원리

버킷에 데이터 입력

일정한 속도로 출력 

버킷이 비었을때  - 새 데이터가 들어올떄까지 아무 액션도 일어나지 않는다.

트래픽 평활화 - 데이터가 갑자기 많이 들어와도 버킷에서 나가는 속도는 같다.

 

장/단점

  • 출력 트래픽 평활화,  시스템 과부하 덜 취약(일정한 출력 속도), 간단한 구현(토큰 버킷 대비)
  • 버스트 불허용, 데이터 손실 가능성 (버킷이 꽉차면 버려짐), 지연 발생(데이터 쌓이면 대기시간이 늘어난다)

 

고정 윈도 카운터 알고리즘(fixed window Counter)

속도 제한(Rate Limiting)을 구현하는 데 사용되는 간단한 방법중 하나이다. 주로 API 요청이나 네트워크 트래픽 제어 활용, 시간단위를 고정된 윈도로 나누어 처리량을 관리한다.

 

 

 

동작원리

시간 윈도 설정 - 시간을 고정된 간격으로 나눈다 ex)  1분을 하나의 윈도로 설정

카운터 관리 - 각 윈도 마다  카운터가 있어 들어오는 요청 추적하여 관리

요청 처리 - 요청이 들어오면 카운터 1씩 증가 (최대 허용치 넘지 않게 처리하면 넘을 경우 거부하거나 대기)

윈도 리셋 - 정해진 시간이 지나면 윈도가 끝나고 카운터가 0으로 리셋 되며 새로운 윈도가 시작된다.

 

 

장/단점

  • 구현이 간단하고 메모리 효율성이 좋다. 예측 가능성(고정된 시간동알 일정 요청수 보장)
  • 윈도 경계문제(윈도 끝과 시작 점이 트래픽이 물릴경우 동작 하지 않을 수 있음)
  • 유연성이 부족하고, 짧은시간 단위 제어가 어려움

이동 윈도 로깅 알고리즘(sliding wondow log)

고정 윈도 카운터 알고리즘의 단점을 보완하기 위해 개발되어졌다.

 

동작원리

타임스탬프 추적 - 각 요청의 타임스탬프를 기록 하고 캐시(redis)에 저장

만료된 타임스탬프 제거 - 새로운 요청이 들어오면 현재 윈도의 시작 시점보다 오래된 타임스탬프 제거

새 요청 타임스탬프 추가 - 새로운 요청의 타임스탬프 로그 추가

요청 처리 결정 - 로그의 크기가 허용치보다 작거나 같으면 요청을 시스템에 전달 아닌경우 거부

 

장/단점

  • 호용되는 요청의 개수는 시스템 처리율 한도를 넘지 않는다. 
  • 짧은시간 에 몰리는 트래픽에도 대응 가능
  • 거부된 요청의 타임스탬프도 보관하여 다량의 메모리가 필요할 수 있다.

 

이동 윈도 알고리즘(sliding wondow counter)

고정 윈도 카운터 +  이동 윈도 로그 결합 한 방식

 

 

동작원리

현재 윈도 요청 수 계산- 현재 시간부터 과거 특정 시간까지 요청 수 계산.

이전 윈도 요청 수 계산 - 이전 시간부터 과거 특정 시간까지 요청 수 계산

가중 평균 계산 - 현재 윈도와 이전 윈도의 요청수를 가중 평균하여 현재 윈도 요청 수 추정

요청 처리 결정 - 추정된 요청 수가 허용치보다 적거나 같으면 요청을 시스템에 전달 그렇지 않으면 요청 거부

 

 

장/단점

  • 짧은시간 몰리는 트래픽에도 대응 가능, 메모리 효율이 좋다.
  • 이전 시간대에 도착한 요청이 균등하게 분포되어 있다고 가정한 상태에서 추정치를 계산하기에 다소 느슨.

 

실제 스프링부트에서 사용가능한 대표 라이브러리들은 

Bucket4j - 토큰 버킷 알고리즘 기반 java 속도 제한 라이브러리로 동시lock-free한 구현으로 멀티스레딩 환경에서 확정이 우수하면 추가적인 동시성 전략도 제공.

Guava - 구글에서 개발한 라이브러리로 토큰 버킷 알고리즘 기반

RateLimitJ - 이동 윈도 알고리즘 기반. java 속도제한 라이브러리

 

 

 

특정 업체의 요청량이 워낙 적어서  개발중이 서버에는  이동 윈도 알고리즘(rateLimitJ)을 적용하여    초당 제한량을 제한하여 최대한 안전성 을 높여 처리하도록 구현하였다.

 

 

 

728x90

'코드 > dev' 카테고리의 다른 글

도커(Docker) 컨테이너(Container)  (1) 2025.04.21
Bastion  (0) 2025.04.13
Nginx  (0) 2025.04.04
네트워크 연결 확인 방법: ping, telnet, curl 활용  (0) 2025.04.04
subnet mask 서브넷팅 계산법  (0) 2025.04.03
728x90

Nginx는 고성능 웹서버, 리버스 프록시 서버, 메일 프록시 서버로 사용되는 오픈 소스 소프트웨어이다.

Nginx는 특히 높은 동시 접속 처리 능력과 낮은 메모리 사용량으로 유명하다.

주요특징

웹서버 - 정적 콘텐츠(HTML, CSS, 이미지 등)를 빠르게 제공하며, Apach 같은 전통적인 웹서버보다 효율적

리버스 프록시 - 클라이언트 요청을 백엔드 서버로 전달하고 로드 밸런싱(부하 분산)을 통해 트래픽을 여러 서버에 
분산할 수 있다.

비동기 이벤트 기반 구조 - 다수의 동시 접속을 처리하기 위해 스레드 대신 비동기 이벤트 루프를 사용해 성느을 극대화

로드 밸런싱 - HTTP, TCP, UDP 트래픽을 여러 서버로 분산하여 가용성과 안전성을 높인다.

캐싱 및 압축 - 콘텐츠 캐싱과 Gzip 압축을 지원해 응답 속도를 개선

보안 - SSL/TLS 암호화를 지원, DDOS 공격 방어와 같은 보안 기능도 설정 가능

 

 

사용사례

정적 파일 제공 - 이미지 비디오 등 정적 콘텐츠를 빠르게 서빙

애플리케이션 프록시 - nodejs, python flask, ruby 등  애플리케이션 서버 앞단에 배치

로드밸런서 - 트래픽이 많은 사이트에서 서버 부하 분산

CDN - 콘텐츠 전송 네트워크 - 캐싱을 활용해 전 세계 사용자에게 빠른 응답 제공

 

 

 

리버스 프록시(reverse proxy)

클라이언트 요청을 대신 받아 내부 서버로 전달하는 것

하나 이상의 웹 서버 앞에 위치하여 클라이언트의 요청을 가로채는 서버이다.  프록시가 클라이언트 앞에 위치하는 포워트 프록시와는 다르다.

리버스 프록시는 클라이언트가 웹 사이트 원본 서버 요청 보낼때  리버스 프록시 서버가 네트워크 에지에서 해당 요청을 가로챈다.

그 다음 리버스 프록시 서버가 원본 서버에 요청을 보내고 응답을 받는다.

 

 

리버스 프록시를 사용하는 이유

  • 부하 분산
  • DDOS 등의 공격으로부터 보호
  • 전역 서버 부하 분산
  • 캐싱 
  • SSL 암호화

 

 

 

 

포워드 프록시(forward proxy)

정방향 프록시는 클라이언트 시스템 그룹 앞에 위치하는 서버dl다. 이러한 컴퓨터가 인터넷의 사이트 및 서비스에 요청하면 프록시 서버가 이러한 요청을 가로채고 중개자처럼 해당 클라이언트를 대신하여 웹 서버와 통신.

 

포워드 프록시를 사용하는 이유는 

  • 주 당국 또는 기관의 검색 제한을 피하기 위해 
  • 특정 콘텐츠에 대한 액세스를 차단
  • 온라인에서 자신의 신원을 보호

 

 

 

 

 

요약하면 정방향 프록시는 클라이언트 앞에 위치하며 원본 서버가 해당 특정 클라이언트와 직접 통신하지 못하도록 하는 것 이다. 반면에 리버스 프록시는 원본 서버 앞에 위치하며 어떤 클라이언트도 원본 서버와 직접 통신하지 못 하도록 한다.

 

 

728x90

'코드 > dev' 카테고리의 다른 글

Bastion  (0) 2025.04.13
처리율 제한 알고리즘  (0) 2025.04.04
네트워크 연결 확인 방법: ping, telnet, curl 활용  (0) 2025.04.04
subnet mask 서브넷팅 계산법  (0) 2025.04.03
Internet Gateway & NAT Gateway  (0) 2025.04.02

+ Recent posts