数据卷 Volume: 目录映射, 目录挂载
匿名绑定:
匿名绑定的 volume 在容器删除的时候, 数据卷也会被删除, 匿名绑定是不能做到持久化的, 地址一般是 /var/lib/docker/volumes/xxxxx/_data
绑定卷时修改宿主机的目录或文件, 容器内的数据也会同步修改, 反之亦然
# 查看所有 volume
docker volume ls
# 用法: -v [容器内目录] 仅仅指定容器内的目录, 不指定宿主机的目录, 默认会自动创建一个匿名卷
docker run -d -p 80:80 --rm --name nginx_volume01 -v /usr/share/nginx/html nginx
# 查看卷详情
docker inspect nginx_volume01 # 里面 Mounts 的关键词就是 映射卷信息
docker volume ls
具名绑定:
具名绑定与匿名绑定是类似的, 只是具名绑定会指定一个名字, 具名绑定卷在容器删除的时候, 数据卷不会删除, 具名绑定是可以做到持久化的, 路径一般是 /var/lib/docker/volumes/xxxxx/_data
# 用法: -v [卷别名]:[容器内目录] 指定卷名和容器内的目录, 创建后由docker统一管理
docker run -d -p 80:80 --rm --name nginx_volume02 -v nginx_test:/usr/share/nginx/html nginx
# 查看卷详情
docker inspect nginx_volume02
docker volume ls # 会查到一个名字为 nginx_test 的卷
# 重新创建新的容器并使用持久化挂载卷
## 先进行删除
docker stop nginx_volume02
docker rm nginx_volume02
## 重新创建新的容器并使用持久化挂载卷
docker run -d -p 80:80 --rm --name nginx_volume -v nginx_test:/usr/share/nginx/html nginx
## 查看
docker inspect nginx_volume
docker volume ls
Bing Mount:
前面两种方式都是docker内部自动管理这些卷的, 但是bing mount是手动管理这些卷的, 也就是手动指定宿主机的目录和容器内的目录
# 用法: -v [宿主机的目录]:[容器内的目录] 指定宿主机的目录和容器内的目录
# 可以映射多个目录, 一个 -v 只能映射一个目录, 多个目录需要多个 -v
docker run -d -p 80:80 --rm --name nginx_volume03 -v /root/projects/www/nginx_test:/usr/share/nginx/html nginx
# 查看卷详情
docker inspect nginx_volume03
docker volume ls
volume 的常用命令
# 查看帮助
docker volume --help
# 列出所有 volume
docker volume ls
# 查看卷详情
docker volume inspect [卷名]
# 删除一个 volume
docker volume rm [卷名]
# 清理无用的 volume
docker volume prune
网络配置 Network
- 提供了多种模型, 可以定制化为每个容器制定不同的网络
- 自定义网络模式, 划分不同的子网以及网关, dns等配置
- 网络互通
- 实现不同子网之间的网络互通
- 基于容器名(主机名)的方式在网络内访问
网络模式
bridge 模式 (桥接模式), 默认使用
在主机中创建一个 docker0 的虚拟网桥(虚拟交换机), 在 docker0 创建一对虚拟网卡, 有一半在宿主机上 vethxxxx, 还是一半在容器内 eth0
bridge 模式 容器互联通信
# 启动两个容器, 用于测试两个容器之前的通信
docker run -d -P --rm --name centos_network1 centos tail -f /dev/null
## tail -f /dev/null 是让容器启动时运行的命令, 为了让容器一直运行, 不退出
# 使用 --link 参数, 让两个容器之间建立连接
docker run -d -P --rm --name centos_network2 --link centos_network1 centos tail -f /dev/null
# 测试两个容器是否可以通信
docker exec -it centos_network2 ping centos_network1 # 由于 centos_network2 link centos_network1, 所以可以通信
docker exec -it centos_network1 ping centos_network2 # 但是 centos_network1 不能 ping centos_network2, 因为 --link 参数是单向的
# 参看容器的详细信息
docker inspect centos_network1
docker inspect centos_network2
host 模式 (主机模式)
容器将不会获得一个独立的网络命名空间, 而是和宿主机共享网络命名空间, 容器将不会虚拟出自己的网卡以及配置自己的 IP 等, 那么基于该模式启动的容器对应的ip实际就是与宿主机同一个子网, 同一个网段
192.168.113.1 --> 192.168.113.x
none 模式
docker 会拥有自己的网络空间, 不与宿主机共享, 在这个网络模式下的容器, 不会被分配网卡 ip 路由等相关信息
特点: 完全隔离, 与外部任何机器都无网络访问, 只有自己的本地网络lo网卡, 即127.0.0.1
container 模式
新建的容器和已经存在的一个容器共享一个网络命名空间, 新的容器不会创建自己的网卡以及配置自己的 IP, 而是和指定的容器共享 IP, 端口范围等. 同样, 新的容器也不能访问已经存在的容器, 两者除了网络方面, 其他方面都是独立的
自定义网络模式(推荐)
不使用docker自带的网络模式, 而是自己去定制化自己特有的网络模式, 比如划分不同的子网, 网关, dns等配置
- 自定义网络模式, 划分不同的子网以及网关, dns等配置
- 网络互通
- 实现不同子网之间的网络互通
- 基于容器名(主机名)的方式在网络内访问
自定义网络创建
- 查看主机的网络
# 查看网络的命令
ifconfig
# 或
ip addr
docker network [Command]
# 如:
docker network --help
docker network ls
- 创建自定义网络
# 创建自定义网络
docker network create --help
## 创建一个名为 wolfcode的网络, 子网为 192.168.30.0/24, 网关为 192.168.30.1
docker network create --driver bridge --subnet 192.168.30.0/24 --gateway 192.168.30.1 wolfcode
# --driver bridge 指定网络模式为 bridge 模式, docker默认就是 bridge 模式, 可以不写
# --subnet 192.168.30.0/24 指定子网, 桥接模式可以自定义, 但注意子网尽量不要和宿主机的子网冲突(可以使用 ifconfig/ip addr 查看宿主机的子网)
# --gateway 192.168.30.1 指定网关, 网关的ip地址需要和子网在同一个网段
# wolfcode 自定义网络名称
# 查看网络是否在里面
docker network ls
# ifconfig 或 ip addr 也可以查看网络
ifconfig
# 或
ip addr
- 自定义网络启动容器
# 启动一个 nginx 容器, 指定网络为 wolfcode
docker run -d -p 3001:80 --rm --name nginx_network1 --net wolfcode nginx
## --net wolfcode 指定网络模式为使用自定义的 wolfcode 网络
## 启动容器时指定网络 --net
# 查看容器网络详情
docker inspect nginx_network1
# 进入容器内部看网络相关的信息
docker exec -it nginx_network1 /bin/bash
ip addr
## 有些容器没有 ip addr 命令, 可以使用参看 hosts 文件的方式查看容器内部的主机名对应的ip地址是否与自定义网络配置一致
cat /etc/hosts
容器互联通信
# 启动两个 centos 容器, 指定网络为 wolfcode, 测试容器之间是否可以相互通信
docker run -d -P --rm --name centos_network1 --net wolfcode centos tail -f /dev/null
docker run -d -P --rm --name centos_network2 --net wolfcode centos tail -f /dev/null
## -P 随机端口映射
## --net wolfcode 指定网络模式为使用自定义的 wolfcode 网络
## centos 是镜像名称
## tail -f /dev/null 是为了让容器一直运行, 否则容器会自动停止
# 查看容器的网络详情
docker inspect centos_network1
docker inspect centos_network2
# 进入容器内部看网络相关的信息
docker exec -it centos_network1 /bin/bash
cat /etc/hosts
## 192.168.30.2 centos_network1
# 也可以使用 ifconfig 或 ip addr 查看网络信息
ifconfig
# 或
ip addr
# 在 centos_network1 容器内部 ping centos_network2, 测试容器之间是否可以基于主机名相互通信
ping centos_network2
# 也可以直接使用docker exec -it 使用容器执行ping命令
docker exec -it centos_network1 ping centos_network2
## ping centos_network2 是ping centos_network2 的主机名, 而不是ip地址, 测试容器之间是否可以基于主机名进行通信
不同网络下容器互相通信
测试: 默认的bridge网络容器和自定义的wolfcode网络容器通信问题
# 使用不同的两个网络模式启动两个容器, 测试容器之间是否可以相互通信
# 启动一个 centos 容器, 默认网络为 bridge
docker run -d -P --rm --name centos_network1 centos tail -f /dev/null
# 启动一个 centos 容器, 自定义网络为 wolfcode
docker run -d -P --rm --name centos_network2 --net wolfcode centos tail -f /dev/null
# 查看容器的网络详情
docker inspect centos_network1
docker inspect centos_network2
# 尝试 centos_network2 去 ping centos_network1, 测试容器之间是否可以相互通信
docker exec -it centos_network1 ping centos_network2
## 或
docker exec -it centos_network1 ping 192.168.30.2
## 结果: 两种方式都无法ping通, 因为两个容器不在同一个网络下, 无法相互通信
解决方案: docker network connect
# 将 centos_network1 容器连接到 wolfcode 网络下