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

180 阅读12分钟

Docker数据管理

一、容器的数据管理的概述

Docker镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加了一层可读写的文件系统,用户写入的数据都保存在这一层中。

1. 容器的数据分层目录

  • LowerDir:image 镜像层,即镜像本身,只读
  • UpperDir:容器的上层,容器变化的数据存放在此处,可读写
  • MergedDir:容器的文件系统,使用Union FS(联合文件系统)将lowerdir 和 upperdir 合并完成后给容器使用,最终呈现给用户的统一视图
  • WorkDir:容器在宿主机的工作目录,挂载后内容会被清空,且在使用过程中其内容用户不可见

查看指定容器数据分层

 docker inspect 镜像名:tag版本

2. 容器数据持久保存方式

因为容器的数据是临时的,一旦容器被删除,数据将永久丢失。想要将容器中的数据持久化,可以将宿主机目录挂载到容器中。

Docker的数据类型分为两种:

  • 数据卷(Data Volume): 直接将宿主机目录挂载至容器的指定的目录 ,推荐使用此种方式,此方式较常用
  • 数据卷容器(Data Volume Container): 间接使用宿主机空间,数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据 ,此方式不常用

二、 数据卷(Data Volume)

1. 数据卷使用场景

  • 数据库
  • 日志输出
  • 静态web页面
  • 应用配置文件
  • 多容器间目录或文件共享

2. 数据卷的特点

  • 数据卷是目录或者文件,并且可以在多个容器之间共同使用,实现容器之间共享和重用对数据卷更改数据在所有容器里面会立即更新。
  • 数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。
  • 在容器里面的写入数据不会影响到镜像本身,即数据卷的变化不会影响镜像的更新
  • 依赖于宿主机目录,宿主机出问题,上面容器会受影响,当宿主机较多时,不方便统一管理
  • 匿名和命名数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,会拷贝到新初始化的数据卷中

3. 数据卷使用方法

启动容器时,可以指定使用数据卷实现容器数据的持久化,数据卷有三种:

  • 指定宿主机目录或文件 :指定宿主机的具体路径和容器路径的挂载关系

    • 容器和真机共用空间, 把容器的文件挂载到 真机的文件夹
  • 匿名卷 :不指定数据名称,只指定容器内目录路径充当挂载点,docker自动指定宿主机的路径进行挂载

  • 命名卷 :指定数据卷的名称和容器路径的挂载关系,和匿名卷在一个目录,只是取了一个自定义的名字

docker run 命令的以下格式可以实现数据卷:

-v, --volume=[host-src:]container-dest[:<options>]
<options>
ro 从容器内对此数据卷是只读,不写此项默认为可读可写
rw 从容器内对此数据卷可读可写,此为默认值

注意:一般只建议在创建容器时进行挂载,不建议启动容器后再挂载。因为启动容器后再挂载的话,需要修改配置文件,且不一定能挂载成功。

方式一:指定宿主机目录或文件

-v   <宿主机绝对路径的目录或文件>:<容器目录或文件>[:ro]  
#将宿主机目录挂载容器目录,两个目录都可自动创建

示例

[root@localhost ~]#  docker  run -it --name c1 -v  /data:/opt  centos:7.9
# -it  表示使用交互式终端来运行容器
# --name c1  指定容器的名称为c1
# -v /data:/opt  将主机的/data目录挂载到容器中的/opt目录,实现主机和容器之间的文件共享
# centos:7.9 指定使用CentOS 7.9镜像来创建容器

方式二:匿名卷

-v <容器内路径>
#匿名卷,只指定容器内路径,没有指定宿主机路径信息,宿主机自动生成/var/lib/docker/volumes/<卷ID>/_data目录,并挂载至容器指定路径

方式三:命名卷

命名卷将固定的存放在/var/lib/docker/volumes/<卷名>/_data

-v <卷名>:<容器目录路径>

docker volume create <卷名>
#可以通过以下命令事先创建,如可没有事先创建卷名,docker run时也会自动创建卷

4. 管理卷的操作命令

命令作用
docker volume create创建卷
docker volume inspect显示一个或多个卷的详细信息
docker volume  ls列出卷
docker volume prune删除所有匿名卷
docker volume rm移除一个或多个卷

三、数据卷容器(Data Volume Container)

多个容器通过同一个数据卷容器为基点,实现所有容器数据共享

--volumes-from选项用于在Docker容器之间共享卷(volume)。通过该选项,可以让一个容器共享另一个容器的卷,从而实现数据共享和持久化

docker run --volumes-from <容器名或容器ID> <要运行的镜像>这将创建一个新的容器,并使用指定的容器作为卷源,使得新的容器可以访问同一卷中的数据。这对于在不同容器之间共享数据或配置信息非常有用。

示例:

docker run -d --name vo-server -v  /data/testdir/:/usr/share/nginx/html/ nginx

Docker 网络管理

一、 Docker默认的网络通信

1. Docker安装后默认的网络设置

Docker服务安装完成之后,默认在每个宿主机会生成一个名称为docker0的网卡其IP地址都是172.17.0.1/16

2. 创建容器后的网络配置

每次新建容器后:

  • 宿主机多了一个虚拟网卡,和容器的网卡组合成一个网卡,比如: 137: veth8ca6d43@if136,而在容器内的网卡名为136,可以看出和宿主机的网卡之间的关联
  • 容器会自动获取一个172.17.0.0/16网段的随机地址,默认从172.17.0.2开始,第二次容器为172.17.0.3,以此类推
  • 容器获取的地址并不固定,每次容器重启,可能会发生地址变化

3. 容器间的通信

默认情况下,同一个宿主机的不同容器之间可以相互通信

4. 修改默认网络设置

新建容器默认使用docker0的网络配置,可以修改默认指向自定义的网桥网络

示例: 用自定义的网桥代替默认的docker0

新建网桥

[root@localhost ~]# brctl addbr docker1
[root@localhost ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.0242ce991a6e	no		
docker1		8000.000000000000	no		
virbr0		8000.525400dcec9c	yes		virbr0-nic
[root@localhost ~]# ip a a 192.168.1.1/24 dev docker1
[root@localhost ~]# ip a
6: docker1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 52:63:78:b2:a3:d8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global docker1
       valid_lft forever preferred_lft forever
  • 让容器使用docker1 网桥
`修改service 文件`
[root@localhost ~]#  vim /usr/lib/systemd/system/docker.service
 13 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -b docker1
//在启动命令行加入   -b  docker1
  • 重启服务
[root@localhost ~]#  systemctl daemon-reload
[root@localhost ~]#  systemctl restart docker
[root@localhost ~]#  docker run  -it centos:7.9  //进入容器
[root@13dddf5a694d /]# ifconfig
bash: ifconfig: command not found
[root@13dddf5a694d /]# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2     13dddf5a694d
  • 可以看网桥
[root@localhost ~]#  docker run  -d   nginx
b1fff2e22fbe402596a3495feaa40eccb84c278f50b1c4ae64497b1f3d3ec3b2
[root@localhost ~]#  brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.024202703cc2       no
docker1         8000.262a9ea12ee2       no              vethdc13d7c
virbr0          8000.52540005857c       yes             virbr0-nic

5. 修改docker 0默认的网段

[root@localhost ~]#vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -bip  192.168.2.1/24
//在启动命令行加入   -b  docker1
[root@localhost ~]#systemctl daemon-reload
[root@localhost ~]#systemctl restart docker

二、 容器名称互联

1. 容器名称介绍

新建容器时,docker会自动分配容器名称,容器ID和IP地址,导致容器名称,容器ID和IP都不固定,那么如何区分不同的容器,实现和确定目标容器的通信呢?

解决方案是给容器起个固定的名称,容器之间通过固定名称实现确定目标的通信。

2. 容器名称实现

docker run 创建容器,可使用--link选项实现容器名称的引用

docker run --name <容器名称>                   //先创建指定名称的容器
docker run --link <目标通信的容器ID或容器名称>  //再创建容器时引用上面容器的名称

示例

  • 先建立一个带有名字的容器
[root@localhost _data]#  docker run -it --name c1 centos:7.9 bash
  • 再建立第二个容器 和第一个连接
[root@localhost ~]#  docker  run -it --name c2  --link c1 centos:7.9 bash
[root@7aa539347616 /]# ping c1
PING c1 (172.17.0.2) 56(84) bytes of data.
64 bytes from c1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from c1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from c1 (172.17.0.2): icmp_seq=3 ttl=64 time=0.142 ms

三、 docker网络连接模式

Docker支持5种网络模式:

  • brige :网桥模式 默认的模式,nat 地址转换
  • host :容器和真机共享网络,直连
  • none :没有网络只有一块回环网卡
  • container :容器和容器共享网络,两个容器共用一块网卡
  • network-name :自定义模式

使用 docker network ls 命令查看默认的网络模式

1. 指定网络模式

默认新建的容器使用Bridge模式,创建容器时,docker run 命令使用以下选项指定网络模式

docker run --network <mode>
docker run --net=<mode>

<mode>: 可是以下值
none
bridge
host
container:<容器名或容器ID>
<自定义网络名称>

2. brige模式

本模式是docker的默认模式,即不指定任何模式就是bridge模式,也是使用比较多的模式,此模式创建的容器会为每一个容器分配自己的网络IP等信息,并将容器连接到一个虚拟网桥与外界通信。

可以和外部网络之间进行通信,通过SNAT访问外网,使用DNAT可以让容器被外部主机访问,所以此模式也称为NAT模式。

bridge网络模式特点:

  • 网络资源隔离:不同宿主机的容器无法直接通信,各自使用独立网络
  • 无需手动配置:容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改
  • 可访问外网:利用宿主机的物理网卡,SNAT连接外网
  • 外部主机无法直接访问容器:可以通过配置DNAT接受外网的访问
  • 低性能较低:因为通过NAT,网络转换带来更多的损耗
  • 端口管理繁琐:每个容器必须手动指定唯一的端口,容器产生端口冲容

⭐使用此模式一定要开启\color{red}{开启}开启net.ipv4.ip_forward

修改默认的bridge模式网络配置

[root@localhost ~]#vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],  //指定了Docker镜像的镜像加速地址,Docker将会从这个镜像地址加速器下载镜像
  "bip": "192.168.100.100/24",          //指定了Docker守护进程使用的网桥的IP地址和子网掩码
  "fixed-cidr": "192.168.100.128/26",   //用于配置Docker守护进程的固定CIDR地址,指定了Docker守护进程的固定CIDR地址范围
  "default-gateway": "192.168.100.200"  //指定了Docker守护进程使用的默认网关地址。容器将使用这个默认网关来访问外部网络
}
//注意每一行结尾加,逗号  最后一行不用加

3. host模式

如果指定host模式启动容器,那么新创建的容器不会创建自己的虚拟网卡,而是直接使用宿主机的网卡和IP地址,因此在容器里面查看到的IP信息就是宿主机的信息,访问容器的时候直接使用 宿主机IP+容器端口 即可,不过容器内除网络以外的其它资源,如: 文件系统、系统进程等 仍然和宿主机保持隔离。

此模式由于直接使用主机的网络无需转换,网络性能最高,但是各容器内使用的端口不能相同,适用于运行容器端口比较固定的业务。

Host 网络模式特点:

  • 使用参数 --network host 指定
  • 共享宿主机网络
  • 网络性能无损耗
  • 网络故障排除相对简单
  • 各容器网络无隔离
  • 网络资源无法分别统计
  • 端口管理困难:容易产生端口冲突
  • 不支持端口映射

示例

docker run -d --network host --name web1  nginx

4. none模式

在使用none 模式后,Docker 容器不会进行任何网络配置,没有网卡、没有IP也没有路由,因此默认无法与外界通信,需要手动添加网卡配置IP等,所以极少使用。

none模式特点:

  • 使用参数 --network none 指定
  • 默认无网络功能,无法和外部通信

示例

docker run -it  --network  none  centos:7.9

5. container模式

使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的IP,而是和一个被指定的已经存在的容器共享IP和端口范围,因此这个容器的端口不能和被指定容器的端口冲突,除了网络之外的文件系统、进程信息等仍然保持相互隔离,两个容器的进程可以通过lo网卡进行通信。

Container 模式特点:

  • 使用参数 –-network container:名称或ID 指定
  • 与宿主机网络空间隔离
  • 空器间共享网络空间
  • 适合频繁的容器间的网络通信
  • 直接使用对方的网络,较少使用

示例

[root@localhost ~]#docker run -d --name web1  nginx
[root@localhost ~]#docker run -d --name web2 --network container:web1   nginx