Docker网络和存储详解
网络用于容器之间的通信,存储用于容器数据的持久化
Docker网络概述
什么是Docker网络
Docker网络是容器之间通信的桥梁,可以容器之间通信,也可以容器与外部进行通信。
Docker网络类型
| 类型 | 说明 |
|---|---|
| bridge | 默认网络类型,容器连接到默认的bridge网络 |
| host | 容器使用主机的网络栈 |
| none | 容器没有网络接口 |
| overlay | 用于Swarm集群的网络类型 |
| macvlan | 为容器分配MAC地址 |
| ipvlan | 为容器分配IPv4或IPv6地址 |
| custom | 自定义网络 |
Docker网络管理
查看网络
docker network ls #查看网络
docker network 特定网络类型 #查看网络详情
创建网络
创建bridge网络
docker network create mybridge
创建bridge网络(指定子网)
docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 mybridge
创建overlay网络
docker network create --driver overlay myoverlay
创建macvlan网络
docker network create --driver macvlan --subnet 192.168.1.0/24 --gateway 192.168.1.1 -o parent=eth0 mymacvlan
连接容器
运行容器时连接网络
docker run -d --name mycontainer --network mybridge ubuntu:20.04
将运行中的容器连接到网络
docker network connect mybridge mycontainer
将容器从网络断开
docker network disconnect mybridge mycontainer
删除网络
删除网络
docker network rm mybridge
删除所有未使用的网络
docker network prune
删除所有网络
docker network prune -f
Docker网络模式详解
bridge模式
bridge模式是Docker的默认网络模式,其特点有:容器与主机的网络隔离;支持端口映射;同一网络的容器可以互相通信。
运行容器(bridge模式)
docker run -d --name mycontainer -p 80:80 nginx
查看容器网络
docker inspect mycontainer | grep -A 20 "Networks"
host模式
host模式是让容器使用主机的网络,特点有:性能好;容器与主机无隔离;但可能存在端口冲突。
运行容器(host模式)
docker run -d --name mycontainer --network host nginx
查看容器网络
docker inspect mycontainer | grep -A 20 "Networks"
none模式
none模式下,容器无网络接口,无法与外界进行通信。
运行容器(none模式)
docker run -d --name mycontainer --network none ubuntu:20.04
查看容器网络
docker inspect mycontainer | grep -A 20 "Networks"
overlay模式
overlay适用于Swarm集群(Docker的一种容器编排技术,把多个Docker的服务器整合成一个虚拟的大型服务器进行统一管理使用)。特点有:支持跨主机通信;支持隔离;支持服务发现(swarm集群内部部署的服务会被分配一个虚拟IP,并将这个服务的命名进行域名解析到这个虚拟IP上,只需要通过其命名即可访问,不需要知道其真实IP)。
初始化Swarm集群
docker swarm init
创建overlay网络
docker network create --driver overlay myoverlay
运行服务(overlay模式)
docker service create --name myservice --network myoverlay nginx
Docker存储概述
Docker存储是Docker容器持久化存储数据的方式,使得容器中的数据在容器重启后依然存在。起到了数据持久化、数据共享、数据迁移、数据备份的作用。
Docker存储类型
| 类型 | 说明 |
|---|---|
| volume | Docker管理的卷 |
| bind mount | 绑定挂载到主机目录 |
| tmpfs | 临时文件系统 |
| named pipe | 命名管道 |
Docker存储管理
查看卷
查看所有卷 docker volume ls
查看卷详情 docker volume inspect myvolume
创建卷
创建卷
docker volume create myvolume
创建卷(指定驱动,驱动是Docker的存储插件,其决定了数据存储的方式以及位置。不指定默认local,即存储在本地。但是Docker也支持第三方的存储插件,如nfs,cloud等。)
docker volume create --driver local myvolume
创建卷(指定选项,通过--opt后面的选项修改其存储行为,常见的参数有type:指定文件系统类型,以及device:指定存储设备等)
docker volume create --driver local --opt type=tmpfs --opt device=tmpfs(内存) myvolume
使用卷
运行容器并挂载卷
docker run -d --name mycontainer -v myvolume:/data ubuntu:20.04
运行容器并挂载多个卷
docker run -d --name mycontainer -v myvolume1:/data1 -v myvolume2:/data2 ubuntu:20.04
运行容器并挂载主机目录
docker run -d --name mycontainer -v /host/path:/container/path ubuntu:20.04
运行容器并挂载tmpfs
docker run -d --name mycontainer --tmpfs /tmp ubuntu:20.04
删除卷
删除卷
docker volume rm myvolume
删除所有未使用的卷
docker volume prune
删除所有卷
docker volume prune -f
Docker存储驱动
存储驱动是Docker用来管理文件系统的组件,其作用有:实现镜像的分层存储、提供容器文件系统的隔离、优化文件系统性能。
存储驱动类型
| 驱动 | 说明 |
|---|---|
| overlay2 | 默认存储驱动,推荐使用 |
| aufs | 旧版存储驱动,适用于Ubuntu |
| devicemapper | 设备映射驱动,适用于CentOS |
| btrfs | Btrfs文件系统驱动 |
| zfs | ZFS文件系统驱动 |
配置存储驱动
查看当前存储驱动
docker info | grep "Storage Driver"
配置存储驱动
sudo vim /etc/docker/daemon.json
实战案例
案例1:容器间通信
1. 创建自定义网络
docker network create mynetwork
2. 运行第一个容器 这两处测试用到的镜像替换成alpine,原因可能是因为ubuntus:20.04中并不自带ping命令,导致第四步测试容器间通信时出现报错。
docker run -d --name container1 --network mynetwork ubuntu:20.04 alpine sleep infinity
3. 运行第二个容器
docker run -d --name container2 --network mynetwork ubuntu:20.04 alpine sleep infinity
4. 测试容器间通信
docker exec -it container1 ping container2
5. 查看容器IP
docker inspect container1 | grep -A 10 "IPAddress"
docker inspect container2 | grep -A 10 "IPAddress"
6. 删除容器和网络
docker rm -f container1 container2
docker network rm mynetwork
案例2:容器数据持久化
1. 创建Docker卷
docker volume create datavolume
2. 运行容器并挂载卷 (-d 后台运行;-e 设置环境变量,数据库管理员密码为root;-v挂载卷,后接卷名:容器内路径)
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=root -v datavolume:/var/lib/mysql mysql:8.0
3. 进入容器
docker exec -it mysql mysql -u root -p
4. 在容器中创建数据库 注意,此处每一行结束都要打个";",分号在mysql客户端中代表一段语句的结束
CREATE DATABASE test;
USE test;
CREATE TABLE users (id INT, name VARCHAR(255));
INSERT INTO users VALUES (1, 'test');
SELECT * FROM users;
EXIT;
5. 停止并删除容器
docker stop mysql
docker rm mysql
6. 重新运行容器并挂载相同的卷
docker run -d --name mysql2 -e MYSQL_ROOT_PASSWORD=root -v datavolume:/var/lib/mysql mysql:8.0
7. 进入新容器
docker exec -it mysql2 mysql -u root -p
8. 验证数据是否存在
USE test;
SELECT * FROM users;
EXIT;
9. 停止并删除容器
docker stop mysql2
docker rm mysql2
10. 删除卷
docker volume rm datavolume
案例3:多容器应用网络配置
1. 创建自定义网络
docker network create appnetwork
2. 运行MySQL容器
docker run -d --name mysql --network appnetwork -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=app(指定启动时创建一个名为app的数据库) mysql:8.0
3. 运行Redis容器
docker run -d --name redis --network appnetwork redis
4. 运行Web应用容器
docker run -d --name web --network appnetwork -p 8080:80(端口映射,将主机的8080端口映射到容器的80端口上) --link mysql:mysql --link redis:redis nginx:alpine 这里与案例1同理,要用alpine版本,带ping命令
5. 查看容器网络
docker network inspect appnetwork
6. 测试容器间通信
docker exec -it web ping mysql
docker exec -it web ping redis
7. 停止并删除容器
docker stop mysql redis web
docker rm mysql redis web
8. 删除网络
docker network rm appnetwork