네트워크
네트워크와 IP주소
네트워크는 여러 갱의 장치들이 서로 연결되어서 정보를 주고받을 수 있는 시스템이다.
네트워크는 기계와 기계 사이를 랜선이라는 케이블로 물리적으로 연결한다.
그리고 이 물리적인 케이블을 통해서 전기신호를 통해서 정보를 주고받을 수 있다.
네트워크에서는 전기 신호로 만들어진 정보가 인터넷 선을 타고 기기들 사이를 이동할 수 있다.
바다 건너에 미국에 있는 컴퓨터의 정보를 받아올 때는 아시아와 미국을 연결하는 해저 케이블을 통해 정보를 주고받는다.
정리하면 전 세계의 전자기기들은 물리적인 인터넷 선으로 연결되어 있고 이 선들이 그물망처럼 촘촘히 짜여 있다고 해서 네트워크라고 부르게 되었다. 편지를 보낼 때 주소가 필요한 것처럼 네트워크에서도 어떤 정보를 보내기 위해서는 목적지의 주소가 필요하다.
네트워크에서는 IP 주소로 장치들의 위치를 관리한다. 집들에 각각 고유한 주소가 있는 것처럼 컴퓨터가 인터넷에 연결될 때 IP 주소라는 것을 할당받는다. 이 IP 주소를 활용해서 컴퓨터나 기계들이 인터넷에서 서로를 찾고 통신할 수 있다. IP 주소는 8비트에 3자리 숫자 4개 조합으로 만들어진 주소이다. 그리고 주소 역할을 하려면 고유해야 하기 때문에 다른 IP 주소와 중복될 수 없다.
집 주소와의 차이는 IP가 특정 위치에 고정되어 있는 것은 아니고 IP는 바뀔 수도 있다.
IP 주소는 각각 통신사가 관리하고 있다. 고정적인 IP를 받아서 사용할 수 있고 일반적으로 가정용 인터넷은 동적 IP를 사용하기 때문에 시간이 지나면서 집에 할당된 IP가 바뀔 수도 있다.
정리
네트워크는 기기 간의 정보를 주고받기 위한 통신망
전 세계의 네트워크 신호는 IP 주소 체계를 사용해서 원하는 목적지로 찾아갈 수 있다.
공인 IP와 사설 IP
하나의 IP로 여러 기기가 인터넷을 사용하려면 사설 IP를 활용해야 한다.
IP는 공인 IP와 사설 IP로 분리할 수 있다.
공인 IP와 사설 IP를 집 주소와 집 안에 있는 방의 번호로 비유할 수 있다.
집 주소는 전 세계에서 유일하고, 방 번호는 한 집 안에서만 의미가 있다.
편지를 보낼 때 보내는 목적지에 방 번호만 적으면 정상적으로 보낼 수 없다.
목적지에 인천 42-1 1번 방으로 적어야 정상적으로 보낼 수 있다.
이렇게 공인 IP는 집 주소처럼 인터넷상에서 고유하다.
사설 IP는 집 내부에서 방 번호를 나누는 것처럼 하나의 공인 IP를 나누어서 정의된다.
공인 IP 안에서 사설 IP로 나눌 때는 네트워크 장비가 필요하다.
가정에서 일반적으로는 공유기를 사용한다.
공인 IP를 받는 인터넷 선을 꽂아놓는 부분을 WAN 포트라고 부른다.
WAN 포트는 외부에서 들어오는 인터넷 신호를 연결해야 한다.
그리고 각각의 기기에 연결해서 사설 IP를 분배하는 곳을 LAN 포트라고 부른다.
이 기기의 LAN 선을 연결해서 인터넷 신호를 분배할 수 있다.
그러면 이 공유기에 연결된 장비들은 새로운 사설 IP 주소를 할당받아서 인터넷을 사용할 수 있다.
이 사설 IP는 공유기처럼 하나의 네트워크 장비 안에서만 고유한 것이다.
사설 IP 주소의 대역은 위에 보는 것처럼 정해져 있다.
이 주소 범위에 해당하는 주소는 모두 사설 IP라고 보면 된다.
정리
IP는 외부에서 사용하는 공인 IP와 내부에서만 사용하는 사설 IP로 관리할 수 있다.
공인 IP를 공유기에 연결해서 여러 개의 사설 IP로 분리한다.
이 사설 IP들은 공유기에 연결되어 있는 TV와 컴퓨터, 스마트 폰이 하나씩 받아서 사용하게 된다.
이렇게 사설 IP를 사용하면 하나의 공인 IP만 가지고도 여러 기기들로 인터넷을 나눠서 사용할 수 있다.
공인망과 사설망
이제 IT 기업이 운영하는 인프라 환경으로 이해해 보자.
공인 IP를 사용하는 네트워크 통신을 공인망이라고 부른다.
기업 안에서 사설 IP를 사용한 통신망을 사설망이라고 부른다.
기업에서 사용하는 IP가 124.111.46.91이라고 치면 이 IP를 각각의 사내 서버로 분배해 주는 라우터라는 장비가 존재한다.
라우터는 공유기와 비슷한 역할을 수행한다. 실제로는 기업의 네트워크 환경은 더 복잡한 계층 구조로 되어 있다.
어쨌든 이런 네트워크 장비들을 통해서 결국 맨 아래에 있는 실제 서버에 인터넷 선이 연결되고 사설망의 사설 IP가 할당된다.
인터페이스와 포트
네트워크 인터페이스는 인터넷에 연결하기 위해서 컴퓨터에 장착하는 부품 중의 하나이다.
네트워크의 인터페이스는 IP를 가질 수 있다.
이 네트워크 인터페이스의 IP를 할당받고 인터넷에 연결하려면 네트워크 장비와 랜선으로 연결되어 있어야 한다.
무선 기능을 지원하는 인터페이스는 랜선으로 연결하지 않고 와이파이에 연결해서 사용할 수도 있다.
하나의 기기는 한 개 이상의 네트워크 인터페이스를 장착할 수 있다.
그래서 보통 유선과 무선이 다 되는 노트북 같은 경우는 무선 인터페이스와 유선 인터페이스 두 개가 장착되어 있다.
그러면 이제 서버에 네트워크 인터페이스가 장착되어 있고 이 네트워크 인터페이스에 할당된 IP로 데이터를 주고받는다.
그런데 보통 서버에는 여러 개의 소프트웨어가 실행된다.
실행되는 여러 개의 소프트웨어 중 어떤 소프트웨어로 데이터를 전달하지 지정하는 것이 바로 포트 넘버다.
포트는 물리적으로 존재하지 않고 서버 안에서 정의해서 사용할 수 있다.
네트워크를 사용하는 프로그램은 실행될 때 자기가 사용할 포트를 지정할 수 있다.
NAT와 포트포워딩
네트워크의 통신은 크게 아웃바운드와 인바운드로 나눌 수 있다.
하나의 서버를 기준으로 했을 때 서버에서 출발하는 신호는 아웃바운드이다.
다른 클라이언트나 외부의 서버에서 출발해서 자신의 서버로 오는 통신은 인바운드이다.
그런데 외부 서버와 내부 서버의 통신이 어떻게 이루어질지를 생각해 보면 일단 근본적인 문제가 있다.
외부 서버는 전 세계에서 유일한 공인 IP를 가지고 있는데 내부 서버는 사설망 안에서만 식별 가능한 사설 IP 주소를 가지고 있다.
그러면 외부의 공인 IP와 내부의 사설 IP가 어떻게 통신이 이루어질 수 있을까?
여기서 사용되는 기술이 NAT와 포트포워딩 기술이다.
편지를 보낼 때는 보내는 사람과 받는 사람에 대한 정보를 적어야 한다.
그래야 누가 편지를 보냈는지 알 수 있고 답장도 보낼 수 있다.
네트워크 신호를 보낼 때도 마찬가지로 출발지와 목적지에 정보가 있어야 한다.
아웃바운드처럼 내부에서 시작돼서 외부로 나가는 통신을 한번 생각해 보자.
외부의 공인 IP가 유일한 주소이기 때문에 이 네트워크 안에서 목적지에 문제없이 도착할 수 있다.
예를 들어 192.168.0.4에서 223.130.200.107로 데이터를 전송하는 것은 어렵지 않다.
그러면 이제 반대로 외부 서버에서 출발지로 응답을 보낼 때를 생각해 보자.
외부 서버에서 도착지에는 124.111.46.91로 설정해야 한다.
그래야 네트워크망에서 컴퓨터를 찾아서 올 수 있기 때문이다.
192.168.0.4는 내부에서만 사용하는 IP주소 이기 때문에 외부에서는 이 주소로 찾아올 수 없다.
그래서 실제 네트워크의 도착지인 192.168.0.4로 돌아오려면 추가적인 처리가 필요하다.
이때 사용되는 기술이 NAT라는 기술이다. 이 기술은 공인 IP와 사설 IP를 매핑해 주는 기술이다.
NAT 기술은 공인 IP와 사설 IP의 매핑 테이블을 만들어 둔다.
그리고 어떤 서버로 전달할지에 대한 정보를 기록해 둔다.
사설망을 구성하는 라우터 장비는 모두 NAT 기능을 가지고 있다.
그래서 서버 1에서 만들어진 트래픽이 밖으로 전달될 때 라우터는 NAT 테이블에 서버의 정보를 기록해 둔다.
그리고 외부 서버로 트래픽을 전달할 때 192.168.0.4에서 124.111.46.91:10001으로 수정해서 보낸다.
이를 통해 외부 서버는 서버의 트래픽을 받을 때 출발지가 192.168.0.4처럼 사설 IP가 아니라 124.111.46.91:10001로 인식한다.
그래서 외부 서버에서 서버로 응답을 보낼 때도 124.111.46.91:10001로 응답을 전송한다.
외부 서버로부터 응답이 왔을 때 응답에 기록되어 있는 124.111.46.91:10001 정보를 NAT 테이블에서 확인한 다음에 통신이 시작되었던 1번 서버로 응답을 다시 전달한다. NAT 테이블은 이렇게 공인 IP의 랜덤 한 포트를 여러 개 지정해 두고 각각의 포트에 사설 IP의 정보를 매칭시켜서 활용한다.
이제 InBound 방식에 대해 알아보자.
외부서버에서 공인 IP주소와 공인 포트 번호를 조합하여 전송할 수 있다.
그러면 NAT 테이블의 규칙에 맞추어서 서버 1번이나 서버 2번으로 요청을 전달한다.
그런데 보통은 외부에서 사내망으로 요청을 보내는 경우에는 포트를 랜덤으로 사용한느 것보다 미리 포트를 지정해 두는 것이 자연스럽다.
하지만 NAT 테이블은 동적으로 정보를 관리하기 때문에 외부에서 서버를 접근하는데 혼란이 생길 수 있다.
그래서 외부에서 사내망으로 접근할 때는 포트 포워딩이라는 기술을 사용한다.
사용자가 직접 NAT 테이블과 같은 매핑 정보를 관리하는 것이다.
위 포트포워딩 예시처럼 포트포워딩을 설정하면 외부에서 공인 IP의 포트에 접근할 때 포트 포워딩 룰에 맞는 사설 IP로 변환해서 트래픽을 전달해 준다. 외부 서버에서 124.111.46.91:80 포트로 요청을 보내면 실제로 포트 포워딩을 거쳐서 서버 1:80포트로 전달이 된다.
정리
IP는 공인 IP와 사설 IP로 나눌 수 있다.
공인 IP끼리의 통신을 공인망, 이 공인망에서 라우터를 사용해서 만들어진 내부 네트워크 망을 사설망이라고 한다.
하나의 공인 IP에서 네트워크 신호를 나누기 위해서 사설 IP로 분류한다.
하나의 공인망에서 사설 네트워크를 구축하기 위해서 공유기나 라우터 같은 장비들이 필요하다.
이 장비들에 연결된 기기들이 각각 사설 IP를 할당받는다.
그리고 사설 IP를 할당받은 기기들이 외부의 서버와 통신하기 위해서 NAT와 포트포워딩 기술을 사용한다.
NAT는 보통 내부 서버에서 출발하는 네트워크 신호가 외부 서버를 거쳐서 출발했던 기기로 다시 돌아올 수 있도록 NAT 테이블에 해당 정보를 기록하는 기술이고 포트포워딩 기술은 외부에서 내부 서버로 요청을 보낼 때 사용자가 직접 포트를 지정해서 어떤 포트로 왔을 때 어떤 내부 서버로 전달할지를 지정하는 기술이다.
도커 네트워크
가상 네트워크
지금까지 배운 네트워크는 말 그대로 실제 눈으로 볼 수 있는 인터넷 선들과 장비들로 구성되어 있다.
공인망과 사설망 모두 랜선들과 서버들을 직접 눈으로 관찰할 수 있었다.
이제는 도커 컨테이너 가상화에서 네트워크 구성이 어떻게 되는지 알아보자.
컨테이너 가상화 기술은 서버 한 대를 여러 대의 컨테이너로 격리하는 기술이었다.
가상 네트워크도 역시 서버 한 대 안에서 새로운 네트워크를 구성하는 기술이다.
그리고 이 네트워크 망 안에서 컨테이너들이 서로 통신할 수 있고, 내부의 컨테이너와 바깥의 서버와도 통신할 수 있다.
그래서 가상 네트워크에 대해서 얘기할 때는 서버 한 대 안에 초첨을 맞춰야 한다.
실습용 PC의 IP가 할당된 상태에서 도커의 가상화 기술을 사용해서 내부의 컨테이너를 여러 대 실행시켰다고 생각해 보자.
그러면 이 컨테이너들의 IP는 어떻게 정의되고, 컨테이너 간의 통신은 어떤 식으로 이루어질까?
그리고 다른 외부 네트워크에서 이 컨테이너로 접속하고 싶을 때는 어떤 경로로 접근해야 할까?
이런 모든 요구사항들은 도커의 가상 네트워크 기술을 사용해서 해결할 수 있다.
도커는 가상 네트워크 기술을 활용해서 컨테이너의 네트워크를 구성한다.
이 가상 네트워크는 실제로 인터넷 선이나 공유기 없이 오로지 한 대의 서버 내에서 논리적으로 정의되어 있는 네트워크이기 때문에 가상 네트워크라고 부른다. 그러면 실제로 가상 네트워크가 어떻게 구성되는지 알아보자.
도커를 설치하고 실행시키면 도커는 가상의 네트워크인 브릿지 네트워크와 가상의 공유기인 docker0를 만든다.
여기서 가상의 공유기 docker0를 도커에서는 브릿지라고 부른다. 이 브릿지는 가상의 IP 주소를 할당받는다.
일반적으로는 172.17.0.1의 IP를 할당받는다. 여기서 가상의 IP 주소라는 것은 실제로 존재하는 IP가 아니다.
서버나 실습용 PC 안에서 논리적으로 정의되어 있는 가상의 IP이다.
도커의 브릿지 네트워크는 컨테이너들에게 IP를 할당해주고 컨테이너들끼리 통신할 수 있도록 만들어준다.
도커에서 컨테이너를 실행하면 도커는 브릿지 네트워크의 IP 주소 범위 안에서 컨테이너에 IP 주소를 하나 할당해 준다.
컨테이너 3대를 추가로 실행하면 각각의 컨테이너들은 같은 대역대에서 겹치지 않는 IP를 할당받는다.
이렇게 같은 브릿지에서 생성된 네트워크는 브릿지를 통해서 서로 통신할 수 있다.
정리
도커는 브릿지 네트워크를 통해서 가상 네트워크를 구성하고 컨테이너의 IP를 할당하면서 컨테이너 간의 통신을 전달해 준다.
이렇게 논리적으로 네트워크 환경을 구성하는 기술을 SDN이라고 부른다.
가상 네트워크와 가상 인터페이스
가상 네트워크에서 네트워크 신호가 어떤 원리로 전달되는지 알아보자.
먼저 일반적인 PC나 서버를 설치하면 물리적인 네트워크 인터페이스에 인터넷 선을 꽂아서 사용하게 된다.
이렇게 물리 인터페이스에 인터넷 선을 연결하면 기기의 공인 IP나 사설 IP를 할당받는다.
그리고 이 PC 위에서 도커를 설치하고 실행하면 도커는 가상의 인터페이스를 한 개 생성한다.
그리고 이 가상의 인터페이스는 호스트 OS에 만들어진다.
컨테이너들을 실행할 때 각각의 컨테이너에 해당하는 가상 인터페이스들이 Veth라는 접두어로 호스트 OS에 만들어진다.
여기서 가상의 인터페이스로 전달되는 네트워크 신호는 각각의 인터페이스로 해당되는 컨테이너로 전달된다.
가상의 인터페이스 간의 네트워크 패킷을 전달하는 규칙은 HostOS의 커널 소프트웨어인 IP Tables에 정의된다.
예를 들어 172.17.0.3으로 향하는 요청은 Veth2 인터페이스로 전달하자 라는 규칙이 IP Tables에 정의되어 있다.
IP Tables은 Linux OS의 패킷 필터링 시스템이다.
서버 내부에서 네트워크 트래픽을 제어하고 라우팅 규칙을 정의한다.
IP Tables에는 특정 IP 주소로 네트워크를 보냈을 때 어떤 인터페이스로 전달할지에 대한 규칙이 설정되어 있다.
정리
도커는 컨테이너의 통신을 위해서 브릿지 네트워크를 정의하고 호스트 OS의 가상 인터페이스들을 생성한다.
그리고 호스트 OS의 IP Tables 규칙을 관리하면서 가상 인터페이스들 간의 통신 규칙을 만든다.
그래서 사용자는 별도의 설정을 하지 않아도 같은 브릿지 네트워크에서 생성된 컨테이너들은 서로 통신을 할 수 있는 상태로 구성되어 있다.
그리고 도커는 가상 네트워크 내부에서 여러 개의 브릿지 네트워크를 관리할 수 있다.
네트워크 지도: 컨테이너 간 통신
도커를 설치하면 기본적으로 브릿지 네트워크가 하나 있다.
그리고 세컨드 브릿지 네트워크를 만들었다고 하자.
네트워크를 만들 때는 IP의 대역대를 설정할 수 있다.
세컨드 브릿지 네트워크는 10.0.0.0부터 10.0.0.255까지 지정했다.
그리고 게이트웨이는 10.0.0.1로 지정했다. 그 다음 3개의 컨테이너를 만들었다.
같은 브릿지 네트워크에 있는 우분투A와 우분투B는 서로 통신이 가능하고 우분투C와는 통신이 안된다.
[
{
"Name": "bridge",
"Id": "58cb60a50c7b0fb4e0400a2ff8f7775d996cb18b487037ac4ab205629d5c18f3",
"Created": "2024-08-12T05:43:22.803073458Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"829fd51515171afb4d62780a93890cebb2692077b9c22dbd0e67baa2e85861ab": {
"Name": "mysql-container",
"EndpointID": "f6abf5bdfc3a88ee33af096b5d185a69ec550f04bd887d9290d82126691bc0cb",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "65535"
},
"Labels": {}
}
]
docker network inspect bridge을 실행하면 위와 같이 출력된다.
중요한 부분만 살펴보자.
"Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" }
Subnet: 네트워크 안에서 생성되는 컨테이너들이 할당받는 IP의 범위를 나타낸다. /16으로 표기되어 있는 부분이 IP의 범위를 숫자로 나타내는 CIDR 방식이다. 여기서 16으로 나타낸 부분은 172.17.0.0 ~ 172.17.255.255까지를 의미하는 숫자이다.
Gateway에 표시되어 있는 172.17.0.1이 도커 네트워크에 해당하는 도커 브릿지의 IP 주소이다.
가상 네트워크와 포트포워딩
docker run -p HostOS의포트:컨테이너의포트
HostOS로의 네트워크 접근을 컨테이너로 포트포워딩
가상 네트워크 바깥에 있는 서버에서 컨테이너로 접근하려면 포트포워딩 기술을 사용해야 한다.
외부의 서버에서 컨테이너로 접근하다고 가정해 보자.
외부 서버에서의 접근은 실제로 도커가 실행 중인 192.168.0.10을 통해서 접근을 해야 한다.
여기서 포트포워딩을 사용해서 192.168.0.10의 특정 포트로 접근했을 때 사용자가 지정한 컨테이너로 전달하도록 포트포워딩을 등록해야 한다.
docker run -d -p 8002:3000 --name redColorApp --env COLOR=red devwikirepo/envnodecolorapp
위와 같이 Nginx을 실행하고 여기에 접속하기 위한 방법은 3가지다.
http://localhost:8002/
http://127.0.0.1:8002/
http://192.168.0.30:8002/
localhost는 호스트OS 자신의 주소를 의미한다. 그리고 사실 localhost와 127.0.0.1은 같은 의미다.
192.168.0.30은 현재 본인 PC의 IP다.
192.168.0.30은 사설 IP이기 때문에 이 사설망의 IP를 사용하는 기기들은 192.168.0.30:8002로 접근했을 때 웹서버 컨테이너로 접속할 수 있다. 예를 들어 같은 와이파이를 사용하는 스마트폰에서 포트포워딩을 통해서 컨테이너의 웹서버로 접근할 수 있다.
네트워크 지도: 포트포워딩
가상 네트워크와 DNS
도커는 컨테이너들이 기본적으로 사용할 수 있는 DNS 서버를 제공한다.
이 DNS 서버에는 IP주소와 도메인 명이 저장되어 있다.
여기서 도메인은 컨테이너의 이름으로 자동으로 저장된다.
그래서 컨테이너들은 기본적으로 컨테이너의 IP가 아닌 컨테이너의 이름으로 서로 통신할 수 있다.
즉 같은 네트워크에 속해 있는 컨테이너들은 IP가 아니라 컨테이너의 이름으로 통신할 수 있다.
도커의 네트워크 드라이버
- 브릿지 네트워크(Bridge) : 도커 브릿지를 활용해 컨테이너 간 통신, NAT 및 포트포워딩 기술을 활용해 외부 통신 지원
- 호스트 네트워크(Host) : 호스트의 네트워크를 공유, 모든 컨테이너는 호스트 머신과 동일한 IP를 사용, 포트 중복 불가능
- 오버레이 네트워크(Overlay) : Kubernetes에서 사용, 호스트 머신이 다수일 때 네트워크 관리 기술
- Macvlan 네트워크 : 컨테이너에 MAC 주소를 할당하여 물리 네트워크 인터페이스에 직접 연결
참고
인프런의 개발자를 위한 쉬운 도커 강의를 보고 정리한 글입니다.
'Docker' 카테고리의 다른 글
9. Docker Compose (0) | 2024.08.16 |
---|---|
7. 도커 볼륨 (0) | 2024.08.16 |
5. 컨테이너 애플리케이션 구성 (0) | 2024.08.15 |
4. 이미지 빌드 (0) | 2024.08.14 |
3. 이미지 레지스트리 (0) | 2024.06.29 |