Docker (二) Docker網路配置
Docker提供網路服務
當我們在容器中執行一些網路服務,如httpd,nginx,php等。要讓外部使用者可以訪問這些服務,這就需要我們進行一些配置,才能達到這些效果。如埠對映或容器互聯的方式。
埠對映方式
我們可以在啟動容器的時候用-p或-P引數來制定埠對映。使用-p引數指定一個指定的埠對映到容器應用中,而使用-P是選擇一個隨機的埠對映到容器應用埠中。
方式一:使用-p引數,指定一個對映的埠,且這個被指定的埠只能繫結一個容器
# 繫結方式一: hostport:containerPort
[root@hd3 ~]# docker run -d -p 88:80 --name myweb nginx dac9b2d7ecab288e3fd3186e34941a78b94f4cee9368a3f0ccef8b8136a590a0 [root@hd3~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dac9b2d7ecab nginx "/docker-entrypoint.…" 4 seconds ago Up 2 seconds 0.0.0.0:88->80/tcp myweb [root@hd3 ~]# curl localhost:88<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
# 繫結方式二:host:port:containerPort [root@hd3 ~]# docker run -d -p 127.0.0.1:89:80 --name myweb nginx 1ce3a804f6ed20beaa353e7b9a8d8069c75f592a529fcbf95e23564a52c1d634 [root@hd3 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1ce3a804f6ed nginx "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 127.0.0.1:89->80/tcp myweb [root@hd3 ~]# curl 127.0.0.1:89
# 繫結方式三:host::containerPort 這種方式是選擇一個該主機的隨機埠 [root@hd3 ~]# docker run -d -p 127.0.0.1::80 --name myweb nginx 93a420d642bc36ec1f3c53bf10959b9b252603a5caff75cabc19c26a4e7f007f [root@hd3 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 93a420d642bc nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 127.0.0.1:32768->80/tcp myweb [root@hd3 ~]# curl 127.0.0.1:32768
# 可以指定對映埠的連線協議
[root@hd3 ~]# docker run -d -p 127.0.0.1:82:80/udp --name myweb nginx 34917ff1230b6a8d072507df71053afee430435fd1cd232c06f010b69eb663d0 [root@hd3 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 34917ff1230b nginx "/docker-entrypoint.…" 3 seconds ago Up 1 second 80/tcp, 127.0.0.1:82->80/udp myweb
# 也可以一次性繫結多個埠 [root@hd3 ~]# docker run -d -p 88:80 -p 89:443 --name myweb nginx 76764e3c6fa2e15b28dd3da5bba28713c00d89516953927cef10c290169ea112 [root@hd3 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 76764e3c6fa2 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:88->80/tcp, 0.0.0.0:89->443/tcp myweb
方式二:使用-P引數,Docker會隨機對映一個埠到內部的網路開放的埠和上述的第三種情況類似
[root@hd3 ~]# docker run -d -P --name myweb nginx 6e8f0737f38efea2c183b97babeaf5bc2bc12e4fa417ba5198b8cf04e75f0f6b [root@hd3 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e8f0737f38e nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:32772->80/tcp myweb
通過docker logs -f containername可以檢視docker日誌資訊
[root@hd3 ~]# docker logs -f myweb /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Configuration complete; ready for start up
通過docker ports containername檢視容器埠資訊
[root@hd3 ~]# docker port myweb 80/tcp -> 0.0.0.0:32772 [root@hd3 ~]#
Docker容器互聯
容器的連線系統除了埠對映外,另一種是容器的互動方式。該系統會在源和接受容器之間建立一個隧道,接受容器可以看到源容器指定的資訊。
使用 --link引數可以讓容器與容器之間進行安全的互動
[root@hd3 ~]# docker run -e MYSQL_ROOT_PASSWORD=123456 -d --name mydb mysql # 先啟動一個mysql容器 5b835f77eb9ad738ce55286ce1837ed84f59eab3c7a25a2e52b12a457f548fad [root@hd3 ~]# docker run -d -P --name myweb --link mydb:db nginx # 再啟動一個web容器,並將它連線到資料庫容器中 e74c38a73c7eee83fe017540f92284e5a71293c7159e1397a845a638b801d515 [root@hd3 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e74c38a73c7e nginx "/docker-entrypoint.…" 4 seconds ago Up 2 seconds 0.0.0.0:32773->80/tcp myweb 5b835f77eb9a mysql "docker-entrypoint.s…" 34 seconds ago Up 33 seconds 3306/tcp, 33060/tcp mydb
從上面可以看到,此時myweb和mydb容器已經相互連線起來
--link 引數的格式: --link name:alias
name:是要連結的容器的名稱,
alias:是這個連結的別名
Docker容器之間的互聯,是在容器與容器之間建立一個安全的隧道,而且不用對映他們的埠到主機上,在啟動mydb容器的時候沒有使用-p或-P引數,從而避免了暴露過多的埠到外部網路上。
Docker通過兩種方式為容器公開連線的資訊:
1. 環境變數
2. 更新/etc/hosts檔案
通過env可以檢視環境變數
[root@hd3 ~]# docker run --rm --name myweb01 --link mydb:db nginx env DB_PORT_33060_TCP_ADDR=172.17.0.2 HOSTNAME=37a871abaf9d DB_PORT=tcp://172.17.0.2:3306 DB_PORT_3306_TCP=tcp://172.17.0.2:3306 DB_PORT_33060_TCP_PORT=33060 DB_ENV_MYSQL_VERSION=8.0.21-1debian10 DB_PORT_33060_TCP_PROTO=tcp HOME=/root DB_NAME=/myweb01/db PKG_RELEASE=1~buster DB_PORT_33060_TCP=tcp://172.17.0.2:33060 NGINX_VERSION=1.19.1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin NJS_VERSION=0.4.2 DB_ENV_MYSQL_MAJOR=8.0 DB_PORT_3306_TCP_ADDR=172.17.0.2 DB_ENV_MYSQL_ROOT_PASSWORD=123456 PWD=/ DB_ENV_GOSU_VERSION=1.12 DB_PORT_3306_TCP_PORT=3306 DB_PORT_3306_TCP_PROTO=tcp
其中DB_開頭的環境變數是供web容器連線 DB 容器使用的。可以看到連線容器的協議,埠,密碼等
除了環境變數,Docker 還新增host資訊到父容器的 /etc/hosts 的檔案:
[root@hd3 ~]# docker run --rm -it --name myweb03 --link mydb:db nginx /bin/bash root@f1ee3a4dec86:/# cat /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.2 db 5b835f77eb9a mydb 172.17.0.4 f1ee3a4dec86
可以看到這裡有2個hosts,第一個是 web 容器,web容器用id作為他的主機名,第二個是 DB 容器的 ip 和主機名。可以在web 容器中使用ping命令來測試跟 DB 容器的連通。
Docker四種網路模式
Host模式
Docker使用了Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離程序,Mount Namespace隔離檔案系統,Network Namespace隔離網路等。一個Network Namespace提供了一份獨立的網路環境,包括網絡卡、路由、Iptable規則等都與其他的Network Namespace隔離。一個Docker容器一般會分配一個獨立的Network Namespace。但如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網絡卡,配置自己的IP等,而是使用宿主機的IP和埠。
表現形式:容器和宿主IP一致
特點: 用於網路效能要求較高的場景,但安全性和隔離性相對差一些
結構如下:
配置方式:--network host
[root@hd3 ~]# docker run -itd --name host_test --network host centos # 指定網路模式 837dd3e985b2b7e936940ee44b5cab13dc6d02a05c225a24c2e19f13c06c2d2c [root@hd3 ~]# docker exec -it host_test /bin/bash [root@hd3 /]# ip a # 進入容器可以發現連容器的主機名也和宿主的主機名一致,通過ip a 檢視到網路配置也都是一致的 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:4b:a1:4f brd ff:ff:ff:ff:ff:ff inet 192.168.239.132/24 brd 192.168.239.255 scope global noprefixroute ens32 valid_lft forever preferred_lft forever 。。。 [root@hd3 /]# exit exit [root@hd3 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:4b:a1:4f brd ff:ff:ff:ff:ff:ff inet 192.168.239.132/24 brd 192.168.239.255 scope global noprefixroute ens32 。。。
Bridge模式
bridge模式是Docker預設的網路設定,此模式會為每一個容器分配Network Namespace、設定IP等,並將一個主機上的Docker容器連線到一個虛擬網橋上。類似於Vmware的nat網路模式。同一個宿主機上的所有容器會在同一個網段下,相互之間是可以通訊的。docker程序會建立一個docker0網橋,容器內的資料通過這個網絡卡裝置於主機之間進行通訊。
特點:
配置方式:預設情況下就是bridge的模式
[root@hd3 ~]# docker run -d -it --name bridge_test centos 083ba95f39ae455be1f91efaa00a368db5bbf452a611ff2a0c4d39d2889a9d78 [root@hd3 ~]# [root@hd3 ~]# docker inspect bridge_test [ 。。。。。。。。。。 "Networks": { # 這一行顯示了該容器的網路是bridge "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "80c570b6c4ea28598da690765604caa14e02882735dc86807b6950205be8219c", "EndpointID": "e62963d786270c3d1f68b5c5aba10dfaa9a1d6328807409e894976c4aa983aaf", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ] [root@hd3 ~]# docker exec -it bridge_test /bin/bash [root@083ba95f39ae /]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 123: eth0@if124: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@083ba95f39ae /]# ping www.baidu.com PING www.a.shifen.com (180.101.49.12) 56(84) bytes of data. 64 bytes from 180.101.49.12 (180.101.49.12): icmp_seq=1 ttl=127 time=36.1 ms
注意: 若該預設方式容器無法訪問外網可以檢視一下該配置 systcl net.ipv4.ip_forward 1 # 若該值為0則無法訪問外網 systcl -w net.ipv4.ip_forward=1 # 將其修改為1
Container模式
這個模式指定新建立的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新建立的容器不會建立自己的網絡卡,配置自己的IP,而是和一個指定的容器共享IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過lo網絡卡裝置通訊。
表現形式:多個容器使用的是共同的網路,看到的IP也是一致的。
特點:K8S中的pod就是使用這種模式,平時使用不多
結構如下:
[root@hd3 ~]# docker run -itd --name container_test --net=container:bridge_test centos # 指定為container模式 0ab83d070c9c9ecff083a91ae4c3a5324c4b72eb4f726a4223cff0f31c5fd5f0 [root@hd3 ~]# docker attach container_test [root@083ba95f39ae /]# ip a # 檢視ip發現和上面bridge的ip一致的 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 123: eth0@if124: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
None模式
在這種模式下,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。也就是說,這個Docker容器沒有網絡卡、IP、路由等資訊。需要我們自己為Docker容器新增網絡卡、配置IP等。
[root@hd3 ~]# docker run -itd --name none_test --network none centos # 指定為none模式 ac35a1a7d54315b917197ce8a73f3b328ad78348f7f919144d34824459f7dab3 [root@hd3 ~]# docker attach none_test [root@ac35a1a7d543 /]# ip a # 檢視網路配置發現沒有任何資訊 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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
自定義網路
與預設的bridge一樣,但是自定義的網路具備內部的DNS發現,可以通過容器名或主機名進行容器之間的相互通訊。
[root@hd3 ~]# docker network create test_network # 自定義一個網路 cb23126382b281f7e9ec21dfb7471d0d1db382773b3b6596b05526b36deb49c9 [root@hd3 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 80c570b6c4ea bridge bridge local 7a4c931b7874 host host local 671303b2ec10 lnmp bridge local 89b85fcb7fd0 none null local cb23126382b2 test_network bridge local # 可以看到我們自己定義的網路
[root@hd3 ~]# docker run -itd --name test1 --net=test_network centos # 建立容器指定自定義的網橋 5137f1f35471832a65a275537dde5cef5671841fd18ac53ee5b0fccd0426a4c0 [root@hd3 ~]# docker run -itd --name test2 --net=test_network centos 58bf03132e8a8c51ffbe2d7ee9f4572233007de1d8d0383b7cef31968df34f6c [root@hd3 ~]# docker attach test1 [root@5137f1f35471 /]# ping test2 # 進入網橋ping 可以自定義解析test2 PING test2 (172.19.0.3) 56(84) bytes of data. 64 bytes from test2.test_network (172.19.0.3): icmp_seq=1 ttl=64 time=0.714 ms 64 bytes from test2.test_network (172.19.0.3): icmp_seq=2 ttl=64 time=0.077 ms [root@5137f1f35471 /]# cat /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.19.0.2 5137f1f35471
Docker的DNS配置
我們在建立容器的時候,並沒有指定主機名和DNS等配置,如果我們需要配置,那麼怎麼自定義配置容器的主機名和DNS配置?裡面的原理有事什麼樣的呢?
祕訣就是它利用虛擬檔案來掛載到容器的3個相關的配置檔案:
[root@hd3 ~]# docker run --rm --name mydocker -it centos /bin/bash [root@20265bbb21cd /]# mount # 檢視掛載資訊 。。。 /dev/sda3 on /etc/resolv.conf type xfs (rw,relatime,seclabel,attr2,inode64,noquota) /dev/sda3 on /etc/hostname type xfs (rw,relatime,seclabel,attr2,inode64,noquota) /dev/sda3 on /etc/hosts type xfs (rw,relatime,seclabel,attr2,inode64,noquota) 。。。
這種機制可以讓宿主機DNS資訊發生更新後,所有Docker容器的 dns 配置通過 /etc/resolv.conf 檔案立刻得到更新。
如果想要手動指定容器的配置,可以利用下面的選項。
-h HOSTNAME or --hostname=HOSTNAME 設定容器的主機名,它會被寫到容器的/etc/hostname 和 /etc/hosts。 但它在容器外部看不到,既不會在docker ps中顯示,也不會在其它容器的 /etc/hosts看到
--link=CONTAINER_NAME:ALIAS 選項會在建立容器的時候,新增一個其他容器 的主機名到/etc/hosts 檔案中,
讓新容器的程序可以使用主機名 ALIAS 就可以 連線它。
--dns=IP_ADDRESS 新增DNS伺服器到容器的 /etc/resolv.conf中,讓容器利用這個伺服器來解析所有不在 /etc/hosts 中的主機名
[root@hd3 ~]# docker run --rm --name mydocker -h host_test -it centos /bin/bash # 指定主機名 [root@host_test /]# cat /etc/hostname # 檢視一下主機名是我們指定的 host_test [root@host_test /]# cat /etc/hosts # 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.2 host_test
注意:如果沒有--dns 和--dns-search選項時,Docker會預設用宿主機上的 /etc/resolv.conf 來配置容器。
Docker容器訪問控制
容器訪問外網
容器的訪問控制,主要通過Linux上的 iptables 防火牆來進行管理和實現。
容器要想訪問外部網路,需要本地系統的轉發支援,在linux系統中,檢查轉發是否開啟
[root@hd3 ~]# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
如果為0,說明沒有開啟轉發,則需要手動開啟
[root@hd3 ~]# sysctl -w net.ipv4.ip_forward=1
注意:
如果在啟動Docker服務的時候指定 --ip-forward=true,Docker就會自動設定系統的 ip_forward 引數為1。
處理引數原因,另一個就是防火牆了,容器所有到外部網路的連線,源地址都會被NAT成本地系統的IP地址,這是使用iptables 的源地址偽裝操作實現的。
檢視主機的NAT規則
[root@wallace ~]# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LO # 預設情況下是可以出去的.
容器之間訪問
預設情況下,容器之間是可以相互通訊的
容器之間的訪問需要兩個方面的支援:
1. 容器的網路拓撲是否已經互聯,預設情況下,所有的容器都會
2.本地系統的iptable是否允許
訪問所有的埠
當啟動Docker服務時,預設會新增一條轉發策略到iptables的FORWARD鏈上,策略為通過(ACCEPT)還是禁止(DROP)取決於配置--icc=true還是--icc=false。如果手動指定--iptables=false則不會新增iptables 規則。
可見,預設情況下,不同容器之間是允許網路互通的。如果是為了安全考慮,可以在/etc/default/docker 檔案中配置DOCKER_OPTS=--icc=false來禁止它。
外部網路訪問容器
容器允許外部訪問,可以在docker run 時候通過 -p 或 -P 引數來啟用。不論用哪種,其實也是在本地的 iptables 的nat表中新增相應的規則。
使用 -P 時:
[root@server ~]# iptables -t nat -nL #檢視防火牆nat表的規則 ... Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:32770 to:172.17.0.3:443 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:32771 to:172.17.0.3:80 ...
使用 -p 88:80 時:
[root@server ~]# iptables -t nat -nL #檢視防火牆規則 Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:88 to:172.17.0.5:80
注意:這裡規則映射了 0.0.0.0,意味著將接收主機來自所有的介面的流量。
配置docker0網橋
Docker 服務預設會建立一個 docker0 網橋(其實有一個 docker0 內部介面),它在核心層連通了其它的物理網絡卡或虛擬網絡卡,這就將所有容器和本地主機都放到同一個物理網路。
Docker 預設指定了 docker0 介面的 IP 地址和子網掩碼,讓主機和容器之間可以通過網橋相互通訊,它還給出了MTU(介面允許接收的最大傳輸單元),通常是1500Bytes,或宿主機網路路由上支援的預設值,這些值都可以在服務啟動的時候進行配置。
--bip=CIDR --IP地址加掩碼格式,例如 192.168.1.2/24 --mtu=BYTES --覆蓋預設的 Docker mtu配置
也可以在配置檔案中配置 DOCKER_OPTS, 然後重啟服務,由於目前Docker網橋是Linux網橋,可以使用 brctl show 來檢視網橋和埠連線資訊
[root@server ~]# brctl show #檢視網橋和埠資訊 bridge name bridge id STP enabled interfaces docker0 8000.0242d8da46c0 no veth07c5f5c veth0bed0f7
每次建立一個新容器的時候,Docker 從可用的地址段中選擇一個空閒的 IP 地址分配給容器的 eth0 埠。使用本地主機上 docker0 介面的IP 作為所有容器的預設閘道器
[root@server ~]# docker run -it --rm --name myCentos centos /bin/bash [root@4636797a8e7c /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.6 netmask 255.255.0.0 broadcast 172.17.255.255 ... [root@4636797a8e7c /]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
自定義網橋
除了預設的 docker0 網橋,也可以指定網橋來連線各個容器
在啟動Docker 服務的時候, 使用-b BRIDGE或--bridge=BRIDGE來指定使用的網橋
(1)先建立網橋
[root@server ~]# systemctl stop docker #停止docker服務 [root@server ~]# ip link set dev docker0 down #停止docker0網橋 [root@server ~]# brctl delbr docker0 #刪除docker0網橋 [root@server ~]# brctl addbr bridge0 #新建bridge0網橋 [root@server ~]# ip addr add 192.168.2.1/24 dev bridge0 #繫結ip給bridge0網橋 [root@server ~]# ip link set dev bridge0 up #啟動bridge0網橋 [root@server ~]# brctl show #檢視網橋資訊 bridge name bridge id STP enabled interfaces bridge0 8000.000000000000 no virbr0 8000.525400caf93e yes virbr0-nic [root@server ~]# ifconfig bridge0 #檢視bridge0網橋資訊 bridge0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.2.1 netmask 255.255.255.0 broadcast 0.0.0.0
( 2 )配置docker
[root@server ~]# vim /lib/systemd/system/docker.service #由於新版本的沒有/etc/default/docker配置檔案,so 需要自己新增。 ExecStart=/usr/bin/dockerd -H unix:// $DOCKER_OPTS #在ExecStart末尾新增 $DOCKER_OPTS EnvironmentFile=-/etc/default/docker #指定配置檔案的路徑 [root@server ~]# vim /etc/default/docker #自定義編輯配置檔案,寫入啟動指定網橋的網橋資訊 DOCKER_OPTS="-b=bridge0" [root@server ~]# systemctl start docker #啟動docker服務 [root@server ~]# docker run --rm -ti --name Mycentos centos /bin/bash #建立一個容器 [root@0a13bd05faae /]# ifconfig #檢視容器的ip地址,檢查是否橋接到birdge0上面 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.2.2 netmask 255.255.255.0 broadcast 192.168.2.255 [root@0a13bd05faae /]# ping 192.168.2.1 #測試和網橋是否通 PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data. 64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.094 ms
說明:在老版本docker上面預設就有/etc/default/docker配置檔案,直接編輯即可, 在新版本上面沒有,所以需要自己指定。