Hướng dẫn chi tiết cho người mới bắt đầu về Docker network, các loại network cơ bản như bridge, host, none và các khái niệm nâng cao như MacVlan, IPVlan.
Trong môi trường container hóa, việc quản lý và cấu hình mạng cho các container là một yếu tố quan trọng để đảm bảo sự liên kết và bảo mật giữa các dịch vụ. Docker network cho phép bạn kiểm soát cách các container giao tiếp với nhau cũng như với bên ngoài. Từ các loại network cơ bản như bridge, host, none đến các tùy chọn nâng cao như MacVlan và IP Vlan. Bài viết này sẽ giúp bạn hiểu rõ các khái niệm này và cách áp dụng chúng trong thực tế.
1. Docker network là gì?
Khi chúng ta tạo ra các container thì sẽ đặt ra một câu hỏi. Các container sinh ra là để cô lập với môi trường bên ngoài vậy thì làm cách nào để người dùng bên ngoài có thể liên lạc vào trong hay các container liên lạc với nhau bằng cách nào hay có cách nào để giới hạn các container liên lạc được với nhau không?
Câu trả lời chính là docker network. Docker network sẽ sử dụng cơ chế namespace network nhưng sẽ được tối ưu hơn với các câu lệnh docker. Tương tự như network namespace nó sẽ tạo ra các linux bridge và gắn các container vào switch ảo này để các switch ảo có thể liên lạc được với nhau.
Docker network là gì?
2. Các loại network cơ bản trong docker
Trong docker có 3 loại network cơ bản là:
- bridge : Tạo ra 1 switch ảo và các container sẽ được gắn vào đây.
- host : container sẽ chia sẻ network namespace với máy chủ, điều này có nghĩa là container sẽ không có địa chỉ IP riêng và thay vào đó sử dụng địa chỉ IP của host.
- none: không gán container vào bất kỳ network nào, container sẽ không có mạng, thường được sử dụng khi không cần hoặc không muốn container có quyền truy cập vào mạng.
Mặc định khi tải xuống docker và chưa cấu hình gì sẽ chỉ có 3 loại network này.
root@Quang-U22:~# docker network ls NETWORK ID NAME DRIVER SCOPE 17ffd945dc03 bridge bridge local d9ad904d640c host host local 0cdeca6e882e none null local |
2.1 Network bridge
Mô hình hoạt động của network bridge
Loại network này sẽ sử dụng 1 switch ảo và gắn các interface container lên switch này. Để xem chi thông tin chi tiết ta có thể sử dụng lệnh.
docker inspect bridge |
Thông tin chi tiết về network bridge
Khi bạn tạo bất kỳ một container nào mà không khai báo network thì nó sẽ sử đụng network mặc định này. Các IP được cấp cho container sẽ là dhcp và có thể thay đổi. Chính vì thế docker còn cung cấp cơ chế liên lạc với nhau thông qua docker name. Ta có thể ping được các container với nhau bằng nhưng khi chạy container trên network mặc định này ta cần khai báo thêm option --link vì trên network mặc định này không cung cấp dns.
# Tạo container 1 tồn tại trong 300s root@Quang-docker:~# docker run --rm --name container1 busybox sleep 300 |
# Tạo container 2 và ping đến container 1 bằng tên root@Quang-docker:~# docker run --rm --name container2 --link container1 busybox ping container1 PING container1 (172.17.0.4): 56 data bytes 64 bytes from 172.17.0.4: seq=0 ttl=64 time=0.278 ms 64 bytes from 172.17.0.4: seq=1 ttl=64 time=0.198 ms 64 bytes from 172.17.0.4: seq=2 ttl=64 time=0.150 ms 64 bytes from 172.17.0.4: seq=3 ttl=64 time=0.147 ms 64 bytes from 172.17.0.4: seq=4 ttl=64 time=0.154 ms 64 bytes from 172.17.0.4: seq=5 ttl=64 time=0.149 ms 64 bytes from 172.17.0.4: seq=6 ttl=64 time=0.149 ms |
2.2 Network host
Containers sẽ dùng mạng trực tiếp của máy host. Network configuration bên trong container đồng nhất với host.
root@Quang-docker:~# docker run --rm --network host busybox sleep 300 PING 172.16.66.41 (172.16.66.41): 56 data bytes 64 bytes from 172.16.66.41: seq=0 ttl=64 time=0.244 ms 64 bytes from 172.16.66.41: seq=1 ttl=64 time=0.125 ms 64 bytes from 172.16.66.41: seq=2 ttl=64 time=0.115 ms 64 bytes from 172.16.66.41: seq=3 ttl=64 time=0.131 ms |
2.3 None network
root@Quang-docker:~# docker run --rm --network none busybox sleep 300 root@Quang-docker:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5e0789246384 busybox "sleep 300" 28 seconds ago Up 27 seconds elated_cannon aad1921503e3 busybox "sleep 300" 4 minutes ago Up 4 minutes gracious_davinci |
3. User-defined networks
Người dùng có thể tự tạo docker network cho riêng mình. Mặc định thì vẫn sẽ chỉ có 3 loại driver mà đã giới thiệu ở trên.
docker network create --driver bridge --subnet 172.20.0.0/16 mynetwork |
Tao 2 container với image busybox trên cùng 1 network mynetwork
root@Quang-docker:~# docker run -it --name busybox1 --network mynetwork busybox / # root@Quang-docker:~# docker run -it --name busybox2 --network mynetwork busybox / # ping busybox2 PING busybox2 (172.20.0.2): 56 data bytes 64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.707 ms 64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.132 ms 64 bytes from 172.20.0.2: seq=2 ttl=64 time=0.132 ms |
Tạo thêm 1 container với image busybox nhưng trên network bridge mặc định.
root@Quang-docker:~# docker run -it --name busybox3 busybox |
Thêm container3 vào mynetwork
root@Quang-docker:~# docker network connect mynetwork busybox3 |
Ping thử
root@Quang-docker:~# docker run -it --name busybox3 busybox / # ping busybox1 ping: bad address 'busybox1' / # ping busybox1 PING busybox1 (172.20.0.3): 56 data bytes 64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.998 ms 64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.299 ms 64 bytes from 172.20.0.3: seq=2 ttl=64 time=0.188 ms |
4. DNS Server
Ta thấy rằng khi sử dụng network bridge thì các container không thể ping được với nhau bằng container name. Điều này xảy ra chính là do chưa có bản ghi dns.
Khi container được chạy với network default bridge thì container sẽ sao chép nội dung file /etc/resolv.conf của host vào trong container. Do đó, dns-server được cấu hình trên máy host như thế nào, thì trên container tương tự như vậy.
User-defined networks: Docker sẽ sử dụng built-in dns riêng cho các container cùng 1 network. Ngay khi tạo container thì các bản ghi dns sẽ được tạo ra để có thể phân biệt các container với nhau.
Chỉ sử dụng dns-server riêng.
docker run -it --name hcm --dns=10.10.10.1 ubuntu /bin/bash |
5. MacVlan và IPVlan
Trên môi trường vật lý VLAN được sử dụng để có thể phân chia ra các mạng riêng biệt. Tương tự như thế trên môi trường ảo hóa docker cũng cung cấp cho ta tính nằng như vậy được gọi là MacVlan và IPVlan.
Điểm giồng nhau của chúng là cho phép các container hoạt động như các thiết bị mạng độc lập tương tự như cách các thiết bị mạng vật lý hoạt động. Chúng cũng được sử dụng để phân chia các mạng riêng biệt như Vlan vậy. Mỗi container cũng sẽ có địa chỉ IP ứng với vlan riêng.
Điểm khác nhau cơ bản của 2 mạng này là MacVlan sử dụng địa chỉ Mac để phân biệt còn IPVlan sử dụng địa chỉ IP để phân biệt.
Giả sử bạn có một mạng vật lý với dải IP 192.168.1.0/24 và một máy chủ (host) có địa chỉ IP 192.168.1.10. Bạn muốn các container trên Docker có địa chỉ IP trong cùng dải mạng, để chúng có thể giao tiếp với các thiết bị trên mạng LAN mà không cần thông qua NAT.
docker network create -d macvlan \ --subnet=192.168.1.0/24 \ --gateway=192.168.1.1 \ -o macvlan_mode=bridge \ macvlan_net |
Giả sử bạn có một mạng vật lý với dải IP 192.168.2.0/24 và muốn sử dụng IPVlan để cấp địa chỉ IP cho các container mà không cần phải sử dụng địa chỉ MAC.
docker network create -d ipvlan \ --subnet=192.168.2.0/24 \ --gateway=192.168.2.1 \ -o ipvlan_mode=l2 \ ipvlan_net |
- -o ipvlan_mode=l2 chỉ định chế độ layer 2 cho mạng IPVlan.
Tổng kết
Network là một phần không thể thiếu trong bất kỳ hệ thống nào và docker cũng không ngoại lệ. Chỉ khi nắm bắt được network thì quá trình triển khai và tùy chỉnh container mới có thể thực hiện theo đúng ý của chúng ta. Hiện nay hầu hết trên docker chỉ tập trung vào 3 loại network cơ bản được liệt kê ở mục 2 và 3. Chúng ta cần nắm chắc để có thể triển khai container của chúng ta mà không gặp bất kỳ lỗi gì.