2017-08-19 13 views
3

serverd.pyがメッセージをclientd.pyに送信し、クライアントがPUSH/PULLを使用して単純に表示する、macOSでZeroMQを使用したDockerネットワークのおもちゃの例を設定しようとしています。私はコンテナの外にそれらを実行する場合、彼らは正常に動作しますが、別のコンテナ内で実行するときに、彼らが通信するようになっている。私のclientd.pyは、同じブリッジネットワーク内にあるにもかかわらず、コンテナ名に接続できないようです。私はserverd_dev_1の割り当てられたIPアドレスでホスト名を置き換えようとしましたが、これはどちらも動作しません。ここでZeroMQが2つのDockerコンテナ間の通信に失敗しました

は私の設定です:

  1. 私はdocker network create -d bridge mynetで新しいネットワークを作成しました。私はこのようなserverd.pyclientd.pyを作成し、そのDockerfilesとドッキングウィンドウ-compose.ymlと一緒に別々のフォルダに入れて

    { 
        "Name": "mynet", 
        "Id": "cec7f8037c0ef173d9a9a66065bb46cb6a631fea1c0636876ccfe5a792f92412", 
        "Created": "2017-08-19T09:52:44.8034344Z", 
        "Scope": "local", 
        "Driver": "bridge", 
        "EnableIPv6": false, 
        "IPAM": { 
         "Driver": "default", 
         "Options": {}, 
         "Config": [ 
          { 
           "Subnet": "172.18.0.0/16", 
           "Gateway": "172.18.0.1" 
          } 
         ] 
        }, 
        "Internal": false, 
        "Attachable": false, 
        "Ingress": false, 
        "ConfigFrom": { 
         "Network": "" 
        }, 
        "ConfigOnly": false, 
        "Containers": { 
         "5fa8dc2f8059d675dfd3dc4f2e50265be99361cd8a8f2730eb273772c0148742": { 
          "Name": "serverd_dev_1", 
          "EndpointID": "3a62e82b1b34d5c08f2a9f340ff93aebd65c0f3dfde70e354819befe21422d0b", 
          "MacAddress": "02:42:ac:12:00:02", 
          "IPv4Address": "172.18.0.2/16", 
          "IPv6Address": "" 
         }, 
         "ec1e5f8c525ca8297611e02bcd3a64198fda3a07ce8ed82c0c4298609ba0357f": { 
          "Name": "clientd_dev_1", 
          "EndpointID": "a8ce6f178a225cb2d39ac0009e16c39abdd2dae02a65ba5fd073b7900f059bb8", 
          "MacAddress": "02:42:ac:12:00:03", 
          "IPv4Address": "172.18.0.3/16", 
          "IPv6Address": "" 
         } 
        }, 
        "Options": {}, 
        "Labels": {} 
    } 
    

serverd.pyここdocker network inpsect mynetからの出力は次のようになります。

import zmq 
import time 

context = zmq.Context() 
socket = context.socket(zmq.PUSH) 
address = "tcp://127.0.0.1:5557" 
socket.bind(address) 
print("Sending to {}...".format(address)) 
while True: 
    message = socket.send_string("Got it!") 
    print("Sent message") 
    time.sleep(1) 

clientd.py:

clientd.pyため

FROM python:3.6 

RUN mkdir src 
ADD serverd.py /src/ 
RUN pip install pyzmq 
WORKDIR /src/ 
EXPOSE 5557 

Dockerfile:serverd.pyため

Dockerfile:

FROM python:3.6 

RUN mkdir src 
ADD clientd.py /src/ 
RUN pip install pyzmq 
WORKDIR /src/ 
EXPOSE 5557 

ドッキングウィンドウ・コン0

import zmq 

context = zmq.Context() 
socket = context.socket(zmq.PULL) 
address = "tcp://serverd_dev_1:5557" 
socket.connect(address) 
print("Listening to {}...".format(address)) 
while True: 
    message = socket.recv_string() 
    print("Client got message! {}".format(message)) 

は、私は2つのDockerfilesとドッキングウィンドウ-compose.ymlを持っています。 yml for serverd.py:

dev: 
    build: . 
    command: ["python", "-u", "./serverd.py"] 
    net: mynet 
clientd.py、10

-構成ドッカー:

dev: 
    build: . 
    command: ["python", "-u", "./clientd.py"] 
    net: mynet 
docker-compose upと期待どおり
  • serverd.py起動

    Sending to tcp://127.0.0.1:5557...

    1. clientd.pyは、ホスト名が見つからないため、このように起動しませんtcp://serverd_dev_1:5557。私はtcp://172.18.0.2:5557とURI tcp://serverd_dev_1:5557を交換する場合

      Attaching to countd_dev_1 
      dev_1 | Traceback (most recent call last): 
      dev_1 | File "./countd.py", line 6, in <module> 
      dev_1 |  socket.connect(address) 
      dev_1 | File "zmq/backend/cython/socket.pyx", line 528, in zmq.backend.cython.socket.Socket.connect (zmq/backend/cython/socket.c:5971) 
      dev_1 | File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:10014) 
      dev_1 | zmq.error.ZMQError: Invalid argument 
      
    2. それはもうクラッシュしませんが、それは単にサーバーからのメッセージのいずれかを受けずに空転されます。明らかに私は間違ったことをやっているが、正確には何かを完全には分かっていない。 Dockerのドキュメンテーションにできるだけ近づいてきたような気がしていて、アイディアがあれば大変感謝しています。

  • +0

    私の容疑者は、デバイスのドッキング・アイソレーションです。あなたは '' .bind() '** - 側で' 'address =" tcp://172.18.0.2:5557 "'というようにターゲットアドレスをIPv4絶対形式で設定してもらえますか?任意のDNS解決をクライアント側の '.connect()' -targetとしても使用できますか? ** 'EXPOSE' **は、ホスト0/Sリソース管理と分離のために使用されるドッカー抽象化の間のポート管理を仲介するように見えるので、内部(ドッカーコンテナ)のコードでは適切なセットアップ' :\\ address:port# '(インサイダーの視点から)世界の自分の視点で。 – user3666197

    答えて

    3

    あなたの主な問題は、サーバーにアドレスtcp://127.0.0.1:5557を設定していることです。 localhost(127.0.0.1)にバインドされているため、そのソケットはそのコンテナの外側にあるものには表示されません。最初に修正する必要があるのは、サーバーのバインドアドレスです。考えてみましょう:

    address = "tcp://0.0.0.0:5557" 
    

    使用時にディレクトリ名に依存するという第二の問題は、あなたがクライアントに名前serverd_dev_1を使用しているということですが、それはこれをクリアしていない、実際に(あなたのServerDにコンテナの名前になりますあなたはdocker-compose upを実行します)。

    単一のdocker-compose.yamlファイルを使用すると、名前の管理が容易になります。例えば、私はこのようなものを設定します

    version: "2" 
    
    services: 
        serverd: 
        build: serverd 
        command: ["python", "-u", "./serverd.py"] 
        environment: 
         SERVER_LISTEN_URI: tcp://0.0.0.0:5557 
    
        clientd: 
        build: clientd 
        command: ["python", "-u", "./clientd.py"] 
        environment: 
         SERVER_CONNECT_URI: tcp://serverd:5557 
    

    をこれは(これはドッキングウィンドウ-COMPOSEは、デフォルトでは何をするかであるため)専用のネットワークで両方のコンテナが起動しますので、あなたが明示的に作成または参照する必要はありません。 mynet

    上記のことから推測できますが、環境変数からZMQ URIを取得するようにコードを修正しました。これにより、実験が簡単になりました。あなたがで上記ドッキングウィンドウ-compose.yamlと変更されたコードを見つけることができます:あなたが本当にしたい場合は

    更新

    を/二つの別々のdocker-compose.yamlのファイルを持っている必要があり、この例では、サービスごとのファイルを含めるように更新しました。

    version: "2" 
    
    services: 
        serverd: 
        build: . 
        command: ["python", "-u", "./serverd.py"] 
        environment: 
         SERVER_LISTEN_URI: tcp://0.0.0.0:5557 
        networks: 
         mynet: 
         aliases: 
          - serverd 
    
    networks: 
        mynet: 
        external: True 
    

    この設定を使用して、コンテナを育てる前にmynetを作成する必要があります。これらの例は、クライアントがローカルのディレクトリレイアウトに関係なく、サーバーに連絡することが可能な名前を提供するために、aliasオプションを使用します。

    +0

    O/Pは、最初の部分(**上記の項目2 **、** serverd.py **および** clientd.py **)からテスト対象コードを投稿しました。 ( '' '、DNS /ホスト名の解決と' 'IPv4アドレス:ポート# 'を適切に固定している)コードが機能するので、ZeroMQ部分のバグについての仮説は正しくありません。 – user3666197

    +0

    @larsksこのような徹底的な答えをありがとう!私は2つの部分で混乱していました。ホストマシンへのポート転送を使用している例ではlocalhostを使用していたので、ドッカーネットワークを使用すると仮定しました。第二に、 'docker network inspect mynet'のContainers - > Nameはホスト名として使う名前だと思いました。 docker-compose.ymlを組み合わせるというあなたの提案は、すべてのことをより良くしました。あなたの時間をとってくれてありがとう! –

    +0

    @ user3666197バグについて不平を言っている人が彼のコメントを引っ張っているように見えるので、答えにはあまり関係がないので、私も私のものを取り除くつもりです... – larsks

    関連する問題