Khi chúng ta cài đặt Docker, những thiết lập sau sẽ được thực hiện:
- Virtual bridge docker0 sẽ được tạo ra
- Docker tìm một subnet chưa được dùng trên host và gán một địa chỉ cho docker0
Sau đó, khi chúng ta khởi động một container (với bridge network), một veth (Virtual Ethernet) sẽ được tạo ra nối 1 đầu với docker0 và một đầu sẽ được nối với interface eth0 trên container.
CHÚ Ý: bài này chúng ta sẽ dùng Image busybox để thực hành nhé
- link tham khảo: https://busybox.net/
- busybox là 1 image chứa các câu lệnh linux, như 1 linux thu nhỏ giúp thực hành tốt
root@adk:/# docker pull busybox
root@adk:/# docker run -it --rm busybox
/# ls /bin/ -la
1. Default network
Mặc định khi cài đặt xong, Docker sẽ tạo ra 3 card mạng mặc định là:
-
bridge
-
host
-
none.
-
Tương ứng với các nền tảo ảo hóa khác, ta có các chế độ card mạng của docker so với các nền tảng đấy là:
General Virtualization Term | Docker Network Driver |
---|---|
NAT Network | bridge |
Bridged | macvlan, ipvlan (experimental since Docker 1.11) |
Private / Host-only | bridge |
Overlay Network / VXLAN | overlay |
Để xem chi tiết, ta có thể dùng lệnh
docker network ls
root@adk:/# docker network ls
NETWORK ID NAME DRIVER SCOPE
1d8aa8d520a2 bridge bridge local
a8ddedeecca8 host host local
ad1c5f949ef2 none null local
root@adk:/#
Mặc định khi tạo container mà ta không chỉ định dùng network nào, thì docker sẽ dùng dải bridge.
1.1 None network
Các container thiết lập network này sẽ không được cấu hình mạng.
1.2 Bridge
Docker sẽ tạo ra một switch ảo. Khi container được tạo ra, interface của container sẽ gắn vào switch ảo này và kết nối với interface của host.
root@adk:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "1d8aa8d520a2775b5f02279e2ff057e2d781a67e116e603d367edab58211a5d9",
"Created": "2017-03-14T09:35:39.561628223+07:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
root@adk:~#
trong đó:
- bridge: chỉ định network muỗn kiểm tra
- containers: là nơi các container sử dụng network này
1.3 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.
THỰC HÀNH:
root@adk:~# docker run -it --name B1 busybox
/#
root@adk:~# docker ps
NETWORK ID IMAGE COMMAND CREATED STATUS
fbca466d36b74 busybox "sh" 12 seconds ago Up 12 seconds
- Xem network đang có những container nào và details
root@adk:~# docker network inspect bridge
[
{
"Name": "bridge"
......
"Containers":{
"fbca466d36b74....": {
"Name": "B1",
"EndpointID": "c2f644c93861500240...",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
}
......
}
]
- Cách xem container đang dùng network nào
root@adk:~# docker inspect B1
[
{
"Id": "fbca466d36b74..."
"State": {
...
"Status": "running"
...
}
"NetworkSettings":{
...
"Networks":{
"bridge":{
...
}
}
...
}
}
]
- Hiện tại container đã kết nối với host thông qua bridge (chú ý chỉ container ra host), kiểm tra:
root@adk:~# docker attach B1
/ # ping google.com
64 bytes from 172.217.31.14: seq=0 ttl=37 time=48.884 ms
64 bytes from 172.217.31.14: seq=1 ttl=37 time=27.338 ms
- Tạo thêm 1 conainer B2 và ping sang B1 (chung network bridge)
root@adk:~# docker run -it --name B2 busybox
/#
root@adk:~# docker network inspect bridge
[
{
"Name": "bridge"
......
"Containers":{
"00e8d51c2ffd": {
"Name": "B2",
"IPv4Address": "172.17.0.3/16",
},
"fbca466d36b74....": {
"Name": "B1",
"IPv4Address": "172.17.0.2/16",
}
}
......
}
]
root@adk:~# docker attach B2
/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.380 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.098 ms
- Gủi gói tin từ container B1 qua container B2 (busybox có sẵn 1 máy chủ web http)
root@adk:~# docker attach B1
/ # ls
bin dev etc home lib lib64 proc root sys tmp usr var
/ # cd var
/var # ls
spool www
/var # cd www
/var/www # httpd
/var/www # vi index.html (chú ý: thoát vim bằng shift+:wd)
web server is running .....
~
~
- index.html 1/1 100%
root@adk:~# docker attach B2
/ # wget -o - 172.17.0.2
Connecting to 172.17.0.2 (172.17.0.2:80)
saving to 'index.html'
index.html 100% |************************************************************| 28 0:00:00 ETA
'index.html' saved
- Kết nối từ host vào trong container (expose port từ container ra ngoài), chú ý: nhớ xóa B1 và tạo lại như:
root@adk:~# docker run -it --name B1 -p 5001:80 busybox
/#
root@adk:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d441bb1aedfc busybox "sh" 19 seconds ago Up 18 seconds 0.0.0.0:5001->80/tcp B1
00e8d51c2ffd busybox "sh" 24 minutes ago Up 24 minutes B2
root@adk:~# docker attach B1
/# cd var/www
/var/www # httpd
web server is running ......
~
~
I index.html [Modified] 1/1 100%
/var/www #
#ra ngoài google gõ : http://localhost:5001/ hoặc 127.0.0.1:5001
2. User-defined networks
Ngoài việc sử dụng các network mặc định do docker cung cấp. Ta có thể tự định nghĩa ra các dải network phù hợp với công việc của mình.
Để tạo network, ta dùng lệnh
docker network create --driver bridge --subnet 192.168.1.0/24 bridgexxx
Trong đó:
- –driver bridge: Chỉ định dải mạng mới được tạo ra sẽ thuộc kiểu nào: bridge, host, hay none.
- –subnet: Chỉ định địa địa chỉ mạng.
- bridgexxx: Tên của dải mạng mới.
Khi chạy container chỉ định sử dụng 1 dải mạng đặc biệt, ta dùng lệnh
docker run --network=bridgexxx -itd --name=container3 busybox
Trong đó:
- –network=bridgexxx: Chỉ định ra dải mạng bridgexxx sẽ kết nối với container.
Container mà bạn chạy trên network này đều phải thuộc về cùng một Docker host. Mỗi container trong network có thể communicate với các containers khác trong cùng network.
THỰC HÀNH:
chú ý: nhớ giữ container của thực hành ở trên nhé
- Tạo và xóa mynetwork với driver là bridge
root@adk:~# docker network create --driver bridge mynetwork
e977f2a7f03963c199cd2779bf734994c590e1a0f0953ba6b6b8acd34a1dcf02
root@adk:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
259cc29f0e16 bridge bridge local
2a40928577af host host local
e977f2a7f039 mynetwork bridge local
ab4917835c95 none null local
root@adk:~# docker network rm mynetwork
mynetwork
- Tạo container B3 trên network là mynetwork
root@adk:~# docker run -it --name B3 --network mynetwork busybox
/#
root@adk:~# docker network inspect mynetwork
[
{
"Name": "mynetwork",
"Containers": {
"813250dde4": {
"Name": "B3",
"IPv4Address": "172.20.0.2/16",
}
},
}
]
- Tạo container B4 trên network là mynetwork và expose port : 5002
root@adk:~# docker run -it --name B4 -p 5002:80 --network mynetwork busybox
/#
root@adk:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4846e47341b5 busybox "sh" 11 seconds ago Up 8 seconds 0.0.0.0:5002->80/tcp B4
74ee691ba3b0 busybox "sh" 56 seconds ago Up 55 seconds B2
813250dde4bd busybox "sh" 7 minutes ago Up 7 minutes B3
d441bb1aedfc busybox "sh" 38 minutes ago Up 38 minutes 0.0.0.0:5001->80/tcp B1
- Chúng ta sẽ thử trường hợp B3 ping sang B2( ipv4: 172.17.0.3), CHÚ Ý: 2 container khác network
root@adk:~# docker attach B3
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
-
(ta thấy nó đứng im ko ping sang dc)
- Chúng ta sẽ gán network cho 1 container đang chạy …. CHÚ Ý: 1 container có thể kết nối nhiều network
root@adk:~# docker network connect bridge B3
root@adk:~# docker network inspect bridge
[
{
"Name": "bridge",
...
"Containers": {
"74ee691ba3b0fe14": {
"Name": "B2",
"IPv4Address": "172.17.0.3/16",
},
"813250dde4bd4": {
"Name": "B3",
"IPv4Address": "172.17.0.4/16",
},
"d441bb1aedfcf7d": {
"Name": "B1",
"IPv4Address": "172.17.0.2/16",
}
},
...
}
]
root@adk:~# docker attach B3
/# ping 172.17.0.3 (ping lại sang B2, thoát ctrl+c)
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.405 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.083 ms
/# wget -o - 172.17.0.3
Connecting to 172.17.0.3 (172.17.0.2:80)
saving to 'index.html'
index.html 100% |************************************************************| 28 0:00:00 ETA
'index.html' saved
CHÚ Ý: trong docker chúng ta có thể giao tiếp thẳng bằng tên không cần thông qua ipv4 cũng được ( được dùng nhiều nhé)
- ví dụ:
root@adk:~# docker attach B3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.405 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.083 ms
/# ping B2
3. An overlay network with Docker Engine swarm mode
- Overlay network là mạng có thể kết nối nhiều container trên các Docker Engine lại với nhau, trong môi trường cluster.
- Swarm tạo ra overlay network chỉ available với các nodes bên trong swarm. Khi bạn tạo ra một service sử dụng overlay network, manager node sẽ tự động kế thừa overlay network tới các nodes chạy các service tasks.
Ví dụ sau sẽ hướng dẫn cách tạo ra một network và sử dụng nó cho một service từ một manager node bên trong swarm:
# Create an overlay network `my-multi-host-network`.
$ docker network create \
--driver overlay \
--subnet 10.0.9.0/24 \
my-multi-host-network
400g6bwzd68jizzdx5pgyoe95
# Create an nginx service and extend the my-multi-host-network to nodes where
# the service's tasks run.
$ $ docker service create --replicas 2 --network my-multi-host-network --name my-web nginx
716thylsndqma81j6kkkb5aus
4. “Nói chuyện” giữa các container với nhau.
- 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. Tuy nhiên, các container được cấp ip động nên nó có thể thay đổi, dẫn đến nhiều khó khăn. Vì vậy, thay vì dùng địa chỉ ip, ta có thể dùng name của các container để “liên lạc” giữa các container với nhau.
- Trong trường hợp sử dụng default bridge network thì ta khai báo thêm lệnh
--link=name_container
. - Trong trường hợp sử dụng user-defined bridge network thì ta không cần phải link nữa.
4.1 Trường hợp sử dụng default bridge network để kết nối các container
- Giả sử ta có mô hình:
web - db
- container web phải link được với container db.
docker run -itd --name=db -e MYSQL_ROOT_PASSWORD=pass mysql:latest
docker run -itd --name=web --link=db nginx:latest
- Kiểm tra:
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
...
4.2 Trường hợp sử dụng user-defined bridge network để kết nối các container
- 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.
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 --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
5. DNS server.
5.1 Default bridge network
- 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. - Kiểm tra trên container:
root@292a65a743ac:/# mount | grep /etc
/dev/disk/by-uuid/d9ed83b8-98cb-428a-9ad0-e7bf8ae36117 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/d9ed83b8-98cb-428a-9ad0-e7bf8ae36117 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/d9ed83b8-98cb-428a-9ad0-e7bf8ae36117 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)
=> Ta thấy các file trên container được mount từ các file trên máy host.
- Kiểm tra nội dung file
resolv.conf
root@292a65a743ac:/# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
nameserver 8.8.4.4
=> Tương tự trên máy host.
5.2 User-defined networks
- Docker sẽ sử dụng
built-in dns
riêng cho các container cùng 1 network. - Nội dung file
/etc/resolv.conf
root@07c8c10a7a81:/# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
root@07c8c10a7a81:/#
- Docker chưa cung cấp công cụ để xem thông tin các record của built-in dns này.
5.3 Chỉ định sử dụng dns-server riêng
- Dùng cờ
--dns
: để khai báo dns-server sẽ sử dụng trong container:
root@docker2:/opt# docker run -it --name hcm --dns=10.10.10.1 ubuntu /bin/bash
6. MacVlan.
Macvlan cho phép cấu hình sub-interfaces (hay còn gọi là slave devices) trên một Ethernet interface vật lý (còn gọi là upper device), mỗi sub-interfaces này có địa chỉ MAC riêng và do đó có địa chỉ IP riêng. Các ứng dụng, VM và các containers có thể kết nối với một sub-interface nhất định để kết nối trực tiếp với mạng vật lý, sử dụng địa chỉ MAC và địa chỉ IP riêng của chúng.
LAB macvlan chế độ bridge
Trong khi macvlan có 4 chế độ (VEPA, bridge, private, passthrough), thì Docker macvlan driver chỉ hỗ trợ macvlan bridge mode.
- Mô hình:
- Kiểm tra card mạng máy host
root@docker4:~# ifconfig -a
docker0 Link encap:Ethernet HWaddr 02:42:b5:a4:86:55
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth0 Link encap:Ethernet HWaddr 52:54:00:f6:70:7a
inet addr:172.16.69.234 Bcast:172.16.69.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fef6:707a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:754142 errors:0 dropped:4 overruns:0 frame:0
TX packets:225721 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:87515346 (87.5 MB) TX bytes:34434449 (34.4 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:576 (576.0 B) TX bytes:576 (576.0 B)
- Tạo card mạng macvlan chế độ bridge
root@docker4:~# docker network create -d macvlan --subnet 172.16.69.0/24 --gateway 172.16.69.1 --ip-range=172.16.69.240/28 -o parent=eth0 macvlan0
Trong đó:
-
subnet và gateway: chỉ ra dải địa chỉ mạng thật.
-
ip-range: Chỉ ra dải địa chỉ sẽ được cấp cho container.
-
Kiểm tra card mạng vừa tạo
root@docker4:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
89aacb502e1e bridge bridge local
d1b81f6ed217 docker_gwbridge bridge local
e1ea5196a974 host host local
re92zy5a0lvn ingress overlay swarm
bf347a55a5a4 macvlan0 macvlan local
120c2a080b4f none null local
- Tạo container1 và gắn vào card mạng vừa tạo
root@docker4:~# docker run -it --net macvlan0 --name alpine1 alpine /bin/sh
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
24: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 02:42:ac:10:45:f0 brd ff:ff:ff:ff:ff:ff
inet 172.16.69.240/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe10:45f0/64 scope link tentative
valid_lft forever preferred_lft forever
/ #
- Kiểm tra ping gateway và ping ra ngoài internet
/ # ping 172.16.69.1
PING 172.16.69.1 (172.16.69.1): 56 data bytes
64 bytes from 172.16.69.1: seq=0 ttl=64 time=0.856 ms
64 bytes from 172.16.69.1: seq=1 ttl=64 time=0.580 ms
^C
--- 172.16.69.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.580/0.718/0.856 ms
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=45 time=40.851 ms
^C
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 40.851/40.851/40.851 ms
/ #
/ # exit
root@docker4:~#
- Tạo container2 và gắn vào card mạng vừa tạo
root@docker4:~# docker run -it --net macvlan0 --name alpine2 alpine /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
25: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 02:42:ac:10:45:f1 brd ff:ff:ff:ff:ff:ff
inet 172.16.69.241/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe10:45f1/64 scope link
valid_lft forever preferred_lft forever
/ #
- Ping container1, google
/ # ping 172.16.69.240
PING 172.16.69.240 (172.16.69.240): 56 data bytes
64 bytes from 172.16.69.240: seq=0 ttl=64 time=0.349 ms
64 bytes from 172.16.69.240: seq=1 ttl=64 time=0.139 ms
64 bytes from 172.16.69.240: seq=2 ttl=64 time=0.090 ms
64 bytes from 172.16.69.240: seq=3 ttl=64 time=0.282 ms
^C
--- 172.16.69.240 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.090/0.215/0.349 ms
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=45 time=32.703 ms
64 bytes from 8.8.8.8: seq=1 ttl=45 time=32.804 ms
64 bytes from 8.8.8.8: seq=2 ttl=45 time=32.803 ms
64 bytes from 8.8.8.8: seq=3 ttl=45 time=32.768 ms
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 32.703/32.769/32.804 ms
LAB macvlan chế độ bridge tính năng vlan
-
Tính năng vlan sẽ phân chia các containers nằm trên từng vlan khác nhau. Giúp chúng ta dễ dàng quản lý các container.
-
Định dạng của vlan sub-interface là
interface_name.vlan_tag
. Ví dụ: eth0.50 -
Mô hình:
- Tạo network với
vlan tag
là50
dựa trên interfaceeth0
docker network create -d macvlan \
--subnet=192.168.50.0/24 \
--gateway=192.168.50.1 \
-o parent=eth0.50 macvlan50
- Tạo 2 containers dùng card mạng này:
docker run --net=macvlan50 -it --name macvlan_test5 --rm alpine /bin/sh
docker run --net=macvlan50 -it --name macvlan_test6 --rm alpine /bin/sh
- Tạo network với
vlan tag
là60
dựa trên interfaceeth0
docker network create -d macvlan \
--subnet=192.168.60.0/24 \
--gateway=192.168.60.1 \
-o parent=eth0.60 -o \
--macvlan_mode=bridge macvlan60
- Tạo 2 containers:
docker run --net=macvlan60 -it --name macvlan_test7 --rm alpine /bin/sh
docker run --net=macvlan60 -it --name macvlan_test8 --rm alpine /bin/sh
Kiểm tra
- Sau khi tạo 2 macvlan, ta thấy xuất hiện 2 sub-interface tương ứng là:
eth0.50@eth0
vàeth0.60@eth0
root@docker4:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:f6:70:7a brd ff:ff:ff:ff:ff:ff
inet 172.16.69.234/24 brd 172.16.69.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fef6:707a/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:b5:a4:86:55 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
33: eth0.50@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 52:54:00:f6:70:7a brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fef6:707a/64 scope link
valid_lft forever preferred_lft forever
36: eth0.60@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 52:54:00:f6:70:7a brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fef6:707a/64 scope link
valid_lft forever preferred_lft forever
- Trên containers
macvlan_test5
ping đến containersmacvlan_test6
:
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
34: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 02:42:c0:a8:32:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.50.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:3202/64 scope link
valid_lft forever preferred_lft forever
/ # ping 192.168.50.3
PING 192.168.50.3 (192.168.50.3): 56 data bytes
64 bytes from 192.168.50.3: seq=0 ttl=64 time=0.357 ms
64 bytes from 192.168.50.3: seq=1 ttl=64 time=0.107 ms
^C
--- 192.168.50.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.107/0.232/0.357 ms
/ #
- Trên containers
macvlan_test5
ping đến containersmacvlan_test7
:
/ # ping 192.168.60.2
PING 192.168.60.2 (192.168.60.2): 56 data bytes
^C
--- 192.168.60.2 ping statistics ---
21 packets transmitted, 0 packets received, 100% packet loss
/ #
Tạo multi-subnet trên cùng 1 sub-interface:
### Create multiple bridge subnets with a gateway of x.x.x.1:
docker network create -d macvlan \
--subnet=192.168.164.0/24 --subnet=192.168.166.0/24 \
--gateway=192.168.164.1 --gateway=192.168.166.1 \
-o parent=eth0.166 \
-o macvlan_mode=bridge macvlan64
docker run --net=macvlan64 --name=macnet54_test --ip=192.168.164.10 -itd alpine /bin/sh
docker run --net=macvlan64 --name=macnet55_test --ip=192.168.166.10 -itd alpine /bin/sh
docker run --net=macvlan64 --ip=192.168.164.11 -it --rm alpine /bin/sh
docker run --net=macvlan64 --ip=192.168.166.11 -it --rm alpine /bin/sh
- Khi tạo containers phải chỉ định rõ là sử dụng subnet nào.
- Mặc dù cùng 1 sub-interface nhưng các containers chỉ có thể nói chuyện với nhau nếu nó nằm cùng 1 subnet.
7. Ipvlan
Ipvlan khá giống so với macvlan, tuy nhiên nó có điểm khác so với macvlan là không gán địa chỉ MAC riêng cho các sub-interfaces. Các sub-interfaces chia sẻ chung địa chỉ MAC với parent interfaces (card vật lý trên đó tạo các sub-interfaces), nhưng có địa chỉ IP riêng.
-
Ipvlan L2: Ipvlan L2 hay Layer 2 mode tương tự với chế độ macvlan bridge mode.
-
Ipvlan L3: Ipvlan L2 được coi coi như bridge hay switch giữa các sub-interfaces và parent interface. Tương tự như vậy, Ipvlan L3 hay Layer 3 mode được coi như thiết bị lớp 3 (như router) giữa các sub-interfaces và parent interfaces.
-
Thông tin về macvlan và ipvlan các bạn có thể tham khảo thêm tại đây: https://github.com/hocchudong/networking-team/blob/master/ThaiPH/Linux%20Networking/ThaiPH_macvlan_vs_ipvlan.md
-
Lab ipvlan mode 2 khá tương tự với phần macvlan chế độ bridge nên tôi sẽ không đề cập tại đây
-
Để sử dụng được chế độ ipvlan, các bạn phải kích hoạt tính năng Experimental và nên update lên kernel mới nhất:
- Tạo file
/etc/docker/daemon.json
với nội dung:
{ "experimental": true }
- Khởi động lại docker:
service docker restart
- Kiểm tra: Nếu trả về true là ok.
$ docker version -f '{{.Server.Experimental}}' true
- Tạo file
Lab ipvlan L3: Multi-Subnet Ipvlan L3 Network
- Mô hình
- Kiểm tra card mạng máy host
root@docker4:~# ifconfig -a
docker0 Link encap:Ethernet HWaddr 02:42:b5:a4:86:55
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth0 Link encap:Ethernet HWaddr 52:54:00:f6:70:7a
inet addr:172.16.69.234 Bcast:172.16.69.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fef6:707a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:754142 errors:0 dropped:4 overruns:0 frame:0
TX packets:225721 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:87515346 (87.5 MB) TX bytes:34434449 (34.4 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:576 (576.0 B) TX bytes:576 (576.0 B)
- Tạo network
root@docker4:~# docker network create -d ipvlan --subnet=192.168.100.0/24 --gateway=192.168.100.1 --subnet=192.168.200.0/24 --gateway=192.168.200.1 -o parent=eth0 -o ipvlan_mode=l3 ipvlan
root@docker4:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
20504846ae2b bridge bridge local
e1ea5196a974 host host local
0f6b33a6df54 ipvlan ipvlan local
120c2a080b4f none null local
root@docker4:~#
- tạo container1 với subnet 192.168.100.0/24
root@docker4:~# docker run -it --name ipvlan_c1 --net=ipvlan --ip=192.168.100.2 alpine /bin/sh
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
31: eth0@if2: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 52:54:00:f6:70:7a brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fef6:707a/64 scope link
valid_lft forever preferred_lft forever
/ #
=> cùng mac với máy host
- tạo container2 với subnet 192.168.200.0/24
root@docker4:~# docker run -it --name ipvlan_c2 --net=ipvlan --ip=192.168.200.2 alpine /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
32: eth0@if2: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 52:54:00:f6:70:7a brd ff:ff:ff:ff:ff:ff
inet 192.168.200.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fef6:707a/64 scope link
valid_lft forever preferred_lft forever
/ #
=> cùng mac với máy host
- Trên container2 ping container1
/ # ping 192.168.100.2
PING 192.168.100.2 (192.168.100.2): 56 data bytes
64 bytes from 192.168.100.2: seq=0 ttl=64 time=0.399 ms
64 bytes from 192.168.100.2: seq=1 ttl=64 time=0.095 ms
64 bytes from 192.168.100.2: seq=2 ttl=64 time=0.091 ms
64 bytes from 192.168.100.2: seq=3 ttl=64 time=0.104 ms
64 bytes from 192.168.100.2: seq=4 ttl=64 time=0.100 ms
64 bytes from 192.168.100.2: seq=5 ttl=64 time=0.292 ms
^C
--- 192.168.100.2 ping statistics ---
6 packets transmitted, 6 packets received, 0% packet loss
round-trip min/avg/max = 0.091/0.180/0.399 ms
/ #
Reference
- https://gist.github.com/nerdalert/c0363c15d20986633fda
- https://github.com/hocchudong/networking-team/tree/master/ThaiPH/Linux%20Networking
- http://www.dasblinkenlichten.com/docker-networking-101-host-mode/
- https://viblo.asia/euclid/posts/XqakEmmbkWK
- https://docs.docker.com/engine/userguide/networking/#the-dockergwbridge-network
- https://kipalog.com/posts/Cach-lien-ket-cac-container-lai-voi-nhau-trong-docker
- https://docs.docker.com/engine/userguide/networking/get-started-macvlan/
- https://www.slideshare.net/bbsali0/docker-networking-with-new-ipvlan-and-macvlan-drivers
- https://hicu.be/docker-networking-macvlan-bridge-mode-configuration
- https://hicu.be/docker-container-network-types
- https://sreeninet.wordpress.com/2016/05/29/docker-macvlan-and-ipvlan-network-plugins/
- https://sreeninet.wordpress.com/2016/05/29/macvlan-and-ipvlan/