docker中網絡的使用

一、docker網絡

1、docker網絡原理

         Docker本地網絡創建是利用了linux系統上的網絡命名空間和虛擬網絡設備,在本地主機和容器你分別創建一個虛擬接口,並讓他們彼此連通。

2、docker網絡創建過程

(1)創建一對虛擬接口,分別放到本地主機和新容器的命名空間中

(2)本地主機的一段連接到默認的docker0橋上,並修改爲以veth開頭的名字,容器一端的放到容器中並修改名稱爲eth0

(3)從網橋可用地址段中獲取一個空閒地址分配給容器的eth0,並配置默認的網關爲docker0網卡的內部接口docker0的IP地址。

# 創建一個不帶網絡的容器
]# docker run --name n1 --net=none -it -d busybox 
]# docker exec -it n1 ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  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:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B) 
# 在本地查找容器的進程ip,併爲容器創建網絡命名空間
]# docker inspect -f '{{.State.Pid}}' n1
7381
]# pid=7381
]# mkdir -p /var/run/netns
]# ln -s /proc/$pid/ns/net /var/run/netns/$pid
# 檢查橋接網卡的信息
]# ip addr show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:97:3e:f3:ad brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/16 brd 10.0.255.255 scope global docker0
       valid_lft forever preferred_lft forever
# 創建一對“veth pair”接口A和接口B綁定A接口到網橋docker0並啓用
]# ip link add A type veth peer name B
]# brctl addif docker0 A
]# ip link set A up
# 將接口B放到容器的網絡命名空間,命名爲eth0啓用並配置IP地址
]# ip link set B netns $pid
]# ip netns exec $pid ip link set dev B name eth0
]# ip netns exec $pid ip link set eth0 up
]# ip netns exec $pid ip addr add 10.0.0.100/16 dev eth0
]# ip netns exec $pid ip route add default via 10.0.0.1
# 查看容器內的網絡
]# docker exec -it n1 ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 32:B3:BF:24:BD:81  
          inet addr:10.0.0.100  Bcast:0.0.0.0  Mask:255.255.0.0

3、創建容器時指定容器網絡配置

   在使用”docker run”命令創建容器的過程中,可以通過”--net”參數來指定容器的網絡配置:

(1)--net-bridge:默認值,在docker網橋docker0爲容器創建新的網絡棧

(2)--net-none:創建容器時,不創建網絡,之後,用戶可以自行進行配置。

(3)--net-container:NAME_or_ID:將新建容器的進程放到一個已存在的網絡容器棧中

(4)--net=host:讓創建的容器使用本地主機的網絡

(5)--net=user_defined_network:使用用戶自定義網絡

# 創建容器時使用本地網絡
]# docker run --name n2 --net=host -it -d  busybox
]# docker exec -it n2 ifconfig ens33
ens33     Link encap:Ethernet  HWaddr 00:0C:29:1D:3E:4D  
          inet addr:192.168.16.160  Bcast:192.168.16.255  Mask:255.255.255.0

4、創建容器時的更多網絡配置

(1)以下選項只有在docker服務啓動時指定

         -b BRIDGE或—bridge=BRIDGE:指定容器掛載的網橋

         --bip=CIDR:指定docker0的掩碼

         -H SOCKET或—host=SOCKET:docker服務端接收命令的通道

         --icc=true|false:是否支持容器之間進行通信

         --ip-forward=true|false:啓用net.ipv4.ip_forward,打開轉發功能

         --iptables=true|false:禁止docker添加iptables規則

網絡的一些相關配置也可以配置在配置文件/etc/docker/daemon.json中,配置如下

{
  "bip": "192.168.1.5/24",
  "fixed-cidr": "192.168.1.5/25",
  "fixed-cidr-v6": "2001:db8::/64",
  "mtu": 1500,
  "default-gateway": "10.20.1.1",
  "default-gateway-v6": "2001:db8:abcd::89",
  "dns": ["10.20.1.2","10.20.1.3"]
}

(2)dns的配置也可在創建容器及啓動容器時配置

         1)--dns=IPADDRESS:使用指定的dns服務器

         2)--dns-search=DOMAIN:指定dns搜索域

         容器中的DNS和主機名配置都是通過宿主機的三個系統配置文件/etc/resolv.conf,/etc/hostname,/etc/hosts來維護,在啓動容器時,這三個文件都會被掛在到容器中的對應位置,/etc/resolv.conf中的內容回和宿主機該文件內容保持一致,而/etc/hosts文件中默認只記錄了容器自身的一些地址和名稱。Docker1.2開始可以直接編輯這三個文件,但修改只是臨時的。

(3)在啓動容器時可以使用的選項:

         -h HOSTNAME(--hostname=HOSTNAME):配置容器的主機名

         --link=CONTAINER_NAME:ALIAS:添加到另一個容器的連接

         -p SPEC(--publish=SPEC):映射容器端口到宿主主機

         -P (--publish-all=true|false):映射容器所有端口到宿主主機

二、容器訪問控制

1、容器訪問外部網絡的實現

         容器訪問外部網絡時需要打開宿主機的網絡轉發功能。在沒有打開時,需要打開,否則容器無法訪問外部網絡。

# 查看網絡轉發功能是否打開,值等於0時表示沒有打開
]# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
# 打開網絡轉發功能
]# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

         容器訪問外部網絡時則會進行源地址轉化(在創建容器時,默認會在iptables中添加規則),以實現容器訪問外部網絡。

# IPTABLES的轉發規則
]# iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 449 packets, 33898 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    5   345 MASQUERADE  all  --  *      !docker0  10.0.0.0/16          0.0.0.0/0  

2、容器之間的互相訪問

         容器之間的訪問需要容器之間的網絡拓撲連通的情況下本地系統的iptables允許訪問時,各容器之間才能互相訪問。

3、外部網絡訪問容器的實現

         讓外部網絡訪問容器,在啓動容器時通過”-P”或者”-p”參數將容器內的端口映射到宿主機上,再通過宿主機的IP加端口去訪問;其實也是對訪問的外部的IP地址進行了目的地址轉化。

]# docker run --name web1 -p 80:80 -d busybox /bin/httpd -f
]# iptables -t nat -vnL
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    5   345 MASQUERADE  all  --  *      !docker0  10.0.0.0/16          0.0.0.0/0           
    0     0 MASQUERADE  tcp  --  *      *       10.0.0.2             10.0.0.2             tcp dpt:80

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:10.0.0.2:80

三、docker網絡應用

1、使用自定義的網橋

         創建容器時在不指定網絡的情況下默認通過docker0網橋來橋接的,如果不想使用docker0網橋橋接也可通過自己創建的網橋來橋接。

# 創建一個網橋
]# docker network create --driver bridge test-net
b66df5a40b4984ccb41efcb389c8772ae5e1abe5b2be8a48461b38298d6823e1
# 查看創建的網橋的配置信息
]# docker inspect network test-net
[
    {
        "Name": "test-net",
        "Id": "b66df5a40b4984ccb41efcb389c8772ae5e1abe5b2be8a48461b38298d6823e1",
        "Created": "2018-12-18T22:41:42.30515433-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
……
# 創建一個容器指定網絡爲test-net
]# docker run -it --name t1 --network test-net busybox /bin/sh
/ # ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0

2、使用OpenvSwitch網橋

         Docker默認使用的是linux自帶的網橋,同時,docker也可以使用openvswitch實現網絡功能

(1)安裝openvswitch

# 安裝openvswitch
]# yum install openvswitch
# 添加網橋
]# ovs-vsctl add-br br0
]# ovs-vsctl show
04ab1358-e6d4-4712-a89e-e49d175362f3
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
ovs_version: "2.0.0"

(2)配置容器連接到openvswitch網橋

# 創建不帶網絡功能的容器
]# docker run -it -exec -d --name o1 --net=none busybox 
743a5cc99fc20b00cf719aee81ea18f3ae5583124e586a2f8d7c9d14e44659d6
# 下載openvswitch提供的輔助腳本,並賦予執行權限(腳本地址爲https://github.com/openvswitch/ovs/blob/master/utilities/ovs-docker)
]# chmod a+x ovs-docker
# 爲容器添加網卡,並掛在到br0上
]# ./ovs-docker add-port br0 eht0 o1 --ipaddress=192.168.0.2/16
]# docker exec -it o1 ifconfig
eht0      Link encap:Ethernet  HWaddr 3E:E4:8F:74:7B:38  
          inet addr:192.168.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
# 爲網橋br0添加IP地址
]# ifconfig br0 192.168.0.1/16

3、實現兩個容器之間點到點的連接

         有時需要兩個容器之間可以直接連接通信,不需要通過主機網橋進行橋接,此時可以創建一對peer接口,分別放到兩個容器接口中,配置成點到點鏈路即可。

# 創建兩個沒有網絡的容器
]# docker run -it --name p1 -d --net=none busybox
0d8d5dcdf28cfeddc97a9c13a8d3609f18aad9527927007a5cb00447b96e3117
]# docker run -it --name p2 -d --net=none busybox
a035e11b33a45dffa3ebd922ea24777c51713412fe7816cfd0d0aacb65e5bc94
# 找到進程號,創建網絡名稱空間的的追蹤文件
]# docker inspect -f {{.State.Pid}} 0d8d5dcdf28c
12823
]# docker inspect -f {{.State.Pid}} a035e11b33a4
12897
]# mkdir /var/run/netns
]# ln -s /proc/12823/ns/net /var/run/netns/12823
]# ln -s /proc/12897/ns/net /var/run/netns/12897
# 創建一對peer接口C和D
]# ip link add C type veth peer name D
# 爲兩個接口分別添加IP地址及路由信息
]# ip link set C netns 12823
]# ip netns exec 12823 ip addr add 1.1.1.1/32 dev C
]# ip netns exec 12823 ip link set C up
]# ip netns exec 12823 ip route add 1.1.1.2/32 dev C
]# ip link set D netns 12897
]# ip netns exec 12897 ip addr add 1.1.1.2/32 dev D
]# ip netns exec 12897 ip link set D up
]# ip netns exec 12897 ip route add 1.1.1.1/32 dev D

四、docker網絡命令的使用

1、插件化網絡

         Docker從1.7.0版本開始把網絡和存儲的功能實現都已插化形式剝離出來,允許用戶通過指令來選擇不同的後端實現;剝離出來的獨立容器的網絡項目叫做libnetwork。

2、容器的網絡模型

         Libnetwork中容器網絡模型(CNM)十分簡潔,可以讓上層使用網絡的應用容器最大程度上不去關心底層實現。網絡模型的結構如下所示:

(1)模型中的三種元素

         1)Sandbox(沙盒):代表一個容器(容器的網絡命名空間)

         2)Endpint:代表網絡上可以掛在容器的網絡接口,會分配IP地址

         3)Network:可以連通多個接入點的一個子網

(2)網絡模型CNM支持的驅動的類型

         1)Null:不提供網絡服務,容器啓動後無網絡接入

         2)Bridge:Docker傳統上默認用linux網橋和iptables實現的單機網絡

         3)Overlay:用vxlan隧道實現的跨主機容器網絡

         4)Remote:擴展類型,預留給其他外部實現的方案

3、docker網絡相關命令

(1)常用的網絡命令

         使用”docker network  --help”查看有如下的網絡命令:

]# docker network --help
Usage:    docker network COMMAND
Manage networks
Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks    
(2)創建網絡

         命令:docker network create [OPTIONS] NETWORK

         支持的選項(可通過docker network create –help查看):    

                   --aux-address:輔助IP地址    

                   --driver string(-d):網絡驅動類型    

                   --gateway:網關地址    

                   --internal:禁止外部對創建網絡的訪問         

                   --ip-range:分配IP地址範圍

                   --ipam-driver:IP地址管理的插件類型

                   --ipam-opt:ip地址管理插件的選項           

                   --label:爲網絡添加元標籤信息       

                   --opt:網絡驅動支持的選項 

                  --subnet:網絡地址段

(3)刪除網絡

         命令:docker network rm NETWORK [NETWORK…]

         刪除指定的網絡時,只有當網絡上不存在接入點時才能刪除成功。

(4)接入容器

         接入容器是將容器連接到一個已存在的網絡上

         命令:docker network connect [OPTIONS] NETWORK CONTAINER

         主要選項(可”docker network connect –help”命令查看):

                   --alias strings:爲容器添加一個別名,此別名僅在所添加網絡上可見       

                   --ip string:指定IP地址           

                   --ip6 string:指定ipv6地址          

                   --link list:添加連接到另外一個容器           

                   --link-local-ip strings:爲容器添加一個連接地址

(5)刪除容器網絡

         將一個連接到網絡上的容器從網絡上刪除

         命令:docker network disconnect [OPTIONS] NETWORK CONTAINER

(6)查看網絡信息

         命令:docker network inspect [OPTIONS] NETWORK [NETWORK…]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章