Birden fazla liman işçisi oluşturma projesi arasındaki iletişim


254

İki ayrı olması docker-compose.ymliki farklı klasörlerde dosyaları:

  • ~/front/docker-compose.yml
  • ~/api/docker-compose.yml

İçindeki bir kapsayıcıdaki bir kapsayıcıya frontistek gönderebileceğinden nasıl emin olabilirim api?

Bu kapsayıcıya ayrı bir kapsayıcı için --default-gatewayayarlanabileceğini biliyorum docker run, böylece bu kapsayıcıya belirli bir IP adresi atanabilir, ancak bu seçenek kullanılırken kullanılamıyor gibi görünüyor docker-compose.

Şu anda sonunda bir docker inspect my_api_container_idçıkış yapmak ve çıkış ağ geçidine bakmak. Çalışıyor ama sorun bu IP rastgele atfedilir, bu yüzden ona güvenemiyorum.

Bu sorunun başka bir biçimi de şöyle olabilir:

  • Sabit bir IP adresini docker-compose kullanarak belirli bir kapsayıcıyla ilişkilendirebilir miyim?

Ama sonunda baktığım şey:

  • İki farklı liman işçisi oluşturma projesi birbirleriyle nasıl iletişim kurabilir?

4
Bugün buna tekrar baktım. Geliştiriciler sonunda rasgele ağ adlandırmasına izin verdiler. Oluşturma dosyası sürüm 3.5'i kullanarak 'ağlar' tuşu altında varsayılan ağ için bir ad belirleyebilirsiniz. Bu yoksa, normal proje adı öneki olmadan adlandırılmış bir ağ oluşturur ..
cstrutton

Yanıtlar:


326

Birbirinizle konuşmak istediğiniz kapların aynı ağda olduğundan emin olmanız yeterlidir. Ağlar birinci sınıf bir docker yapısıdır ve oluşturmaya özgü değildir.

# front/docker-compose.yml
version: '2'
services:
  front:
    ...
    networks:
      - some-net
networks:
  some-net:
    driver: bridge

...

# api/docker-compose.yml
version: '2'
services:
  api:
    ...
    networks:
      - front_some-net
networks:
  front_some-net:
    external: true

Not: Uygulamanızın ağına, içinde bulunduğu dizinin adını temel alan "proje adı" na dayalı bir ad verilir, bu durumda bir önek front_eklenir

Daha sonra hizmet adını kullanarak birbirleriyle konuşabilirler. Gönderen frontyapabileceğiniz ping apive tersi.


1
Jivan bu bir çözüm değil. Kaplarınızın ana makine hakkında hiçbir şey bilmesine veya bu şekilde manipüle edilmesine gerek yoktur. Cevabım oldukça kısaydı, daha ayrıntılı olarak güncelledim.
johnharris85

3
Robert Moskal, sadece docker sunucunuzun ipini konteynırlara almak için hacklerseniz. Bağlantı birimiyle tanımlanmış ortak bir ağda iletişim kurmalarını sağlamak daha iyidir.
johnharris85

2
Lütfen ağın "front_" önekinin çalıştığı klasörden otomatik olarak oluşturulduğunu unutmayın. Dolayısıyla, ilk docker-compose dosyanız "example / docker-compose.yml" içinde bulunacaksa, bunun yerine "example_default" olarak adlandırılır.
AngryUbuntuNerd

7
Ayrıca name, proje adı ile otomatik ön eklemeyi devre dışı bırakacak özelliği kullanarak bir ağa ad da verebilirsiniz . Daha sonra her iki proje de bu ağı kullanabilir ve henüz yoksa otomatik olarak oluşturabilir.
SteveB

2
@SteveB - name özelliğinin yalnızca docker-compose dosya sürüm 3.5 ve üzeri sürümlerden çalıştığını unutmayın
kramer65

78

@ Johnharris85'in harika cevabına sadece küçük bir adittion, bir docker compose dosyası çalıştırdığınızda, bir " default" ağ oluşturulur, böylece onu diğer compose dosyasına harici bir ağ olarak ekleyebilirsiniz:

# front/docker-compose.yml 
version: '2' 
  services:   
    front_service:
    ...

...

# api/docker-compose.yml
version: '2'
services:
  api_service:
    ...
    networks:
      - front_default
networks:
  front_default:
    external: true

Benim için bu yaklaşım daha uygun çünkü ilk docker-compose dosyasına sahip değildim ve onunla iletişim kurmak istedim.


bu harici ağ için statik IP atamanın doğru yolunu bulduk. Bunu services:etiket içinde yapmayı başardım , sintaks daha networks:sonra iç içe front_default:ipv4_address: '172.20.0.44'
geçirilir

77

GÜNCELLEME: Compose dosyası sürüm 3.5 itibariyle:

Şimdi çalışıyor:

version: "3.5"
services:
  proxy:
    image: hello-world
    ports:
      - "80:80"
    networks:
      - proxynet

networks:
  proxynet:
    name: custom_network

docker-compose up -d'custom_network' adlı bir ağa katılacak. Eğer yoksa, yaratılacak!

root@ubuntu-s-1vcpu-1gb-tor1-01:~# docker-compose up -d
Creating network "custom_network" with the default driver
Creating root_proxy_1 ... done

Şimdi bunu yapabilirsiniz:

version: "2"
services:
  web:
    image: hello-world
    networks:
      - my-proxy-net
networks:
  my-proxy-net:
    external:
      name: custom_network

Bu, dış ağda olacak bir kap oluşturur.

Dokümanlarda henüz referans bulamıyorum ama işe yarıyor!


İki hizmeti belirli bir sırada başlatmanız gerekiyor mu? İkisinden birini başlatabilir misiniz ve ilki ağı oluşturacak, ikincisi de ağa katılacak mı?
slashdottir

4
İlk hizmet (yukarıdaki proxy) ağı oluşturur. İkinci örnekteki sözdizimi buna katılır.
cstrutton

2
@slashdottir Sen edebilirsiniz değil ikinci hizmetinde harici olarak şebekeyi işaretlemek ve henüz yoksa o oluşturulacaktır.
SteveB

2
Çalışıyor. En son docker bestesiyle bir DO damlacık çıkardım. Örneği gerçek bir çalışma örneğinde düzenledim.
cstrutton

1
Benim durumumda, bu kabul edilen cevaptan daha uygun bir çözüm olarak ortaya çıktı. Harici ağ ile ilgili sorun, kapsayıcıları önceden tanımlanmış sırayla başlatması gerektiğiydi. Müvekkilim için bu kabul edilemezdi. Adlandırılmış bir ağın (3.5'ten beri) mükemmel bir çözüm olduğu ortaya çıktı. Teşekkürler.
ygor

25

Alanından gelen tüm kapsayıcılar varsayılan ağa aşağıdaki yapılandırma ile apikatılabilir :front

# api/docker-compose.yml

...

networks:
  default:
    external:
      name: front_default

Docker oluşturma kılavuzuna bakın: önceden var olan bir ağı kullanma (aşağıya bakın)


12

Önceki gönderi bilgileri doğrudur, ancak "external_links" olarak bağlanması gereken kapsayıcıların nasıl bağlanacağıyla ilgili ayrıntılara sahip değildir.

Umarım bu örnek size daha açıktır:

  • İki hizmetle (svc11 ve svc12) app1 / docker-compose.yml ve iki daha fazla hizmetle (svc21 ve svc22) app2 / docker-compose.yml olduğunu ve çapraz bir şekilde bağlanmanız gerektiğini varsayalım:

  • svc11'nin svc22'nin konteynerine bağlanması gerekiyor

  • svc21'in svc11'in konteynerine bağlanması gerekir.

Yani yapılandırma şu şekilde olmalıdır:

Bu app1 / docker-compose.yml:


version: '2'
services:
    svc11:
        container_name: container11
        [..]
        networks:
            - default # this network
            - app2_default # external network
        external_links:
            - container22:container22
        [..]
    svc12:
       container_name: container12
       [..]

networks:
    default: # this network (app1)
        driver: bridge
    app2_default: # external network (app2)
        external: true

Bu app2 / docker-compose.yml dosyasıdır:


version: '2'
services:
    svc21:
        container_name: container21
        [..]
        networks:
            - default # this network (app2)
            - app1_default # external network (app1)
        external_links:
            - container11:container11
        [..]
    svc22:
       container_name: container22
       [..]

networks:
    default: # this network (app2)
        driver: bridge
    app1_default: # external network (app1)
        external: true

6

Compose 1.18 (spesifikasyon 3.5) olduğundan, ihtiyacınız olan tüm Compose YAML dosyaları için kendi özel adınızı kullanarak varsayılan ağı geçersiz kılabilirsiniz. Onlara aşağıdakileri eklemek kadar basit:

networks:
  default:
    name: my-app

Yukarıdaki version, 3.5(veya 4+'de kullanımdan kaldırmazlarsa yukarıda) olarak ayarladığınızı varsayar .

Diğer cevaplar da aynı şeyi gösterdi; bu basitleştirilmiş bir özettir.


2

Tüm kapları docker-composeaynı ağda bir araya getirerek aynı ağa yerleştirildiğinden emin olurdum :

docker compose --file ~/front/docker-compose.yml --file ~/api/docker-compose.yml up -d

Bu, örneğin, bir linkveyadepends_on ön biri kaptan API biri kaba?
Jivan

aslında ne önerdiğini yaptığımda, docker-compose cevapları ya build path ~/front/api either does not exist or is not accessibleda başka bir yolla,build path ~/api/front either does not exist or is not accessible
Jivan

1
Onları aynı anda oluşturuyorsanız, buna gerek yoktur. Üzerinde tüm kapsayıcılarınızın bulunduğu bir ağ oluşturulacak, hepsi oluşturma dosyasındaki hizmet adıyla iletişim kurabilecek ( kapsayıcı adı değil ) .
Nauraushaun

İki oluşturma dosyasının aynı klasörde olması daha kolay olabilir. Ama bunun gerekli olduğunu düşünmüyorum - her iki şekilde de çalışması gerektiğini düşünüyorum.
Nauraushaun

2
Bu çözüm çalışmıyor, bu konudaki yorumuma bakın: yorumuma github.com/docker/compose/issues/3530#issuecomment-222490501
johnharris85

2

GÜNCELLEME: Compose dosyası sürüm 3.5 itibariyle:

Benzer bir sorunla karşılaştım ve docker-compose.yml projemden birine küçük bir değişiklik ekleyerek çözdüm.

Mesela iki api scoringve ner. Scoringapi'nin nergiriş talebini işlemek için api'ye bir istek göndermesi gerekir . Bunu yapmak için her ikisinin de aynı ağı paylaşması gerekiyor.

Not: Her kapsayıcı, uygulamayı docker'ın içinde çalıştırırken otomatik olarak oluşturulan kendi ağına sahiptir. Örneğin ner api ağı gibi oluşturulacak ner_defaultve puanlama api ağı olarak adlandırılacaktır scoring default. Bu çözüm '3' sürümü için çalışacaktır.

Yukarıdaki senaryoda olduğu gibi, puanlama api ner api ile iletişim kurmak istiyorsa o zaman aşağıdaki satırları ekleyeceğim. Bu, ner api için kap oluşturduğumda otomatik olarak scoring_default ağına eklendi demektir.

networks:
  default:
      external:
        name: scoring_default

ner / docker-compose.yml

version: '3'
services:
  ner:
    build: .
    ...

networks:
  default:
      external:
        name: scoring_default

skor / docker-compose.yml

version: '3'
services:
  api:
    build: .
    ...

Yukarıdaki kapsayıcıların artık şu scoring_defaultkomutu kullanarak aynı ağın bir parçası olduğunu görebiliyoruz :

docker inspect Instagram Hesabındaki Resim ve Videoları scoring_default

{
    "Name": "scoring_default",
        ....
    "Containers": {
    "14a6...28bf": {
        "Name": "ner_api",
        "EndpointID": "83b7...d6291",
        "MacAddress": "0....",
        "IPv4Address": "0.0....",
        "IPv6Address": ""
    },
    "7b32...90d1": {
        "Name": "scoring_api",
        "EndpointID": "311...280d",
        "MacAddress": "0.....3",
        "IPv4Address": "1...0",
        "IPv6Address": ""
    },
    ...
}

1

Aşağıdakileri .enviçeren tüm projelerinize bir dosya ekleyebilirsiniz .COMPOSE_PROJECT_NAME=somename .

COMPOSE_PROJECT_NAME , tüm projeleriniz kullanacağı için kaynakları adlandırmak için kullanılan öneki geçersiz kılarsomename_default ağ olarak ve hizmetlerin aynı projede olduğu gibi birbirleriyle iletişim kurmasını sağlayacaktır.

Not: Diğer projelerden oluşturulan "artık" kapsayıcılar için uyarılar alırsınız.


0
version: '2'
services:
  bot:
    build: .
    volumes:
      - '.:/home/node'
      - /home/node/node_modules
    networks:
      - my-rede
    mem_limit: 100m
    memswap_limit: 100m
    cpu_quota: 25000
    container_name: 236948199393329152_585042339404185600_bot
    command: node index.js
    environment:
      NODE_ENV: production
networks:
  my-rede:
    external:
      name: name_rede_externa

0

Başka bir docker-compose ağı kullanmak için aşağıdakileri yapmanız yeterlidir (docker-compose arasında ağları paylaşmak için):

  1. İlk docker-compose projesini up -d
  2. İlk docker-compose ağ adını bulun: docker network ls (Kök dizin projesinin adını içerir)
  3. Ardından, ikinci docker-compose dosyasında bu adı aşağıdaki yapıya göre kullanın.

ikinci docker-compose.yml

version: '3'
services:
  service-on-second-compose:  # Define any names that you want.
    .
    .
    .
    networks:
      - <put it here(the network name that comes from "docker network ls")>

networks:
  - <put it here(the network name that comes from "docker network ls")>:
    external: true

0

Başka bir seçenek de sadece ilk modülü 'docker-compose' ile çalıştırmak, modülle ilgili ipi kontrol etmek ve ikinci modülü harici gibi bir önceki ağa bağlamak ve dahili ip'i işaret etmektir.

örnek app1 - hizmet hatlarında oluşturulan yeni ağ, dış olarak işaretleyin: altta doğru: app2 - uygulama1 tarafından oluşturulduğunda oluşturulan "yeni ağ" ı belirtin, harici olarak işaretleyin: altta doğru: ve yapılandırmada ayarlayın bağlamak için, app1 bu net var ip.

Bununla, birbirinizle konuşabilmelisiniz

* Bu yol sadece yerel test odağı içindir, aşırı karmaşık bir yapılandırma yapmamak için ** Biliyorum çok 'yama yolu' ama benim için çalışıyor ve bence çok basit, bazıları bundan faydalanabilir


0

Eğer sen

  • dan iki kap arasında iletişim kurmaya çalışıyor farklı liman işçisi-oluşturma projelerinde ve aynı ağ kullanmak istemiyorum diyelim aynı bağlantı noktasında PostgreSQL veya Redis kapsayıcı olurdu demek çünkü (ve bunu kullanmak bu portları değişmiyor tercih ve olmaz aynı ağda)
  • yerel olarak gelişmek ve arasındaki iletişimi taklit etmek istemek iki liman işçisi oluşturma projesi
  • localhost üzerinde iki liman işçisi oluşturma projesi yürütme
  • özellikle Django uygulamaları veya Django Rest Framework (drf) API'sini geliştirmek ve bazı açık portlarda konteyner içinde uygulamayı çalıştırmak
  • alma Connection refusediki kap arasında iletişim kurmak için çalışırken

Ve sen istiyorsun

  • konteyner aynı "docker ağı" olmadan api_ailetişim kurabilir api_b(veya tam tersi)

(aşağıdaki örnek)

ikinci kabın "ana bilgisayarını", bilgisayarınızın ve Docker kabının içinden eşlenen bağlantı noktasının IP'si olarak kullanabilirsiniz. Bu komut dosyası ile bilgisayarınızın IP'sini alabilirsiniz ( adresinden : Python's stdlib kullanarak yerel IP adreslerini bulma ):

import socket
def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

Misal:

project_api_a/docker-compose.yml:

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_a
    image: api_a:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

api_akonteyner içinde Django uygulamasını çalıştırıyorsunuz: manage.py runserver 0.0.0.0:8000

ve diğer projeden ikinci docker-compose.yml:

project_api_b/docker-compose-yml :

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_b
    image: api_b:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

api_bkonteyner içinde Django uygulamasını çalıştırıyorsunuz: manage.py runserver 0.0.0.0:8001

Ve kapsayıcıdan api_adaha api_bsonra URL'sine bağlanmaya çalışıyorapi_b konteyner olacaktır: http://<get_ip_from_script_above>:8001/

İkiden fazla (üç veya daha fazla) liman işçisi oluşturma projesi kullanıyorsanız özellikle değerli olabilir ve hepsine ortak ağ sağlamak zordur - iyi bir çözüm ve çözüm

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.