文章目录
- 一、Docker数据管理
- Docker容器的分层
- 哪些数据需要持久化
- 容器数据持久保存方式
- 数据卷(data volume)
- 数据卷的使用场景
- 数据卷的特点
- 数据卷使用方法
- 实际例子
- 二、网络管理
- Docker安装完成后默认的网络设置
- 创建容器后的网络配置
- 修改默认网络设置
- 容器名称互联
- 容器名称介绍
- 容器名称实现
- Docker网络连接模式
- 网络模式介绍
一、Docker数据管理
Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW copy on write)"机制。如果将正在运行中的容器修改生成了新的数据,那么新产生的数据将会被复制到读写层,进行持久化保存,这个读写层也就是容器的工作目录,也为写时复制(COW) 机制。COW机制节约空间,但会导致性低下,虽然关闭重启容器,数据不受影响,但会随着容器的删除,其对应的可写层也会随之而删除,即数据也会丢失.如果容器需要持久保存数据,并不影响性能可以用数据卷技术实现。
将对应的数据写入容器的可写层,但是把/data中的数据写入到另外一个volume中用于数据持久化。
Docker容器的分层
Docker镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加一层可读写的文件系统,用户写入的数据都保护在这一层中。
容器的数据分层目录:
-
LowerDir: image 镜像层,即镜像本身,只读。
-
UpperDir: 容器的上层,可读写 ,容器变化的数据存放在此处。
-
MergedDir: 容器的文件系统,使用Union FS(联合文件系统)将lowerdir 和 upperdir 合并完成后给容器使用,最终呈现给用户的统一视图。
-
WorkDir: 容器在宿主机的工作目录,挂载后内容会被清空,且在使用过程中其内容用户不可见。
查看指定容器数据分层。
docker inspect
哪些数据需要持久化
有状态的协议
有状态协议就是就通信双方要记住双方,并且共享一些信息。而无状态协议的通信每次都是独立的,与上一次的通信没什么关系。
"状态”可以理解为“记忆”,有状态对应有记忆,无状态对应无记忆。
- 左侧是无状态的http请求服务,右侧为有状态。
- 下层为不需要存储的服务,上层为需要存储的部分服务。
容器数据持久保存方式
如果要将写入到容器的数据永久保存,则需要将容器中的数据保存到宿主机的指定目录。
Docker的数据类型分为两种:
- 数据卷(Data Volume): 直接将宿主机目录挂载至容器的指定的目录 ,推荐使用此种方式,此方式较常用。
- 数据卷容器(Data Volume Container): 间接使用宿主机空间,数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据 ,此方式不常用。
数据卷(data volume)
数据卷的使用场景
- 数据库
- 日志输出
- 静态web页面
- 应用配置文件
- 多容器间目录或文件共享
数据卷的特点
- 数据卷是目录或者文件,并且可以在多个容器之间共同使用,实现容器之间共享和重用对数据卷更改数据在所有容器里面会立即更新。
- 数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。
- 在容器里面的写入数据不会影响到镜像本身,即数据卷的变化不会影响镜像的更新。
- 依赖于宿主机目录,宿主机出问题,上面容器会受影响,当宿主机较多时,不方便统一管理。
- 匿名和命名数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,会拷贝到新初始化的数据卷中。
数据卷使用方法
启动容器时,可以指定使用数据卷实现容器数据的持久化,数据卷有三种:
- 指定宿主机目录或文件: 指定宿主机的具体路径和容器路径的挂载关系。
- 容器和真机共用空间, 把容器的文件挂载到真机的文件夹。
- 匿名卷: 不指定数据名称,只指定容器内目录路径充当挂载点,docker自动指定宿主机的路径进行挂载。
- 命名卷: 指定数据卷的名称和容器路径的挂载关系 和匿名卷在一个目录 , 只是取了一个自定义的名字。
Docker run命令的以下各市可以实现数据卷。
-v, --volume=[host-src:]container-dest[:<options>]
<options>
ro 从容器内对此数据卷是只读,不写此项默认为可读可写
rw 从容器内对此数据卷可读可写,此为默认值
实际例子
方式1
指定宿主机目录或文件格式:
-v: <宿主机绝对路径的目录或文件>:<容器目录或文件>[:ro]
将宿主机目录挂载容器目录,两个目录
目录都可自动创建
docker run -it --name c1 -v /data:/opt centos:7
方式2
匿名卷,只指定容器内路径,没有指定宿主机路径信息,宿主机自动生成/var/lib/docker/volumes/<卷ID>/_data目录,并挂载至容器指定路径
-v <容器内路径>
docker run -d --name nginx -v /etc/nginx nginx
docker exec -it nginx bash
方式3
命名卷将固定的存放在/var/lib/docker/volumes/<卷名>/_data
-v <卷名>:<容器目录路径>
可以通过以下命令事先创建,如可没有事先创建卷名,docker run时也会自动创建卷。
docker volume create <卷名>
docker run -d -p 80:80 --name nginx01 -v vol1:/usr/share/nginx/html nginx
docker rm -v 选项可以伤处容器时,同时删除相关联的匿名卷。注意是匿名卷。
管理卷的操作
docker volume
命令 | 含义 |
---|---|
create | 用于创建一个新的 Docker 卷 |
inspect | 用于查看一个或多个 Docker 卷的详细信息。 |
ls | 列出系统中所有可用的 Docker 卷。 |
prune | 删除系统中所有未被容器使用的 Docker 卷。可以用于清理无用的卷,释放存储空间。 |
rm | 删除一个或者多个指定的Docker卷。 |
二、网络管理
Docker安装完成后默认的网络设置
Docker服务安装完成之后,默认在每个宿主机会生成一个名称为docker0的网卡其IP地址都是172.17.0.1/16。
docker会有三种网络设置:
bridge:桥接网络,默认使用的模式,容器基于SNAT进行地址转换访问宿主机以外的环境。
host:直接使用宿主机的网络( 不创建net namespace),性能最好,但是容器端口不能冲突。因为是直接用宿主机网络。
空网络:容器不会分配有效的IP地址(只有一个回环网卡用于内部通信),用于离线数据处理等场景。单机版本。
创建容器后的网络配置
每次新建容器后
- 宿主机多了一个虚拟网卡,和容器的网卡组合成一个网卡,比如: 137: veth8ca6d43@if136,而在容器内的网卡名为136,可以看出和宿主机的网卡之间的关联。
- 容器会自动获取一个172.17.0.0/16网段的随机地址,默认从172.17.0.2开始,第二次容器为172.17.0.3,以此类推。
- 容器获取的地址并不固定,每次容器重启,可能会发生地址变化。
同一宿主机的不同容器可以相互通信
修改默认网络设置
新建容器默认使用docker0的网络配置,可以修改默认指向自定义的网桥网络。
新建网桥
brctl addbr docker1
brctl show
给网桥设置地址
ip a a 192.168.1.1/24 dev docker1
第一个a是add的缩写,第二个a是address的缩写,后面是IP地址和子网掩码 ,dev docker1是指定网络接口名称。
让容器使用docker1网桥
需要修改service文件
重启服务后,可以观察到容器内的IP地址为上述设置的。
修改docker0默认的网段。
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -bip 192.168.2.1/24
容器名称互联
新建容器时,docker会自动分配容器名称,容器ID和IP地址,导致容器名称,容器ID和IP都不固定,那么如何区分不同的容器,实现和确定目标容器的通信呢?解决方案是给容器起个固定的名称,容器之间通过固定名称实现确定目标的通信。
有两种固定名称:
- 容器名称
- 容器名称的别名
容器名称介绍
即在同一个宿主机上的容器之间可以通过自定义的容器名称相互访问,比如: 一个业务前端静态页面是使用nginx,动态页面使用的是tomcat,另外还需要负载均衡调度器,如: haproxy 对请求调度至nginx和tomcat的容器,由于容器在启动的时候其内部IP地址是DHCP 随机分配的,而给容器起个固定的名称,则是相对比较固定的,因此比较适用于此场景。
容器名称实现
docker run创建容器,可以使用–link选项实现容器名称的引用。
格式:
docker run --name <容器名称>
先创建指定名称的容器
docker run --link <目标通信的容器ID或容器名称>
再创建容器时引用上面容器的名称
实际例子
建立一个带有名字的容器
docker run -it --name c1 centos:7 bash
建立第二个容器与第一个相连
docker run -it --name c2 --link c1 centos:7 bash
实现LAMP
vim env_mysql.list
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
MYSQL_PASSWORD=wppass
vim env_wordpress.list
WORDPRESS_DB_HOST=mysql:3306
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wpuser
WORDPRESS_DB_PASSWORD=wppass
WORDPRESS_TABLE_PREFIX=wp_
docker run --name mysql -v /data/mysql:/var/lib/mysql --env-file=/data/env_mysql.list -d -p 3306:3306 mysql:5.7.32
暴露端口3306 加上变量文件
docker run -d --name wordpress --link mysql --env-file=/data/env_wordpress.list -p 80:80 wordpress
加上--link 等于说是可以调用mysql
Docker网络连接模式
网络模式介绍
Docker 的网络支持5种网络模式:
- none
- 没有网络只有一块回环网卡
- bridge
- 网桥模式 默认的模式 nat 地址转换
- host
- 容器和真机共享网络 , 直连
- container
- 容器和容器共享网络 两个容器共用一块网卡
- network-name
- 自定义模式
网络模式指定
默认新建的容器使用Bridge模式,创建容器时,docker run命令使用以下选项指定网络模式。
格式
- 自定义模式
docker run --network <modde>
docker run --net=<mode>
mode可以是以下值
none
bridge
host
container:<容器名或容器ID>
<自定义网络名称>
bridge网络模式架构
可以和外部网络之间进行通信,通过SNAT访问外网,使用DNAT可以让容器被外部主机访问,所以此模式也称为NAT模式。此模式宿主机需要启动ip_forward功能。
bridge网络模式特点
- 网络资源隔离: 不同宿主机的容器无法直接通信,各自使用独立网络。
- 无需手动配置: 容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改。
- 可访问外网: 利用宿主机的物理网卡,SNAT连接外网。
- 外部主机无法直接访问容器: 可以通过配置DNAT接受外网的访问。
- 低性能较低: 因为通过NAT,网络转换带来更多的损耗。
- 端口管理繁琐: 每个容器必须手动指定唯一的端口,容器产生端口冲容。
修改默认的网桥模式网络配置
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
"bip": "192.168.100.100/24",
"fixed-cidr": "192.168.100.128/26",
"default-gateway": "192.168.100.200"
}
host模式
如果指定host模式启动的容器,那么新创建的容器不会创建自己的虚拟网卡,而是直接使用宿主机的网卡和IP地址,因此在容器里面查看到的IP信息就是宿主机的信息,访问容器的时候直接使用宿主机IP+容器端口即可,不过容器内除网络以外的其它资源,如: 文件系统、系统进程等仍然和宿主机保持隔离。此模式由于直接使用宿主机的网络无需转换,网络性能最高,但是各容器内使用的端口不能相同,适用于运行容器端口比较固定的业务。
Host 网络模式特点:
- 使用参数 --network host 指定
- 共享宿主机网络
- 网络性能无损耗
- 网络故障排除相对简单
- 各容器网络无隔离
- 网络资源无法分别统计
- 端口管理困难: 容易产生端口冲突
- 不支持端口映射
none模式
在使用none 模式后,Docker 容器不会进行任何网络配置,没有网卡、没有IP也没有路由,因此默认无法与外界通信,需要手动添加网卡配置IP等,所以极少使用。
none模式特点:
- 使用参数 --network none 指定。
- 默认无网络功能,无法和外部通信。
Container 模式
使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的IP,而是和一个被指定的已经存在的容器共享IP和端口范围,因此这个容器的端口不能和被指定容器的端口冲突,除了网络之外的文件系统、进程信息等仍然保持相互隔离,两个容器的进程可以通过lo网卡进行通信。
Container 模式特点
- 使用参数 –-network container:名称或ID 指定
- 与宿主机网络空间隔离
- 空器间共享网络空间
- 适合频繁的容器间的网络通信
- 直接使用对方的网络,较少使用
docker run -d --name web1 nginx
docker run -d --name web2 --network container:web1 nginx
建立容器时选择相应的网络模式。
使用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式:
- host模式:使用 --net=host 指定。
- none模式:使用 --net=none 指定。
- container模式:使用 --net=container:NAME_or_ID 指定。
- bridge模式:使用 --net=bridge 指定,默认设置,可省略。