Docker数据持久化与网络

1 数据持久化

官网:https://docs.docker.com/storage/

1.1 Volume

1.1.1 初始Volume

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker rm -f $(docker ps -aq)

docker volume ls

docker run -d --name test-mysql -e MYSQL_ROOT_PASSWORD=jack123 mysql:5.7

# 查看volume
docker volume ls
# 查看mysql Dockerfile文件
VOLUME /var/lib/mysql
# 在容器中寻找该目录/var/lib/mysql
docker exec -it test-mysql bash
ls /var/lib/mysql
# 在centos物理机中寻找与之对应的目录
docker volume inspect volume_name
# 查看物理机中的目录
ls /var/lib/docker/volumes/e2ca4be02931e3310f6f136eb663e173d314bb3b3f243bacef776936898d4926/_data

1.1.2 自定义Volume

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#创建并查看volume
docker volume create test-mysql-volume
docker volume ls
docker volume inspect test-mysql-volume
ls /var/lob/docker/volumes/test-mysql-volume/_data

#创建容器并使用自定义的volume
docker run -d --name test-mysql -v test-mysql-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=test123 mysql:5.7

#再次查看volume对应的物理目录
ls /var/lib/docker/volumes/test-mysql-volume/_data

# 可以这样理解
-v test-mysql-volume:/var/lib/mysql 就等同于在Dockerfile中定义的VOLUME命令

1.1.3 Volume数据修改

(1)修改container目录的数据,观察物理机的数据变化

1
2
3
4
5
6
7
docker exec -it test-mysql bash
cd /var/lib/mysql
echo "test volume test." > test-volume.txt
exit
cd /var/lib/docker/volumes/test-mysql-volume/_data
ls
cat test-volume.txt

(2)修改物理机的数据,观察container目录的数据变化

1
2
3
4
5
echo "test-centos." > test-centos.txt
docker exec -it test-mysql bash
cd /var/lib/mysql
ls
cat test-centos.txt

1.1.4 默认Volume

1
2
docker run -d --name test-nginx -p 60:80 nginx
docker volume ls # 发现并没有自动创建volume,是因为在nginx的Dockerfile文件中没有指定VOLUME

1.1.5 验证持久化效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建容器并使用自定义volume
docker run -d --name test-mysql -v test-mysql-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=test123 mysql:5.7
# 进入容器并创建数据库
docker exec -it test-mysql bash
create database db_test
show databases;
# 删除mysql容器并查看volume是否存在
docker rm -f test-mysql
docker volume ls
# 重新创建一个mysql container并使用test-mysql-volume
docker run -d --name any-mysql -v test-mysql-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=test123 mysql:5.7
# 进入容器并查看数据
docker exec -it any-mysql bash
mysql -uroot -ptest123
show databases;

1.2 Bind Mounting

想把容器中任意的目录和centos的目录做一个绑定,比如centos中的~/shop 与tomcat container中的/usr/local/tomcat/webapps/shop进行绑定

1
2
3
4
5
6
7
8
9
10
11
# 创建tomcat容器,并指定目录绑定关系
docker run -d --name my-tomcat -p 8888:8080 -v ~/shop:/usr/local/tomcat/webapps/shop tomcat:8.0
# 查看两个目录是否存在
centos: ls ~
tomcat容器:
docker exec -it my-tomcat bash
ls /usr/local/tomcat/webapps
# 在centos的shop文件夹下创建文件
echo "<p style='color:orange; font-size:20pt;'>Bind Mounting.</p>" > index.html
# 访问该页面
centosip:8888/shop/index.html

2 网络

官网:https://docs.docker.com/network/

2.1 网卡

2.1.1 查看linux中的网卡

1
2
3
4
5
6
# 方式1
ip link show
# 方式2
ls /sys/class/net
# 方式3
ip a

2.1.2 分析ip a

1
2
3
4
5
6
7
8
9
10
# 状态: UP、DOWN、UNKNOW
# link/ether:MAC地址
# inet:该网卡绑定的IP4地址
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group
default qlen 1000
link/ether 52:54:00:8a:fe:e6 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
valid_lft 83668sec preferred_lft 83668sec
inet6 fe80::5054:ff:fe8a:fee6/64 scope link
valid_lft forever preferred_lft forever

2.1.3 网卡对应的配置文件

在Linux中网卡对应的其实就是文件,所以找到对应的网卡文件即可

具体目录为:/etc/sysconfig/network-scripts/

比如打开ifcfg-eth0

1
2
3
4
5
6
7
8
9
10
DEVICE="eth0" 				# 表示网卡名称
BOOTPROTO="dhcp" # 表示网卡类型:dhcp-动态 static-静态 none-固定
ONBOOT="yes" # 开机或重启网卡的时候,是否启用该网卡
TYPE="Ethernet" # 表示接口类型:Ethernet-以太网 Bridge-桥接接口
HWADDR=00:0c:29:90:89:d9 # HWADDR HardWare Address 硬件地址 MAC地址
NETMASK=255.255.255.0 # 子网掩码 决定这个局域网中最多有多少台机器
IPADDR=192.168.0.100
GATEWAY=10.0.0.2 # 网关
USERCTL=no # 普通用户是否能控制网卡
PERSISTENT_DHCLIENT="yes"

2.2 Network Namespace

linux上,网络的隔离是通过network namespace来管理的,不同的network namespace是互相隔离的

1
2
3
4
5
6
# 查看
ip netns list
# 添加
ip netns add ns1
# 删除
ip netns delete ns1

2.2.1 创建Namespace

1
2
3
4
5
6
7
8
9
# 创建一个network namespace
ip netns add ns1
# 查看该namespace下网卡的情况
ip netns exec ns1 ip a
# 启动ns1上的lo网卡
ip netns exec ns1 ifup lo 或 ip netns exec ns1 ip link set lo up
ip netns exec ns1 ip a
# 再次创建一个network namespace
ip netns add ns2

2.2.2 连接Namespace之间的网络

veth pair:virtual ethernet pair,是一个成对的端口,可以实现上述功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建一对link,也就是接下来要通过veth pair连接的link
ip link
ip link add veth-ns1 type veth peer name veth-ns2
ip link
# 将veth-ns1加入ns1中,将veth-ns2加入ns2中
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
# 查看宿主机和ns1,ns2的link情况
ip link
ip netns exec ns1 ip link
ip netns exec ns2 ip link
# 给veth-ns1和veth-ns2添加IP地址并启动
ip netns exec ns1 ip addr add 192.168.0.11/24 dev veth-ns1
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip addr add 192.168.0.12/24 dev veth-ns2
ip netns exec ns2 ip link set veth-ns2 up
ip netns exec ns1 ip a
ip netns exec ns2 ip a
# 彼此ping测试一下
ip netns exec ns1 ping 192.168.0.12
ip netns exec ns2 ping 192.168.0.11

2.2.3 容器的Network Namespace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建两个tomcat容器
docker run -d --name tomcat01 -p 8081:8080 tomcat:8.0
docker run -d --name tomcat02 -p 8082:8080 tomcat:8.0
# 进入容器并安装ip命令
docker exec -it tomcat01 bash
apt update
apt install -y iproutes
docker exec -it tomcat02 bash
apt update
apt install -y iproutes
# 查看容器的IP
docker exec -it tomcat01 ip a
docker exec -it tomcat02 ip a
# ping一下
docker exec -it tomcat01 ping 172.17.0.3
docker exec -it tomcat02 ping 172.17.0.2
ping 172.17.0.2
ping 172.17.0.3

2.3 Docker常见网络类型

2.3.1 Bridge之docker0

1
2
3
4
5
# 查看centos的veth
ip link
# 查看两个tomcat容器的veth
docker exec -it tomcat01 ip link
docker exec -it tomcat02 ip link

1
2
3
4
# 查看docker中的网络模式
docker network ls
# 查看bridge的细节
docker network inspect bridge

2.3.2 Bridge网络模式实战

1
2
3
4
5
6
7
8
9
# 创建一个network,类型为bridge
docker network create --subnet=172.18.0.0/24 tomcat-net
docker network ls
# 查看tomcat-net细节
docker network inspect tomcat-net
# 创建tomcat容器并指定网络为tomcat-net
docker run -d --name custom-net-tomcat --network tomcat-net tomcat:8.0
docker exec -it custom-net-tomcat ip link
ip link

1
2
3
4
5
6
7
8
9
10
# 此时在custom-net-tomcat容器中ping一下tomcat01的ip会如何?发现无法ping通
docker exec -it custom-net-tomcat ping 172.17.0.2
# 让tomcat01网络连接tomcat-net
docker network connect tomcat-net tomcat01
docker network inspect tomcat-net
# 再次尝试在custom-net-tomcat中ping一下tomcat01
docker exec -it custom-net-tomcat ping 172.18.0.2
docker exec -it custom-net-tomcat ping tomcat01
# ping tomcat02,发现是不能ping通的
docker exec -it custom-net-tomcat ping tomcat02

2.3.3 Host

1
2
3
4
5
6
7
8
# 创建一个tomcat容器,并且指定网络为host
docker run -d --name my-tomcat-host --network host tomcat:8.0
# 查看ip地址,可以发现和centos是一样的
docker exec -it my-tomcat-host ip a
# 直接访问8080端口
curl centosip:8080
# 查看host网络细节
docker network inspect host

2.3.4 None

1
2
3
4
5
6
# 创建一个tomcat容器,并且指定网络为none
docker run -d --name my-tomcat-none --network none tomcat:8.0
# 查看ip地址
docker exec -it my-tomcat-none ip a
# 检查none网络
docker network inspect none

Docker数据持久化与网络
http://www.zivjie.cn/2023/04/22/云原生(容器化)/docker/Docker数据持久化与网络/
作者
Francis
发布于
2023年4月22日
许可协议