1. 모델링

→ 복잡한 현실 세계를 단순화시켜 표현하는 것

① 추상화 : 현실 세계를 일정한 형식에 맞추어 표현

② 단순화 : 복잡한 현실 세계를 약속된 규약에 의해 제한된 표기법이나 언어로 표현

③ 명확화 : 누구나 이해하기 쉽게 하기 위해 대상에 대한 애매모호함을 제거하고 정확하게 현상을 기술

 

 

2. 데이터 모델링

1) 개념

- 정보 시스템을 구축하기 위한 데이터 관점의 업무 분석 기법

- 현실세계의 데이터에 대해 약속된 표기법에 의해 표현되는 과정

- 데이터베이스를 구축하기 위한 분석/설계의 과정

 

2) 데이터 모델링의 중요성 

① 파급효과 

- 시스템 구축 작업 중 데이터 설계가 가장 중요

- 데이터 모델링을 잘못했을 경우 어떤 설계보다 위험성에 대한 파급효과 뚜렷

② 복잡한 정보 요구사항의 간결한 표현

- 구축할 시스템의 정보 요구사항과 한계를 가장 명확하고 간결하게 표현할 수 있는 도구

③ 데이터 품질

- 데이터 품질 문제가 야기되는 중대한 이유 중 하나가 데이터 구조의 문제

- 모델링을 잘못하면 데이터 품질이 저하될 수 있음

 

3) 데이터 모델링의 유의점

① 중복 (Duplication) : 데이터베이스는 여러 장소에 같은 정보를 저장하는 잘못을 하지 않음

② 비유연성 (Inflexibility) : 데이터의 정의를 데이터의 사용 프로세스와 분리하여 작은 변화가 중대한 변화를 일으킬 수 있는 가능성을 줄임

③ 비일관성 (Inconsistency) : 데이터와 데이터 간 상호 연관 간계에 대한 명확한 정의는 이러한 위험을 사전에 예방

 

4) 데이터 모델링의 중요한 3가지 

① 엔티티 : 업무가 관여하는 어떤 것 (Things)

② 속성 : 어떤 것이 가지는 성격 (Attributes)

③ 관계 : 업무가 관여하는 어떤 것 간의 관계 (Relationships)

 

 

3. 데이터 모델링의 3단계

1) 개념적 데이터 모델링

- 추상화 수준이 높고 업무 중심적이며 포괄적인 수준의 모델링

- 전사적 데이터 모델

- 핵심 엔티티와 그들 간의 관계를 발견하고, 그것을 표현하기 위해 엔티티-관계 다이어그램(ERD)을 생성

 

2) 논리적 데이터 모델링

- 시스템으로 구축하고자 하는 업무에 대해 key, 속성, 관계 등을 정확하게 표현

- 재사용성 높음

- 이 단계에서 하는 중요한 활동은 정규화

 

3) 물리적 데이터 모델링

- 실제 데이터베이스에 이식할 수 있도록 성능, 저장 등 물리적인 성격을 고려하여 설계

- 테이블, 칼럼 등으로 표현되는 저장구조와 사용될 저장 장치, 자료를 추출하기 위해 사용될 접근 방법 등

 

 

4. 데이터 독립성

1) 데이터 독립성의 필요성

- 유지보수 비용 증가

- 데이터 중복성 증가

- 데이터 복잡도 증가

- 요구사항 대응 저하

 

2) 데이터베이스 3단계 구조

① 외부스키마 : 사용자 관점

- View 단계 여러 개의 사용자 관점으로 구성, 즉 개개 사용자 단계로서 개개 사용자가 보는 개인적 DB 스키마

- DB의 개개 사용자나 응용프로그래머가 접근하는 DB 정의

② 개념스키마 : 통합 관점

- 개념단계 하나의 개념적 스키마로 구성 모든 사용자 관점을 통합한 조직 전체의 DB를 기술하는 것
- 모든 응용시스템들이나 사용자들이 필요로 하는 데이터를 통합한 조직 전체의 DB를 기술한 것으로 DB에 저장되는 데이터와 그들간의 관계를 표현하는 스키마

③ 내부스키마 : 물리적 저장구조

- 내부단계, 내부 스키마로 구성, DB가 물리적으로 저장된 형식
- 물리적 장치에서 데이터가 실제적으로 저장되는 방법을 표현하는 스키마

 

3) 두 영역의 데이터 독립성

① 논리적 독립성 : 개념 스키마가 변경되어도 외부 스키마에는 영향을 미치지 않도록 지원하는 것

- 논리적 구조가 변경되어도 응용 프로그램에 영향 없음

- 사용자 특성에 맞는 변경가능
- 통합 구조 변경가능

② 물리적 독립성 : 내부스키마가 변경되어도 외부/개념 스키마는 영향을 받지 않도록 지원하는 것

- 저장장치의 구조변경은 응용프로그램과 개념스키마에 영향 없

- 물리적 구조 영향 없이 개념구조 변경가능

- 개념구조 영향 없이 물리적인 구조 변경가능

 

4) 사상

① 외부적/개념적 사상 (논리적 사상) : 외부적 뷰와 개념적 뷰의 상호 관련성을 정의함

② 개념적/내부적 사상 (물리적 사상) : 개념적 뷰와 저장된 데이터베이스의 상호관련성을 정의함

'네트워크캠퍼스 > DATABASE' 카테고리의 다른 글

WHERE절  (0) 2024.02.16
DML  (0) 2024.02.15
DDL  (0) 2024.02.15
관계형 데이터베이스  (0) 2024.02.14
데이터 모델링의 중요 개념  (0) 2024.02.13

1. 프록시

1) 프록시가 없다면?

- 사용자 요청이 직접 웹서버에 전달 → 서버 부담 증가

- 단일 웹서버 : 장애 발생 시 서비스 가용성에 치명적인 문제

- 다중 웹서버 : hotspot → 한 서버에 트래픽이 몰리는 현상, 사용자 입장에서 레이턴시가 증가하는 문제 

 

2) 프록시

- 사용자의 요청을 대리로 받아 서버들에게 적절히 분배

- 다중 호스트에 트래픽을 분산시킬 수 있는 로드밸런싱 구현이 가능

- html, js, css 등의 정적 파일을 캐싱할 수 있는 캐시서버 구현

- 학교나 사내망에서 특정 사이트 접근을 제어하는 차단 기능 구현

- 무중단 배포를 통한 서비스 경험 향상 및 내구성 증가

- SSL 암호화 적용을 통한 보안 강화 가능

- 프록시 서버 종류

① 포워드 프록시 : 사용자의 존재를 서버에게서 숨김

② 리버스 프록시 : 서버의 존재를 사용자에게서 숨김

 

3) nginx

- 기본 구성값으로 웹서버 실행 가능, 점유율 높음

- config 파일의 간단한 수정만으로 리버스 프록시 구현 가능

- 쿠버네티스의 인그레스 컨트롤러로 엔진엑스 인그레스 컨트롤러 선택 가능

- API 트래픽 처리를 고급 http 기능으로 사용 가능한 API gateway 구성 가능

- MSA 트래픽 처리를 위한 MicroGateway로 사용 가능

- /etc/nginx 하위에 있는 nginx.conf 파일에 대한 변경을 통해 구성 가능

 

 

2. nginx 리버스 프록시

1) nginx 리버스 프록시

- nginx 기본 설정 : 80번 포트

- 기본 분배 방식 : round-robin

- 요청이 더 적게 들어오는 서버에 배정을 늘리는 least_conn 방식 채택 가능

- weight 설정 등을 통해 비중을 다르게 가져갈 수도 있음

 

2) nignx 리버스 프록시 실습

$ sudo apt update
$ sudo apt-get -y install nginx
$ sudo nginx -v

먼저, 위와 같은 명령어로 nginx를 hostos에 설치한 후 진행한다.

nginx는 기본적으로 80번 포트를 사용하기 때문에 포트바인딩이 80번 포트로 되어 있다면 기존에 돌고 있는 컨테이너를 종료시켜줘야 한다.

위 명령어로 서비스가 잘 가동되고 있는 것을 확인할 수 있다.

위와 같이 nginx:master로 80번 포트가 잡힌 것을 볼 수 있다.

먼저, myweb:1.1 컨테이너의 노출 포트번호를 확인해보면 80번 포트로 되어 있는 것을 확인할 수 있다.

위와 같이 3개의 컨테이너를 띄워준다.

<h1>포트번호 : xxxxx, 컨테이너명 : mywebx</h1>

nginx 내부의 index.html 파일 내용을 바꿔주기 위해 위와 같이 수정한 후

위 명령어를 이용해 index.html을 각각 컨테이너명에 복사해준다.

위와 같이 세 개의 컨테이너가 잘 띄워진 것을 확인할 수 있다.

 

☆ 사용자 입장에서는 서버 3개의 주소로 직접 접속하지 않아도 nginx 서버 접속 시 번갈하가며 분배되도록 host nginx의 reverse proxy 설정을 해야 한다. → 프록시의 역할

 

reverse proxy 설정은 /etc/nginx/nginx.conf 파일을 통해 할 수 있다. (해당 파일을 백업해둔 후 진행하자..)

위와 같이 nignx.conf 파일을 수정해준다. 

80번 포트로 접속 시 localhost:11111, 22222, 33333을 번갈아가면서 배정하라는 의미이다.

위와 같이 nginx 서버를 restart해준 후 active 상태를 확인해준다.

이제 그냥 localhost(80번포트)로 접속해도 위와 같이 번갈아가면서 배정되는 것을 확인할 수 있다.

호스트에 설치되어 있던 리버스 프록시를 컨테이너화 시키기 위해 먼저 서버 중단 후 현재 리버스 프록시 설정된 파일을 백업해둔다.

해당 백업파일을 이용하여 새로운 컨테이너의 nginx.conf 파일을 갱신해주면 리버스 프록시를 수행할 수 있다.

위와 같이 nginx를 제거하면 리버스 프록시는 사라지지만 개별 컨테이너는 삭제되지 않은 상태이다.

위와 같이 nginx 컨테이너를 하나 더 띄워주었다.

컨테이너 입장에서는 127.0.0.1이 localhost이므로 nginx.conf 파일의 server 부분을 내부 IP 주소(192.168.56.101)로 수정해주어야 한다.

해당 컨테이너의 nginx.conf 파일을 위와 같이 갱신해준다.

해당 컨테이너를 재시작한 후 접속해보면 위와 같이 프록시가 잘 설정된 것을 확인할 수 있다.

events { worker_connections 1024; }
http {
	upstream lb-node {
		server hostip:11111 weight=80;
		server hostip:22222 weight=10;
		server hostip:33333 weight=10;
	}
	server {
		listen 80 default_server;
		location / {
			proxy_pass	http://lb-node;
		}
	}
}

위와 같이 weight를 주면 가중치에 따라 각 서버가 받는 하중을 다르게 가져가도록 설정할 수도 있다.

 

 

3. HAproxy

1) HAproxy

- 하드웨어 기반의 L4/L7 스위치를 대체하기 위한 프록시 솔루션

- TCP 및 HTTP 기반 애플리케이션을 위한 고가용성, 로드밸런싱 및 프록시 기능 제공

- 주요 기능 : SSL 지원, 로드밸런싱, 액티브 헬스체크, keep alived 등

- L4 스위치 대체 기능 : IP를 통한 트래픽 전달 수행, 요청에 대한 처리는 round-robin 방식을 기본으로 함

- L7 스위치 대체 기능 : HTTP 기반의 URI를 통한 트래픽 전달 가능 , 동일한 도메인의 하위에 존재하는 여러 WAS 사용 가능

 

2) HAproxy를 활용한 컨테이너 L7 스위치 프록시 실습 : HTTP 기반

먼저, haproxy-network라는 네트워크를 생성하고 ls와 route 명령어로 조회해보면 172.21번대 대역을 사용하는 것을 확인할 수 있다.

chadchae1009/haproxy:echo를 받아오고 실행했다.

컨테이너 상태를 확인해보면 위와 같이 잘 띄워졌고, 8080포트를 이용하고 있는 것을 확인할 수 있다.

global
	stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners 
	log stdout format raw local0 info

defaults
	mode http
	timeout client 10s
	timeout connect 5s
	timeout server 10s
	timeout http-request 10s
	log global

frontend stats
	bind *:8404
	stats enable
	stats uri /
	stats refresh 10s

frontend myfrontend
	bind :80
	default_backend webservers

backend webservers
	server s1 서버명:포트 check // 172.17.0.x:8080
	server s2 서버명:포트 check // 컨테이너명:8080
	server s3 서버명:포트 check

위와 같은 haproxy.cfg 파일을 생성해준다.

global 부분은 기본 설정이고, defaults의 mode는 http를 줄 경우 L7, tcp를 줄 경우 L4이다.

frontend stats의 경우 haproxy의 통계를 잡기 위해 8404번 포트를 오픈했다.

frontend myfrontend는 디폴트 설정에 대한 그룹설정으로 80번 포트로 들어오는 것을 webservers로 보낸다는 의미이다.

backend webservers에는 해당 리버스 프록시가 연결해줄 서버 목록들을 적어준다.

$ docker run -d --name=haproxy-con --net=haproxy-network -p 80:80 -p 8404:8404 \
-v $(pwd):/usr/local/etc/haproxy:ro haproxytech/haproxy-alpine:2.5

위와 같이 haproxy를 설치한 후 실행한다.

$(pwd)을 이용하여 pwd 수행의 결과와 컨테이너 내부를 연결해주기 위한 볼륨설정을 해주었기 때문에 haproxy.cfg 파일을 따로 보내주지 않아도 자동으로 동기화된다.

위와 같이 8404 포트로 접속 시 report 페이지에 잘 접속되는 것을 확인할 수 있다.

또한, localhost(80번포트)에 접속 시 위와 같이 부하분산이 적용된 백엔드 서버들을 순차적으로 오가는 것을 볼 수 있다.

 

2) HAproxy를 활용한 컨테이너 L4 스위치 프록시 실습 : URI 기반

global
	stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners \
	log stdout format raw local0 info

defaults
	mode http
	timeout client 10s
	timeout connect 5s
	timeout server 10s
	timeouthttp-request 10s
	log global

frontend stats
	bind *:8404
	stats enable
	stats uri /
	stats refresh 10s

frontend myfrontend
	bind :80
	default_backend webservers

	acl 서버명1 path_beg /서버명1
	acl 서버명2 path_beg /서버명2
	acl 서버명3 path_beg /서버명3

	use_backend 서버명1_backend if 서버명1
	use_backend 서버명2_backend if 서버명2
	use_backend 서버명3_backend if 서버명3

backend webservers
	balance roundrobin
	server s1 서버명1:포트 check
	server s2 서버명2:포트 check
	server s3 서버명3:포트 check

backend 서버명1_backend
	server s1 서버명1:포트 check
backend 서버명2_backend
	server s2 서버명2:포트 check
backend 서버명3_backend
	server s3 서버명3:포트 check

위와 같이 haproxy.cfg 파일을 수정해준다.

acl과 path_beg은 우측의 /서버명으로 접근 시 좌측의 서버명으로 이동시킨다. 또한, roundrobin 방식으로 배정된다.

이는 서버명/추가uri를 붙이는 경우 추가 uri로 특정 서버를 구분할 수 있게 된다.

위와 같이 특정 uri로 구분이 가능한 것을 확인할 수 있다.

하지만, 이 방식에서는 사용자가 좀 더 몰릴 것으로 예상되는 uri에 더 많은 자원을 배정하기에는 무리가 있다.

 

따라서 다음과 같은 방식으로 특정 URI에 서버를 여러개 붙일 수 있다.

global
	stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners \
	log stdout format raw local0 info

defaults
	mode http
	timeout client 10s
	timeout connect 5s
	timeout server 10s
	timeouthttp-request 10s
	log global

frontend stats
	bind *:8404
	stats enable
	stats uri /
	stats refresh 10s

frontend myfrontend
	bind :80
	default_backend webservers

	acl 서버명1 path_beg /uri1
	acl 서버명2 path_beg /uri1
	acl 서버명3 path_beg /uri2
	acl 서버명4 path_beg /uri2

	use_backend 그룹명1_backend if 서버명1
	use_backend 그룹명1_backend if 서버명2
	use_backend 그룹명2_backend if 서버명3
	use_backend 그룹명2_backend if 서버명4

backend webservers
	balance roundrobin
	server s1 서버명1:포트 check
	server s2 서버명2:포트 check
	server s3 서버명3:포트 check
	server s4 서버명4:포트 check

backend 그룹명1_backend
	server s1 서버명1:포트 check
	server s2 서버명2:포트 check
backend 그룹명2_backend
	server s3 서버명3:포트 check
	server s4 서버명4:포트 check

이제 URI가 1인지 2인지에 따라 전달되는 서버가 달라지기 때문에 URI 별로 프록시 설정이 가능하다.

위와 같이 수정해주면 된다.

위와 같이 4개의 컨테이너를 생성 및 실행해준다.

마지막으로 테스트해보기 위한 컨테이너를 실행해보면 다음과 같은 결과를 확인할 수 있다.

localhost/80 : web 1, 2, 3, 4가 로드밸런싱 ∵ default_backend (round robin 방식)

localhost/item : web 1, 2가 로드밸런싱 ∵ item_server 그룹 

localhost/basket : web 3, 4가 로드밸런싱 ∵ basket_server 그룹

 

'네트워크캠퍼스 > DOCKER' 카테고리의 다른 글

도커 DNS  (0) 2024.02.08
사용자 정의 네트워크 실습  (0) 2024.02.07
도커 사용자 정의 네트워크 구성  (0) 2024.02.06
도커 네트워크  (0) 2024.02.05
아틸러리를 활용한 스트레스 테스트  (0) 2024.02.05

1. 도커 DNS

1) 개념

- 사용자 정의 네트워크 내부 컨테이너의 이름을 자동으로 확인하도록 도커 호스트에 생성

- 127.0.0.11 대역 활용

- docker0에는 작동하지 않음

- 동일 network alias 할당을 통해 round robin 방식으로 응답 → 로드밸런서처럼 사용할 수 있음

- 컨테이너 생성 시 호스트 시스템에서 다음 세 파일을 복사하여 컨테이너 내부에 적용 → 컨테이너간 이름 조회 가능

① /etc/hostname

② /etc/hosts

③ /etc/resolv.conf

 

2) DNS 조회 방식

- 도커 DNS는 libnetwork라는 sandbox의 구현체에 구현

- 핵심 네트워킹 및 서비스 검색 기능 제공 → 등록된 모든 컨테이너를 이름으로 찾게 도와줌

- --name 혹은 --net-alias에 명칭을 적으면 DNS에 등록되는 방식

① ping 컨테이너명 입력

② DNS resolver를 이용하여 컨테이너 내부에 등록된 이름인지 검색

③ 컨테이너 내부에 등록된 이름이 아니라면 도커엔진 내의 DNS 서버에 질의

④ 질의한 타겟에게 결과를 전달

⑤ 최종적으로 전달된 내역을 토대로 연결

 

 

2. 도커 DNS 실습

먼저, dnsnet이라는 네트워크를 생성해준다.

route 명령어로 확인해보면 172.19 대역에 배정되어 있는 것을 확인할 수 있다.

$ docker run -d --name=es1 --net=dnsnet --net-alias=esnet-tg \
 -p 9201:9200 -p 9301:9300 -e "discovery.type=single-node" elasticsearch:7.17.10

$ docker run -d --name=es2 --net=dnsnet --net-alias=esnet-tg \
 -p 9202:9200 -p 9302:9300 -e "discovery.type=single-node" elasticsearch:7.17.10

위와 같이 elasticsearch를 이용하여 컨테이너 2개를 실행해준다.

이때 --net-alias 옵션을 통해 esnet-tg이라는 타겟 그룹을 생성해줬고, 이를 통해 현재 그룹은 1개인데 컨테이너는 2개가 된 상태이다.

조회해보면 위와 같이 컨테이너 2개가 잘 돌아가고 있는 것을 확인할 수 있다.

위와 같이 inspect 명령어로 조회하여 해당 컨테이너들의 IP를 기억해두고 진행한다.

$ docker run -it --rm --name=request-container --net=dnsnet busybox nslookup esnet-tg

사용자 정의 네트워크에 DNS 기능이 자동으로 활성화되는지 확인해보기 위해 busybox라는 이미지의 컨테이너를 실행한 후 busybox의 nslookup 기능을 이용하여 esnet-tg을 조회해보면 DNS 관련 정보를 확인할 수 있다.

위와 같이 해당 서버 IP 주소로 조회해보면 각 컨테이너가 등록된 DNS 서버의 이름이 정확하게 나오는 것을 확인할 수 있다.

es3이라는 컨테이너를 띄워준 후 다시 조회해보면 마찬가지로 잘 등록되어 있고,

elasticsearch의 특성 상 9200번 포트를 모두 열어야 하므로 같은 네트워크를 사용하는 centos를 활용해 조회해보도록 한다.

centos:8 버전의 컨테이너를 띄운 후 bash로 진입하여 alias로 설정했던 esnet-tg 그룹에서 9200번 포트를 사용하는 모든 요소를 검색해보면 위와 같은 정보를 확인할 수 있고, 해당 name을 기억한 후 같은 명령을 다시 내려본다.

위와 같이 name 부분이 계속 달라지는 것을 볼 수 있고, 이는 라운드로빈 형태로 최대한 순회하여 컨테이너 접속을 하고 있는 것을 의미한다.

$ docker inspect 컨테이너명

컨테이너에서 alias에 대한 정보는 위와 같이 inspect 명령어로 확인할 수 있다.

 

 

3. 도커 DNS로 Load Balancing 구현하기

먼저, lbdns라는 새로운 네트워크를 생성해주었고, route 명령어로 조회해보면 172.20 대역을 사용하고 있는 것을 확인할 수 있다.

위 명령어를 이용하여 lbdns 네트워크를 이용하고 nnet-tg이라는 별명을 가진 nlb1과 nlb2 컨테이너를 실행해주었다.

위와 같이 해당 컨테이너의 IP 주소를 알 수 있다.

등록된 DNS를 확인하기 위해 dnsutil을 설치해주었고, dig [타겟그룹명] 명령어를 사용하여 조회할 수 있다.

dns를 이용한 로드밸런싱을 확인하기 위해  nnet-request라는 컨테이너를 생성 및 실행했다.

bash로 접속 후 위와 같이 ping 명령어를 날려보면 nnet-tg이라는 그룹에 들어오는 요청을 nnet-tg에 속한 IP들로 랜덤하게 배분하는 것을 확인할 수 있다.

<실습> 아래 토폴로지를 보고 브릿지와 컨테이너를 구성해보자.

토폴로지 구성

먼저, create 명령어로 frontnet과 backnet을 생성해주었고, 목록을 조회해보면 네트워크가 잘 생성된 것을 확인할 수 있다.

inspect 명령어로 조회해보면 frontnet의 대역은 172.20으로, backnet의 대역은 172.21으로 설정된 것을 확인할 수 있다.

route 명령어로 조회하여 확인할 수도 있다.

frontnet 네트워크에는 front-con이라는 컨테이너를, backnet 네트워크에는 back-con과 db-con이라는 컨테이너를 생성하고 실행해주었다.

각 컨테이너들의 bash 창에서 ifconfig를 조회해보면 위와 같은 결과를  확인할 수 있다.

front-con 컨테이너는 frontnet의 172.20 대역을 사용하고 있고, back-con과 db-con 컨테이너는 backnet의 172.21 대역을 사용하고 있는 것을 확인할 수 있다.

또한, 네트워크 자체에 inspect 명령어를 수행해봐도 위와 같은 결과를 확인할 수 있다.

front-con 컨테이너를 backnet 네트워크에 연결하기 위해 connect 명령어를 사용하여 연결해주었고,

front-con 컨테이너에서 ip를 조회해보면 위와 같이 backnet의 172.21 대역이 잘 추가되어 있는 것을 확인할 수 있다.

front-con 컨테이너는 backnet 네트워크에 연결이 된 상태이기 때문에 backnet의 컨테이너인 back-con과 db-con에 ping을 수행해보면 잘 통신되는 것을 확인할 수 있다. 

또한, 연결된 엔드포인트를 모두 해제해준 후 disconnect 명령어로 네트워크 연결을 해제할 수 있고, 컨테이너가 모두 종료된 상태에서 rm 명령어로 네트워크 자체를 삭제할 수 있다.

'네트워크캠퍼스 > DOCKER' 카테고리의 다른 글

컨테이너 프록시  (0) 2024.02.08
도커 DNS  (0) 2024.02.08
도커 사용자 정의 네트워크 구성  (0) 2024.02.06
도커 네트워크  (0) 2024.02.05
아틸러리를 활용한 스트레스 테스트  (0) 2024.02.05

1. 사용자 정의 네트워크 구성

자동으로 생성된 브릿지 docker0은 기본 기능이다보니 빠진 기능이 많고, 보통 사용자가 정의한 네트워크를 구성하여 사용한다.

먼저, 위 명령을 이용하여 사용자 정의 bridge network 생성이 가능하다.

도커는 기본적으로 HostOS와 bridge 간 연결을 하는데 이는 --net 옵션으로 네트워크 설정을 할 수 있다.

※ --net 옵션에 줄 수 있는 효과

bridge 브릿지 접속을 하도록 설정
none 네트워크 외부 노출을 하지 않음
container:컨테이너명
container:컨테이너ID
다른 컨테이너의 네트워크 활용
(다른 컨테이너의 대역을 빌림)
host 컨테이너가 host os의 네트워크를 함께 쓰도록 설정
macvlan 물리 네트워크에 컨테이너 MAC 주소를 통한 직접 연결 사용
NETWORK 기타 사용자 정의 네트워크 활용

 

위와 같이 포트포워딩 정보 없이 컨테이너를 띄웠는데도 불구하고 연 적도 없는 80번 포트가 열리는 것을 확인할 수 있다.

위와 같이 nginx가 그냥 호스트 주소로도 잘 돌아가는 것을 확인할 수 있다.

nginx의 80번 포트에 대한 PID를 조회해보면 host 내부 프로세스처럼 잡히는 것을 볼 수 있다.

해당 컨테이너는 자체적인 IP 주소를 갖지 않는 것을 볼 수 있다.

호스트의 IP를 쓰기 때문에 따로 배정받을 필요가 없는 것이고, 이는 docker0을 쓰지 않는다는 의미이다.

 

1) 사용자 정의 네트워크 생성

먼저, network create 명령어로 생성 후 확인해보면 아무 옵션도 주지 않은 경우 기본 bridge로 만들어지는 것을 볼 수 있다.

route를 이용하여 현재 ip routing table을 조회해보면 위와 같이 인터페이스명이 br로 시작하는 브릿지가 생성된 것을 확인할 수 있다.

172.18 대역으로 브릿지가 생성되었다.

ifconfig로 조회해보면 가장 상단에 해당 인터페이스를 볼 수 있다.

현재까지의 네트워크 구성은 위 그림과 같다.

또한, inspect 명령어를 통해 자세한 네트워크 상황을 조회해볼 수 있다. 

마찬가지로 아무 설정하지 않았을 경우 기본값은 브릿지로 생성되는 것을 확인할 수 있다.

위와 같이 터미널을 각각 띄워 해당 네트워크 브릿지에 2개의 컨테이너를 연결한다.

ifconfig 명령어로 각각 배정받은 ip 주소를 확인할 수 있다.

route 명령어를 통해 연결되어 있는 대역을 확인할 수 있고, 위쪽에서 새로 생성했던 172.18 대역에 연결된 것을 알 수 있다.

현재까지의 네트워크 구성은 위 그림과 같다.

inspect로 조회해보면 브릿지 입장에서도 확인할 수 있고, 연결된 컨테이너들도 볼 수 있다.

brctl show를 수행해보면 위와 같이 2개의 브릿지를 확인할 수 있고, 생성한 브릿지가 2개의 인터페이스를 가지는 것을 볼 수 있다.

컨테이너는 무조건 하나 당 하나 이상의 가상이더넷을 가지므로 컨테이너 두 개가 띄워진 현재는 위와 같이 설정된다.

network1의 bash 창에서 ping을 해보면 위와 같이 컨테이너 이름만 가지고도 잘 수행되고, network2의 IP 주소도 확인할 수 있다.

사용자 정의 네트워크는 자체적으로 DNS를 구성해주고, 그곳에 알아서 도메인까지 구성된다.

원래 컨테이너 이름만 가지고는 당연히 IP 주소를 조회할 수 없지만, 같은 커스텀 네트워크 내부에서는 예외적으로 docker DNS가 구축되기 때문에 컨테이너 이름만으로도 조회가 가능하다.

위와 같이 아무런 옵션 없이 newnode를 만들어주면 기본브릿지(192.17 대역)로 연결된다.

현재까지의 네트워크 구성은 위 그림과 같다.

따라서 network1 컨테이너에서는 newnode 컨테이너에 ping을 보낼 수 없는 것을 학인할 수 있다.

 

2) 좀 더 상세한 네트워크 만들어보기

위와 같이 좀 더 상세한 옵션들을 지정해준 후 네트워크를 생성하고 조회해보면 목록에 잘 생성된 것을 확인할 수 있다.

라우트 목록을 조회해보면 위에서 설정한 대역으로 브릿지가 생성된 것을 확인할 수 있다.

여기서 다음 컨테이너를 띄우면 IP는 172.33.1 대역으로 가져가게 될 것이다.

컨테이너를 띄운 후 ip를 조회해보면 역시 172.33.1.0 대역으로 진행되고, 처음 만든 컨테이너라 2번으로 배정된다.

자동 순서대로 배정하고 싶지 않으면 위와 같이 --ip 옵션으로 내부 IP를 지정할 수도 있다.

위와 같이 네트워크 자체를 조회해봐도 위와 동일한 정보들을 확인할 수 있다.

brctl로 확인해보면 위와 같이 생성한 브릿지 목록을 확인할 수 있다.

또한, ip addr 명령어로 해당 브릿지들을 확인할 수 있다.

ip route로도 역시 확인 가능하다.

exec를 이용해 net1에 ip addr 명령을 전달하여 조회해봐도 위와 같이 연결 현황을 확인할 수 있다.

최종 네트워크 구성은 위 그림과 같다.

 

3) 브릿지가 다른 경우의 구성

먼저, vswitch에 연결한 net1의 경우 172.33 대역을 사용하고 있다.

반면, mynetwork에 연결한 network1이나 network2는 172.18 대역을 사용하고 있다.

network1에서 net1으로 ping을 보내면 위와 같이 연결이 안되는 것을 확인할 수 있다.

즉, 같은 내부망이어도 현재 구성만으로는 브릿지 간 통신이 불가능하다는 것을 알 수 있다.

 

4) 네트워크 연결

먼저, con-net2라는 새로운 네트워크를 생성해주었고, 위 명령어를 통해 172.19 대역을 사용하고 있는 것을 확인할 수 있다.

위와 같이 connect 명령어를 사용하여 network2 컨테이너를 con-net2에 연결해주었다.

network2의 bash 창에서 확인해보면 위와 같이 eth1에 con-net2의 대역이 추가되어 있는 것을 확인할 수 있다.

이렇게 되면 양쪽 네트워크 모두에 연결된 형태가 되기 때문에 자연스럽게 양쪽 망과 통신이 가능해지게 된다.

con-net2 대역을 사용하는 connet라는 컨테이너를 만들어준 후 network2의 bash창에서 ping을 날려보면 위와 같이 잘 통신되는 것을 확인할 수 있다.

또한, con-net2를 inspect해보면 컨테이너 목록에서 위와 같이 network2를 인지하고 있는 것을 확인할 수 있다.

rm을 이용하여 con-net2 브릿지를 삭제해보면 위와 같이 연결된 컨테이너 엔드포인트가 존재하여 불가능하다는 오류가 발생한다.

컨테이너와 브릿지의 연결은 disconnect 명령어로 진행할 수 있다.

con-net2에 연결되어 있던 conneet 컨테이너를 삭제해주면 con-net2 네트워크도 정상적으로 삭제가 진행되는 것을 볼 수 있다.

'네트워크캠퍼스 > DOCKER' 카테고리의 다른 글

도커 DNS  (0) 2024.02.08
사용자 정의 네트워크 실습  (0) 2024.02.07
도커 네트워크  (0) 2024.02.05
아틸러리를 활용한 스트레스 테스트  (0) 2024.02.05
CLI에서 컨테이너 관리  (0) 2024.01.31

+ Recent posts