data에 대한 데이터를 말하는 것으로, 다른 데이터를 설명해준다.


 정보를 효율적으로 찾기 위해서 일정한 규칙에 따라 컨텐츠에 부여되는 데이터이다.


 데이터 자체를 좀더 적은 정보량으로 표현하기 위하여 만들어졌으며, 이는 인터넷에서 문서들을 찾기 위한 일종의 태그 역할을 수행하기도 한다.


 즉, 메타데이터를 기준으로 문서를 구분할 수 있는 일종의 Unique 한 Key 역할을 할 수 있으며 이로 인해 주로 분석이나 분류 목적으로 따로 쓰이기도 한다.


실무에서도 주로 서버를 구성할 때, 관리하는 데이터는 이 meta data가 되며, meta data를 이용한 참조 혹은 인덱스로 실제 데이터를 가리키는 데 사용한다.


메타 데이터의 쓰임새는 워낙 무궁무진하며 혹자는 메타 데이터에 대한 설계 능력이 data를 설계하는 중요한 역량이라고 말하기도 하더라.


* 실무에서도 많이 쓰이는 용어이기 때문에 간단하지만 알아둘 필요가 있다.



회사마다 사용하는 테스팅의 종류가 다를 수는 있으나, 여지껏 다니던 회사들에서 주로 사용하던 테스팅 방법 들을 정리해보았다.


회사마다 QA 팀이 갖추어져 있는 경우도 있고 스타트업의 경우 별도의 QA팀 없이 개발팀에 해당 책무가 주어지는 경우가 있다.


다음은 몇가지 테스팅의 종류들이다.


(1)   Sanity Testing : 새로운 버전이 주요 테스트를 수행하기 적합한지를 판단하기 위한 테스팅. 만약 사용 초기의 Crash 등으로 프로그램이 사용불가능하다면 시스템은 테스팅이 불가능하다. , QA 위한 테스트라 있다.


(2)    BlackBox Testing : 내부설계 구현은 고려하지 않고 요구사항과 기능성에만 기반한 테스팅을 수행한다.


(3)    WhiteBox Testing : 글래스박스 테스팅이라고도 하며, 내부로직에 대한 지식을 기반으로 코드구문, 분기, 조건 등에 대한 커버리지를 포함한다.


(4)    Unit Testing : 개발자에 의해 수행되며 소프트웨어 모듈 각각에 대한 세부적 테스팅


(5)    End to End Testing : 주로 네트워크, DB 연동, 시스템간 커넥션에 대한 테스팅이다.


(6)    Load Testing : 부하가 걸린 상황에서 시스템의 동작을 점검한다.


(7)    Stress Testing : 허용 범위를 초과하여 한계치를 측정하는 테스팅이다.


(8)    Alpha Testing : 개발 부서 내에서 만든 가상환경에서의 테스팅


(9)    Beta Testing : 상용화 릴리즈 이전 end user 의해 완료되는 테스팅


(10)  Recovery Testing : 시스템의 회복을 테스팅한다.


(11) Smoke Testing : Sanity Test와 유사하게 테스트가 가능한지 여부를 판단한다. (연기가 나는지를 판단하는 작업) 여러 개의 스모크 테스트를 스위트라고 한다.


 * Sanity Test와 Smoke Test 의 차이는 기능 검사에 있다. Sanity Test가 새로 테스트 항목에 추가된 추가된 기능 / 수정된 버그 에 초점을 둔다면 Smoke Test 는 프로그램의 핵심적인 부분을 같이 검사한다. (즉, 새로운 기능추가가 기존의 핵심 기능에 영향을 안미치지는지 테스트 한다.)

또한, 같은 QA 이전의 테스팅이지만 주로 Smoke Test 는 개발팀 내에서 직접, Sanity Test 는 개발팀에서 기능 검사만 하고, QA팀으로 넘기는 경우가 많다.

(보다 자세한 비교는 다음 링크가 잘 설명해주고 있다.)

 - 참조 : https://www.guru99.com/smoke-sanity-testing.html




배치 작업을 할때, 이용할 수 있는 도구는 많지만 개인적으로 가장 손꼽는 프로그램은 Linux 에서 기본적으로 제공해주는 크론탭(Crontab) 이라고 생각한다. 사용하기도 쉽고 강력한 스케줄링 기능을 할 수 있다.


다음은 크론탭의 사용방법이다.


- crontab -e : 크론탭 편집기 실행. VI 가 기본으로 실행된다.

- crontab -i : 크론탭의 내용 조회


- 크론탭 작성 방법


*                *                    *                *                *

분(0-59)       시간(0-23)       일(1-31)       월(1-12)       요일(0-7)


- 매분 실행

* * * * * /home/script/test.sh


- 특정 시간 실행

# 매주 월요일 오전 5시에 test.sh 실행

0 5 * * 5 /home/script/test.sh


- 반복 실행

# 매일 매시간 0분, 20분, 40분에 test.sh 실행

0, 20, 40 * * * * /home/script/test.sh


- 범위 실행

# 매일 1시 10분 부터 30분까지 매분 test.sh 실행

10-30 1 * * * /home/script/test.sh


* 크론탭은 한줄에 한 명령어만 작성해야 하며 #을 통해 주석을 달 수 있다.


또한 실행하는 쉘에 Redirection (>) 을 연결함으로써 출력을 리다이렉트할 수 있으며 이를 통해 로깅이 가능하다.



TCP/IP 전송제어 프로토콜은 신뢰성에 초점을 맞추고 데이터가 신뢰성있게 올바른 순서로 유실되지 않게 빨리 전송할 수 있도록 설계된 프로토콜이다.


TCP 의 기본적인 작동 원리는 다음과 같다.

<TCP hand shake >

<출처 : https://wiki.mikrotik.com/wiki/Manual:Connection_oriented_communication_(TCP/IP)>


TCP 는 통신을 위해 3 way handshake 란 방식을 이용한다. 먼저 통신이 가능한지 SYN 을 보내고, 통신이 가능하다는 SYN-ACK을 받는다. 이 과정에서 문제가 없으면 이제 통신하고자 하는 메시지를 보내고, 양방향 통신이 된다. 이 과정을 3-WAY Handshake 라 하며, 이 과정은 TCP 매 통신 시마다 적용이 되며, 통신이 끝날때에는 SYN 대신 FIN 을 보내서 서로 확인을 받는다. 이러한 과정을 통해 TCP 는 무조건 메시지가 잘 전달되었으며 잘 도착했다는 확인을 받게 되고, 신뢰성을 보장받게 된다. 이러한 특성으로 TCP는 주로 전화에 비견된다. 이러한 TCP 통신을 위한 헤더는 다음과 같다.



위의 헤더 정보에는 보내는 메시지의 목적지 주소와, 순서 보장을 위한 일련 번호(Sequence Number), 에러 체크를 위한 Checksum 정보 등이 포함된다.

그 외에 사용하는 TCP 알고리즘 별로 슬라이딩 윈도우 정보 등 다양한 정보가 포함될 수 있다.


 슬라이딩 윈도우는 패킷의 흐름을 제어하기 위한 메모리 버퍼(Window) 로, 다양한 경우에 대비해서 사용된다. 가령 3WAY Handshaking 중 네트워크 장애 발생이나, 받은 메시지가 중간에 누락이 된 경우 해당 패킷의 재전송이 필요하다. 다음 패킷의 전송을 멈추고 이전 패킷의 전송을 기다리는 Stop And Wait 방식 보다, 훨씬 효율적일 수 있다.


<슬라이딩 윈도우 송신 측>


 위의 그림 처럼 슬라이딩 윈도우는 이미 전송하고 확인이 완성된 부분, 전송했지만 확인되지 않은 부분, 보내지 않았지만 수신자가 수신 준비 된부분, 수신준비 되지 않았으며 송신하지 않은 부분으로 영역을 나누어 네트워크 상황에 따라 포인터를 관리한다.


<슬라이딩 윈도우 수신 측>


 위의 그림은 수신측이다. 받았고 승인한 버퍼를 갖고 있으며 ( 이 버퍼는 나중에 다른 패킷으로 덮어써진다.) 수신자가 아직 받지 못한 부분, 수신준비되지 않았으며 수신하지 않은 부분으로 나뉘며 전송 상태에 따라 포인터를 조정한다.

(관련 내용의 예시를 잘 정리한 블로그는 다음을 참조하기 바란다. http://blog.naver.com/donjobani/30110435544)



 위의 내용들을 바탕으로 한 TCP 의 특징을 정리하자면 다음과 같다.


(1) Connection Oriented : 2개의 endpoint간 연결을 먼저 맺고 데이터 통신을 한다.


(2) Bidirectional byte stream : 양방향 Data stream(Byte stream)


(3) In-order delivery : 송신자가 보낸 순서대로 수신하며 Segment의 데이터 순서 표시를 위한 32비트의 정수를 사용한다.


(4) Reliability through ACK : 송신자는 수신자가 ACK 보내는 것을 체크하고 보내지 않은 데이터를 보관한다.


(5) Flow control : 송신측과 수신측의 처리 속도 차이를 해결하기 위해(특히 수신측이 느린 경우) 지원하는 제어 방식으로 흐름 제어라 불린다. 속도 차이로 전송 누수가 생기는 것을 방지하기 위해서 수신자는 받을 수 있는 버퍼의 크기(Receive window)를 송신자에 전달하여 송신자가 보내는 양을 제어하게 한다.


(6) Congestion control : 통신시 한 Router에 데이터가 몰려 혼잡할 경우, 호스트 들이 데이터 유실 때문에 재전송을 하게 되고 결국 혼잡이 더 늘어나는 악순환이 생긴다. 이를 막기 위해 송신측에서는 Congestion window가 존재하여 허용하는 만큼만 전송하게 하여 혼잡을 제어한다. TCP Vegas, BIC, CUBIC 등의 알고리즘을 사용한다.



 반면 UDP는 이러한 Hand shaking 과정이 없다. UDP 의 통신과정은 단순하다. 단순히 명시받은 IP 주소와 포트로 메시지를 UDP 헤더를 담은 메시지를 보낸다. UDP 헤더가 담긴 메시지를 받으면, 어플리케이션은 해당 메시지를 해독해서 로직을 처리한다. UDP 헤더는 다음과 같다. TCP 헤더보다 많이 단순한 모양이다.


 하지만 TCP 와 다르게 UDP 는 응답값을 기대하면 안된다. 신뢰성이 보장되지 않기 때문에, 중간에 네트워크 이슈로 인해 데이터가 손실되더라도 이를 알아차릴 방법이 없다. 그렇게 때문에 UDP 는 편지에 비유되며, 상대방 IP 주소의 포트에 메시지를 놓고온다고 이해하면 쉽다.


 정리하자면, TCP의 경우 좀 더 시간이 오래 걸리는 무거운 프로토콜이지만 신뢰성이 보장되며 UDP 의 경우 가볍지만 신뢰성을 보장할 수는 없다. 이런 특징 때문에 신뢰성이 중요한 메시지 들은 TCP로, 몇몇 패킷이 누락되어도 상관없는, 가령 이미지나 실시간 스트리밍 들은 UDP 로 구현이 된다.

 물론 몇몇 서비스의 경우에는 비즈니스 로직에 따라 UDP 로 구현하되, 헤더를 커스터마이즈하여 특정 조건에서 신뢰성을 갖으면서 가볍고 빠른 자체 프로토콜을 만들어 서비스 품질을 높이는 경우가 많다.






마이크로 서비스 아키텍처 (Micro Service Architecture) 란, 최근에 각광받고 있는 웹 기반 분산 서비스 시스템 아키텍처를 말하며, 이러한 아키텍처를 갖는 서비스 자체를 마이크로 서비스 (Micro Service) 라 한다.


앞선 포스팅에서 언급한 모놀리식(Monolithic) 아키텍처가 하나의 어플리케이션 또는 서비스가 여러개의 모듈이 결합된 강건한 형태의 아키텍처를 갖는다면, 마이크로 서비스 아키텍처는 반대로 독립된 각각의 모듈을 조립하여 만드는 하나의 서비스를 위한 아키텍처라고 볼 수 있다.

(참조(모놀리식 아키텍처) : http://jins-dev.tistory.com/entry/%EC%A0%84%ED%86%B5%EC%9D%98-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EB%AA%A8%EB%8D%B8-%EB%AA%A8%EB%86%80%EB%A6%AC%EC%8B%9DMonolithic-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98?category=760149)


즉, Software 설계 시에 Loose Coupling 을 위하여 고려되는 "모듈화" 의 개념이 Web API 를 이용하여 서비스 레벨로 확장된 것으로 이해하면 편하다.


이는 오래된 개념이며, 최근에 클라우드 시스템 및 도커 등의 발달로 인해 보다 손쉬운 구현이 가능해지면서 대세로 자리잡고 있다.


마이크로 서비스 아키텍처는 작은 서비스들의 컬렉션으로 구성된다. 각각의 작은 서비스 단위들은 단일 비즈니스 기능을 구현할 수 있어야 한다.



 마이크로 서비스 아키텍처에서 서비스는 작고 독립적이며 느슨하게 결합되어 있다. 각 서비스는 작은 개발 팀이 관리할 수 있는 개별 코드 베이스이다. 서비스들을 독립적으로 배포할 수 있으며 팀이 전체 응용 프로그램을 다시 빌드한 후 재배치하지 않고도 기존 서비스를 업데이트 할 수 있다


서비스는 해당 데이터 또는 외부 상태를 유지해야하고 이는 별도의 데이터 레이어를 갖는 기존의 모델과 다른점이다. 각 서비스들은 API를 사용하여 통신하고, 구현 내용은 감춰진다. 각 서비스들은 동일한 기술 스택, 라이브러리 또는 프레임워크를 공유할 필요가 없다.


 마이크로 서비스 아키텍처는 노드 간의 서비스들을 관리할 수 있는 특징적인 구성요소를 지닌다. 또한 서비스 목록을 조회하거나 클라이언트로부터 들어오는 API의 진입점을 별도 인터페이스의 게이트웨이로 분리하는 특징을 지닌다. 이는 API 서버일수도, 어드민 형태의 웹페이지일 수도 있다.


 마이크로 서비스 아키텍처가 사용되는 경우는 빠른 릴리즈 개발 속도가 요구되거나 고확장성이 필요한 복합적인 프로그램, 많은 하위도메인을 가진 거대한 프로그램 또는 소규모 개발 팀으로 구성된 조직에 유용하다. 이는 다음과 같은 이점들로 인해 기인한다.


-      독립배포 : 전체 프로그램을 다시 배포하지 않고도 업데이트가 가능하다. 이에 따라 버그 수정 및 릴리즈 관리가 용이하고 위험부담이 덜하다.


-      독립개발 : 독립적인 개발팀들에 의해 개발될 수 있다.


-      집중화된 소규모팀 : 팀이 각 서비스에만 집중할 수 있다.


-      결함격리 : 한 서비스가 다운되더라도 전체 서비스에 영향을 미치지 않는다.


-      혼합기술스택 : 각 서비스에 적합한 기술을 선택하여 조합할 수 있다.


-      세분화된 확장성 : 서비스를 독립적으로 확장할 수 있다. 이에 따라 리소스의 유연한 운용이 가능하다.


 위와 같은 장점을 갖고 있음에도 아직 마이크로 서비스 아키텍처는 모놀리식 아키텍처에 비해 복잡하며 독립된 구조로 인해 통합적인 유지 관리가 어려워질 수 있다. 가령 에러가 난 서비스의 권한이 다른 팀에 있다면, 그 부분의 보수를 위해서 우리가 직접 수정하는 것이 아닌 커뮤니케이션이 필요하게 된다.


또한 서비스 구성에 있어 네트워크 정체 및 통신에 신경을 써줘야 하며 데이터 일관성 및 버전 관리가 중요해진다. 그리고 프로젝트 진행에 있어 팀원들이 이루는 문화가 중요해진다. 이러한 기조에서 알맞은 개발 문화가 개발자가 운영까지 담당하는 DevOps(데브옵스) 문화라 할 수 있다.

 

 



 Linux 서버 관리를 하다가 가장 자주 마주치는 것 중 하나가 서버의 포트 및 방화벽 문제라고 할 수 있는데 삽질하면서 알아낸 바를 적는다.


 : 리눅스에서 열린 포트를 확인 하는 방법

 - netstat -tnlp : 상태를 인 아웃 port 정보를 포함해서 볼 수 있다.


 : CentOS, Fedora 등의 리눅스에서 포트 방화벽을 확인 하는 방법

-    iptables -list

-    iptables -L(리스팅) -v(자세히)


 : Ubuntu 에서 포트 방화벽을 확인하는 방법

-    sudo ufw status


 : Ubuntu 에서 포트 방화벽을 활성화 / 비활성화 하는 방법

-    sudo ufw enable

-    sudo ufw disable


 : CentOS, Fedora 등의 리눅스에서 포트를 추가하는 방법

-    iptables -I INPUT 1 -p tcp -dport 80 -j ACCEPT  (80 Input 포트를 1번으로 추가)

-    iptables -I OUTPUT 2 -p tcp -dport 8080 -j ACCEPT     (8080 Output 포트를 2번으로 추가)


 : Ubuntu 에서 포트를 추가하는 방법

-    sudo ufw allow <port>/<optional: protocol> (sudo ufw allow 443/tcp)


 : CentOS, Fedora 등의 리눅스에서 포트 예외를 제거하는 방법

-    iptables -D INPUT 2   (INPUT 2번째 규칙 제거)


 : Ubuntu 에서 포트를 제거하는 방법

-    sudo ufw deny <port>/<optional: protocol>


 : Iptables 를 이용한 포트포워딩

-    iptables -t nat -A PREROUTING -p tcp -m tcp dport 80 -j REDIRECT to-ports 8080

-    iptables -t filter -A FORWARD -p tcp -m tcp dport 80 -j ACCEPT

 

 * 이 글을 정리할 때를 돌아보자면 클라우드 VM에서 자체 방화벽을 잘못 건드려서 2차 참사를 유발한 케이스였다, 당시 사내 플랫폼은 유일한 게이트웨이에서 리눅스 서버에 접속할 수 있도록 허용되어 있었는데, 이 부분이 기존 사내 플랫폼 방화벽에 WhiteList로 등록되어있지 않은 상태에서 방화벽을 걸어버려서, 인스턴스 하나를 날린 참사가 일어났었다... ㅡㅡ 

방화벽 설정은 각별히 주의하자.





 DHCP란 Dynamic Host Configuration Protocol 의 약자로, 호스트의 동적 설정을 위한 프로토콜이다.


 장치들이 동적으로 적절한 IP주소들을 찾을 수 있도록 고안된 프로토콜로 2014년 기준 IPv4 네트워크의 표준이 되었다고 한다.


 TCP/IP 통신을 실행하기 위한 설정 정보의 할당을 관리하며 그를 위해 네트워크 관리자들이 IP 주소를 중앙에서 관리하고 할당할 수 있게 제공한다.


 OSI 상위 계층의 프로토콜들은 DHCP를 통해 결정지어진 IP 주소를 기반으로 인터넷을 이용하게 된다.



 인터넷에 접근 시 DHCP를 사용하지 않는 경우에는 컴퓨터마다 IP가 수작업으로 입력되어야 하며 다른 네트워크로 편입 시 IP 주소를 새로 받아야 한다. DHCP는 이를 자동으로 할당하게 끔 해준다.


(1)  DHCP Discover : 단말이 DHCP 서버를 찾기 위해 동일 Subnet 상에 브로드캐스트.


(2)  DHCP Offer : DHCP 서버가 단말로 단말에 할당할 IP, Gateway IP 등 네트워크 정보를 송신


(3)  DHCP Request : 단말이 DHCP 들 중 자신이 사용할 DHCP 서버를 선택하고 해당 서버에 자신이 사용할 네트워크 정보를 요청


(4)  DHCP ACK : 선택된 DHCP 서버가 단말로 네트워크 정보를 송신 -> 인터넷 가능

 

 

본 내용은 위키에도 잘 정리되어있으니, 좀 더 공부하고자 한다면 참고하면 좋다.

(https://ko.wikipedia.org/wiki/%EB%8F%99%EC%A0%81_%ED%98%B8%EC%8A%A4%ED%8A%B8_%EA%B5%AC%EC%84%B1_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C)




가끔 프로젝트 관리를 하다보면 인코딩이 말썽을 일으킬 때가 있다. 

가령 원격 환경에서 GIT 작업을 했는데, 마침 에디터가 제공하는 인코딩이 달라서 저장할 때 파일 전체의 인코딩이 바뀌는 경우가 있다.

(대표적인 경우로 메모장이나 이상하게 세팅되어있던 예전 노트북의 에디터 플러스가 그랬다.)


관련 일을 하는 것이 아니라면 일반 개발자에게 크게 중요하지는 않아보이지만 어느정도 기본적인 유니코드에 대해서 지식은 필요하다고 생각한다.



일반 유니코드는 모든 글자를 2byte로 표현하는 모든 문자를 표현할 수 있는 기본적인 인코딩 형식이다

HTML로 작성이 불가능하다.


 UTF8 인코딩은 모든 문자를 표현하기 위한 개선된 인코딩 형식으로 영문/숫자/기호는 1byte, 

한글 및 한자 등은 3byte를 잘 안쓰이는 문자는 4byte로 표현한다.


통상 유니코드라 하면 UTF8인코딩을 의미하기 때문에, 웬만한 설정은 UTF-8 로 통일시켜주면 큰 문제는 일어나지 않는다.


 *참고로 EUC-KR은 한글 인코딩에 특화되어있는 유니코드 인코딩으로 한글에 2Byte를 사용한다.





 모놀리식 아키텍처란, 마이크로서비스의 각광에 따라 마이크로서비스가 아닌 전통의 아키텍처를 지칭하는 의미로 생겨난 단어이다. 위의 그림에서 처럼 모든 모듈은 서비스 내부의 Product 형태로 종속되어 있으며, 서비스에만 집중할 수 있는 구조로 되어 있다.


이는 Monolithic 이라는 단어의 뜻 그대로 하나의 Massive 한 Context 형태의 아키텍처를 의미하며 

하나의 서비스 또는 어플리케이션이 하나의 거대한 아키텍처를 가질 때, Monolithic 하다고 한다. 


 모놀리식 아키텍처를 갖는 Software의 특징은 그 자체로 강건하며 내부 요소간의 Dependency 를 크게 가질 수 있다는 점이다. 그리고 이는 필연적으로 구조적인 Coupling 이 강력하게 유지되는 결과를 초래한다. 


 또한 각 비즈니스 컴포넌트들이 하나의 강한 결합 구조를 지니며 통일성이 있다.

이는 비즈니스 로직이 서비스에 최적화된 코드를 만들어내는데 좀 더 집중할 수 있는 반면 복합적인 예외를 만들 수 있는 위험성을 내포하게 된다.



장점과 단점


 개발 초기에는 단순한 아키텍처 구조와 개발의 용이함이 큰 장점이지만 규모가 커짐에 따라 복잡도가 심각하게 증가한다.


 가령 토이 프로젝트를 한다고 생각해보자. 생각이 흐르는대로 Prototyping 을 할 때는 구조가 복잡하고 Dependency 가 크더라도 손쉽게 만들 수 있으며 오히려 모듈별로 분리하고 나누는 것은 코드의 최적화 및 구현에 방해가 되는 경우가 많다.


 그러나 프로토 타이핑 이후에 새로운 컨텐츠를 추가하거나 새로운 팀원이 생겼을 때 문제는 시작된다. 이 거대한 구조가 본인에게는 간단하고 쉬울 수 있으나 새로운 팀원에게는 가혹하게 느껴질 것이다.


 또한 최근 클라우드 환경이 각광받으면서 두드러지게된 단점으로 하나의 모듈을 수정하기 위해서는 전체 어플리케이션의 배포가 수반되며 서버 기동, 빌드 및 배포 시간이 오래걸린다는 점이 있다.


마이크로 서비스 아키텍처 관련 포스팅에서 한번 더 언급을 하겠으나, 일반적으로 마이크로서비스 아키텍처의 Scalability 복잡도가 N+M 이라면 모놀리식 아키텍처의 복잡도는 N*M 형태로 증가하기 때문에 컨테이너의 과부하와 배포 및 스케일링의 어려움을 겪게 된다.


또한 기술 스택의 선택폭이 좁아지며 많은 문제를 해결하기 위해 보다 강력하고 탄탄한 기술력이 요구된다. 이는 내부 구성요소들 간의 강력한 Dependency 문제 때문이다. 한 모듈의 선택은 다른 외부 모듈에서 버그를 초래할 수 있다. 따라서 사용하고자 하는 프로젝트의 큰 그림이 아키텍처 구성 단계에서 그려져 있어야 문제를 최소화할 수 있다.


 최근에는 많은 서비스들이 초창기에 모놀리식으로 개발되고 향후 마이크로서비스 아키텍처로 구조를 변경한다. 

혹은 인프라가 잘 갖추어진 회사에서라면 여러분을 도와줄 많은 플랫폼들이 이미 마이크로 서비스 아키텍처로 존재할 것이다.






IP 주소를 이해하는데 있어 중요한 개념이 서브넷 마스크의 개념이다.



많이 알려져있듯이 서브넷 마스크는 커다란 네트워크를 다루기 위해 서브넷으로 네트워크들을 분리하고 나누어진 네트워크를 지정(designated) 하는 데 사용된다. 


서브넷 마스크는 서브넷을 분리하기위한 기준으로 클래스별로 어디까지가 네트워크 부분이고 어디까지가 호스트부분인가를 나타낸다. 


서브넷 마스크는 다음과 같은 형태를 띈다.


Class A: 255.0.0.0


Class B: 255.255.0.0


Class C: 255.255.255.0


클래스 A가 명시하는 바는, IP주소의 첫 8개 비트가 네트워크 영역을, 나머지 24 비트가 호스트 영역을 나타낸 다는 것을 의미한다. 


여기서 기존의 IP 주소와 자신이 갖고 있는 서브넷 마스크를 AND 연산 하면 네트워크 주소를 얻을 수 있다.


AND 연산이 갖는 의미는 자신이 가진 IP 주소의 1만큼의 부분, 즉 AND 연산으로 살아남는 부분들은 네트워크의 주소라는 일종의 Masking 이 된다. 


그리고 나머지 네트워크 주소가 아닌 호스트의 주소가 의미하는 바는 해당 서브넷에서 호스트로 할당할 수 있는 IP 주소의 범위가 된다. 


이 때 얻어진 네트워크 주소에서 Subnet Mask 의 0으로 된 비트를 모두 1로 바꾸어주면, 즉 마지막 주소가 브로드캐스트 주소가 된다.




가령 위와 같은 IP 주소가 Class C 의 서브넷 마스크를 가질 때, 위의 AND 연산의 결과로 다음과 같은 주소를 알아낼 수 있다.

(AND 연산은 연산하고자 하는 두 비트가 모두 1이면 1을, 그렇지 않으면 0을 반환한다.)


- 네트워크 주소 : 10.9.32.0

- 브로드캐스팅 주소 : 10.9.32.255

- Gateway 주소 : 10.9.32.1 (끝자리만 다른형태로 일반적으로 1)


이렇게 서브넷 마스크를 이용해서 서브넷을 나누는 것을 서브넷팅 이라 한다.

위의 변환은 일반적인 Class 의 서브넷팅을 설명한 내용이고 서브넷 마스크의 기본적인 동작을 나타낸다. 위와 같이 기본 Class C 로 나눈 경우에 해당 서브넷에 할당된 주소는 256개가 된다. 만약 나누어야하는 지역의 IP 가 이보다 훨씬 수가 적다면 이렇게 나누는 것은 낭비가 될 수 있으므로, 그럴 때는 서브넷 마스크를 변경하여 호스트 수를 조절하는 방법도 가능하다. 그리고 이를 bit를 빌려온다(borrowed)라고 표현한다. (ex) 255.255.255.128


(*서브넷팅에 대한 좀더 발전된 사례는 클라우드 쪽 포스팅에서 다룰 수 있을 듯 하다.)



위와 같은 원리로 분리된 서브넷 들을 연결한다면 다양한 네트워크를 연결하여 거대한 네트워크를 구성하기에 효율적이며 관리적 측면에서도 용이하다.


이렇게 분리된 네트워크가 갖는 장점은 보다 기능적인 브로드 캐스팅 도메인을 구성할 수 있고, 


좀 더 큰 의미에서 보자면 IP 주소의 절약 및 효율적인 사용에도 도움이 되기 때문이다. 


라우터를 중간에 둔 상태에서 여러 개의 간섭받지 않는 서브넷을 둔다면 큰 네트워크는 단지 대표 주소 들에 대한 서브넷을 관리하여 계층적인 구조를 이룰 수 있기 때문이다. (자세한 내용은 라우터를 다루면서 한번 더 정리한다.)



일반적인 서브넷은 IP 네트워크 주소를 지역적으로 나누기 때문에, IP가 바뀌더라도 LAN은 동일한 서브넷으로 묶인다. 





+ Recent posts