5、Docker存储与网络
Docker存储与网络
文章目录
一、 Docker存储
概述
docker提供数据卷来实现数据共享与持久化,而数据卷的挂载有两种方式:
- 挂载主机目录(Bind mounts)
- 数据卷容器(Data Volumes)
数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新不会影响镜像
- 卷会一直存在,至到没有容器使用
挂载主机目录
创建一个数据卷
docker run -d -P --name web -v /webapp centos /bin/bash
选项说明:
-d:将容器放入后台运行
-P:将容器中的端口暴露到宿主机的一个随机端口
-v:创建一个数据卷,这个数据卷会自动映射到宿主机的某个目录,一般在/var/lib/docker/vfs下
挂载一个宿主机目录作为数据卷
docker run -d -P --name web -v /data:/webapp centos /bin/bash #将宿主机的/data目录挂载至容器的/webapp目录
#docker挂载数据卷的默认为权限为读写(rw),用户也可以通过ro指定为只读:
docker run -d -P --name web -v /data:/webapp:ro centos /bin/bash
案例
[root@localhost web_data]# docker run -itd --privileged --expose 80 -p 80:80 -v /web_data:/var/www/html/ centos8:web /usr/sbin/init
[root@localhost web_data]# docker run -itd --privileged --expose 80 -p 80:80 -v /web_data:/var/www/html/ centos8:web /usr/sbin/init
###发现两个web容器访问的页面是一致的
数据卷容器
创建一个数据卷容器
docker run -it -v /dbdata:/dbdata --name dbdata centos #创建一个数据卷容器dbdata,并创建一个数据卷挂载至/dbdata
其他容器可以通过–volumes-from来挂载dbdata容器中的数据卷:
docker run -it --volumes-from dbdata --name db1 centos
docker run -it --volumes-from dbdata --name db2 centos
容器db1和db2都挂载同一个数据卷到/dbdata目录,三个容器任何一方在该目录的写入,其他 容器都能看到
--volumes-from参数可以多次使用,从多个容器挂载多个数据卷
如果删除了挂载的容器,数据卷并不会被自动删除,如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显示的使用
docker rm -v 命令来指定同时删除关联的容器。
利用数据卷容器迁移数据
备份数据:
#先创建一个容器worker,并使用--volumes-from将dbdata挂载到worker容器,然后使用-v参数将容器的/backup目录映射到宿主机的backup目录。然后在容器中执行备份操作,这样就把数据备份到宿主机的/backup目录中了
docker run -it --volumes-from dbdata -v /backup:/backup --name worker centos
tar zcf /backup/backup.tar.gz /dbdata
还原数据:
#创建一个新容器,并用-v参数挂载本地的备份目录,然后执行解压操作,将备份文件解压至/dbdata目录
docker run -it -v /dbdata --name dbdata2 centos /bin/bash #创建一个容器dbdata2
docker run -it --volumes-from dbdata2 -v /backup:/backup centos tar xf /backup/backup.tar.gz
删除数据盘 【docker迁移后,进行数据清理时使用!!!】
查看主机上现有的数据盘
docker volume ls
默认情况下,在删除容器时,docker并不会删除其数据盘,查看没有容器在使用的数据盘方法如下:
docker volume ls -f dangling=true ##dangling是过滤关键字
如果想要删除没有使用的数据盘,使用如下指令:
docker volume rm VOLUME_NAME
删除掉容器时,同时删掉数据盘,则使用:
docker rm -v container_name
docker程序数据目录迁移
mkdir /home/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://ustc-edu-cn.mirror.aliyuncs.com/",
"https://ccr.ccs.tencentyun.com/",
"https://docker.m.daocloud.io/"
],
"data-root": "/home/docker1"
}
systemctl stop docker
systemctl daemon-reload
mv /var/lib/docker/* /home/docker1
####docker29之前版本:当原有的数据目录与新的数据目录不在同一分区时,有如下报错: 解决方案: 先删除新的数据目录中的文件,再移动
[root@www ~]# mv /var/lib/docker/image/* /home/docker/image/
mv:是否覆盖'/home/docker/image/overlay2'? yes
mv: 无法进行跨设备的移动:'/var/lib/docker/image/overlay2' 至'/home/docker/image/overlay2';无法删除目标: 目录非空
#####docker29之后的版本。镜像的存储默认路径更改为:/var/lib/containerd/,进行数据目录更改后,只影响volume和network
systemctl start docker
####验证
docker images
二、Docker网络
概述
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥(交换机),此主机上启动的docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连接在了一个二层网络中。从docker0子网中分配一个ip给容器使用,并设置docker0的ip地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。而这种网络模式即称之为bridge网络模式。
除了bridge模式以外,docker原生网络,还支持另外两种模式: none和host
可以通过如下方法查看docker的网络:
root@k8s-m:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
93392a2471d3 bridge bridge local
05c5ebb39921 host host local
3cb2552dc6e9 none null local
bridge网络
bridge网络基本用法
查看bridge网络信息:
# 通过如下命令会列出bridge网络的相关信息,其中"Containers"字段的表示是信息是指当前节点上有哪些容器使用了该网络
docker network inspect bridge
[
{
"Name": "bridge",
"Id": "4a118c0b7b7ddfc172abe32f255835edcb891040dc683f3a331d148212516338",
"Created": "2024-01-16T13:43:52.537602956+08: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": {
"684421dc592005ed59e7e4cbe24ea2049e6c34cdd154217f10ce734372ab9079": {
"Name": "determined_tu",
"EndpointID": "1f97fa7ee645c72b50a4e645e5af3e0c955e69c25e3661d3b4c285d503280850",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"9cdb580e64d4b2d3a482d87a76b054115d7ea6697b1e14b298249a60a66d5cd8": {
"Name": "reverent_williamson",
"EndpointID": "f425545770ac14c8e58b91847b080e27046c14f7f379c6e6e4650f943e265aef",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"c16a74b18e99129ff8ee50ada9204c12c311f65305fb3343efd4b73a357c9c40": {
"Name": "angry_shannon",
"EndpointID": "592cc5e9838aab0c0ce42a023d39f83f929d440e424abde82d0768671e2c03da",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"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@localhost ~]#
创建使用bridge网络容器的示例:
docker run -d --name web1 --net bridge nginx
基于bridge网络的容器访问外部网络
默认情况下,基于bridge网络容器即可访问外部网络,这是因为默认情况下,docker使用了iptables的snat转发来实现容器对外部的访问(需要内核开启net.ipv4.ip_forward=1)
外部网络访问基于bridge网络的容器
如果想让外界可以访问到基于bridge网络创建的容器提供的服务,则必须要告诉docker要使用的端口。
可以通过如下方法查看镜像会使用哪些端口:
docker inspect nginx | grep "ExposedPorts"
####查看镜像端口
docker run 镜像名
EXPOSE列会显示暴露的端口号
在创建容器的时候可以指定这个容器的端口与主机端口的映射关系:
docker run -d --name web -p 8888:80 nginx
-p: 可以指定主机与容器的端口关系,冒号左边是主机的端口,右边是映射到容器中的端口
-P:该参数会分配镜像中所有的会使用的端口,并映射到主机上的随机端口
这种端口映射基于iptables的dnat实现
查看容器的端口情况:
docker port web
如果创建容器时,-p参数后面只一个指定端口,意思是主机会随机一个端口,映射到容器的该指定端口:
docker run -d --name web -p 80 nginx
下面是一个基于端口映射的示例:
docker run -d --dns 8.8.8.8 -p 8080:80 -p 2022:22 --name webserver1 httpd:2.4
docker run -d --dns 8.8.8.8 -P --name webserver1 httpd:2.4
none网络
故名思议,none网络就是什么都没有的网络。使用none网络的容器除了lo,没有其他任何网卡,完全隔离。用于既不需要访问外部服务,也不允许外部服务访问自己的应用场景。
查看none网络信息:
docker network inspect none
创建使用none网络容器的示例:
docker run -d --name web_none --net none nginx
host网络
使用host网络的主机,与宿主机共享网络地址,可以获得最好的数据转发性能。缺点是,同一个宿主机上的多个容器共享同一个ip地址,如果多容器使用相同的端口,需要自行解决端口冲突问题。
同样的,可以通过如下方式查看host网络信息:
docker network inspect host
创建一个使用host网络容器的示例:
# 可以看到该容器没有自己的IP地址,因为它直接使用宿主机IP地址
docker run -d --name web_host -net host nginx
自定义网络
Docker除了提供三种的默认网络模式之外,也允许用户针对一些特定的应用场景去创建一些自定义的网络。这样属于这个网络的容器就可以单独隔离出来,它们之间可以相互通信,而不在这个网络的容器就不能直接访问到它们。一个容器可以属于多个网络,同一个自定义网络下的容器可以通过各自的容器名访问到对方,因为会使用到docker内嵌的一个dns功能。
Docker提供三种自定义网络驱动:
- bridge
- overlay
- macvlan
自定义bridge网络
创建一个自定义网络
1、创建一个叫作my_net的自定义网络:
docker network create --driver bridge my_net #--driver用于指定网络类型
[root@localhost ~]# docker network inspect mynetwork
[
{
"Name": "mynetwork",
"Id": "230a75e1fb8d4f8a15e4d625ed34f57c1cc1dffaed8d9b22b46ea97eb3b19828",
"Created": "2024-01-16T16:42:53.010786799+08: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 ls 查看到新创建的my_net网络相关信息,Subnet表示这个网络下的子网IP段,那么基于my_net自定义网络创建的容器IP都会以该IP段开头。
2、基于my_net网络创建容器:
docker run -d --name web2 --net my_net nginx
通过指定子网和网关的方式创建自定义网络
1、通过指定子网和网关的方式创建my_net2网络:
docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
2、创建一个容器使用my_net2网络:
docker run --it --network=my_net2 busybox
3、创建一个容器的使用my_net2网络的同时指定其ip地址:
docker run --it --network=my_net2 --ip=172.22.16.8 busybox
使用自定义网络与默认网络互通
假设我们在默认的bridge网络中,还有一个httpd的容器:
docker run -d --name webserver httpd:2.4
此时默认网络中的容器与my_net2网络中的容器是无法互相通信的。
如果想让默认bridge网络的httpd与my_net2中的容器通信,可以给httpd容器添加一块自定义网络的网卡,使用如下指令:
docker network connect my_net2 webserver
####进入webserver主机验证即可,发现多了一个使用bridge网络的网卡###
36: eth1@if37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth1
valid_lft forever preferred_lft forever
如果要将webserver新添加的这块网卡移除,可以使用如下命令:
docker network disconnect bridge webserver
同一台宿主机容器互联(基于容器名称)
同一台宿主机上的容器互联有两种方式,第一种是基于ip,默认情况下,同一个宿主机上的容器ip是互通的。另一种方式是使用--link实现:
docker run -itd --name web1 centos8:web
docker run -itd --name web2 --link web1 centos8:web
docker exec -it web2 /bin/bash
ping web1
####发现是通信的,但是web1无法ping通web2
####实际就是在主机的/etc/hosts中填写解析条目######
erred_lft forever
如果要将webserver新添加的这块网卡移除,可以使用如下命令:
```bash
docker network disconnect bridge webserver
同一台宿主机容器互联(基于容器名称)
同一台宿主机上的容器互联有两种方式,第一种是基于ip,默认情况下,同一个宿主机上的容器ip是互通的。另一种方式是使用--link实现:
docker run -itd --name web1 centos8:web
docker run -itd --name web2 --link web1 centos8:web
docker exec -it web2 /bin/bash
ping web1
####发现是通信的,但是web1无法ping通web2
####实际就是在主机的/etc/hosts中填写解析条目######
更多推荐


所有评论(0)