Ana makine bağlantı noktasını docker kapsayıcısına iletme


167

Ana makine tarafından bir Docker kapsayıcı erişim bağlantı noktası açmak mümkün müdür? Somut olarak ben ana bilgisayar üzerinde çalışan MongoDB ve RabbitMQ var ve ben kuyruk dinlemek ve (isteğe bağlı olarak) veritabanına yazmak için bir Docker kapsayıcısında bir işlem çalıştırmak istiyorum.

Ben konteynırdan ana bilgisayara (-p seçeneği ile) bir bağlantı noktası iletebileceğimi ve Docker konteynerinden dış dünyaya (yani internet) bağlanabileceğimi biliyorum ama RabbitMQ ve MongoDB portlarını açığa çıkarmak istemiyorum ev sahibinden dış dünyaya.

EDIT: bazı açıklamalar:

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

Kapsayıcı ile herhangi bir internet bağlantısı elde etmek için bu hile yapmak zorunda kaldım: Güvenlik duvarım docker kapsayıcıdan dışarıya ağ bağlantılarını engelliyor

EDIT : Sonunda boru hattı kullanarak özel bir köprü oluşturma ve hizmetleri köprü IP'leri dinlemek zorunda gitti . MongoDB ve RabbitMQ'yu docker köprüsünde dinlemek yerine bu yaklaşıma gittim çünkü daha fazla esneklik sağlıyor.

Yanıtlar:


54

Docker sunucunuz tüm kapsayıcılara bir bağdaştırıcı sunar. Son ubuntu'da olduğunuzu varsayarsak, koşabilirsiniz

ip addr

Bu size biri gibi görünecek ağ bağdaştırıcılarının bir listesini verecektir.

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

Tavşan / mongoya bu IP'ye bağlanmasını söylemeniz gerekir (172.17.42.1). Bundan sonra, konteynerlerinizden 172.17.42.1'e bağlantı açabilmelisiniz.


36
Kapsayıcı hangi IP'lere istek gönderileceğini nasıl biliyor? Ben değeri kodlayabilirsiniz (172.17.42.1 burada ve benim test teçhizat, ama bu her zaman doğru mu?), Ama bu herhangi bir ev sahibi ile çalışma docker ilkelerine aykırı gibi görünüyor!
JP.

2
@Seldo: Bu arayüzün görünmesi için yapılandırmaya ihtiyacı var mı? Docker 1.7.1 kullanıyorum ve sadece love var eth0.
mknecht

8
Ev sahibi sadece 127.0.0.1'de dinliyorsa, bunu bir şekilde yapmak mümkün mü?
HansHarhoff

5
"Tavşan / mongoya bu IP'ye bağlanmasını söylemeniz gerekecek (172.17.42.1). Bundan sonra, konteynerlerinizden 172.17.42.1'e bağlantı açabilmelisiniz." Bunu nasıl yapacağınızı
açıklarsanız

1
@Novaterata'nın belirttiği gibi, birisi bu süreci açıklayabilir mi?
keskinsaf

122

Basit ama nispeten güvensiz bir yol --net=hostseçeneği kullanmak olacaktır docker run.

Bu seçenek, kapsayıcı ana bilgisayarın ağ yığınını kullanmasını sağlar. Ardından, ana makine adı olarak "localhost" kullanarak ana bilgisayarda çalışan hizmetlere bağlanabilirsiniz.

Bunu yapılandırmak daha kolaydır, çünkü hizmeti docker konteynerinizin IP adresinden bağlantıları kabul edecek şekilde yapılandırmanız gerekmeyecek ve docker konteynerine bağlanacak belirli bir IP adresi veya ana bilgisayar adı söylemeniz gerekmeyecektir. bir liman.

Örneğin, görüntünüzün çağrıldığını my_image, görüntünüzün telnetyardımcı programı içerdiğini ve bağlanmak istediğiniz hizmetin 25 numaralı bağlantı noktasında olduğunu varsayarak aşağıdaki komutu çalıştırarak test edebilirsiniz :

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

Bunu bu şekilde yapmayı düşünüyorsanız, lütfen bu sayfadaki güvenlik konusundaki uyarıya bakın:

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

Diyor ki:

--net = host - Docker'a kapsayıcının ayrı bir ağ yığının içine yerleştirilmesini atlamasını söyler. Esasen, bu seçim Docker'a kabın ağını kaplamamasını söyler! Kap işlemleri hala kendi dosya sistemleri ve işlem listesi ve kaynak sınırları ile sınırlı olsa da, hızlı bir ip addr komutu size ağ açısından ana Docker ana bilgisayarında “dışarıda” yaşadıklarını ve ağ arabirimlerine tam erişime sahip olduklarını gösterecektir. . Bunun, kabın ana bilgisayar ağ yığınını yeniden yapılandırmasına izin vermediğini - --privileged = true - gerektirdiğini - ancak kapsayıcı işlemlerinin diğer kök işlemleri gibi düşük numaralı bağlantı noktalarını açmasına izin verdiğini unutmayın. Ayrıca, kabın D-bus gibi yerel ağ hizmetlerine erişmesine izin verir. Bu, kapsayıcıdaki işlemlerin bilgisayarınızı yeniden başlatmak gibi beklenmedik şeyler yapabilmesine yol açabilir.


12
Linux'ta docker kullanmayan herkes için (örn. Bazı sanallaştırma kullanma) bu işe yaramaz, çünkü ana bilgisayar gerçek ana işletim sistemi değil, içeren VM olacaktır.
Sebastian Graf

13
Özellikle, MacOS'ta bu mümkün değildir (bazı geçici çözümler olmadan): docs.docker.com/docker-for-mac/networking/…
pje

15
MacOS'ta, --net=hostkapsayıcı işleminizin ana makinenize kullanarak bağlanmasına izin vermek için çalışmaz localhost. Bunun yerine, kapsayıcınızın docker.for.mac.host.internalyerine özel MacOS ana bilgisayar adına bağlanmasını sağlayın localhost. docker runBunun çalışması için fazladan parametreye gerek yoktur . -eKonteyner platformunuzu agnostik tutmak istiyorsanız bunu bir env var olarak aktarabilirsiniz . Bu şekilde env var adlı ana bilgisayara bağlanıp docker.for.mac.host.internalMacOS ve localhostLinux'a geçebilirsiniz .
tul

18
mac için en son ana makine adı host.docker.internal, bkz. doc
xysun

Windows için aynı docker run --rm -it --net=host postgres bashsonrapsql -h host.docker.internal -U postgres
Leo Cavalcante

12

Ayrıca bir ssh tüneli de oluşturabilirsiniz.

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

Bu şekilde elasticsearchçalışan hizmete (Elasticsearch, MongoDB, PostgreSQL) sahip sunucuya bir tünel vardır ve bu hizmetle 9200 numaralı bağlantı noktasını açığa çıkarır.


8
Temelde özel anahtarı Docker görüntüsüne koyuyorsunuz. Sırlar asla Docker görüntüsüne girmemelidir.
Teoh Han Hui

2
Bu şimdiye kadar kullanılabilir tek aklı başında çözümdür.
helvete

5

Bir docker kapsayıcısından bir LDAP sunucusuna erişirken benzer bir sorun yaşadım. Kapsayıcı için sabit bir IP ayarladım ve bir güvenlik duvarı kuralı ekledim.

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 kuralı:

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

Konteyner içi erişim dockerhost:portnumberOnHost


3

MongoDB ve RabbitMQ ana bilgisayarda çalışıyorsa, bağlantı noktası Docker'da olmadığı için zaten açıkta olmalıdır.

-pBağlantı noktalarını kapsayıcıdan ana bilgisayara açığa çıkarmak için seçeneğe ihtiyacınız yoktur . Varsayılan olarak, tüm bağlantı noktaları açıktır. -pSeçenek konağın, kaptan dışarı bir liman göstermesini sağlar.

Yani, benim tahminim hiç ihtiyacınız yok -pve iyi çalışıyor olmalı :)


1
Bunu biliyordum, ancak biraz bilgi eksik olduğum anlaşılıyor: ana bilgisayardaki bağlantı noktalarına erişemediğim için son düzenlemeye bakın.
JoelKuiper

2
Sadece ana ağ arayüzünüzü değil, aynı zamanda köprüyü dinlemek için rabbitmq ve mongodb ayarlamanız gerekir.
13'te

13
@creack rabbitmq ve mongodb'un köprüyü dinlemesini nasıl sağlıyorsunuz?
Ryan Walls
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.