- vừa được xem lúc

Giao tiếp giữa các container trong docker và sử dụng docker compose

0 0 52

Người đăng: Trieu

Theo Viblo Asia

Tiếp tục series bài viết về docker, phần 1 mình đã giới thiệu những cơ bản về docker, các lệnh để thao tác trong docker và cách deploy 1 ứng dụng đơn giản trong container. Nếu bạn còn đang chưa biết về docker, bạn có thể tham khảo phần 1 để hiểu cơ bản về docker qua bài viết: Tìm hiểu cơ bản về docker qua ví dụ
Trong bài viết tiếp theo này mình sẽ tiếp tục giới thiệu về docker network, cách để các container có thể giao tiếp và liên kết với nhau và sử dụng docker compose để biên tập, xây dựng và triển khai các dịch vụ trong các container. Nào hãy cùng bắt đầu nào, let's go!!!

Default network

Khi bạn cài đặt docker, nó sẽ tự động tạo ra 3 network tự động, ta có thể xem các network mặc định đó bằng lệnh sau: docker network ls

~# docker network ls
NETWORK ID NAME DRIVER SCOPE
7c62340c2fa9 bridge bridge local
f60c58334851 host host local
fbd0315gha15 none null local

Ba network trên được dựng lên trong Docker, khi run container ta có thêm flag --network thể chỉ định container đó kết nối vào mạng nào.
Network bridge đại diện cho network docker0 khi bạn cài đặt docker, trừ khi bạn chỉ định network cho container khi run bằng cách thêm vào docker run --network=<NETWORK> còn không, nó sẽ là network mặc định khi container được run và kết nối vào. Thử kiểm tra các cài đặt IP address, network trên máy ta sẽ thấy 2 network docker0 là network default:

~# ifconfig docker0 Link encap:Ethernet HWaddr 02:42:47:bc:3a:eb inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:4aff:fe7f:92f5/64 Scope:Link UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:36 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:5013 (5.0 KB)

Xem thông tin network trong docker bằng lệnh docker network inspect <NETWORK>
Để dễ dàng tiếp cận hơn, chúng ta cùng tìm hiểu thông qua ví dụ sau: tạo 2 container được run bởi image busybox và cùng tìm hiểu network mặc định của các container đó.
Đầu tiên, chúng ta cùng pull image busybox về bằng lệnh docker pull busybox. Nói qua về image tên busybox, nó là một image rất nhỏ gọn, chỉ hơn 1MB, nhưng nó chứa nhiều thứ rất hữu ích.
busybox là một software, nó tập hợp nhiều UNIX utilities (các câu lệnh) thành một file duy nhất. Các câu lệnh cung cấp bởi busybox thường tương đương với các câu lệnh cung cấp bởi GNU nhưng có ít option hơn.
Okay, đến đây chúng ta cùng thử tạo 2 container C1 & C2 được run bới busybox:

~# docker run -itd --name=C1 busybox
82cc2ba61825b8d24dfb87fe773af7bd65a6ea093d1j7a602a1a1a5h4c905adb
~# docker run -itd --name=C2 busybox
2e1ee5131c2f29b67570720078180c95fce63cc2a45677b2a2ee4f2039ed6255
~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2e1ee5131c2f busybox "sh" 6 seconds ago Up 3 seconds C2
82cc2ba61825 busybox "sh" 17 seconds ago Up 15 seconds C1

Kiểm tra network bridge để xen thông tin các container kết nối vào bằng lệnh docker network inspect bridge . Chúng ta sẽ nhận được 1 file json chứa thông tin về bridge network, trong đó có thông tin các container kết nối vào:

... "Containers": { "2e1ee5131c2f29b67570720078180c95fce63cc2a45677b2a2ee4f2039ed6255": { "Name": "C2", "EndpointID": "4baeadde1e4ba40542e2e71039735dab99bd4d91dd2d1c5d569k88752194ef7a", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "82cc2ba61825b8d24dfb87fe773af7bd65a6ea093d1j7a602a1a1a5h4c905adb": { "Name": "C1", "EndpointID": "df64cddf8081f9363b1c56891b18b6da534f694348838a81c327cbab581943a7", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, ...

Dễ dàng thấy container C1 và C2 vừa tạo đã được kết nối vào mạng bridge, mạng mặc định của docker khi chúng ta run container.
Bây giờ chúng ta cùng vào trong container C1 kiểm tra thử kết nối tới container C2 xem sao. Sử dụng lệnh docker exec -it C1 sh để truy cập vào trong container C1, gõ lệnh ifconfig ta sẽ thấy được địa chỉ của container C1. Sau đó chạy lệnh ping 172.17.0.3 (172.17.0.3 là địa chỉ IP của container C2 lấy được bằng các tương tự) ta sẽ thấy thông báo kết quả ping kết nối được tới container C2.

User-defined networks

Bạn cũng có thể tự define 1 network riêng và cho phép những container chỉ định được kết nối với nhau thông qua network đó.
Để tạo một network riêng bằng cách sử dụng lệnh sau:

~# docker network create --driver bridge my_network
7824916e5e5ef2928a6cfa957256cea7792f4368aed965ce09c64a66f486a537

network được tạo ra với tên là my_network được sử dụng chung driver bridge giống như network bridge mặc định. Bây giờ chúng ta có thể chạy lệnh start container với network chỉ định của chúng ta:

~# docker run -itd --network my_network --name C3 busybox
c90488b76bdca110190428073e7ac45e9bbae6ae01e8f5de98d43b6dd8555677

Chúng ta vừa chỉ định container C3 được run kết nối vào mạng my_network vừa được tạo. Sử dụng lệnh docker exec -it C3 sh để truy cập container C3 và xem địa chỉ IP ta sẽ thấy có địa chỉ thuộc dải mạng khác với dải mạng bridge mà container C1, C2 kết nối vào. Thử ping đến địa chỉ container C1, C2 tạo ở trên thì thấy không phản hồi. Như vậy rõ ràng container C3 tạo ra đã kết nối đến network my_network riêng mà chúng ta tạo ra hoàn toàn độc lập với container C1, C2 ở trên.
Bạn cũng có thể setting cho container C3 connect đến network bridge bằng lệnh docker network connect bridge C3. Sau khi chạy lệnh container C3 sẽ được kết nối thêm đến mạng bridge mặc định, chúng ta có thể truy cập C3 và ping được đến các container C1, C2.

Links

Trước khi Docker bao hàm các mạng do user dự định nghĩa, bạn cũng có thể sử dụng --link cho phép container có thể giải quyết tên của container khác thành địa chỉ IP. Đồng thời cũng cho nó quyền truy cập vào các biến môi trường của các container khác được liên kết. Nếu có thể bạn cũng nên tránh sử dụng flag --linkvì khi tạo link, chúng hoạt động khác so với sử dụng bridge network hoặc network do user tự định nghĩa.

Docker Compose

Tiếp theo, mình sẽ chỉ cho các bạn cách sử dụng Docker Compose để tạo và chạy các lệnh dịch vụ trên docker.
Nói qua về docker-compose: Khi phân phối các ứng hoàn thành, từng phần của ứng dụng đó ở dạng sản phẩm gọi nó là các service (dịch vụ). Những thành phần này khi phân phối ứng dụng chúng đều được gọi là các dịch vụ service. Như vậy các service thực chất là các container chạy đáp ứng chức năng thành phần tạo nên ứng dụng. Bạn cần hiểu sơ qua về khái niệm này vì ta sẽ sử dụng nó trong docker-compose giúp tạo ra các service trên một cách tự động
Một phần quan trọng nữa của docker-compose đó chính là file docker-compose.yml. File docker-compose.yml gần giống ý nghĩa với file Dockerfile đã tìm hiểu trong bài viết trước, là một file text, viết với định dạng YAML (Ain’t Markup Language, đọc nhanh định dạng Định dạng YML) là cấu hình để tử đó lệnh docker compose sinh ra và quản lý các service (container), các network, các ổ đĩa ... cho một ứng dụng hoàn chỉnh. Đầu tiên, bạn phải cài đặt thêm docker-compose, để cài đặt các bạn có thể tham khảo cách cài đặt docker compose.
Sau khi cài đặt thành công bạn có thể kiểm tra:

~# docker-compose -v
docker-compose version 1.24.1, build 4667896b

Đến đây, sau khi đã hoàn tất việc cài đặt bạn tạo ra file docker-compose.yml ở ngay trong thư mục gốc của project. Hãy cùng xem qua file docker-compose.yml sau đó mình sẽ giải thích chi tiết nội dung trong file.

version: "3" networks: my_network: driver: bridge
services: my_database: container_name: my_database image: "mysql:5.7" networks: - my_network restart: always ports: - 3306:3306 volumes: - ./database:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=my_database - MYSQL_USER=my_user - MYSQL_PASSWORD=password my_app: build: context: ./my_app networks: - my_network container_name: my_app restart: always ports: - 8080:8080 depends_on: - my_database links: - my_database

Giải thích:

  • version: chọn viết theo phiên bản 3 docs.docker.com/compose/compose-file/
  • services: Các dịch vụ, container nằm trong services
  • networks: define một network dùng chung cho các container. Network này có tên là my_network sử dụng driver bridge
  • my_database: Dịch vụ đầu tiên có tên là my_database, được build từ image mysql:5.7, sử dụng mạng my_network đã định nghĩa ở trên
  • restart: always: luôn khởi động lại khi xảy ra lỗi hặc bị stop.
  • ports: mapping port 3306 trong container với port 3306 ở máy local. (chú ý port đằng trước là port chỉ định máy local, port sau là port trong container)
  • volumes: mount dữ liệu ra ngoài máy local: mapping thư mục ./database trên máy local với thư mục /var/lib/mysql trong database. Sở dĩ phải mapping như vậy để tránh việc mất dữ liệu khi chúng ta chạy lại docker-compose. Vì khi chạy lại docker-compose thì nó cũng tạo ra 1 container mysql mới, chúng ta lưu trữ dữ liệu trong container ra ngoài máy local để khi start lại, container mới tạo ra vẫn ánh xạ đến thư mục naỳ trên máy local và sử dụng dữ liệu cũ một cách bình thường.
  • environment: Các biến môi trường setting mặc định trong container.
  • my_app: Define service thứ 2, là service chứa ứng dụng web app của project.
  • build: context: ./my_app build service bằng file Dockerfile trong thư mục my_app
  • depends_on, link: Thiết lập container my_app phụ thuộc vào container my_database (khởi động sau khi container my_database start thành công) đồng thời link đến container đó.
  • Các thông số còn lại tương tự như service my_database. Đến đây chúng ta coi như đã hoàn thành xong việc cấu hình docker-compose và các service của nó. Để run docker-compose bạn sử dụng lệnh docker-compose up để run file docker-compose.yml bằng docker compose. Bạn cũng có thể chỉ định docker-compose file để run bằng cách thêm vào -f <file_name>.yml trong trường hợp bạn muốn đặt tên file khác tên docker-compose.yml. Còn không docker compose sẽ tự động run file docker-compose.yml. Sau khi run thành công, chúng ta sẽ có 2 container my_databasemy_app được khởi tạo ra running. Do đã chỉ định port mapping với máy local nên chúng ta có thể dễ dàng truy cập container my_database thông qua localhost:3306 và container my_app thông qua localhost:8080.
    Để stop các dịch vụ trên, bạn sử dụng lệnh docker-compose down. Lệnh này cho phép stop và remove các container được tạo bởi docker-compose.

Kết luận

Bài viết trên mình đã trình bày về network, cách các container giao tiếp với nhau trong docker và cách sử dụng docker compose để xây dựng, triển khai các lệnh dịch vụ trên docker. Hy vọng bài viết đem lại kiến thức và giúp ích cho các bạn trong học tập và công việc. Mình xin cảm ơn các bạn đã theo dõi.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 528

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 407

- vừa được xem lúc

Đặt tên commit message sao cho "tình nghĩa anh em chắc chắn bền lâu"????

. Lời mở đầu. .

1 1 772

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 367

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 460

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 436