侧边栏壁纸
博主头像
canary 博主等级

行动起来,活在当下

  • 累计撰写 7 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

【云原生】Docker的数据管理和网络管理

Administrator
2025-04-15 / 0 评论 / 0 点赞 / 7 阅读 / 0 字

一、Docker的数据管理

  • Docker将运行中的环境打包成容器然后运行,Docker容器就会产生数据,如果Docker容器不通过docker commit生成新的镜像,使数据作为镜像的一部分保存下来,那么当容器删除后,Docker容器中的数据自然也就没有了。因此为了管理Docker容器中的数据,就需要对数据进行持久化

容器按照业务类吸纳管,总体可以分为两类

  • 无状态的(数据不需要被持久化)

  • 有状态的(数据需要被持久化)

管理Docker容器中的数据主要有两种方式

  • 数据卷

  • 数据卷容器

1.1、数据卷

  • 数据卷是供一个或者多个容器使用的目录或文件,由docker挂载到一个容器或多个容器中。但不属于联合文件系统,因此能够绕过联合文件系统用于持续存储或共享数据

  • 数据卷设置目的就是实现数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时刹车农户其挂载的数据卷

1.1.1、数据卷特点

  • 数据卷可以在容器之间共享和重用,实现宿主机与容器之间传递数据

  • 对数据卷的修改立马有效,在容器内部与本地目录均可对数据卷进行修改

  • 对数据卷的更新,不会影响镜像,对数据与应用进行操作

  • 一个数据卷可以被多个容器同时挂载,一个容器也可以被挂载多个数据卷

1.1.2、数据卷创建

  • 在docker run命令中使用-v挂载数据卷,多次-v可以挂载多个数据卷

1.1.3、匿名挂载

  • 匿名挂载就是在指定数据卷的时候,不指定容器对应的主机路径,这样对映射的主机路径就是默认在/var/lib/docker/volumes/中子哦对那个生成一个随机命名的文件夹

  • 通过docker volume ls命令可以查看当前数据卷的目录情况

# 在web容器中创建/data1和/data2目录
# 这种属于匿名挂载,-v只写了容器内的路径,没有宿主机路径
[root@docker-01 ~]# docker run -d -v /data1 -v /data2 --name web httpd:latest
​
# 进入到web容器中
[root@docker-01 ~]# docker exec -it web bash
​
# 查看容器内创建的挂载目录
root@4bae5dfa7cee:/usr/local/apache2# ls -ld /data1
drwxr-xr-x 2 root root 6 May 30 01:59 /data1
root@4bae5dfa7cee:/usr/local/apache2# ls -ld /data2
drwxr-xr-x 2 root root 6 May 30 01:59 /data2
​
# 查看当前数据卷目录
[root@docker-01 ~]# docker volume ls
DRIVER    VOLUME NAME
local     947bc74eec5ad38f05cc40c7a6a8c8edce3c36f56d00bea1c91a79cf4c49c17f
local     98876109bfa0ac5659043c4114d4856efc1b66261a24988d32e95cd867210364
​
# 检查数据卷
# 不指定宿主机挂载目录,默认会在下面这个路径下挂载
[root@docker-01 ~]# ls /var/lib/docker/volumes/
947bc74eec5ad38f05cc40c7a6a8c8edce3c36f56d00bea1c91a79cf4c49c17f
98876109bfa0ac5659043c4114d4856efc1b66261a24988d32e95cd867210364

1.1.4、具名挂载

  • 具名挂载就是指定具体的文件名称,这里的文件夹名称是在docker指定的默认数据卷路径下

# 在宿主机创建httpd数据卷
# 这种数据具名挂载,-v数据卷名:容器内路径
[root@docker-01 ~]# docker run -d -v httpd:/data2 --name web01 httpd:latest
​
# 查看当前数据卷目录
[root@docker-01 ~]# docker volume ls
local     httpd
​
# 进入容器查看目录
[root@docker-01 ~]# docker exec -it web01 bash
root@f52462bab4d9:/usr/local/apache2# ls -ld /data2/
drwxr-xr-x 2 root root 6 May 30 02:05 /data2/
​
# 查看数据卷
# 如果挂载的时候使用的是相对路径,那么也会在默认的docker挂载目录中,但是会自当生成挂载的名称目录
[root@docker-01 ~]# ls /var/lib/docker/volumes/httpd/
_data

1.1.5、指定路径挂载

# 宿主机创建数据
[root@docker-01 ~]# touch /mnt/a.txt
​
# 将宿主机中的/mnt目录挂载到容器中/data1数据卷
# 这种数据指定路径挂载。-v 宿主机绝对路径:容器内路径
[root@docker-01 ~]# docker run -d -v /mnt/:/data1 --name web02 httpd:latest
​
# 进入web02容器查看目录
[root@docker-01 ~]# docker exec -it web02 bash
root@94443e0d28fd:/usr/local/apache2# ls /data1/
a.txt
​
# 删除容器,发现数据依然存在
[root@docker-01 ~]# docker rm -f web02
​
# 宿主机数据仍然存在
[root@docker-01 ~]# ls /mnt/
a.txt
  • 总之:Docker数据卷的实现原理是在宿主机的/var/lib/docker/volumes目录下,根据卷的名称创建相应的目录,然后在每个卷的目录下创建_data目录,在容器启动时如果使用”-v“参数,Docker会把主机上的目录直接映射到容器的指定目录下,实现数据持久化

1.2、数据卷容器

  • 命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据的容器,称之为数据卷容器

1.2.1、数据卷容器特点

  • 是一个普通的容器

  • 数据卷容器专门提供数据卷给其他容器挂载使用

  • 数据卷容器用于在容器之间共享数据

  • 作为数据卷容器并不要求容器中的状态是运行中的

1.2.2、Docker数据卷容器创建

# 若本地没有/data目录,docker容器会自动创建
[root@docker-01 ~]# docker run -it -v /data1 --name centos centos:7 /bin/bash
​
# 查看目录
[root@883cdd63bdda /]# ls -ld /data1/ 
drwxr-xr-x 2 root root 6 May 30 02:22 /data1/
​
## 其他容器创建时挂载数据卷容器
# --volumes-from 指定要从哪个数据卷容器来挂载数据
[root@docker-01 ~]# docker run -it --volumes-from centos --name centos01 centos:7 /bin/bash
​
# 查看目录
[root@0faf44dec9b5 /]# ls -ld /data1/
drwxr-xr-x 2 root root 6 May 30 02:22 /data1/
​
# 在centos01容器中创建数据
[root@0faf44dec9b5 /]# touch /data1/123
​
# 到centos容器中查看数据
[root@docker-01 ~]# docker exec -it centos bash
[root@883cdd63bdda /]# ls -lh /data1/
total 0
-rw-r--r-- 1 root root 0 May 30 02:26 123
  • 注意:删除centos容器,centos01容器中的数据依然存在。数据卷容器的生命周期持续到没有容器使用为止

1.3、扩展

# 创建自定义容器数据卷
docker volume create myvolume
# 查看所有容器数据卷
docker volume ls
# 查看容器数据卷详细信息
docker volume inspect myvolume
# 删除容器数据卷
docker volume rm myvolume 
# 删除所有未被挂载的卷
docker volume prune 

二、Docker的网络管理

Docker未容器提供网络的方法主要有两种:

  • 端口映射

  • 容器互联

2.1、端口映射

  • 端口映射就是将宿主机的指定端口或随机端口映射到容器中,外部网络访问宿主机的端口便可以访问容器内的服务

  • 可随机映射端口(49000-49900)

# 指定宿主机12345端口映射成容器的80端口
[root@docker-01 ~]# docker run -itd -p 12345:80 --name nginx01 nginx:latest
​
​
# 指定随机端口
[root@docker-01 ~]# docker run -itd -P --name nginx02 nginx:latest

2.2、容器互联

  • 容器互联是在源容器和接收容器间建立一条网络通信隧道,实现容器间的互联通信

  • --link name:[alias]实现容器间互联通信

  • 网络通信是单向的

# 使用Dockerfile构建httpd:centos镜像
[root@docker-01 ~]# mkdir -p /opt/apache
[root@docker-01 ~]# cd /opt/apache/
[root@docker-01 apache]# cat Dockerfile
FROM centos:7
MAINTAINER this is apache image
RUN yum -y update
RUN yum -y install httpd
ADD run.sh /run.sh
RUN chmod 775 /run.sh
RUN systemctl enable httpd
EXPOSE 80
CMD ["/run.sh"]
# 创建启动脚本
[root@docker-01 apache]# cat run.sh
#!/bin/bash
#清理httpd的缓存文件,包括进程文件
rm -rf /run/httpd/*
#指定httpd前台启动
/usr/sbin/apachectl -D FOREGROUND
​
# 构建镜像
[root@docker-01 apache]# docker build -t httpd:centos .
​
# 创建容器web02
[root@docker-01 ~]# docker run -d --name web02 httpd:centos 
​
# 创建容器web03链接到web02
[root@docker-01 ~]# docker run -d --name web03 --link web02 httpd:centos 
​
# 测试网络
[root@docker-01 ~]# docker exec -it web03 bash
[root@8e60e7b4d3a2 /]# ping web02
PING web02 (172.17.0.7) 56(84) bytes of data.
64 bytes from web02 (172.17.0.7): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from web02 (172.17.0.7): icmp_seq=2 ttl=64 time=0.059 ms
​

三、Docker网络模式

介绍

  • 当项目大规模使用Docker时,容器通信的问题也就产生了,要解决容器通信问题,必须先了解很多关于网络的知识。Docker一共有四种网络模式分别是host模式,container模式,none模式,bridge模式

网络模式

参数

说明

host模式

--net=host

容器和宿主机共享Network namespace

container模式

--net={id}

容器和另外一个容器共享Network namespace。kubernetes中的pod就是多个容器共享一个Network namespace

none模式

--net=none

容器有独立的Network namespace,但没有对其进行 任何网络设置,如分配veth pair和网桥链接,配置IP等

bridge模式

--net=bridge

默认为该模式,通过-p指定端口映射

3.1、Bridge模式

  • bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看

  • 如果你之前有Docker使用经验,你可能已经习惯了使用--link参数来使容器互联

  • 随着Docker网络的完善,强烈建议大家将容器加入自定义的Docker网络来连接多个容器,而不是使用--link参数

# 创建一个叫my-net的bridge类型的网络
[root@docker-01 ~]# docker network create -d bridge my-net
​
# 查看你都有哪些网络
[root@docker-01 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
d0b9c2202d16   bridge    bridge    local
b4eed7f2cf29   host      host      local
dcddd408905e   my-net    bridge    local
d63d40e49b96   none      null      local
​
# 运行一个容器并连接到新建的my-net网络
[root@docker-01 ~]# docker run -itd --rm --name busybox1 --network my-net busybox sh -c "while true;do echo hello;done"
​
# 再运行一个容器并加入my-net网络
[root@docker-01 ~]# docker run -it --rm --name busybox2 --network my-net busybox sh -c "ping busybox1"
PING busybox1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.064 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.060 ms
​
# 这样,busybox1容器和busybox2容器建立了互联关系
# 如果你有多个容器之间需要互相连接,推荐使用Docker compose

3.2、Host模式

  • 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机公有一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的

[root@docker-01 ~]# docker run -itd --net=host --name docker_host1 busybox
# 使用ifconfig命令可以看到容器的网络和宿主机的是一致的
[root@docker-01 ~]# docker exec -it docker_host1 sh
/ # ifconfig 
br-dcddd408905e Link encap:Ethernet  HWaddr 02:42:24:E1:C0:A0  
          inet addr:172.18.0.1  Bcast:172.18.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:24ff:fee1:c0a0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:84 (84.0 B)  TX bytes:266 (266.0 B)

docker0   Link encap:Ethernet  HWaddr 02:42:28:07:FA:71  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:28ff:fe07:fa71/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:12484 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20357 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:513092 (501.0 KiB)  TX bytes:117156044 (111.7 MiB)

ens33     Link encap:Ethernet  HWaddr 00:0C:29:DA:3D:05  
          inet addr:192.168.93.165  Bcast:192.168.93.255  Mask:255.255.255.0
          inet6 addr: fe80::5a88:87b5:1066:6bc5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:215603 errors:0 dropped:0 overruns:0 frame:0
          TX packets:24704 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:307872309 (293.6 MiB)  TX bytes:3281773 (3.1 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2592 (2.5 KiB)  TX bytes:2592 (2.5 KiB)

veth392f914 Link encap:Ethernet  HWaddr 0A:B1:45:62:A2:79  
          inet6 addr: fe80::8b1:45ff:fe62:a279/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:364 (364.0 B)  TX bytes:894 (894.0 B)

3.3、Container模式

  • 这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡、配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器处理网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过io网卡设备通信

[root@docker-01 ~]# docker run -idt --name host1 busybox

# 创建host2容器共享host1容器的网络
[root@docker-01 ~]# docker run -itd --net=container:host1 --name host2 busybox

# 查询host1容器的网络
e953cd89eab2c1a34d98481978e3b226b1aa99171febf64569b75995e901a0ee
[root@docker-01 ~]# docker exec -it host1 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
     
     
# 查看host2容器的网络,确认和host1容器的网络一致
[root@docker-01 ~]# docker exec -it host2 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

3.4、None模式

  • 使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP

[root@docker-01 ~]# docker run -itd --net=none --name none01 busybox sh
[root@docker-01 ~]# docker exec -it none01 sh
/ # ifconfig 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


0

评论区