저는 Docker에 약간의 초보자입니다. 이 옵션이 docker run 명령에서 수행하는 작업에 대한 명확한 설명을 찾을 수 없었습니다.
포트를 지정하지 않고 Docker 컨테이너에서 실행되는 애플리케이션에 액세스하는 데 사용할 수 있습니까? 예를 들어 -p 8080:8080
docker run 명령의 옵션을 사용하여 포트 8080에서 docker 이미지를 통해 배포 된 웹앱을 실행하는 경우 Docker 컨테이너 ip / theWebAppName의 8080 포트에서 액세스해야한다는 것을 알고 있습니다. 그러나 나는 --net=host
옵션이 어떻게 작동 하는지 정말로 생각할 수 없습니다 .
답변
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에서 포트 8080
와 50000
노출됩니다. 해당 포트는 브리지 네트워크의 컨테이너에 대해 열립니다. 따라서 해당 브리지 네트워크 내부의 모든 것이 포트 8080
및 50000
. 브리지 네트워크에있는 모든 것은 비공개 범위에 "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
액세스 할 때 젠킨스에 액세스하고 있습니다. 나는 이 블로그 가 그것을 더 잘 이해 하는데도 유용 하다고 생각한다 .
답변
이 --net=host
옵션은 Docker 컨테이너 내부의 프로그램이 네트워크 관점에서 호스트 자체에서 실행중인 것처럼 보이게하는 데 사용됩니다. 컨테이너가 일반적으로 얻을 수있는 것보다 더 많은 네트워크 액세스를 허용합니다.
일반적으로 호스트 컴퓨터에서 컨테이너로 포트를 전달해야하지만 컨테이너가 호스트의 네트워크를 공유 할 때 모든 네트워크 활동은 호스트 컴퓨터에서 직접 발생합니다. 프로그램이 내부가 아닌 호스트에서 로컬로 실행되는 것처럼 컨테이너.
이것은 더 이상 포트를 노출하고 컨테이너 포트에 매핑 할 필요가 없음을 의미하지만, 두 개의 컨테이너가 동일한 작업에서 작동 할 수 없기 때문에 충돌을 피하기 위해 Dockerfile을 편집하여 각 컨테이너가 수신하는 포트를 조정해야 함을 의미합니다. 호스트 포트. 그러나이 옵션의 실제 이유는 포트 수준에서 컨테이너로 전달하기 어려운 네트워크 액세스가 필요한 앱을 실행하기위한 것입니다.
예를 들어 DHCP 서버를 실행하려면 네트워크에서 브로드 캐스트 트래픽을 수신하고 패킷에서 MAC 주소를 추출 할 수 있어야합니다. 이 정보는 포트 전달 프로세스 중에 손실되므로 Docker 내에서 DHCP 서버를 실행하는 유일한 방법은 컨테이너를 --net=host
.
일반적으로 --net=host
매우 구체적이고 비정상적인 네트워크 요구가있는 프로그램을 실행할 때만 필요합니다.
마지막으로 보안 관점에서 Docker 컨테이너는 단일 포트만 광고 (노출)하더라도 여러 포트에서 수신 대기 할 수 있습니다. 일반적으로 이것은 당신이 사용하는 경우는 있지만, 하나의 예상 포트를 전달로 괜찮 --net=host
다음거야 모든 호스트에서 수신 컨테이너의 포트를, 심지어 Dockerfile에 나열되지 않은. 즉, 컨테이너를 면밀히 확인해야합니다 (특히 소프트웨어 프로젝트에서 제공하는 공식 컨테이너가 아닌 경우). 실수로 시스템에 추가 서비스를 노출하지 않도록해야합니다.
답변
- –net = “anyname” 과 같은 새로운 네트워크를 만들 수 있습니다.
- 이것은 다른 컨테이너에서 서비스를 분리하기 위해 수행됩니다.
- 동일한 서비스가 다른 컨테이너에서 실행되고 있지만 포트 매핑은 동일하게 유지되고 첫 번째 컨테이너는 잘 시작되지만 두 번째 컨테이너의 동일한 서비스는 실패한다고 가정합니다. 이를 방지하려면 포트 매핑을 변경하거나 네트워크를 만드십시오.