Komunikasi antara berbagai proyek pembuatan buruh pelabuhan


253

Saya memiliki dua docker-compose.ymlfile terpisah di dua folder berbeda:

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

Bagaimana saya bisa memastikan bahwa sebuah wadah frontdapat mengirim permintaan ke sebuah wadah api?

Saya tahu bahwa --default-gatewayopsi dapat diatur menggunakan docker runwadah individu, sehingga alamat IP tertentu dapat ditetapkan untuk wadah ini, tetapi tampaknya opsi ini tidak tersedia saat menggunakan docker-compose.

Saat ini saya akhirnya melakukan docker inspect my_api_container_iddan melihat gateway di output. Ini berfungsi tetapi masalahnya adalah bahwa IP ini dikaitkan secara acak, jadi saya tidak bisa mengandalkannya.

Bentuk lain dari pertanyaan ini adalah:

  • Bisakah saya mengaitkan alamat IP tetap ke wadah tertentu menggunakan docker-compose?

Tetapi pada akhirnya yang saya cari adalah:

  • Bagaimana dua proyek yang terdiri dari pekerja pelabuhan yang berbeda dapat berkomunikasi satu sama lain?

4
Saya hanya melihat ini hari ini lagi. Para dev akhirnya mengalah dan mengizinkan penamaan jaringan yang sewenang-wenang. Menggunakan menulis file versi 3.5 Anda dapat menentukan nama untuk jaringan default di bawah tombol 'jaringan'. Ini akan membuat jaringan bernama tanpa awalan nama proyek yang biasa jika tidak ada ..
cstrutton

Jawaban:


325

Anda hanya perlu memastikan bahwa wadah yang ingin Anda bicarakan satu sama lain berada di jaringan yang sama. Jaringan adalah konstruksi buruh pelabuhan kelas satu, dan tidak spesifik untuk menulis.

# 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

Catatan: Jaringan aplikasi Anda diberi nama berdasarkan "nama proyek", yang didasarkan pada nama direktori tempat tinggalnya, dalam hal ini awalan front_ditambahkan

Mereka kemudian dapat berbicara satu sama lain menggunakan nama layanan. Dari frontyang bisa Anda lakukan ping apidan sebaliknya.


1
Jivan itu bukan solusi. Wadah Anda seharusnya tidak perlu tahu apa-apa tentang tuan rumah atau dimanipulasi seperti itu. Jawaban saya cukup singkat, saya telah memperbarui dengan lebih detail.
johnharris85

3
Robert Moskal hanya jika Anda meretas untuk mendapatkan ip host buruh pelabuhan Anda ke dalam wadah. Lebih baik minta mereka berkomunikasi di jaringan buruh pelabuhan yang ditentukan bersama.
johnharris85

2
Harap perhatikan bahwa awalan "front_" ke jaringan dibuat secara otomatis dari folder yang digunakan. Jadi jika file docker-compose pertama Anda akan berlokasi di "example / docker-compose.yml", itu akan disebut "example_default".
AngryUbuntuNerd

7
Anda juga dapat memberikan nama ke jaringan menggunakan nameproperti, yang akan menonaktifkan pra-otomatis dengan nama proyek. Kemudian salah satu proyek dapat menggunakan jaringan itu dan membuatnya secara otomatis jika belum ada.
SteveB

2
@SteveB - Perhatikan bahwa properti nama hanya berfungsi dari file docker-compose versi 3.5 dan lebih tinggi
kramer65

78

Hanya sedikit jawaban untuk jawaban luar biasa @ johnharris85, ketika Anda menjalankan file penulisan buruh pelabuhan, defaultjaringan dibuat " " sehingga Anda bisa menambahkannya ke file penulisan lainnya sebagai jaringan eksternal:

# 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

Bagi saya pendekatan ini lebih cocok karena saya tidak memiliki file menulis-buruh pelabuhan pertama dan ingin berkomunikasi dengannya.


hanya berkeliaran dengan cara yang benar untuk menetapkan IP statis untuk jaringan eksternal ini. Saya mengatur untuk melakukannya dalam services:tag, sintax networks:kemudian akan bersarang front_default:(menghapus "-") dan kemudian kita membuat IP statis:ipv4_address: '172.20.0.44'
Junior Mayhé

76

UPDATE: Pada penulisan file versi 3.5:

Ini sekarang berfungsi:

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

networks:
  proxynet:
    name: custom_network

docker-compose up -dakan bergabung dengan jaringan yang disebut 'custom_network'. Jika tidak ada, itu akan dibuat!

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

Sekarang, Anda bisa melakukan ini:

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

Ini akan membuat wadah yang akan berada di jaringan eksternal.

Saya belum dapat menemukan referensi di dokumen tetapi itu berhasil!


Apakah Anda harus memulai dua layanan dalam urutan tertentu? Bisakah Anda memulai salah satunya, dan yang pertama akan membuat jaringan dan yang kedua akan bergabung?
slashdottir

4
Layanan pertama (proxy di atas) menciptakan jaringan. Sintaks dalam contoh kedua bergabung.
cstrutton

2
@ slashdottir Anda tidak dapat menandai jaringan sebagai eksternal di layanan kedua dan itu akan dibuat jika belum ada.
SteveB

2
Itu berhasil. Saya hanya memutar droplet DO dengan komposisi buruh pelabuhan terbaru. Saya telah mengedit contoh ke contoh kerja yang sebenarnya.
cstrutton

1
Dalam kasus saya, ini ternyata menjadi solusi yang lebih cocok daripada jawaban yang diterima. Masalah dengan jaringan eksternal adalah, bahwa diperlukan untuk memulai kontainer dalam urutan yang telah ditentukan. Untuk klien saya, ini tidak dapat diterima. Jaringan bernama (sejak 3,5) ternyata menjadi solusi sempurna. Terima kasih.
ygor

24

Semua kontainer dari apidapat bergabung dengan jaringan front default dengan konfigurasi berikut:

# api/docker-compose.yml

...

networks:
  default:
    external:
      name: front_default

Lihat panduan penulisan buruh pelabuhan: menggunakan jaringan yang sudah ada sebelumnya (lihat di bagian bawah)


12

Informasi posting sebelumnya benar, tetapi tidak memiliki rincian tentang cara menautkan wadah, yang harus dihubungkan sebagai "external_links".

Semoga contoh ini memperjelas bagi Anda:

  • Misalkan Anda memiliki app1 / docker-compose.yml, dengan dua layanan (svc11 dan svc12), dan app2 / docker-compose.yml dengan dua layanan lagi (svc21 dan svc22) dan anggap Anda perlu terhubung dengan mode yang dilintasi:

  • svc11 perlu terhubung ke wadah svc22

  • svc21 perlu terhubung ke wadah svc11.

Jadi konfigurasinya harus seperti ini:

ini 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

ini app2 / docker-compose.yml:


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

Sejak Compose 1.18 (spec 3.5), Anda bisa mengganti jaringan default menggunakan nama kustom Anda sendiri untuk semua file Compose YAML yang Anda butuhkan. Ini sesederhana menambahkan yang berikut kepada mereka:

networks:
  default:
    name: my-app

Di atas mengasumsikan Anda telah versionmengatur ke 3.5(atau di atas jika mereka tidak mencabutnya dalam 4+).

Jawaban lain menunjuk hal yang sama; ini adalah ringkasan yang disederhanakan.


2

Saya akan memastikan semua kontainer berada docker-composedi jaringan yang sama dengan menyusunnya bersamaan, menggunakan:

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

Akankah itu memungkinkan saya, misalnya, untuk membuat satu linkatau depends_ondari satu wadah depan ke satu wadah api?
Jivan

sebenarnya ketika saya melakukan apa yang Anda sarankan, balasan buruh pelabuhan menulis baik build path ~/front/api either does not exist or is not accessibleatau dengan sebaliknya,build path ~/api/front either does not exist or is not accessible
Jivan

1
Jika Anda membuat mereka pada saat yang sama Anda tidak perlu melakukannya. Sebuah jaringan akan dibuat dengan semua wadah Anda di dalamnya, mereka semua akan dapat berkomunikasi melalui nama layanan dari file penulisan ( bukan nama wadah).
Nauraushaun

Mungkin lebih mudah jika dua file penulisan berada di folder yang sama. Tapi saya pikir itu tidak perlu - saya pikir itu harus bekerja baik.
Nauraushaun

2
Solusi ini tidak berfungsi, lihat komentar saya di utas ini: github.com/docker/compose/issues/3530#issuecomment-222490501
johnharris85

2

UPDATE: Pada penulisan file versi 3.5:

Saya menemukan masalah yang sama dan saya menyelesaikannya dengan menambahkan perubahan kecil di salah satu proyek docker-compose.yml saya.

Misalnya kita memiliki dua api scoringdan ner. Scoringapi perlu mengirim permintaan ke nerapi untuk memproses permintaan input. Untuk melakukan itu mereka berdua harus berbagi jaringan yang sama.

Catatan: Setiap kontainer memiliki jaringannya sendiri yang secara otomatis dibuat pada saat menjalankan aplikasi di dalam buruh pelabuhan. Misalnya ner jaringan api akan dibuat seperti ner_defaultdan jaringan scoring api akan dinamakan sebagai scoring default. Solusi ini akan berfungsi untuk versi: '3'.

Seperti dalam skenario di atas api penilaian saya ingin berkomunikasi dengan ner api maka saya akan menambahkan baris berikut. Yang berarti Setiap kali saya membuat wadah untuk ner api maka secara otomatis ditambahkan ke jaringan scoring_default.

networks:
  default:
      external:
        name: scoring_default

ner / docker-compose.yml

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

networks:
  default:
      external:
        name: scoring_default

scoring / docker-compose.yml

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

Kita dapat melihat ini bagaimana wadah di atas sekarang menjadi bagian dari jaringan yang sama yang disebut scoring_defaultmenggunakan perintah:

buruh pelabuhan memeriksa 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

Anda dapat menambahkan .envfile di semua proyek Anda yang berisi COMPOSE_PROJECT_NAME=somename.

COMPOSE_PROJECT_NAME mengesampingkan awalan yang digunakan untuk menyebutkan sumber daya, karena itu semua proyek Anda akan digunakan somename_defaultsebagai jaringan mereka, sehingga memungkinkan layanan berkomunikasi satu sama lain seperti mereka berada di proyek yang sama.

NB: Anda akan mendapatkan peringatan untuk kontainer "yatim" yang dibuat dari proyek lain.


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

Untuk menggunakan jaringan pembuat docker lain Anda cukup melakukan ini (untuk berbagi jaringan antara docker-compose):

  1. Jalankan proyek komposisi buruh pelabuhan pertama up -d
  2. Temukan nama jaringan dari docker-compose pertama dengan: docker network ls(Ini berisi nama proyek direktori root)
  3. Kemudian gunakan nama itu dengan struktur ini di bawah di file docker-compose kedua.

docker-compose.yml kedua

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

Pilihan lain adalah menjalankan modul pertama dengan 'docker-compose' periksa ip yang terkait dengan modul, dan hubungkan modul kedua dengan jaring sebelumnya seperti eksternal, dan arahkan ip internal

contoh app1 - jaringan baru yang dibuat di jalur layanan, tandai sebagai eksternal: true di bagian bawah app2 - menunjukkan "jaringan baru" yang dibuat oleh app1 ketika naik, tandai sebagai eksternal: benar di bawah, dan atur di config untuk terhubung, ip yang dimiliki app1 di internet ini.

Dengan ini, Anda harus dapat berbicara satu sama lain

* cara ini hanya untuk fokus uji lokal, agar tidak melakukan konfigurasi yang terlalu rumit ** Saya tahu ini sangat 'tambalan' tetapi berfungsi untuk saya dan saya pikir sangat sederhana sehingga beberapa yang lain dapat mengambil keuntungan dari ini


0

Jika Anda

  • mencoba untuk berkomunikasi antara dua kontainer dari berbagai proyek menulis buruh pelabuhan dan tidak ingin menggunakan jaringan yang sama (karena katakanlah mereka akan memiliki wadah PostgreSQL atau Redis pada port yang sama dan Anda lebih suka untuk tidak mengubah port ini dan tidak menggunakannya di jaringan yang sama)
  • berkembang secara lokal dan ingin meniru komunikasi antara dua proyek pembuatan buruh pelabuhan
  • menjalankan dua proyek pembuatan docker di localhost
  • mengembangkan terutama aplikasi Django atau Django Rest Framework (drf) API dan menjalankan aplikasi di dalam wadah pada beberapa port yang terbuka
  • dapatkan Connection refusedsambil mencoba berkomunikasi antara dua wadah

Dan kamu mau

  • wadah api_aberkomunikasi ke api_b(atau sebaliknya) tanpa "jaringan buruh pelabuhan" yang sama

(contoh di bawah)

Anda dapat menggunakan "host" wadah kedua sebagai IP komputer Anda dan port yang dipetakan dari dalam wadah Docker. Anda dapat memperoleh IP komputer Anda dengan skrip ini (dari: Menemukan alamat IP lokal menggunakan stdlib Python ):

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

Contoh:

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

di dalam api_awadah Anda menjalankan aplikasi Django: manage.py runserver 0.0.0.0:8000

dan docker-compose.yml kedua dari proyek lain:

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

di dalam api_bwadah Anda menjalankan aplikasi Django: manage.py runserver 0.0.0.0:8001

Dan mencoba menghubungkan dari wadah api_ake api_bURL kemudian api_bwadah itu adalah: http://<get_ip_from_script_above>:8001/

Ini bisa sangat berharga jika Anda menggunakan lebih dari dua (tiga atau lebih) proyek pembuatan docker dan sulit untuk menyediakan jaringan bersama untuk semua itu - solusi dan solusi yang baik

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.