[docker] Docker에서 “노출”과 “게시”의 차이점은 무엇입니까?

Dockerfiles를 실험 중이며 대부분의 논리를 이해한다고 생각합니다. 그러나이 컨텍스트에서 포트를 “노출”과 “게시”하는 것의 차이점은 보이지 않습니다.

내가 본 모든 튜토리얼 EXPOSE은 Dockerfile에 다음 명령을 포함합니다 .

...
EXPOSE 8080
...

그런 다음이 Dockerfile에서 이미지를 작성합니다.

$ docker build -t an_image - < Dockerfile

그런 다음 이미지를 실행할 때 위와 동일한 포트 를 게시 하십시오.

$ docker run -d -p 8080 an_image

또는 모든 포트를 사용하여 게시

$ docker run -d -P an_image

Dockerfile에 포트가 노출 될 경우 포트가 노출되는 시점은 무엇입니까? 포트를 먼저 노출하고 나중에 게시 하지 않아야 합니까? 효과적으로, 이미지를 만들 때 Dockerfile에서 사용할 모든 포트를 지정한 다음 다시 방해하지 않고 간단히 다음과 같이 실행합니다.

$ docker run -d an_image

이것이 가능한가?



답변

기본적으로 세 가지 옵션이 있습니다.

  1. 지정 EXPOSE하거나 지정 하지 마십시오-p
  2. 지정 만 EXPOSE
  3. 지정 EXPOSE하고-p

1) 당신은 지정하지 둘 경우 EXPOSE-p, 컨테이너의 서비스는에서 액세스 할 수 있습니다 내부 컨테이너 자체.

2) EXPOSE포트 인 경우 컨테이너의 서비스는 Docker 외부가 아니라 다른 Docker 컨테이너 내부에서 액세스 할 수 있습니다. 컨테이너 간 통신에 좋습니다.

3) 귀하 EXPOSE-p포트 인 경우 컨테이너의 서비스는 Docker 외부에서도 어디서나 액세스 할 수 있습니다.

두 가지가 분리 된 이유는 다음과 같은 이유로 IMHO입니다.

  • 호스트 포트 선택은 호스트에 따라 다르므로 Dockerfile에 속하지 않습니다 (그렇지 않으면 호스트에 따라 다름).
  • 컨테이너의 서비스를 다른 컨테이너에서 액세스 할 수 있으면 충분합니다.

문서는 명시 적으로 상태 :

EXPOSE명령은 링크 내에서 사용할 포트를 제공합니다.

또한 컨테이너연결 하는 방법을 알려줍니다. 기본적으로 내가 이야기 한 컨테이너 간 통신입니다.

추신 : 당신이 -p하지는 않지만 EXPOSEDocker는 암시 적을 수행합니다 EXPOSE. 포트가 공개적으로 열려 있으면 다른 Docker 컨테이너에도 자동으로 열려 있기 때문입니다. 따라서 -p포함됩니다 EXPOSE. 그렇기 때문에 위의 네 번째 사례로 나열하지 않았습니다.


답변

짧은 답변:

  • EXPOSE문서화 하는 방법입니다
  • --publish(나 -p)의 방법 으로 매핑 호스트 포트를 실행에 컨테이너 포트

아래에 주목하십시오 :

  • EXPOSE관련 Dockerfiles( 문서화 )
  • --publish관련 docker run ...( 실행 / 런타임 )

포트 노출 및 게시

Docker 네트워킹에는 네트워크 포트를 직접 포함하는 두 가지 메커니즘, 즉 포트 노출 및 게시가 있습니다. 이는 기본 브리지 네트워크 및 사용자 정의 브리지 네트워크에 적용됩니다.

  • EXPOSEDockerfile 의 키워드 또는 --exposedocker run 의 플래그를 사용하여 포트를 노출 합니다. 포트 노출 은 사용되는 포트 를 문서화 하는 방법 이지만 실제로 포트를 매핑하거나 열지는 않습니다 . 포트 노출은 선택 사항입니다.

  • --publish또는 --publish-all플래그를 사용하여 포트를 게시 합니다 docker run. 이것은 Docker에게 컨테이너의 네트워크 인터페이스에서 열 포트를 알려줍니다. 포트가 게시 될 때 30000런타임에 호스트 시스템에 매핑 할 포트를 지정하지 않는 한 포트는 호스트 시스템에서 사용 가능한 상위 포트 (보다 큼 )에 매핑됩니다. 이미지를 빌드 할 때 (Dockerfile에서) 이미지를 실행하는 호스트 시스템에서 포트를 사용할 수 있는지 보장 할 방법없기 때문에 호스트 시스템에서 맵핑 할 포트를 지정할 수 없습니다 .

from : 도커 컨테이너 네트워킹

2019 년 10 월 업데이트 : 위의 텍스트는 더 이상 문서에 없지만 보관 된 버전은 다음과 같습니다. docs.docker.com/v17.09/engine/userguide/networking/#exposing-and-publishing-ports

현재 문서는 다음과 같습니다.

게시 된 포트

기본적으로 컨테이너를 만들면 해당 컨테이너의 포트가 외부에 게시되지 않습니다. Docker 외부의 서비스 또는 컨테이너 네트워크에 연결되지 않은 Docker 컨테이너에서 포트를 사용 가능하게하려면 --publish또는 -p플래그를 사용하십시오 . 컨테이너 포트를 Docker 호스트의 포트에 매핑하는 방화벽 규칙을 만듭니다.

docs.docker.com/config/containers/container-networking/#published-ports 에서 찾을 수 있습니다.

또한,

폭로

EXPOSE명령 은 실제로 포트를 게시하지 않습니다 . 이미지를 작성하는 사람과 컨테이너를 실행하는 사람 사이에서 공개 할 포트에 대한 문서 유형으로 작동합니다.

from : Dockerfile 참조


EXPOSE/ --publish가 정의되지 않은 경우 서비스 액세스 :

에서 @Golo 로덴의 대답은 그것은 것을 주장한다 ::

“이 중 하나를 지정하지 않으면 컨테이너 내부의 서비스를 제외하고는 컨테이너의 서비스에 액세스 할 수 없습니다.”

어쩌면 답이 기록되는 당시 사건이었다,하지만 지금은 사용하지 않는 경우에도 것 같습니다 EXPOSE또는 --publishhost다른 containers같은 네트워크의 사용자가 해당 컨테이너 안에 시작할 수있는 서비스에 액세스 할 수 있습니다.

이것을 테스트하는 방법 :

나는 다음을 사용했다 Dockerfile. 기본적으로 우분투로 시작하여 작은 웹 서버를 설치합니다.

FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd

나는 build“testexpose”라는 이미지 run와 다음 과 같은 새로운 컨테이너를 가지고 있습니다.

docker run --rm -it testexpose bash

컨테이너 안에서 다음과 같은 몇 가지 인스턴스를 시작합니다 mini-httpd.

root@fb8f7dd1322d:/# mini_httpd -p 80
root@fb8f7dd1322d:/# mini_httpd -p 8080
root@fb8f7dd1322d:/# mini_httpd -p 8090

그런 다음 curl호스트 또는 다른 컨테이너에서의 홈 페이지를 가져올 수 mini-httpd있습니다.


답변

공식 문서 참조를 참조하십시오 : https://docs.docker.com/engine/reference/builder/#expose

EXPOSE당신이 컨테이너가 실행 중일 때의 이미지 빌드시에 노출 개인 (용기)과 공공 (호스트) 포트를 정의 할 수 있습니다 경우 당신이 용기를 실행합니다 -P.

$ docker help run
...
  -P, --publish-all                    Publish all exposed ports to random ports
...

공개 포트 및 프로토콜은 선택 사항입니다. 공개 포트가 지정되지 않은 경우 Docker가 호스트에서 임의의 포트를 선택하여 Dockerfile의 지정된 컨테이너 포트를 표시합니다.

호스트 당 하나의 컨테이너 만 제한하므로 공용 포트를 지정하지 않는 것이 좋습니다 (두 번째 컨테이너는 이미 사용중인 포트를 처리 함).

당신은 사용할 수 있습니다 -pdocker run노출 된 용기 포트가 연결 가능한 일 무슨 공공 포트를 제어 할 수 있습니다.

어쨌든 EXPOSE( -P도커 실행시) 또는 -p을 사용하지 않으면 포트가 노출되지 않습니다.

항상 사용하는 경우 -pdocker run당신이 할 필요가 수행 EXPOSE하지만, 당신이 사용하는 경우 EXPOSE당신 docker run더 간단 할 수있다 명령을 EXPOSE사용하면 포트가 호스트에 노출 될 것을 걱정하지 않는 경우에 유용 할 수 있습니다, 또는 당신은 단지 하나의 컨테이너의 확신하는 경우로드됩니다.


답변

Dockerfile의 EXPOSE 키워드 또는 –expose 플래그를 사용하여 포트를 docker run에 노출합니다. 포트 노출은 사용되는 포트를 문서화하는 방법이지만 실제로는 포트를 맵핑하거나 열지 않습니다. 포트 노출은 선택 사항입니다.

출처 : github commit


답변

대부분의 사람들은 도커 작성 네트워크를 사용합니다. 설명서 에는 다음 이 명시되어 있습니다.

Docker 네트워크 기능은 네트워크 내에서 포트를 노출 할 필요없이 네트워크 생성을 지원합니다. 자세한 내용은이 기능의 개요를 참조하십시오).

컨테이너 간 통신에 네트워크를 사용하는 경우 포트 노출에 대해 걱정할 필요가 없습니다.


답변

EXPOSE는 로컬 포트 ​​컨테이너 포트를 매핑하는 데 사용됩니다. 즉, docker 파일에 노출을 지정하면

EXPOSE 8090

localhost 포트 8090을 컨테이너 포트 8090에 매핑합니다.


답변