클라우드 네이티브 애플리케이션 (Cloud Native Application)
-
클라우드
- 다른 회사의 서버를 빌려서 운영
- 퍼블릭 클라우드: 누구나 사용할 수 있는 클라우드 서비스 (e.g. Azure, AWS, GCP)
-
프라이빗 클라우드: 특정 조직만 사용할 수 있는 클라우드 서비스 (e.g. 조직 내 계열사)
- 보안과 비용이 보다 효율적
- 특징
- 요청 즉시 서버를 생성 (Provisioning)
- 스토리지 저장소에 가상화 기술을 활용
- 사용자가 서버를 구매할 때마다 스펙에 맞는 VM을 만들어 제공
- 사용 시간만 비용 지불 (직접 서버를 운영음 비용이 매우 큼)
- 요청 즉시 서버를 생성 (Provisioning)
-
현대 애플리케이션의 다양한 문제를 해결
- 확장성 (Scalability) : 트래픽 증가에 유연하고 빠르게 대처
- 복원력 (Resilience) : 장애 발생 시 빠르게 복구
- e.g. 서울 데이터 센터에 장애가 났을 때 부산 데이터 센터의 서버로 트래픽 전환 (Disaster Recovery, 복구에 사용하는 서버)
- 효율적인 운영 비용 처리 : 전문 아키텍트의 적절한 서버 구성과 끊임없는 최적화 필요
- -> 클라우드는 시작점이고 애플리케이션이 클라우드에 적합하지 않으면 큰 의미 없을 수 있음
- 다른 회사의 서버를 빌려서 운영
-
클라우드 네이티브 애플리케이션
- 클라우드 환경을 더 잘 활용할 수 있는 애플리케이션 구조
- 필요 사항
- MSA: 트래픽 증가에 빠르게 대처하기 위해선 애플리케이션이 MSA 구조로 개발되어야 함
- 컨테이너: 컨테이너를 활용해 실행 환경에 종속되지 않는 동작을 보장해야 함
- 무상태 (Stateless): 상태를 가지지 않는 애플리케이션 서버는 어디에나 즉시 배포 가능
- DevOps 및 CI/CD: 배포가 자동화되어야 하고 릴리즈가 빠르게 수행되어야 함
- 모놀리식과 MSA
- 잘 활용하면 클라우드 네이티브 애플리케이션으로서의 장점이 커서 MSA로 많이 전환하는 추세
- 모놀리식
- 모든 기능을 하나의 애플리케이션에 구성
- 수직 확장(Scale-Up) 주로 사용
- 장점
- 초반 개발 속도가 빠르다가 코드 베이스가 커질수록 느려짐
- 복잡성이 낮음
- 단점
-
트래픽 대처 능력 감소
- 하나의 애플리케이션 크기가 큼
- 애플리케이션 실행 시간이 오래 걸림
- 개발에 들어가는 빌드 시간 및 배포 시간도 오래 걸림
- 하나의 애플리케이션 크기가 큼
- 서버 확장 시 비효율적인 리소스 사용
- 실제 트래픽은 주문 기능에서만 나는데 상품관리, 회원관리도 함께 확장됨
-
트래픽 대처 능력 감소
-
MSA
- 도메인이나 기능별로 모듈을 분리해 서버 배포
- 수평 확장(Scale-Out) 주로 사용
- 장점
- 각각의 모듈의 크기가 감소해 서버 스케일 아웃 시간 빠름
- 스케일 아웃 시 효율적인 리소스 사용
- 트래픽이 늘어난 모듈만 서버 스케일 아웃 가능
-
모듈별로 완전히 독립됨
- 각각 다른 언어로 개발 가능
- 기능 장애 발생해도 다른 모듈에 영향 방지 가능
- 단점
- 초기 구성이 복잡하고 오래 걸림
- 복잡성이 높음
네트워크 기본
- 전세계가 물리적 케이블을 통해 전기 신호로 정보를 주고 받음 (먼 해외는 해저 케이블 사용)
-
IP
- 전 세계 인터넷상에서 유일한 주소 (동적 IP는 시간에 따라 변하지만 여전히 유일)
-
회선 당 하나 배정하므로 한 회선(공인 IP)을 사설 IP로 나눠 여러 기기가 동시에 IP 사용 가능
- 공인 IP: 집주소, 전세계에서 유일
- 사설 IP: 방번호, 소속된 네트워크 장비(공유기) 내에서 유일
- 사설 IP 주소 대역 (아래 범위 해당하는 주소는 모두 사설 IP)
- 10.0.0.0 — 10.255.255.255 (Class A)
- 172.16.0.0 - 172.31.255.255 (Class B)
- 192.168.0.0 — 192.168.255.255 (Class C)
- 사설 IP 주소 대역 (아래 범위 해당하는 주소는 모두 사설 IP)
-
공유기: 공인 IP를 사설 IP로 분리하는 장치
- e.g. IP Time
- WAN 포트: 공인 IP를 받는 인터넷 선을 꽂는 부분
- LAN 포트: 각각의 기기를 연결해서 사설 IP를 분배하는 곳
- 기업 네트워크 (아래보다 더 복잡)
- 공인망: 공인 IP 끼리 사용하는 네트워크 통신망
- 사설망: 라우터를 사용해 만들어진 내부 네트워크 통신망 (사설 IP 사용, 실제 서버에게 할당)
- 라우터: 공유기와 비슷한 역할
-
네트워크 인터페이스
- 인터넷에 연결하기 위해 컴퓨터에 장착하는 부품 중 하나
- 네트워크 인터페이스마다 IP를 할당 (사설 IP)
-
하나의 기기에는 한 개 이상의 네트워크 인터페이스 장착 가능
- e.g. 노트북 (유선 인터페이스, 무선 인터페이스)
-
포트
- 서버에 있는 프로세스들 중 어떤 프로세스에 데이터를 전달할지 지정
- IP 뒤에
:
붙여 지정 (e.g.192.168.0.5:8080
) - 물리적 존재 X, 서버 안에서 정의해 사용
- 네트워크를 사용하는 프로그램은 실행될 때 자신이 사용할 포트를 지정
- Well-Known 포트: 사전에 약속되어 있는 포트
- e.g. 웹서버 통신(80, 443), SSH(22), FTP(21)
- 네트워크 통신
- 아웃바운드 : 자신의 서버에서 출발하는 통신
- 인바운드 : 외부 서버에서 자신의 서버로 오는 통신
-
NAT (Network Address Translation) - 아웃바운드 통신에 사용
-
매핑 테이블 활용해 공인 IP와 사설 IP를 매핑해주는 기술
- 공인 IP의 랜덤한 포트를 여러 개 지정해두고 각각의 포트에 사설 IP 정보 매칭
- 사설망을 구성하는 라우터가 항상 가지는 기능 (자동 설정)
- 동적으로 정보를 관리하므로 외부에서 서버로 접근할 때는 혼란이 생김 (인바운드 통신)
- NAT 테이블 예시
- 아웃바운드 통신 발생 시 해당 사설 IP 주소 및 포트와 공인 IP 주소 및 포트를 저장
- 공인포트번호는 랜덤 지정
- 외부 서버는 공인 IP 주소
124.111.46.91:10001
을 출발지로 알고 응답을 보냄 - 라우터는 돌아온 정보를 NAT 테이블에서
192.168.0.4:80
으로 응답을 보냄
- 아웃바운드 통신 발생 시 해당 사설 IP 주소 및 포트와 공인 IP 주소 및 포트를 저장
-
매핑 테이블 활용해 공인 IP와 사설 IP를 매핑해주는 기술
-
포트 포워딩 (Port Forwarding) - 인바운드 통신에 사용
-
외부에서 사설망으로 접근할 때 사용하는 NAT 테이블 같은 매핑 정보 관리 기술
- 외부에서 공인 IP에 접근하면 포트 포워딩 룰에 맞는 사설 IP로 변환해 트래픽 전달
- 사용자가 직접 지정
- 포트포워딩 예시
- 외부 서버에서 공인 IP 주소
124.111.46.91:80
으로 요청 보냄 - 포트 포워딩 룰에 따라 요청은 사설 IP
192.168.0.4:80
으로 보내짐
- 외부 서버에서 공인 IP 주소
-
외부에서 사설망으로 접근할 때 사용하는 NAT 테이블 같은 매핑 정보 관리 기술
- DNS (Domain Name System)
- 도메인 주소와 공인 IP를 매핑해주는 기술 (도메인명 <-> IP 주소)
- 일반적인 엔터프라이즈 환경에서는 사내망에서 별도로 DNS 서버를 운영하기도 함
- 사내 서버들끼리 도메인으로 통신할 수 있도록 정보 제공
- DNS 서버 주소도 내부 DNS 서버의 IP로 지정
- DNS 예시
-
devwiki-docker.com
으로 요청을 보냄 - IP 주소가 8.8.8.8인 DNS 서버에 질문을 던져 도메인 주소에 해당하는 IP 주소 받음
- 요청은
124.111.46.91
로 전달됨
-
도커 가상 네트워크
- 가상 네트워크: 한 대의 서버 내에서 논리적으로 여러 네트워크를 구성하는 기술
- 물리적 네트워크 망에는 네트워크 인터페이스로 공인 IP 혹은 사설 IP가 할당된 PC(서버)가 존재
- 해당 서버 내에 가상 네트워크 구성
- SDN(Software Defined Network)라고도 함
-
도커는 가상 네트워크 기술을 활용해 컨테이너 네트워크를 구성
- e.g. 외부와 컨테이너의 통신, 컨테이너와 컨테이너의 통신
- 가상 네트워크 생성 과정
-
도커 설치 및 실행 시 다음 2가지 생성
-
브릿지(
docker0
): 가상 공유기-
가상의 IP 주소를 할당 받음 (일반적으로
172.17.0.1
) - 가상의 IP 주소: 서버 내 논리적으로 정의된 IP (실제 존재 X)
-
가상의 IP 주소를 할당 받음 (일반적으로
- 브릿지 네트워크: 가상 네트워크
-
브릿지(
-
컨테이너 실행 시
-
브릿지 네트워크의 IP 주소 범위 내에서 가상의 IP 주소 할당
- e.g.
172.17.0.2
,172.17.0.3
,172.17.0.4
,172.17.0.5
- 마치 공유기를 통해 사설 IP 할당되는 것과 비슷
- e.g.
-
브릿지 네트워크의 IP 주소 범위 내에서 가상의 IP 주소 할당
- 같은 브릿지에서 생성된 컨테이너는 브릿지를 통해 서로 통신 가능
- 도커는 여러개의 브릿지 네트워크 구성도 가능
-
도커 설치 및 실행 시 다음 2가지 생성
- 네트워크 신호 전달 과정
- 서버(PC)는 물리 네트워크 인터페이스에 인터넷 선을 연결해 공인 IP 혹은 사설 IP를 할당받음
- 해당 서버 내 도커 설치 후 실행 시
- 도커는 호스트 OS에 가상 인터페이스 1개 생성 (
docker0
)
- 도커는 호스트 OS에 가상 인터페이스 1개 생성 (
- 컨테이너 실행 시
-
호스트 OS에 각각 컨테이너에 해당하는 가상 인터페이스들 생성 (
Veth고유번호
)
-
호스트 OS에 각각 컨테이너에 해당하는 가상 인터페이스들 생성 (
- 전달: 물리 인터페이스 -> 호스트 OS -> 컨테이너 가상 인터페이스 -> 컨테이너
- 가상 인터페이스 간 통신은
iptables
를 활용해 규칙을 정의하고 소프트웨어적으로 패킷 전달-
iptables
- Linux OS의 패킷 필터링 시스템
- 내부 네트워크 트래픽 제어 및 라우팅 규칙 정의
-
특정 IP 주소로 네트워크를 보냈을 때 어떤 인터페이스로 전달할지에 대한 규칙 설정
- e.g. 규칙:
172.17.0.3
으로 향하는 요청은Veth2
인터페이스로 전달하자
- e.g. 규칙:
- 물리 네트워크 였다면, 네트워크 장치들이 알아서 해줌
-
- 참고: 호스트 OS -> 물리적 인터페이스 1개 : 가상 인터페이스 여러개 = 하드웨어 : 소프트웨어
- 가상 네트워크와 외부 통신 (포트포워딩)
- 아웃바운드 통신은 가상 네트워크가 알아서 NAT 사용
- 인바운드 통신은 요청이 원하는 컨테이너의 포트로 전달되도록 직접 포트포워딩 옵션 지정
- HOST OS의 포트는 아무거나 지정해도 상관 X
- 이미 등록된 포트는 중복 불가
- 의도적으로 포트포워딩을 하지 않으면, 컨테이너 간 통신만 허용
- e.g. DB 서버는 포트포워딩 없이 컨테이너 간 통신만 허용하여 외부 통신을 막음
- 도커 DNS
- 직접 생성한 브릿지 내 컨테이너가 사용할 수 있는 기본 DNS 서버 제공 (기본 브릿지 제외)
-
컨테이너 이름이 도메인으로 자동 저장됨
- e.g.
containerA - 10.0.02
,containerB - 10.0.03
- e.g.
- 컨테이너 간의 통신에 중요! -> 컨테이너 IP는 컨테이너 재시작 시 계속 바뀔 수 있어 불편
- 외부 DNS 서버와 연동되어 있어, 컨테이너 외부 도메인으로도 접근 가능 (e.g. 구글)
- 도커 네트워크 드라이버
-
브릿지 네트워크 (Bridge)
- 도커 브릿지를 활용해 컨테이너 간 통신 지원
- NAT 및 포트포워딩 기술을 활용해 외부 통신 지원
- 호스트 네트워크 (Host)
- 호스트 네트워크를 공유해 모든 컨테이너가 호스트 머신과 동일한 IP 사용하도록 지원
- 호스트 네트워크와 포트 중복 불가능
- 오버레이 네트워크 (Overlay)
- 호스트 머신이 다수일 때 하나의 네트워크처럼 사용하도록 지원 (Kubernetes에서 사용)
- Macvlan 네트워크
- 컨테이너에 MAC 주소를 할당해, 물리 네트워크 인터페이스에 직접 연결
-
브릿지 네트워크 (Bridge)
스토리지와 볼륨
- 컨테이너의 중요한 속성: Stateless (무상태)
-
컨테이너는 상태가 없음
- 컨테이너 실행 후 모든 변경 사항은 컨테이너 레이어에만 존재
-
불변성: 모든 상태는 이미지에 기록되고 이미지는 한 번 지정된 후 변경되지 않음
- 컨테이너 상태 변경(e.g. 소프트웨어 버전 변경)이 필요하면 새 버전의 이미지 제작 후 배포
- 장점
- 여러 컨테이너를 다른 여러 환경에서 빠르게 배포 가능
- 트래픽이나 장애에도 컨테이너를 쉽게 생성해 빠르게 대처
- 제약
- 상태가 없으므로 데이터는 무조건 외부에 저장해야 함
- 데이터 영구 저장을 위해서는 DB 서버 사용이 필수
-
사용자 세션 정보나 캐시 같은 정보는 캐시 서버나 쿠키를 통해 관리
- e.g. 사용자 로그인 정보, 장바구니 상품 리스트
-
동일한 요청은 항상 동일한 결과를 제공해야 함
- 같은 이미지로 생성한 모든 서버에서 같은 응답을 제공해야 함
- 컨테이너 실행 시점에 설정을 외부에서 주입할 수 있어야 함
- 환경 변수나 구성 파일을 통해 다양한 환경에서 컨테이너 이미지를 활용 가능
- 상태가 없으므로 데이터는 무조건 외부에 저장해야 함
-
컨테이너는 상태가 없음
- 도커 볼륨 (Docker Volume)
-
데이터를 보관하기 위해 도커가 관리하는 외부 공유 저장소
- 호스트 OS의 서버 특정 공간에 저장 (e.g.
/volumes/volume1
) -
볼륨 저장 경로에 사용자가 직접 접근하기는 어려움
- 경로는 리눅스에서는 관찰 가능, MacOS 등은 관찰 불가
- 도커가 가상머신 형태로 실행되어 경로를 자동 관리하고 가상머신 안에 저장하기 때문
- 호스트 OS의 서버 특정 공간에 저장 (e.g.
- 컨테이너가 삭제되도 볼륨은 남아있음
-
볼륨 마운트
- 컨테이너들은 컨테이너의 특정 경로를 도커 볼륨에 마운트해서 사용
- 즉, 컨테이너의 특정 폴더는 공유용 폴더
- e.g. PostgreSQL
- PostgreSQL은
/var/lib/postgresql/data
경로에 실제 DB 데이터 저장 - 해당 경로를 도커 볼륨에 마운트
- 해당 경로에 저장하는 파일들은 컨테이너 레이어가 아니라 외부 볼륨에 저장
- 여러 컨테이너는 1개의 볼륨을 공유해 동일한 데이터를 제공할 수 있음
- 컨테이너가 삭제되거나 새 컨테이너가 생성되어도 데이터 영속성 보장
- PostgreSQL은
- 볼륨과 컨테이너의 관계
- 여러 컨테이너에 하나의 볼륨 마운트 가능
- 하나의 컨테이너에 여러 개의 볼륨 마운트 가능
- 바인드 마운트 (Bind Mount)
- 도커가 자동 관리에서 벗어나 Host OS에서 데이터를 직접 관찰 가능 (볼륨 X)
- 방법:
-v
옵션에서 볼륨 이름 대신 사용자 지정 경로를 전달 - 디버깅에 유용
- 볼륨은 마운트한 컨테이너가 없을 때만 삭제 가능
-
데이터를 보관하기 위해 도커가 관리하는 외부 공유 저장소
컨테이너의 무상태와 서버 관리 방법론
- Pet 방식 (전통적 서버 방법론)
- 서버 한 대 한 대를 소중히 직접 관리하는 방식
- 서버 에러 및 종료를 서비스 장애로 간주
- 서버가 상태를 가져서 교체가 어려움
- e.g. Monolithic, OnPremise
- Cattle 방식
- 컨테이너를 활용한 서버 방법론 (서버는 소모품)
- 서버 에러 및 종료가 충분히 일어난다고 가정
- 문제 서버 삭제 후 빠르게 새 서버를 생성해 대체하는 방식으로 해결
- 서버의 상태를 최대한 제거해 빠르게 교체 가능하도록 함
- e.g. MSA, WEBAPP
마운트
컴퓨터의 특정 디렉토리를 외부 저장소와 연결하는 것을 말한다.
NFS(Network File System)는 PC의 특정 폴더 혹은 드라이브 단위를 NFS에 마운트 시킬 수 있고, 여러 컴퓨터가 접근할 수 있습니다.
도커 컴포즈 (Docker Compose)
-
여러 개의 도커 컨테이너를 편리하게 관리하는 도구
- 여러 개의 컨테이너를 하나의 파일에 정의해 복잡한 애플리케이션 구조를 관리
- e.g. 서비스 간 의존성, 도커 네트워크
- 특징
- YAML 문법으로 IaC 적용 (
docker-compose.yml
) - 도커 데스크탑 설치 시 기본 제공
- 도커 컴포즈의 서비스 = 컨테이너
-
디폴트로 네트워크를 생성해 컴포즈 파일 내 컨테이너들을 포함시킴
- e.g.
--network leafy-network
- e.g.
- YAML 문법으로 IaC 적용 (
- 장점
- 여러 개의 컨테이너를 한 번의 명령어로 실행 혹은 종료 가능 (
docker compose up
) - 로컬 개발 환경에서 활용이 편리 (실제 운영과 비슷한 환경을 빠르게 구성 가능)
- 여러 개의 컨테이너를 한 번의 명령어로 실행 혹은 종료 가능 (
YAML 문법 (YAML Ain’t Markup Language, YAML은 마크업 언어가 아니다)
JSON 같은 데이터 표현 형식 중 하나다.
상대적으로 최근에 나온 포멧으로 가독성에 더 초점을 맞춰 간결하다.
JSON이{}
와""
와,
등이 필수인 반면, YAML은 띄어쓰기 기반으로 정보를 구분한다.
예시로, 띄어쓰기와-
로 리스트와 객체를 표현할 수 있다.
정의서 작성과 같은 사용자가 직접 파일을 작성하는 방식에 많이 쓰인다. (Docker
,Kubernetes
)