[linux] 호스트 포트를 도커 컨테이너로 전달

호스트가 Docker 컨테이너 액세스 포트를 열 수 있습니까? 구체적으로 MongoDB와 RabbitMQ가 호스트에서 실행 중이며 Docker 컨테이너에서 프로세스를 실행하여 대기열을 듣고 (선택적으로) 데이터베이스에 쓰려고합니다.

컨테이너에서 호스트로 포트를 전달하고 (-p 옵션을 통해) Docker 컨테이너 내에서 외부 세계 (예 : 인터넷)에 연결할 수 있지만 RabbitMQ 및 MongoDB 포트를 노출하고 싶지 않습니다. 호스트에서 외부 세계로.

편집 : 약간의 설명 :

Starting Nmap 5.21 ( http://nmap.org ) at 2013-07-22 22:39 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00027s latency).
PORT     STATE SERVICE
6311/tcp open  unknown

joelkuiper@vps20528 ~ % docker run -i -t base /bin/bash
root@f043b4b235a7:/# apt-get install nmap
root@f043b4b235a7:/# nmap 172.16.42.1 -p 6311 # IP found via docker inspect -> gateway

Starting Nmap 6.00 ( http://nmap.org ) at 2013-07-22 20:43 UTC
Nmap scan report for 172.16.42.1
Host is up (0.000060s latency).
PORT     STATE    SERVICE
6311/tcp filtered unknown
MAC Address: E2:69:9C:11:42:65 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 13.31 seconds

컨테이너를 사용하여 인터넷 연결을 얻으려면이 트릭을 수행해야했습니다. 내 방화벽이 도커 컨테이너에서 외부로의 네트워크 연결을 차단하고 있습니다.

편집 : 결국 나는 파이프를 사용하여 사용자 지정 브리지를 만들고 서비스를 브리지 IP에서 수신하도록했습니다. MongoDB와 RabbitMQ가 도커 브리지에서 청취하는 대신이 접근법을 사용하여 유연성을 높였습니다.



답변

도커 호스트는 모든 컨테이너에 어댑터를 노출시킵니다. 최근 우분투를 사용한다고 가정하면 실행할 수 있습니다.

ip addr

네트워크 어댑터 목록이 표시됩니다. 그 중 하나는 다음과 같습니다.

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 22:23:6b:28:6b:e0 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
inet6 fe80::a402:65ff:fe86:bba6/64 scope link
   valid_lft forever preferred_lft forever

토끼 / 몽고에게 해당 IP (172.17.42.1)에 바인딩하도록 지시해야합니다. 그런 다음 컨테이너 내에서 172.17.42.1에 대한 연결을 열 수 있어야합니다.


답변

간단하지만 비교적 안전하지 않은 방법은 --net=host옵션을 사용하는 것 docker run입니다.

이 옵션은 컨테이너가 호스트의 네트워킹 스택을 사용하도록합니다. 그런 다음 “localhost”를 호스트 이름으로 사용하여 호스트에서 실행되는 서비스에 연결할 수 있습니다.

Docker 컨테이너의 IP 주소에서 연결을 수락하도록 서비스를 구성 할 필요가 없으며 Docker 컨테이너에 연결할 특정 IP 주소 또는 호스트 이름을 지정할 필요가 없으므로 구성하기가 더 쉽습니다. 포트.

예를 들어, 이미지가 호출 my_image되고 이미지에 telnet유틸리티가 포함되어 있고 연결하려는 서비스가 포트 25에 있다고 가정 한 다음 명령을 실행하여 테스트 할 수 있습니다 .

docker run --rm -i -t --net=host my_image telnet localhost 25

이 방법으로 작업을 고려하는 경우이 페이지의 보안에 대한주의 사항을 참조하십시오

https://docs.docker.com/articles/networking/

그것은 말한다 :

–net = host-Docker에게 컨테이너를 별도의 네트워크 스택 내에 배치하지 않도록 지시합니다. 본질적 으로이 선택은 Docker에게 컨테이너의 네트워킹을 컨테이너화하지 않도록 지시합니다! 컨테이너 프로세스는 여전히 자체 파일 시스템 및 프로세스 목록 및 리소스 제한에 국한되지만 빠른 ip addr 명령은 네트워크 방식으로 메인 Docker 호스트에서 “외부”에 있으며 네트워크 인터페이스에 완전히 액세스 할 수 있음을 보여줍니다 . 이렇게하면 컨테이너가 호스트 네트워크 스택을 재구성 할 수는 없지만 –privileged = true가 필요하지만 컨테이너 프로세스는 다른 루트 프로세스와 같이 적은 수의 포트를 열 수 있습니다. 또한 컨테이너가 D 버스와 같은 로컬 네트워크 서비스에 액세스 할 수 있도록합니다. 이로 인해 컨테이너의 프로세스가 컴퓨터를 다시 시작하는 등 예기치 않은 작업을 수행 할 수 있습니다.


답변

ssh 터널을 만들 수도 있습니다.

docker-compose.yml:

---

version: '2'

services:
  kibana:
    image: "kibana:4.5.1"
    links:
      - elasticsearch
    volumes:
      - ./config/kibana:/opt/kibana/config:ro

  elasticsearch:
    build:
      context: .
      dockerfile: ./docker/Dockerfile.tunnel
    entrypoint: ssh
    command: "-N elasticsearch -L 0.0.0.0:9200:localhost:9200"

docker/Dockerfile.tunnel:

FROM buildpack-deps:jessie

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get -y install ssh && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY ./config/ssh/id_rsa /root/.ssh/id_rsa
COPY ./config/ssh/config /root/.ssh/config
COPY ./config/ssh/known_hosts /root/.ssh/known_hosts
RUN chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/config && \
    chown $USER:$USER -R /root/.ssh

config/ssh/config:

# Elasticsearch Server
Host elasticsearch
    HostName jump.host.czerasz.com
    User czerasz
    ForwardAgent yes
    IdentityFile ~/.ssh/id_rsa

이 방법으로 elasticsearch서비스를 실행하는 서버 (Elasticsearch, MongoDB, PostgreSQL)로 서버에 터널이 있고 해당 서비스로 포트 9200을 노출합니다.


답변

도커 컨테이너에서 LDAP 서버에 액세스하는 데 비슷한 문제가 있습니다. 컨테이너에 고정 IP를 설정하고 방화벽 규칙을 추가했습니다.

docker-compose.yml:

version: '2'
services:
  containerName:
    image: dockerImageName:latest
    extra_hosts:
      - "dockerhost:192.168.50.1"
    networks:
      my_net:
        ipv4_address: 192.168.50.2
networks:
  my_net:
    ipam:
      config:
      - subnet: 192.168.50.0/24

iptables 규칙 :

iptables -A INPUT -j ACCEPT -p tcp -s 192.168.50.2 -d $192.168.50.1 --dport portnumberOnHost

컨테이너 내부 dockerhost:portnumberOnHost


답변

MongoDB 및 RabbitMQ가 호스트에서 실행중인 경우 포트가 Docker 내에 있지 않으므로 이미 노출되어 있어야합니다.

-p컨테이너에서 호스트로 포트를 노출하기 위해 옵션이 필요하지 않습니다 . 기본적으로 모든 포트가 노출됩니다. 이 -p옵션을 사용하면 컨테이너에서 호스트 외부로 포트를 노출 할 수 있습니다.

그래서 내 추측은 당신이 전혀 필요하지 않으며 -p잘 작동해야한다는 것입니다. 🙂


답변