从零开始的Docker [ 3 ] --- Docker数据卷管理:容器卷创建删除,挂载,网络网桥,host网络,自定义网络

Docker数据卷管理

一、容器卷创建

1.创建一个数据卷

docker volume create neko_vol

2.启动一个容器并挂载一个已经创建好的数据卷

在用 docker run 命令的时候,使用 --mount 标记来将 数据卷 挂载到容器里。
下面创建一个名为 mynginx 的容器,并加载一个 数据卷 到容器的 /webapp 目录。

docker run -it  --mount source=neko_vol,target=/webapp --name mynginx nginx  /bin/sh

3.进入容器后,创建文件

此时在容器的 /webapp 目录下创建文件 nginx.txt

[root@docker ~]# docker run -it  --mount source=neko_vol,target=/webapp --name mynginx nginx  /bin/sh

# touch /webapp/nginx.txt

# echo "nginx server" > /webapp/nginx.txt

4.退出并删除容器

# exit

[root@docker ~]# docker rm mynginx
mynginx

二、挂载

1.挂载容器

启动一个新的容器,并且把刚才的数据卷 neko_vol 挂载到新的容器里

[root@docker ~]# docker run -it --name nginx_new \
> --mount source=neko_vol,target=/neko \
> alpine \
> /bin/sh

2.查看

接着查看容器中目录 /neko 下是否有个刚才的文件 nginx.txt

/ # cat /neko/nginx.txt
nginx server

bind mount 挂载一个主机目录到容器中
使用 --mount 标记可以指定挂载一个本地主机的目录到容器中去。
也可以使用 : -v /src/webapp:/opt/webapp

docker run -it --rm  --mount type=bind,src=/tmp,dst=/opt/webaaa alpine /bin/sh

添加readonly 修改权限为只读

docker run -it --rm  --mount type=bind,src=/tmp,dst=/opt/webaaa,readonly alpine /bin/sh

进入 /opt/webaaa 目录下 尝试创建一个文件 会显示创建失败

/ # cd /opt/webaaa/
/webaaa # touch 1.txt
touch: 1.txt: Read-only file system

挂载docker 主机的本地文件到容器中

[root@docker ~]# docker run -it --rm --mount type=bind,src=/root/.bash_history,dst=/root/.bash_history alpine /bin/sh
/ # ls /root/.bash_history
/root/.bash_history

3.查看数据卷的具体信息

a. 查看所有的 数据卷

docker volume ls

b. 在Docker 宿主机里使用以下命令可以查看指定 数据卷 的元数据信息

[root@docker ~]# docker volume inspect neko_vol
[
    {
    
    
        "CreatedAt": "2021-01-17T20:51:11-05:00",
        "Driver": "local",
        "Labels": {
    
    },
        "Mountpoint": "/var/lib/docker/volumes/neko_vol/_data",
        "Name": "neko_vol",
        "Options": {
    
    },
        "Scope": "local"
    }
]

c. 通过容器查看数据卷挂载的具体信息

在主机里使用以下命令可以查看 nginx_new 容器的信息
数据卷 信息在 “Mounts” Key 下面

docker inspect nginx_new -f "{
    
    {json .Mounts}}" |python -m json.tool

d.删除数据卷

docker volume rm yangge_vol

删除所有未使用的数据卷

docker volume prune

三、Docker 网络网桥

1.查看网络

docker network ls


ip addr show
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:aa:f0:d3:c6 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

2.查看默认网桥的信息

[root@docker ~]# docker network inspect bridge
[
    {
    
    
        "Name": "bridge",
        "Id": "689a224e7c517b2d91eade89ba6059781d9fd1e3a7a803ac30e59030076ce3a8",
        "Created": "2021-01-17T20:41:43.374817415-05: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,
        "Ingress": false,
        "ConfigFrom": {
    
    
            "Network": ""
        },
        "ConfigOnly": 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": {
    
    }
    }
]


3.默认网桥上的容器互相通信

只能使用彼此的 IP 通信,不可以使用容器名。

1.先创建两个容器

[root@docker ~]# docker run -itd --name=container1 busybox
92a5a26f14251be0775c9088bcabeaca583ad0028e4723aa052d7fed87c4562e
[root@docker ~]# docker run -itd --name=container2 busybox
8a3a5b875baa861d5f1ee95bed9be9a430dbb53915607d53314fd33f58eec909

2.观察默认网桥的信息

docker network inspect bridge
        "Containers": {
    
    
            "8a3a5b875baa861d5f1ee95bed9be9a430dbb53915607d53314fd33f58eec909": {
    
    
                "Name": "container2",
                "EndpointID": "61c0b0c8b3748cda00f165180f1c56b5b7d151e5a4ac65d5500dcc1b00019876",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "92a5a26f14251be0775c9088bcabeaca583ad0028e4723aa052d7fed87c4562e": {
    
    
                "Name": "container1",
                "EndpointID": "075eaf90c40f9284d56f4376354c3e9b99120b25fe9d18c1fa03178bfbe43cb1",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""

3.进入容器中测试互相通信

a. 容器 1 的操作
[root@docker ~]# docker exec -it container1 /bin/sh  # 进入容器 1
/ # ip -4 addr        # 查看 IPv4 地址信息
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
inet 127.0.0.1/8 scope host lo
   valid_lft forever preferred_lft forever
51: eth0@if52: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
   valid_lft forever preferred_lft forever
/ # cat /etc/hosts    # 查看本地 DNS 解析文件
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	92a5a26f1425  # 可以看出只有 ip 和 容器 ID 的对应关系
/ # ping -w2 92a5a26f1425      # 尝试 ping 另外一个容器的 ID 
PING 92a5a26f1425 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.847 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.113 ms

--- 92a5a26f1425 ping statistics ---
3 packets transmitted, 2 packets received, 33% packet loss
round-trip min/avg/max = 0.113/0.480/0.847 ms
/ # ping -w2 172.17.0.2           # 尝试 ping 另外一个容器的 IP
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.574 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.155 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.155/0.364/0.574 ms
/ # exit                 # 退出这个容器
b. 容器 2 的简单操作
[root@docker ~]#  docker exec -it container2 /bin/sh
/ # 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.3	8a3a5b875baa
/ # ping -w1 8a3a5b875baa
PING 8a3a5b875baa (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.122 ms

--- 8a3a5b875baa ping statistics ---
2 packets transmitted, 1 packets received, 50% packet loss
round-trip min/avg/max = 0.122/0.122/0.122 ms
/ # exit

值得注意的是: 默认网桥的hosts文件中只有 IP 到容器 ID 之间的对应关系,所以是无法通过容器名称进行互相通信的。

4.配置默认网桥

Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,可以在 Docker 服务启动时改变它:

–bip=CIDR IP 地址加掩码格式,例如 192.168.1.5/24
–mtu=BYTES 覆盖默认的 Docker mtu 配置

[root@docker ~]# yum -y install bridge-utils
[root@docker ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242aaf0d3c6       no              vetha939e41
                                                        vethd8e264b

四、host 网络

1.运行一个容器,并指定让其连接到 host 网络

[root@docker ~]# docker run -itd --rm --name=container_host --network=host busybox
5ec26d4bb21af879699b68fae5de90c7f6be954a503f91f23de1969e42fa142b

2.进入到容器,并查看网络信息

[root@docker ~]# docker exec -it container_host /bin/sh
/ # ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    inet 192.168.31.248/24 brd 192.168.31.255 scope global dynamic ens33
       valid_lft 29472sec preferred_lft 29472sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue 
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

发现也有个 docker0

3.尝试在宿主机上查看网络信息

[root@docker ~]# ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.31.248/24 brd 192.168.31.255 scope global noprefixroute dynamic ens33
       valid_lft 29008sec preferred_lft 29008sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

总结 host 网络

可以看出 host 网络实际上和宿主机共享了同一 Network Namespace。
这样的话,当运行一个 Nginx 容器,并连接到 host 网络后,那么不用发布端口,80 端口就已经在宿主机启用了,直接访问宿主机的 80 端口就可以访问 Nginx 容器的 web 服务。下面我们就来测试以下。

[root@docker ~]# docker run -itd --rm --name=nginx_host --network=host nginx:alpine
57ef10d628986e9d1cb58ddca833a2e08145431aafb0da7a29031055d1d53f6a
[root@docker ~]# ss -ntal
State       Recv-Q Send-Q     Local Address:Port                    Peer Address:Port              
LISTEN      0      128                    *:80                                 *:*                  
LISTEN      0      128                    *:22                                 *:*                  
LISTEN      0      128                 [::]:80                              [::]:*                  
LISTEN      0      128                 [::]:22                              [::]:*                  
[root@docker ~]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Mon, 18 Jan 2021 11:11:32 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 15 Dec 2020 14:55:32 GMT
Connection: keep-alive
ETag: "5fd8ce64-264"
Accept-Ranges: bytes


4.none 网络

同样方法验证

[root@docker ~]# docker run -itd --rm --name=container_none --network=none busybox
aca114c3a8255f9fff010ef78e3a4651d65201dd5490358362553d84db4c2229
[root@docker ~]# docker exec -it container_none /bin/sh
/ # ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
 inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever

五、用户自定义网络

相关命令

docker network create
docker network ls
docker network inspect
docker network connect
docker network disconnect
docker network rm

1.创建网络

1.1 创建一个 bridge 网络

docker network create -d bridge   my-net

或者

docker network create  my-net
[
    {
    
    
        "Name": "my-net",
        "Id": "2ed9a029cbca43dd8a3997136c89ab4bea698e426075d8f52b6d83a75f72d885",
        "Created": "2021-01-18T07:04:25.197531144-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
    
    
            "Driver": "default",
            "Options": {
    
    },
            "Config": [
                {
    
    
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
    
    
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
    
    },
        "Options": {
    
    },
        "Labels": {
    
    }
    }
]

查看网络源数据

docker network inspect my-net

Doker 会为自定义的网络自动分配一个子网(“Subnet”: “172.18.0.0/16”)。

1.2 创建一个 bridge 网络并指定子网

创建一个网络并指定子网为 172.20.0.0/16

docker network create  --subnet=172.20.0.0/16 my-net_172_20

docker network inspect  my-net_172_20

[
    {
    
    
        "Name": "my-net_172_20",
        "Id": "90df0de202918e06f01943d0394dd22d0b8bf802423b62934584740bf81435d3",
        "Created": "2021-01-18T07:05:12.595410079-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
    
    
            "Driver": "default",
            "Options": {
    
    },
            "Config": [
                {
    
    
                    "Subnet": "172.20.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
    
    
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
    
    },
        "Options": {
    
    },
        "Labels": {
    
    }
    }
]

1.3 创建一个网络使用 --label 添加元数据

[root@docker ~]# docker network create \
> --label network_name=my-net_label \
> --label project=LB_nginx \
> my-net_label
> 8c8591b07e41cb634dd629ff384551b49a2724b938574e87f9e063c7d71ea30e

查看元数据,部分数据已截断

[root@docker ~]#  docker network inspect --format='' my-net_label
        "Labels": {
    
    
            "network_name": "my-net_label",
            "project": "LB_nginx"
        }

2.把容器连接到网络

2.1.首先,创建并运行两个容器,container1container2

[root@docker ~]# docker run -itd --rm --name=container1 busybox
81ab11fc0630b8f7573f3ce9389044a9d7bc21facb77401dff5904d2d651708c
[root@docker ~]# docker run -itd --rm --name=container2 busybox
682fdc435256535fc1e5f67f2a65e37c30c0dd6e86ad151f66cd3ff64c9e6b4e

2.2 创建一个隔离的桥接网络 my-net

[root@docker ~]# docker network create  -d bridge --subnet 172.20.0.0/16 my-net
124cb50f08a8ec2a0af44365505e16b3f77b5671373639a1e23f8535a9054d0a

注意现在 container1container2 都被自动连接在默认的桥接网络 bridge

[root@docker ~]# docker network inspect bridge
...
​        "Containers": {
    
    "682fdc435256535fc1e5f67f2a65e37c30c0dd6e86ad151f66cd3ff64c9e6b4e": {
    
    "Name": "container2",
​                "EndpointID": "3078a44affa3771481ae0e76475b0f305852889cdffaaac2a6cd7e3d5d8f055e",
​                "MacAddress": "02:42:ac:11:00:03",
​                "IPv4Address": "172.17.0.3/16",
​                "IPv6Address": ""},
​            "81ab11fc0630b8f7573f3ce9389044a9d7bc21facb77401dff5904d2d651708c": {
    
    "Name": "container1",
​                "EndpointID": "395f3a9edbd0bb6e25a39554c338a0eab62576d3d020f707fecc4f1685df4794",
​                "MacAddress": "02:42:ac:11:00:02",
​                "IPv4Address": "172.17.0.2/16",
​                "IPv6Address": ""}},
...

2.3 现在将 container2 加入到 my-net 网络中

docker network connect  my-net container2

查看 my-net 网络,以验证

[root@docker ~]# docker network inspect my-net 
[
    {
    
    
        "Name": "my-net",
        "Id": "fc7ba902c08c0b0ba6f7c603253a0af161b9046d0f01ad7c6f7e5440663ddcb7",
        "Created": "2021-01-18T07:21:35.054761118-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
    
    
            "Driver": "default",
            "Options": {
    
    },
            "Config": [
                {
    
    
                    "Subnet": "172.20.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
    
    
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
    
    
            "682fdc435256535fc1e5f67f2a65e37c30c0dd6e86ad151f66cd3ff64c9e6b4e": {
    
    
                "Name": "container2",
                "EndpointID": "c972366b3781b9ecd586adcc18dd1f30ba44abf0509937c0d87352c0e9f8790e",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
    
    },
        "Labels": {
    
    }
    }
]

2.4 运行第三个容器并指定网络。

docker run -itd --rm --name=container3 --network=my-net --ip=172.20.0.100 busybox

2.5 查看容器三的源数据网络部分

[root@docker ~]# docker inspect container3
        "Networks": {
    
    
            "my-net": {
    
    
                "IPAMConfig": {
    
    
                    "IPv4Address": "172.20.0.100"
                },
                "Links": null,
                "Aliases": [
                    "c97e947f3887"
                ],
                "NetworkID": "fc7ba902c08c0b0ba6f7c603253a0af161b9046d0f01ad7c6f7e5440663ddcb7",
                "EndpointID": "81ea6488605f82de715189ec8faf1f68cba12b9ca7dc6702d6a0e9264d925f48",
                "Gateway": "172.20.0.1",
                "IPAddress": "172.20.0.100",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "02:42:ac:14:00:64",
                "DriverOpts": null

2.6 再来查看容器二的元数据网络部分

[root@docker ~]# docker inspect container2"Networks": {
    
    "bridge": {
    
    "IPAMConfig": null,
​                    "Links": null,
​                    "Aliases": null,
​                    "NetworkID": "689a224e7c517b2d91eade89ba6059781d9fd1e3a7a803ac30e59030076ce3a8",
​                    "EndpointID": "3078a44affa3771481ae0e76475b0f305852889cdffaaac2a6cd7e3d5d8f055e",
​                    "Gateway": "172.17.0.1",
​                    "IPAddress": "172.17.0.3",
​                    "IPPrefixLen": 16,
​                    "IPv6Gateway": "",
​                    "GlobalIPv6Address": "",
​                    "GlobalIPv6PrefixLen": 0,
​                    "MacAddress": "02:42:ac:11:00:03",
​                    "DriverOpts": null
​                },
​                "my-net": {
    
    "IPAMConfig": {
    
    },
​                    "Links": null,
​                    "Aliases": ["682fdc435256"],
​                    "NetworkID": "fc7ba902c08c0b0ba6f7c603253a0af161b9046d0f01ad7c6f7e5440663ddcb7",
​                    "EndpointID": "c972366b3781b9ecd586adcc18dd1f30ba44abf0509937c0d87352c0e9f8790e",
​                    "Gateway": "172.20.0.1",
​                    "IPAddress": "172.20.0.2",
​                    "IPPrefixLen": 16,
​                    "IPv6Gateway": "",
​                    "GlobalIPv6Address": "",
​                    "GlobalIPv6PrefixLen": 0,
​                    "MacAddress": "02:42:ac:14:00:02",
​                    "DriverOpts": {
    
    }}

可以发现 container2 同时加入了两个网络 bridge 和 my-net ,并且有两个地址 172.17.0.3 和 172.20.0.2

2.7 进入容器 container2 中,查看网卡信息

[root@docker ~]# docker exec -it container2 /bin/sh
/ # ip  -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
31: eth0@if32: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
34: eth1@if35: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    inet 172.20.0.2/16 brd 172.20.255.255 scope global eth1
       valid_lft forever preferred_lft forever

container2 有两个网络接口卡,分别分配了 IP地址。
这是因为,我们一开始运行这个容器的时候,被连接到默认的网络上,后来我们又执行了 docker network connect 命令,把它连接到了 my-net 网络上了,所以这使其有两个网络,并且有两个网卡。

2.8 尝试利用容器名进行通信测试

[root@docker ~]# docker exec -it container2 /bin/sh
/ # ping -w 2 container3
PING container3 (172.20.0.100): 56 data bytes
64 bytes from 172.20.0.100: seq=0 ttl=64 time=0.126 ms
64 bytes from 172.20.0.100: seq=1 ttl=64 time=0.064 ms
^C
/ # ping -w 2 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.161 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.383 ms
^C

注意
container3container1 并没有任何共同的网络,所以他们是无法通信的。

[root@docker ~]# docker exec -it container3 /bin/sh
/ # ping -w 2 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes

--- 172.17.0.2 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

其实即使容器未运行,您也可以将容器连接到网络。但是,docker network inspect仅显示有关正在运行的容器的信息。

猜你喜欢

转载自blog.csdn.net/Houaki/article/details/112794758