본문 바로가기

Computer Science/Kubernetes(CKA) 자격증 준비

Kubernetes 정리 203: Prerequisite - Docker Networking

Docker가 설치된 서버인 단일 Docker 호스트부터 시작해 보겠습니다.  eth0에 IP 주소 192.168.1.10으로 로컬 네트워크에 연결하는 인터넷 인터페이스가 있습니다.  컨테이너를 실행할 때 선택할 수 있는 네트워킹 옵션이 다릅니다.  

먼저, none 네트워크를 살펴보겠습니다.  네트워크가 none인 경우 도커 컨테이너는 네트워크에 연결되지 않습니다.  컨테이너는 외부 세계에 도달할 수 없고, 외부 세계의 누구도 컨테이너에 도달할 수 없습니다. 여러 컨테이너에 있는 경우 네트워크의 일부가 되지 않고 모두 생성되어 서로 또는 외부와 통신할 수 없습니다.  

다음은 호스트 네트워크입니다.  호스트 네트워크를 사용하면 컨테이너가 호스트 네트워크에 연결됩니다.  호스트와 컨테이너 간에는 네트워크 분리가 없습니다.  컨테이너의 포트 80에서 수신 대기하는 웹 애플리케이션을 배포하면 추가 포트 매핑을 수행하지 않고도 호스트의 포트 80에서 웹 애플리케이션을 사용할 수 있습니다.  동일한 포트에서 수신하는 동일한 컨테이너의 다른 인스턴스를 실행하려고 하면 호스트 네트워킹을 공유하기 때문에 작동하지 않으며 두 프로세스가 동일한 포트에서 동시에 수신할 수 없습니다.  

 

세 번째 네트워킹 옵션은 브리지입니다.  이 경우 Docker 호스트 및 컨테이너가 연결되는 내부 전용 네트워크가 생성됩니다.  네트워크에는 기본적으로 주소 172.17.0.0이 있으며, 이 네트워크에 연결된 각 장치는 이 네트워크에서 자체 내부 전용 네트워크 주소를 얻습니다.  

 

 호스트에 Docker를 설치하면 기본적으로 Bridge라는 내부 전용 네트워크가 생성됩니다.  Docker networks ls 명령을 실행하면 이를 확인할 수 있습니다.  이제 Docker는 네트워크를 Bridge라는 이름으로 부르지만 호스트에서는 네트워크가 Docker0이라는 이름으로 생성됩니다.  이는 IP 링크 명령의 출력에서 확인할 수 있습니다.  도커는 브리지로 설정된 유형으로 IP link add 명령을 실행하여 네임스페이스에서 강의에서 본 것과 유사한 기술을 내부적으로 사용합니다.  따라서 Docker networks 출력의 이름 브리지는 호스트의 이름 Docker0을 참조합니다. 그들은 같은 것입니다.  또한 인터페이스나 네트워크가 현재 중단되었다는 것을 유의해주세요.

브리지 네트워크는 호스트와의 인터페이스와 비슷하지만 호스트 내의 네임스페이스 또는 컨테이너로의 전환과 같다고 말했습니다.  따라서 호스트의 인터페이스 Docker0에는 IP 172.17.0.1이 할당됩니다.  이는 IP ADDR 명령의 출력에서 확인할 수 있습니다.  

컨테이너가 생성될 때마다 Docker는 컨테이너에 대한 네트워크 네임스페이스를 생성합니다.  이전 강의에서 네트워크 네임스페이스를 만든 것처럼 말입니다.  IP netns 명령을 실행하여 네임스페이스를 나열합니다.  도커가 만든 네임스페이스를 나열하는 IP netns 명령을 얻기 위해 수행해야 할 사소한 hack(?)이 있습니다.  자세한 내용은 이 강의의 리소스 섹션을 참조하세요.  네임스페이스의 이름은 B3165로 시작합니다.  Docker inspect 명령 출력에서 각 컨테이너와 연결된 네임스페이스를 확인할 수 있습니다.  

그렇다면 Docker는 컨테이너 또는 네트워크 네임스페이스를 브리지 네트워크에 어떻게 연결할까요? 컨테이너와 네트워크 네임스페이스는 동일한 것을 의미합니다.  내가 컨테이너라고 말할 때, 나는 Docker가 그 컨테이너에 대해 만든 네트워크 네임스페이스를 말하는 것입니다.  그렇다면 도커는 어떻게 컨테이너를 브릿지에 부착할까요?

  우리가 전에 했던 것처럼, 이것은 양쪽 끝에 두 개의 인터페이스가 있는 가상 케이블을 만듭니다.  여기서 도커가 무엇을 만들어냈는지 알아봅시다.  Docker 호스트에서 IP link 명령을 실행하면 로컬 브리지인 Docker0에 연결된 인터페이스의 한쪽 끝이 표시됩니다.  네임스페이스가 있는 -n 옵션을 사용하여 동일한 명령을 다시 실행하면 컨테이너 네임스페이스 내 인터페이스의 다른 쪽 끝이 나열됩니다.  또한 인터페이스는 네트워크 내에서 IP를 할당받습니다.  

컨테이너의 네임스페이스 내에서 IP ADDR 명령을 실행하여 이 정보를 볼 수 있습니다.  컨테이너에 172.17.0.3이 할당됩니다.  컨테이너에 연결하여 컨테이너에 할당된 IP 주소를 확인할 수도 있습니다.  

새 컨테이너가 생성될 때마다 동일한 절차가 수행됩니다.  도커는 네임스페이스를 만들고, 인터페이스 쌍을 만들고, 한쪽 끝을 컨테이너에 연결하고, 다른 쪽 끝을 브리지 네트워크에 연결합니다.  인터페이스 쌍은 번호를 사용하여 식별할 수 있습니다.  홀수와 짝수가 짝을 이룹니다.  9와 10, 7과 8,11과 12는 한 쌍입니다.  컨테이너는 이제 모두 네트워크의 일부입니다.  그들은 모두 서로 의사소통을 할 수 있습니다.  

포트 80의 Docker 호스트 내에서 용기의 IP를 사용하여 curl을 사용하여 웹 페이지에 액세스하려고 하면 웹 페이지가 표시됩니다.  호스트 외부에서 동일한 작업을 수행하려고 하면 웹 페이지를 볼 수 없습니다.  외부 사용자가 컨테이너에 호스팅된 응용프로그램에 액세스할 수 있도록 도커는 포트 게시 또는 포트 매핑 옵션을 제공합니다.  컨테이너를 실행할 때 Docker에게 Docker 호스트의 포트 8080을 컨테이너의 포트 80에 매핑하도록 지시합니다.  이렇게 하면 도커 호스트의 IP와 포트 8080을 사용하여 웹 애플리케이션에 액세스할 수 있습니다.  도커 호스트의 포트 8080에 대한 트래픽은 컨테이너의 포트 80으로 전달됩니다.  이제 모든 외부 사용자와 다른 애플리케이션 또는 서버가 이 URL을 사용하여 호스트에 배포된 애플리케이션에 액세스할 수 있습니다. 

하지만 도커는 어떻게 할까요? 어떻게 한 포트에서 다른 포트로 트래픽을 전달합니까? 도커와 다른 모든 것들은 잠시 잊어버립시다.  요구 사항은 한 포트에서 들어오는 트래픽을 서버의 다른 포트로 전달하는 것입니다.  우리는 그것에 대해 우리의 선행 강의 중 하나에서 이야기했습니다. NAT은 이를 위한 NAT 규칙을 만듭니다.  IP 테이블을 사용하여 NAT 테이블에 항목을 생성하여 대상 포트를 8080에서 80으로 변경하는 규칙을 사전 라우팅 체인에 추가합니다. 도커도 같은 방식으로 합니다.  Docker는 Docker 체인에 규칙을 추가하고 컨테이너의 IP도 포함하도록 대상을 설정합니다.