Sự khác biệt giữa các liên kết và phụ thuộc vào docker_compose.yml


292

Theo tài liệu tập tin soạn thảo của Docker Compose :

  • depends_on - Thể hiện sự phụ thuộc giữa các dịch vụ.
  • links- Liên kết với các container trong một dịch vụ khác và cũng thể hiện sự phụ thuộc giữa các dịch vụ theo cùng một cách như phụ thuộc .

Tôi không hiểu mục đích liên kết với các container khác nên sự khác biệt giữa hai tùy chọn vẫn có vẻ khá khó khăn đối với tôi.

Sẽ dễ dàng hơn nhiều nếu có một ví dụ, nhưng tôi không thể tìm thấy bất kỳ.

Tôi nhận thấy, khi tôi liên kết container B với container A thì container B sẽ "có thể ping" bên trong vỏ của container A.

Tôi đã chạy ping Bbên trong container A bashvà nhận được kết quả như thế này (chỉ để tham khảo, hình ảnh từ Internet)

nhập mô tả hình ảnh ở đây


6
Các --linklá cờ hiện nay là một tính năng di sản NỮA của Docker và tài liệu cho thấy "Nó cuối cùng có thể được gỡ bỏ" Docker: liên kết chứa Legacy . Bạn không nên sử dụng tính năng mạng Docker hoặc phương thức soạn thảo docker. Tôi cho rằng điều này sẽ hữu ích cho bất cứ ai ở đây tìm hiểu về tính năng này.
Một ngôi sao

Câu trả lời:


122

Bài đăng cần cập nhật sau khi linkstùy chọn không được chấp nhận.

Về cơ bản, linkskhông còn cần thiết bởi vì mục đích chính của nó, làm cho container khác có thể truy cập bằng cách thêm biến môi trường, được bao gồm hoàn toàn với network. Khi các container được đặt trong cùng một mạng, chúng có thể truy cập lẫn nhau bằng cách sử dụng tên container và bí danh khác làm máy chủ.

Đối với docker run, --linkcũng không được chấp nhận và nên được thay thế bằng một mạng tùy chỉnh.

docker network create mynet
docker run -d --net mynet --name container1 my_image
docker run -it --net mynet --name container1 another_image

depends_ondiễn đạt thứ tự bắt đầu (và thứ tự kéo hình ảnh ngầm), đó là một tác dụng phụ tốt của links.


13
StackOverflow phổ biến, tại sao tôi phải cuộn xuống dưới câu trả lời 147 và 43 điểm để tìm câu trả lời 1 điểm thực sự tốt nhất.
u8it

3
@ u8it Đó là bản chất của thời gian và internet.
Michael Cole

Làm thế nào để làm điều tương tự trong docker-compose? Tôi nghĩ rằng với docker, tất cả các dịch vụ đều nằm trong cùng một mạng và không cần thêm bất cứ thứ gì. Vẫn liên kết giữa các container không hoạt động nếu một trong các container đang cố kết nối với container không ở trạng thái Sẵn sàng.
makkasi

Tôi không thể thấy thông tin về các liên kết bị phản đối trong docker-compose phiên bản 3 docs: docs.docker.com/compose/compose-file/#links . Tôi không thấy tùy chọn này quá hữu ích, vì chúng tôi đã chia sẻ mạng và phụ thuộc, nhưng nó không bị phản đối nếu tôi đọc tài liệu chính xác (họ chỉ đề cập đến - cờ liên kết trên bộ chứa docker).
rideronthestorm

Lưu ý: các container (thực sự là các dịch vụ) trong cùng một mạng có thể truy cập theo tên dịch vụ, không phải tên container. Tài liệu chính thức: docs.docker.com/compose/networking/#links
GarryOne

194

Câu trả lời này dành cho phiên bản docker-compose 2 và nó cũng hoạt động trên phiên bản 3

Bạn vẫn có thể truy cập dữ liệu khi bạn sử dụng phụ thuộc.

Nếu bạn nhìn vào docker docs Docker Compose và Django , bạn vẫn có thể truy cập cơ sở dữ liệu như thế này:

version: '2'
services:
  db:
    image: postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

Sự khác biệt giữa các liên kết và phụ thuộc là gì?

liên kết:

Khi bạn tạo một thùng chứa cho cơ sở dữ liệu, ví dụ:

docker run -d --name=test-mysql --env="MYSQL_ROOT_PASSWORD=mypassword" -P mysql

docker inspect d54cf8a0fb98 |grep HostPort

Và bạn có thể tìm thấy

"HostPort": "32777"

Điều này có nghĩa là bạn có thể kết nối cơ sở dữ liệu từ cổng localhost 32777 (3306 trong container) nhưng cổng này sẽ thay đổi mỗi khi bạn khởi động lại hoặc gỡ bỏ container. Vì vậy, bạn có thể sử dụng các liên kết để đảm bảo rằng bạn sẽ luôn kết nối với cơ sở dữ liệu và không phải biết đó là cổng nào.

web:
  links:
   - db

phụ thuộc:

Tôi tìm thấy một blog đẹp từ Giorgio Ferraris Docker-compose.yml: từ V1 đến V2

Khi docker-compose thực thi các tệp V2, nó sẽ tự động xây dựng một mạng giữa tất cả các container được xác định trong tệp và mọi container sẽ ngay lập tức có thể tham chiếu đến các tệp khác chỉ bằng cách sử dụng các tên được xác định trong tệp docker-compose.yml.

Vì vậy, chúng tôi không cần liên kết nữa; các liên kết đã được sử dụng để bắt đầu giao tiếp mạng giữa bộ chứa db và bộ chứa máy chủ web của chúng tôi, nhưng điều này đã được thực hiện bởi docker-compose

Cập nhật

phụ thuộc

Thể hiện sự phụ thuộc giữa các dịch vụ, có hai tác dụng:

  • docker-compose upsẽ bắt đầu dịch vụ theo thứ tự phụ thuộc. Trong ví dụ sau, db và redis sẽ được khởi động trước web.
  • docker-compose up SERVICEsẽ tự động bao gồm các phụ thuộc của DỊCH VỤ. Trong ví dụ sau, web soạn thảo docker cũng sẽ tạo và bắt đầu db và redis.

Ví dụ đơn giản:

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

Lưu ý: Dep_on sẽ không đợi db và redis trở thành sẵn sàng trước khi bắt đầu web - chỉ cho đến khi chúng được khởi động. Nếu bạn cần đợi một dịch vụ sẵn sàng, hãy xem Kiểm soát thứ tự khởi động để biết thêm về vấn đề này và các chiến lược để giải quyết nó.


Tôi đã cập nhật câu trả lời của mình để làm rõ rằng câu trả lời được dành cho việc soạn tập tin v1.
Xiongbing Jin

1
Điều này vẫn còn hiệu lực cho phiên bản 3?
fabiomaia

Vâng, bạn có thể có một cái nhìn tạihttps://docs.docker.com/compose/compose-file/compose-versioning/
Windsooon

"Điều này có nghĩa là bạn có thể kết nối cơ sở dữ liệu từ cổng localhost 32777 (3306 trong vùng chứa) Nhưng cổng này sẽ thay đổi mỗi khi bạn khởi động lại hoặc gỡ bỏ vùng chứa" chứ không phải nếu bạn chỉ định ràng buộc cổng trong tệp soạn thảo docker, nó sẽ không . Và vì câu hỏi này cụ thể là về docker-compose, tôi cảm thấy rằng ví dụ docker runở đây là hoàn toàn không liên quan, đó không phải là cách container sẽ được chạy. Tôi đang thiếu gì?
Andrew Savinykh

Có, bạn đúng nếu bạn chỉ định cổng. docker run Ví dụ của tôi muốn chỉ ra lý do tại sao chúng ta cần sử dụng phụ thuộc hoặc liên kết thay vì mã cứng một số cổng. Chỉ vì nếu bạn không chỉ định nó, nó sẽ thay đổi mỗi lần. Tôi nghĩ rằng điều này sẽ cho phép mọi người hiểu thêm về phụ thuộc hoặc liên kết.
Windsooon

50

[Cập nhật tháng 9 năm 2016]: Câu trả lời này được dành cho docker soạn tập tin v1 (như được hiển thị bởi tệp soạn thảo mẫu bên dưới). Đối với v2, hãy xem câu trả lời khác của @Windsooon.

[Câu trả lời gốc]:

Nó là khá rõ ràng trong tài liệu. depends_onquyết định sự phụ thuộc và thứ tự tạo container và linkskhông chỉ thực hiện những điều này mà còn

Các thùng chứa cho dịch vụ được liên kết sẽ có thể truy cập được tại một tên máy chủ giống hệt với bí danh hoặc tên dịch vụ nếu không có bí danh nào được chỉ định.

Ví dụ: giả sử docker-compose.ymltệp sau :

web:
  image: example/my_web_app:latest
  links:
    - db
    - cache

db:
  image: postgres:latest

cache:
  image: redis:latest

Với links, mã bên trong websẽ có thể truy cập cơ sở dữ liệu bằng cách sử dụng db:5432, giả sử cổng 5432 được hiển thị trong dbhình ảnh. Nếu depends_onđược sử dụng, điều này sẽ không thể thực hiện được, nhưng thứ tự khởi động của các container sẽ chính xác.


Bạn có thể cho tôi một ví dụ? Bởi vì phần đó là những gì tôi vẫn chưa rõ ràng. Có thể có các tùy chọn tập tin soạn thảo khác có thể làm cho nó cụ thể hơn. Vui lòng cung cấp thêm chi tiết. Cảm ơn!
itjef 6/03/2016

Cảm ơn rât nhiều! Tôi hiểu rồi. Một câu hỏi cuối cùng, xin vui lòng. Vì vậy, trong trường hợp đặc biệt của tôi, tôi đang triển khai ứng dụng ray của tôi, nên tôi sử dụng linkshoặc depends_onhoặc một trong hai số đó là ok? docker-compose.ymlSử dụng hiện tại của tôi depends_onvà mọi thứ dường như làm việc tốt. :)
itjef 7/03/2016

Nếu bạn không cần truy cập trực tiếp vào container khác name:portthì không sao depends_on.
Xiongbing Jin

9
Tên: cổng hoạt động ngay cả khi không liên kết khi bạn sử dụng phơi sáng:
Amit Goldstein

7
"Nếu phụ thuộc vào đã được sử dụng, điều này sẽ không thể thực hiện được, nhưng thứ tự khởi động của các container sẽ chính xác." Điều này LAF không đúng. Nó sẽ hoạt động nếu bạn chỉ sử dụng phụ thuộc. Bạn vẫn có thể truy cập dbvào webtên máy chủ của cơ sở dữ liệu.
prog.Dusan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.