2017-05-25 58 views
2

MONGO我是從內部的docker container 試圖訪問mongo當我試圖創建connection出現的錯誤。不能存取權限由內泊塢窗

new MongoClient(host, port)正在工作。

mongo也以docker container運行和我能夠與robomongo連接到它,並運行的外部應用程序的docker container可以連接做mongo

我得到以下異常

No server chosen by WritableServerSelector from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, serverDescriptions=[ServerDescription{address=172.17.0.1:27017, type=UNKNOWN, state=CONNECTING}]} 


2017-05-25T21:11:32.277 INFO 5 --- [72.17.0.1:27017] org.mongodb.driver.cluster    : Exception in monitor thread while connecting to server 172.17.0.1:27017 
com.mongodb.MongoSocketOpenException: Exception opening socket 
at com.mongodb.connection.SocketStream.open(SocketStream.java:63) 
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) 
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.net.SocketTimeoutException: connect timed out 
at java.net.PlainSocketImpl.socketConnect(Native Method) 
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) 
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) 
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) 
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
at java.net.Socket.connect(Socket.java:589) 
at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:57) 
at com.mongodb.connection.SocketStream.open(SocketStream.java:58) 
... 3 common frames omitted 

docker-compose.yml

mongo: 
image: library/mongo:3.4.4 
ports: 
    - "27017:27017" 
    - "28017:28017" 
    - "28018:28018" 
volumes: 
    - ./data/mongo:/data/db 

dronedelivery: 
    image: paulcurcean/dronedelivery:latest 
    ports: 
    - "8080:8080" 

Dockerfile爲dronedelivery

ADD dronedelivery-0-SNAPSHOT.jar/
ADD start.sh/# java -jar dronedelivery-0-SNAPSHOT.jar 
CMD ["sh", "/start.sh"] 

碼頭工人PS /泊塢窗,撰寫PS

image     ports 
dronedelivery   0.0.0.0:8080 -> 8080/tcp 
mongo     0.0.0.0:27017 -> 27017/tcp, 0.0.0.0:28017-28018 -> 28017-28018/tcp 

我通過new MongoClient(host, port)

+0

請加'泊塢窗,compose.yml'或相應的'Dockerfile's。 – andreim

+0

您還可以提供有關如何連接到容器的信息? – filtfilt

回答

1

連接到mongo你可以使用,而不是搬運工,作曲。

首先,安裝docker-compose

我假設您正在爲您的應用程序使用Dockerfile。

創建一個目錄,其中有一個docker-compose.yml裏面。

version: '2' 
services: 

    mongo: 
    image: mongo:latest 
    restart: always 

    app: 
    build: ./app 
    restart: always 
    volumes: 
     - ./_client/:/var/www/html/ 
    links: 
     - mongo 
    ports: 
     - "80:80" 

現在,在./app中,將當前的Dockerfile放到應用程序中。

在_client /文件夾中放置您的應用程序(您可以根據需要更正內部路徑/ var/www/html)。這兩個文件夾與docker-compose.yml文件處於同一級別。

最後,所有的碼頭工人,撰寫運行:

docker-compose -f /path/to/your/docker-compose.yml build

這個命令會從你的Dockerfile

docker-compose -f /path/to/your/docker-compose.yml up

此命令建立圖像將創建並運行所有定義的容器。

要從應用程序容器中訪問您的mongodb容器,您可以使用「mongo」作爲主機名(在「services:」中定義的同名)。在主機上,您可以使用docker container IP,但是您需要公開端口,與docker-compose.yml中的「app」服務相同。

+1

你'鏈接:'兩次 – Robert

+0

['links'是傳統的(https://stackoverflow.com/questions/39173670/are-docker-links-deprecated)。您應該使用'networks'或/和['network_mode'](https://docs.docker.com/compose/compose-file/#network_mode)來配置容器的連接方式。有許多預定義的網絡'bridge','host','none'。默認是'bridge',因此所有的容器都可以看到對方沒有問題。我認爲問題在另一方面。 – andreim

+0

謝謝@羅伯特,我已經糾正它。 – Gonzalo

2

我認爲你遇到的問題是由於你錯誤地引用了主機。

我創建爲了工作POC here創建兩個容器,一個SpringBoot應用容器和容器蒙戈。信息和說明在README.md

有可能會導致您的應用程序出現故障多點:

  • 您可能需要確保您的應用程序應該蒙戈後運行是否正常
  • 你的容器在默認情況下連接到默認bridge網絡是與主機網絡(您的實際主網絡)分開的網絡。 bridge網絡已連接到您的主要主機網絡。因此,從另一個容器引用一個容器需要針對用於連接容器的網絡進行,因此需要完成bridge網絡。
  • docker-compose.yml - services.mymongo端口12345:27017意味着Mongo數據庫可以從另一個容器中引用爲mymongo:27017,但是來自主機如localhost:12345。使用從另一個容器localhost:27017是不正確的,因爲mymongo是一個主機,例如myapp是另一個。來自myapp的電話localhost並不意味着mymongo房東。
  • 以便查詢您蒙戈實例的健康,你可以讓使用mongod --rest的REST API。因此command: ["mongod", "--rest"]docker-compose.yml。這在啓動應用程序容器時用於瞭解Mongo實例是否已啓動並正在運行。

樣品docker-compose.yml:即蒙戈在端口27017配置並且因此REST接口將可在27017 + 1000 = 28017

version: '3' 

services: 
    myapp: 
    build: ./myapp/docker 
    environment: 
     - SERVER_PORT=8080 
     - MONGODB_URI=mongodb://mymongo:27017/mydb 
     - MONGODB_STATUS_HOST=mymongo 
     - MONGODB_STATUS_PORT=28017 
    ports: 
     - 8888:8080 
    mymongo: 
    image: mongo:3.4 
    volumes: 
     - ./_data:/data/db 
    ports: 
     - 12345:27017 
     - 23456:28017 
    command: ["mongod", "--rest"] 

的通知。

示例應用程序Dockerfile

下面是Dockerfile用於創建連接到蒙戈實例的應用程序的圖像:

FROM openjdk:8-jdk-alpine 
RUN apk update && apk upgrade && apk add netcat-openbsd 
RUN mkdir -p /usr/local/myapp 
ADD ./myapp.jar /usr/local/myapp/ 
ADD run.sh run.sh 
RUN chmod +x run.sh 
CMD ./run.sh 

然後應用程序被啓動具有以下run.sh腳本:

#!/bin/sh 

echo "********************************************************" 
echo "Wait for mongodb to be available" 
echo "********************************************************" 

while ! nc -z $MONGODB_STATUS_HOST $MONGODB_STATUS_PORT; do 
    printf 'mongodb is still not available. Retrying...\n' 
    sleep 3 
done 

echo "********************************************************" 
echo "Starting myapp" 
echo "********************************************************" 

java -Dserver.port=$SERVER_PORT \ 
    -Dspring.data.mongodb.uri=$MONGODB_URI \ 
    -jar /usr/local/myapp/myapp.jar 

請注意,它首先等待Mongo實例明星t通過查詢其REST接口,然後使用OpenJdk 8 JRE從其.jar文件啓動應用程序。

+0

我不能如何正確引用主機,因爲使用相同的引用,我可以使用'robomongo'進行連接,並且應用程序可以在Docker容器外部運行時進行連接。 – Paul

+1

@Paul從你的容器外部,你可以像'mongo:// localhost:27017/...'那樣訪問它,但是從內部你可以像'mongo:// mongo:27017/...'那樣做。 – andreim

+0

@Paul有兩個不同的網絡,一個來自你的主機,另一個是連接容器的網絡 - 默認情況下,它被稱爲「橋」。把它們看作是獨立的網絡,它們之間有一條小網線,以便您也可以在主機上訪問容器。 – andreim