Docker 명령의 --net = host 옵션은 실제로 무엇을합니까?


90

저는 Docker에 약간의 초보자입니다. 이 옵션이 docker run 명령에서 수행하는 작업에 대한 명확한 설명을 찾을 수 없었습니다.

포트를 지정하지 않고 Docker 컨테이너에서 실행되는 애플리케이션에 액세스하는 데 사용할 수 있습니까? 예를 들어 -p 8080:8080docker run 명령의 옵션을 사용하여 포트 8080에서 docker 이미지를 통해 배포 된 웹앱을 실행하는 경우 Docker 컨테이너 ip / theWebAppName의 8080 포트에서 액세스해야한다는 것을 알고 있습니다. 그러나 나는 --net=host옵션이 어떻게 작동 하는지 정말로 생각할 수 없습니다 .

답변:


127

Docker 설치 후 기본적으로 3 개의 네트워크가 있습니다.

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f3be8b1ef7ce        bridge              bridge              local
fbff927877c1        host                host                local
023bb5940080        none                null                local

나는 이것을 단순하게 유지하려고 노력하고있다. 따라서 기본적으로 컨테이너를 시작하면 브리지 (docker0) 네트워크 내부에 생성됩니다.

$ docker run -d jenkins
1498e581cdba        jenkins             "/bin/tini -- /usr..."   3 minutes ago       Up 3 minutes        8080/tcp, 50000/tcp   friendly_bell

jenkins의 dockerfile에서 포트 808050000노출됩니다. 해당 포트는 브리지 네트워크의 컨테이너에 대해 열립니다. 따라서 해당 브리지 네트워크 내부의 모든 것이 포트 808050000. 브리지 네트워크에있는 모든 것은 비공개 범위에 "Subnet": "172.17.0.0/16",있습니다. 외부에서 액세스하려면으로 포트를 매핑해야합니다 -p 8080:8080. 그러면 컨테이너의 포트가 실제 서버 (호스트 네트워크)의 포트에 매핑됩니다. 따라서 서버에 액세스 8080하면 포트의 브리지 네트워크로 라우팅됩니다 8080.

이제 호스트 네트워크도 있습니다. 컨테이너 네트워킹을 컨테이너화하지 않습니다. 따라서 호스트 네트워크에서 컨테이너를 시작하면 다음과 같이 표시됩니다 (첫 번째).

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
1efd834949b2        jenkins             "/bin/tini -- /usr..."   6 minutes ago       Up 6 minutes                              eloquent_panini
1498e581cdba        jenkins             "/bin/tini -- /usr..."   10 minutes ago      Up 10 minutes       8080/tcp, 50000/tcp   friendly_bell

차이점은 포트에 있습니다. 이제 컨테이너가 호스트 네트워크 내부에 있습니다. 따라서 8080호스트에서 포트를 열면 컨테이너에 즉시 액세스 할 수 있습니다.

$ sudo iptables -I INPUT 5 -p tcp -m tcp --dport 8080 -j ACCEPT

8080방화벽에서 포트 를 열었고 이제 포트 에서 서버에 8080액세스 할 때 젠킨스에 액세스하고 있습니다. 나는 이 블로그 가 그것을 더 잘 이해 하는데도 유용 하다고 생각한다 .


4
--net=hostDockerfile 내부에 옵션을 추가 할 수 있습니까?
AnirbanDebnath

6
@AnirbanDebnath 나는 그것을 dockerfile에 넣을 수 없다고 생각하지만 docker v17 이후로 docker 빌드의 매개 변수로 사용할 수 있습니다 docker build --network=host. Docker 빌드 용으로 지정된 호스트 네트워크는 이미지 빌드에 필요한 패키지를 다운로드하기위한 것입니다. 호스트 네트워크에서 컨테이너를 실행하려면 --network = host 옵션을 정의해야합니다.
lvthillo

예 @AnirbanDebnath, Dockerfile에서 허용됩니다. 예 : v3에서- network_mode: "host"( ref-docs.docker.com/compose/compose-file/#network_mode )
Mohnish

컨테이너를 실행하는 방법을 설명하는 Docker-Compose 파일입니다. Dockerfile이 아닙니다. 그러나 실제로 가능하며 docker run
--network

27

--net=host옵션은 Docker 컨테이너 내부의 프로그램이 네트워크 관점에서 호스트 자체에서 실행중인 것처럼 보이게하는 데 사용됩니다. 컨테이너가 일반적으로 얻을 수있는 것보다 더 많은 네트워크 액세스를 허용합니다.

일반적으로 호스트 컴퓨터에서 컨테이너로 포트를 전달해야하지만 컨테이너가 호스트의 네트워크를 공유 할 때 모든 네트워크 활동은 호스트 컴퓨터에서 직접 발생합니다. 프로그램이 내부가 아닌 호스트에서 로컬로 실행되는 것처럼 컨테이너.

이것은 더 이상 포트를 노출하고 컨테이너 포트에 매핑 할 필요가 없음을 의미하지만, 두 개의 컨테이너가 동일한 작업에서 작동 할 수 없기 때문에 충돌을 피하기 위해 Dockerfile을 편집하여 각 컨테이너가 수신하는 포트를 조정해야 함을 의미합니다. 호스트 포트. 그러나이 옵션의 실제 이유는 포트 수준에서 컨테이너로 전달하기 어려운 네트워크 액세스가 필요한 앱을 실행하기위한 것입니다.

예를 들어 DHCP 서버를 실행하려면 네트워크에서 브로드 캐스트 트래픽을 수신하고 패킷에서 MAC 주소를 추출 할 수 있어야합니다. 이 정보는 포트 전달 프로세스 중에 손실되므로 Docker 내에서 DHCP 서버를 실행하는 유일한 방법은 컨테이너를 --net=host.

일반적으로 --net=host매우 구체적이고 비정상적인 네트워크 요구가있는 프로그램을 실행할 때만 필요합니다.

마지막으로 보안 관점에서 Docker 컨테이너는 단일 포트만 광고 (노출)하더라도 여러 포트에서 수신 대기 할 수 있습니다. 일반적으로 이것은 당신이 사용하는 경우는 있지만, 하나의 예상 포트를 전달로 괜찮 --net=host다음거야 모든 호스트에서 수신 컨테이너의 포트를, 심지어 Dockerfile에 나열되지 않은. 즉, 컨테이너를 면밀히 확인해야합니다 (특히 소프트웨어 프로젝트에서 제공하는 공식 컨테이너가 아닌 경우). 실수로 시스템에 추가 서비스를 노출하지 않도록해야합니다.


여러 컨테이너가 '--net = host'옵션으로 시작되면 어떻게됩니까? 요청이 임의의 컨테이너로 전달됩니까?
user482594

@ user482594 : 동일한 컨테이너 내에서 모든 프로그램을 실행 한 것처럼 모두 동일한 네트워크 스택을 공유합니다. 예를 들어 두 개의 웹 서버를 실행하는 경우 서로 다른 포트에서 수신 중인지 확인해야합니다. 그렇지 않으면 두 번째 컨테이너에서 첫 번째 포트가 사용 중이라는 오류가 발생합니다. 들어오는 트래픽은 수신 대기중인 컨테이너로 전달됩니다 (기술적으로 모든 --net=host컨테이너는 트래픽을 볼 수 있지만 물론이 설정에서 실행하는 컨테이너에 관계없이 한 번에 하나의 프로그램 만 주어진 포트에서 수신 할 수 있습니다.) ).
Malvineous

1
  1. --net = "anyname" 과 같은 새로운 네트워크를 만들 수 있습니다.
  2. 이것은 다른 컨테이너에서 서비스를 분리하기 위해 수행됩니다.
  3. 동일한 서비스가 다른 컨테이너에서 실행되고 있지만 포트 매핑은 동일하게 유지되고 첫 번째 컨테이너는 잘 시작되지만 두 번째 컨테이너의 동일한 서비스는 실패한다고 가정합니다. 이를 방지하려면 포트 매핑을 변경하거나 네트워크를 만드십시오.

1
"2. 이것은 다른 컨테이너에서 (네트워크) 서비스를 분리하기 위해 수행됩니다"라고 언급 해 주셔서 감사합니다. host동일한 호스트에서 여러 컨테이너를 실행할 가능성이있는 경우 다른 도커 네트워크 구성 (이외 ) 을 사용하는 것의 가치가 있습니다. 다른 경우 (네트워크 격리가 필요하지 않은 경우)에는 --net=host.
CᴴᴀZ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.