programing

활성 도커 컨테이너의 포트 노출

telecom 2023. 7. 29. 08:12
반응형

활성 도커 컨테이너의 포트 노출

풀온 가상 시스템처럼 작동하는 도커 컨테이너를 생성하려고 합니다.할 수 , EXPLEX를 할 수 .-p로깃을든발로 기치를 docker run포트를 할당하지만 컨테이너가 실제로 실행되면 추가 포트를 라이브로 열고 매핑하는 명령이 있습니까?

예를 들어, sshd를 실행하는 도커 컨테이너가 있다고 가정해 보겠습니다.컨테이너 ssh를 사용하는 다른 사용자가 에 들어가 httpd를 설치합니다.컨테이너의 포트 80을 노출하고 호스트의 포트 8080에 매핑하여 사람들이 컨테이너에서 실행 중인 웹 서버를 다시 시작하지 않고 방문할 수 있는 방법이 있습니까?

도커를 통해 이 작업을 수행할 수는 없지만 호스트 시스템에서 컨테이너의 노출되지 않은 포트에 액세스할 수 있습니다.

포트 8000에서 실행 중인 컨테이너가 있는 경우

wget http://container_ip:8000

컨테이너의 IP 주소를 가져오려면 다음 두 가지 명령을 실행합니다.

docker ps
docker inspect container_name | grep IPAddress

내부적으로 도커는 이미지를 실행할 때 iptables를 호출하기 위해 셸을 사용하므로 이에 대한 변형이 효과적일 수 있습니다.

로컬 호스트의 포트 8001에서 컨테이너의 포트 8000을 표시하려면:

iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

이 문제를 해결할 수 있는 한 가지 방법은 원하는 포트 매핑을 사용하여 다른 컨테이너를 설정하고 iptables-save 명령의 출력을 비교하는 것입니다(그러나 트래픽이 도커 프록시를 통과하도록 강제하는 다른 옵션 중 일부를 제거해야 했습니다).

참고: 이 작업은 도커를 전복시키므로 파란색 연기가 발생할 수 있다는 점을 인식하고 수행해야 합니다.

OR

또 다른 대안은 랜덤 호스트 포트를 사용하는 P 옵션을 검토한 다음 연결하는 것입니다.

OR

0.6.5에서는 LINKs 기능을 사용하여 기존 컨테이너와 통신하는 새 컨테이너를 불러올 수 있으며, 해당 컨테이너의 -p 플래그에 대한 추가 릴레이 기능을 사용할 수 있습니다.(아직 LINK를 사용하지 않았습니다.)

OR

도커 0.11로?사용할 수 있습니다.docker run --net host ..컨테이너를 호스트의 네트워크 인터페이스에 직접 연결합니다(즉, 넷은 네임스페이스가 아닙니다). 따라서 컨테이너에서 여는 모든 포트가 노출됩니다.

제가 할 일은 다음과 같습니다.

  • 활성 컨테이너를 커밋합니다.
  • 포트가 열린 상태에서 새 이미지로 컨테이너를 다시 실행합니다(공유 볼륨을 마운트하고 SSH 포트도 여는 것이 좋습니다).
sudo docker ps 
sudo docker commit <containerid> <foo/live>
sudo docker run -i -p 22 -p 8000:80 -m /data:/data -t <foo/live> /bin/bash

기존 컨테이너의 새 포트를 노출할 수는 없지만 동일한 Docker 네트워크에서 새 컨테이너를 시작하여 트래픽을 원래 컨테이너로 전달하도록 할 수 있습니다.

# docker run \
  --rm \
  -p $PORT:1234 \
  verb/socat \
    TCP-LISTEN:1234,fork \
    TCP-CONNECT:$TARGET_CONTAINER_IP:$TARGET_CONTAINER_PORT

작업 예제

포트 80을 수신하지만 내부 포트 80을 노출하지 않는 웹 서비스를 시작합니다(Ops!).

# docker run -ti mkodockx/docker-pastebin   # Forgot to expose PORT 80!

Docker 네트워크 IP 찾기:

# docker inspect 63256f72142a | grep IPAddress
                    "IPAddress": "172.17.0.2",

시작verb/socat노출된 IP의 808080으로 . IP의 포트 80:80은 TCP의 포트 80입니다.

# docker run --rm -p 8080:1234 verb/socat TCP-LISTEN:1234,fork TCP-CONNECT:172.17.0.2:80

이제 http://localhost:8080/의 pastebin에 액세스할 수 있으며 요청은 다음으로 이동합니다.socat:1234그것을 전달하는 것.pastebin:80반응이 역방향으로 같은 경로를 이동합니다.

적어도 Docker 1.4.1에서는 IP 테이블 해킹이 작동하지 않습니다.

가장 좋은 방법은 노출된 포트로 다른 컨테이너를 실행하고 소캣으로 릴레이하는 것입니다.SQL Plus를 사용하여 데이터베이스에 (일시적으로) 연결하기 위해 수행한 작업은 다음과 같습니다.

docker run -d --name sqlplus --link db:db -p 1521:1521 sqlplus

도커 파일:

FROM debian:7

RUN apt-get update && \
    apt-get -y install socat && \
    apt-get clean

USER nobody

CMD socat -dddd TCP-LISTEN:1521,reuseaddr,fork TCP:db:1521

여기 다른 아이디어가 있습니다.SSH를 사용하여 포트 포워딩을 수행합니다. Docker 호스트가 VM인 경우 OS X(및 윈도우즈)에서도 작동할 수 있습니다.

docker exec -it <containterid> ssh -R5432:localhost:5432 <user>@<hostip>

승인된 답변에 추가하기 iptables솔루션을 외부에 공개하려면 호스트에서 두 개의 명령을 더 실행해야 했습니다.

HOST> iptables -t nat -A DOCKER -p tcp --dport 443 -j DNAT --to-destination 172.17.0.2:443
HOST> iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source 172.17.0.2 --destination 172.17.0.2 --dport https
HOST> iptables -A DOCKER -j ACCEPT -p tcp --destination 172.17.0.2 --dport https

참고: 포트 https(443)를 열고 있었는데, 도커 내부 IP가172.17.0.2

참고 2: 이러한 규칙 및 임시 규칙은 컨테이너가 다시 시작될 때까지만 유지됩니다.

저는 이 문제를 해결해야 했고 실행 중인 컨테이너를 멈추지 않고 해결할 수 있었습니다.이는 Docker 1.9.1을 사용하여 2016년 2월 현재 최신 솔루션입니다.어쨌든, 이 대답은 @ricardo-branco의 대답의 상세한 버전이지만, 새로운 사용자를 위해 더 깊이 있습니다.

제 시나리오에서는 컨테이너에서 실행 중인 MySQL에 임시로 연결하려고 했는데, 다른 애플리케이션 컨테이너가 연결되어 있기 때문에 데이터베이스 컨테이너를 중지, 재구성 및 재실행하는 것은 불가능했습니다.

하고 싶기 에 포트 MySQL을 33306호스트 시스템에 있습니다.(아닙니다.3306외부 MySQL 인스턴스가 실행 중인 경우에 대비합니다.)

한 시간 동안 iptables를 조정했지만 다음과 같은 결과가 나왔습니다.

제가 한 일은 다음과 같습니다.

mkdir db-expose-33306
cd db-expose-33306
vim Dockerfile

dockerfile내부에 배치:

# Exposes port 3306 on linked "db" container, to be accessible at host:33306
FROM ubuntu:latest # (Recommended to use the same base as the DB container)

RUN apt-get update && \
    apt-get -y install socat && \
    apt-get clean

USER nobody
EXPOSE 33306

CMD socat -dddd TCP-LISTEN:33306,reuseaddr,fork TCP:db:3306

그런 다음 이미지를 빌드합니다.

docker build -t your-namespace/db-expose-33306 .

다음 컨테이너에 합니다. (-d-rm명시적으로 중지 및 제거될 때까지 백그라운드에 유지합니다.이 경우에는 임시로만 실행하기를 원합니다.)

docker run -it --rm --name=db-33306 --link the_live_db_container:db -p 33306:33306  your-namespace/db-expose-33306

SSH를 사용하여 터널을 생성하고 호스트의 컨테이너를 노출할 수 있습니다.

컨테이너에서 호스트로, 호스트에서 컨테이너로, 그리고 호스트에서 컨테이너로 이 작업을 모두 수행할 수 있습니다.그러나 OpenSSH와 같은 SSH 툴이 둘 다 필요합니다(클라이언트는 클라이언트, 서버는 서버).

예를 들어, 컨테이너에서 다음 작업을 수행할 수 있습니다.

$ yum install -y openssh openssh-server.x86_64
service sshd restart
Stopping sshd:                                             [FAILED]
Generating SSH2 RSA host key:                              [  OK  ]
Generating SSH1 RSA host key:                              [  OK  ]
Generating SSH2 DSA host key:                              [  OK  ]
Starting sshd:                                             [  OK  ]
$ passwd # You need to set a root password..

컨테이너 IP 주소는 다음 행(컨테이너 내)에서 찾을 수 있습니다.

$ ifconfig eth0 | grep "inet addr" | sed 's/^[^:]*:\([^ ]*\).*/\1/g'
172.17.0.2

그런 다음 호스트에서 다음 작업을 수행할 수 있습니다.

sudo ssh -NfL 80:0.0.0.0:80 root@172.17.0.2

Robm의 답변을 기반으로 Docker 이미지와 Bash 스크립트를 만들었습니다.portcat.

포트캣을 사용하면 여러 포트를 기존 도커 컨테이너에 쉽게 매핑할 수 있습니다.(옵션) Bash 스크립트를 사용한 예:

curl -sL https://raw.githubusercontent.com/archan937/portcat/master/script/install | sudo bash
portcat my-awesome-container 3456 4444:8080

자, 여기 있습니다!포트캣 매핑 중:

  • 좌현 3456my-awesome-container:3456
  • 좌현 4444my-awesome-container:8080

Bash 스크립트는 선택 사항이며 다음 명령을 사용할 수 있습니다.

ipAddress=$(docker inspect my-awesome-container | grep IPAddress | grep -o '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' | head -n 1)
docker run -p 3456:3456 -p 4444:4444 --name=alpine-portcat -it pmelegend/portcat:latest $ipAddress 3456 4444:8080

그러길 바랍니다.portcat당신들에게 도움이 될 것입니다.건배!

편리한 HAProxy 포장지가 있습니다.

docker run -it -p LOCALPORT:PROXYPORT --rm --link TARGET_CONTAINER:EZNAME -e "BACKEND_HOST=EZNAME" -e "BACKEND_PORT=PROXYPORT" demandbase/docker-tcp-proxy

그러면 대상 컨테이너에 대한 HA 프록시가 생성됩니다.태평성대

다음은 몇 가지 솔루션입니다.

https://forums.docker.com/t/how-to-expose-port-on-running-container/3252/12

컨테이너를 실행하는 동안 매핑 포트에 대한 솔루션입니다.

도커 실행 -d --net=host myvnc

포트를 호스트에 자동으로 노출하고 매핑합니다.

다른 사용자에게 아무런 응답이 없는 경우 - 대상 컨테이너가 이미 도커 네트워크에서 실행 중인지 확인합니다.

CONTAINER=my-target-container
docker inspect $CONTAINER | grep NetworkMode
        "NetworkMode": "my-network-name",

에 할 수 있도록 합니다.$NET_NAME:

NET_NAME=$(docker inspect --format '{{.HostConfig.NetworkMode}}' $CONTAINER)

가능한 경우 프록시 컨테이너를 동일한 네트워크에서 실행해야 합니다.

다음으로 컨테이너의 별칭을 검색합니다.

docker inspect $CONTAINER | grep -A2 Aliases
                "Aliases": [
                    "my-alias",
                    "23ea4ea42e34a"

에 할 수 있도록 합니다.$ALIAS:

ALIAS=$(docker inspect --format '{{index .NetworkSettings.Networks "'$NET_NAME'" "Aliases" 0}}' $CONTAINER)

지금실을 실행합니다.socat의 .$NET_NAME다리연다하결로▁에 다리를 놓다$ALIAS는 않음) ed ed 너공노포출트의않음테지컨(ed 되개이공않:음)지▁ed):

docker run \
    --detach --name my-new-proxy \
    --net $NET_NAME \
    --publish 8080:1234 \
    alpine/socat TCP-LISTEN:1234,fork TCP-CONNECT:$ALIAS:80

컨테이너에 고유한 IP 주소를 할당하고 모든 포트를 네트워크의 모든 컨테이너 부분에 암시적으로 노출하는 Weave Net과 같은 오버레이 네트워크를 사용할 수 있습니다.

또한 위브는 호스트 네트워크 통합 기능을 제공합니다.기본적으로 비활성화되어 있지만 호스트에서 컨테이너 IP 주소(및 모든 포트)에도 액세스하려면 간단히 실행할 수 있습니다.weave expose.

전체 공개:위브웍스에서 일해요

라이브 포트 매핑을 수행할 수는 없지만 가상 시스템과 같은 실제 인터페이스에 해당하는 Docker 컨테이너를 제공할 수 있는 여러 가지 방법이 있습니다.

Macvlan 인터페이스

이제 도커에는 Macvlan 네트워크 드라이버가 포함되어 있습니다.이렇게 하면 도커 네트워크를 "실제" 인터페이스에 연결하고 해당 네트워크 주소를 컨테이너에 직접 할당할 수 있습니다(가상 시스템 브리지 모드처럼).

docker network create \
    -d macvlan \
    --subnet=172.16.86.0/24 \
    --gateway=172.16.86.1  \
    -o parent=eth0 pub_net

pipework또한 실제 인터페이스를 컨테이너에 매핑하거나 이전 버전의 Docker에서 하위 인터페이스를 설정할 수 있습니다.

라우팅 IP

네트워크를 제어할 수 있는 경우 컨테이너에서 사용할 추가 네트워크를 도커 호스트로 라우팅할 수 있습니다.

그런 다음 해당 네트워크를 컨테이너에 할당하고 패킷을 도커 네트워크를 통해 라우팅하도록 도커 호스트를 설정합니다.

공유 호스트 인터페이스

--net host옵션을 사용하면 호스트 인터페이스를 하나의 컨테이너로 공유할 수 있지만 공유 특성으로 인해 하나의 호스트에서 여러 컨테이너를 실행하기에는 적합하지 않을 수 있습니다.

리카도의 반응을 먼저 읽어보세요.이것은 저에게 효과가 있었습니다.

그러나 실행 중인 컨테이너가 도커 합성을 사용하여 시작된 경우에는 작동하지 않는 시나리오가 있습니다.이는 도커 합성(Docker 1.17을 실행하고 있습니다)이 새 네트워크를 생성하기 때문입니다.이 시나리오를 해결하는 방법은 다음과 같습니다.

docker network ls

그런 다음 다음을 추가합니다.

docker run -d --name sqlplus --link db:db -p 1521:1521 sqlplus --net network_name

도커 실행 -i --docker=22 b5593e60c33bash

참조: https://forums.docker.com/t/how-to-expose-port-on-running-container/3252/5

이것은 당신에게 도움이 될 것입니다.

언급URL : https://stackoverflow.com/questions/19897743/exposing-a-port-on-a-live-docker-container

반응형