Cách liên kết các container lại với nhau trong docker
TIL
595
Docker
29
White

manhdung viết ngày 22/07/2016

Liên kết các container trên cùng một host

Trên cùng một host, các container chỉ cần dùng bridge network để nói chuyện được với nhau. Nhưng có một trở ngại là IP của các container được cấp động nên nếu sử dụng IP thì không tiện chút nào. Cách duy nhất giải quyết là dùng name, vừa thân thiện lại có thể map động nên khi IP thay đổi cũng không lo mất kết nối giữa các dịch vụ chạy trên các container khác nhau. Phương thức thực hiện của docker lại hơi khác nhau trong hai trường hợp: sử dụng default bridge network và sử dụng user-defined bridge network. MÌnh sẽ đi lần lượt từng trường hợp.

Về bridge network bạn có thể tìm đọc một bài mình từng viết:
http://kipalog.com/posts/Tim-hieu-bridge-network-trong-Docker

Trường hợp sử dụng default bridge network để kết nối các container

Để kết nối được các container trong host qua name thì chỉ có cách dùng dns hoặc /etc/hosts

Trong trường hợp sử dụng default bridge network mặc định sẽ không có một built-in DNS hoạt động. Thử kiểm tra xem

Run alpine image và xem resolv.conf của nó

docker run -it alpine sh
/ # cat /etc/resolv.conf 
nameserver 8.8.8.8

Thông tin trong /etc/resolv.conf của container là sao chép từ con host, chỉ sao chép chứ không tham chiếu. Nameserver 8.8.8.8 chắc chắn không thể biết phân giải name của các container được. Bạn có thể sửa đổi nameserver qua docker run --dns

Tìm tiếp trong /etc/hosts

127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.8  81d8c4cf33ff

Dòng 172.17.0.8 81d8c4cf33ff là cho localhost
Cũng không có thông tin để phân giải name ra IP cho các container khác.

Ở đây hostname khi không được xác định trong docker run -h thì sẽ dùng container id

Cả ba file /etc/hosts, /etc/resolv.conf và /etc/hostname đều được mount từ ngoài vào

/ # mount | grep etc
/dev/md126p3 on /etc/resolv.conf 
/dev/md126p3 on /etc/hostname
/dev/md126p3 on /etc/hosts

Vậy nếu giờ muốn liên kết các container qua default bridge network thì làm thế nào ?
Có thể dùng giải pháp link container.

Giả sử có mô hình
web - redis - db
ở đây từ container web phải connect được đến redis và đến db. Đặt tên cho từng container. Sau đó link theo tên, phải đảm bảo container được link phải tồn tại. Do đó phải run theo thư tứ db -> redis -> web

docker run -itd --name=db -e MYSQL_ROOT_PASSWORD=pass mysql:latest
docker run -itd --name=redis redis:latest
docker run -itd --name=web --link=redis --link=db nginx:latest
docker exec -it web sh
# ping redis
PING redis (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.245 ms
...
# ping db
PING db (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.126 ms
...

Lý do web container liên lạc được db và redis qua name là nhờ docker engine đã tự set thông tin link vào /etc/hosts của web container:

# cat /etc/hosts
172.17.0.3  redis 21cdcee10183
172.17.0.2  db 158aed2b8df9

Link này chỉ link một chiều, từ db và redis bạn không thể ping đến web được. Nói chung dùng link thì rất bất tiện, phải định nghĩa rõ chiều kết nối, phải đảm bảo start container theo đúng thứ tự. Phương thức kết nối qua link đã bị xem là lịch sử. Hiện tại nó chỉ còn được dùng để đảm bảo thứ tự khỏi chạy của các container.

Có lẽ lý do default bridge network không sử dụng một built-in dns sẵn là tránh cho người dùng cấu hình bừa bãi trong network này khiến nó trở thành một mạng quá lớn, các container liên kết với nhau quá dễ dàng dễ gây loạn. Vừa giải quyết vấn đề của link mà không khiến mạng bridge quá phình to thì docker khuyến khích dùng các user-defined bridge network

Trường hợp sử dụng user-defined bridge network để kết nối các container

Như đã nói, trường hợp này docker sẽ có sẵn một built-in dns, bạn không cần thực hiện thao tác link qua link lại giữa các container nữa.

Mỗi một user-defined network này sẽ có một built-in dns riêng.

docker network create my-net
docker network ls
NETWORK ID          NAME                DRIVER
716f591e185a        bridge              bridge              
4b0041303d6d        host                host                
7239bb9e0255        my-net              bridge              
016cf6ec1791        none                null

docker run -itd --name=web1 --net my-net nginx:latest
docker run -itd --net my-net --name=redis1 redis:latest
docker run -itd --name=db1 --net my-net -e MYSQL_ROOT_PASSWORD=pass mysql:latest

docker exec -it web1 sh
# ping db1
PING db1 (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.161 ms
# ping redis1
PING redis1 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.168 ms

Và do không dùng link mà qua một dns built-in nên các container có thể kết nối lẫn nhau, từ db1 bạn có thể ping được redis1 và web1

cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

Nếu trong default bridge network, cố tính set nameserver 127.0.0.11 cũng không active được built-in dns này.

Hiện tại docker chưa cung cấp công cụ để xem thông tin các record của built-in dns này.

Tham khảo:
https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/
https://docs.docker.com/engine/userguide/networking/configure-dns/

manhdung 22-07-2016

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

manhdung

44 bài viết.
263 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
76 11
Giới thiệu RabbitMQ là một message broker ( messageoriented middleware) sử dụng giao thức AMQP Advanced Message Queue Protocol (Đây là giao thức ph...
manhdung viết 3 năm trước
76 11
White
48 4
Giả định bạn tiếp nhận một server mới toanh, bạn cần tìm một số thông tin về nó như loại CPU, loại main, loại memory, memory dùng của hãng nào... c...
manhdung viết gần 2 năm trước
48 4
White
41 12
Trong phần 1, tôi đã giới thiệu về sơ lược rabbitmq, vai trò của rabbitmq trong hệ thống phân tán và hướng dẫn cài đặt. Trong phần này, tôi sẽ trìn...
manhdung viết 3 năm trước
41 12
Bài viết liên quan
White
0 2
fCC: Technical Documentation Page note So I have finished the HTML part of this exercise and I want to come here to lament about the lengthy HTML ...
HungHayHo viết 1 tháng trước
0 2
White
19 1
Toán tử XOR có tính chất: + A XOR A = 0 + 0 XOR A = A Với tính chất này, có thể cài đặt bài toán sau với độ phức tạp O(N) về runtime, và với O(1)...
kiennt viết gần 2 năm trước
19 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
44 bài viết.
263 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!