写在前面:
由于红帽在Linux界的影响力,相信很多朋友在测试和生产系统用的是RedHat或者CentOS系统,这次我在CentOS系统上遇到了一个很有意思的故障,通过这次故障的原因分析及解决,特意写了这篇文章分享给大家。
我们在CentOS上部署了一套Docker系统,运行了一段时间后,突然发现所有容器运行异常,同时宿主机内核报磁盘I/O错误:kernel: Buffer I/O error on devicekernel: EXT4-fs warning: ext4_end_bio:332: I/O errorkernel: EXT4-fs: Remounting filesystem read-only
看到问题的第一反映是查看磁盘状态和空间使用情况,发现系统的根目录已经用完:Filesystem Type Size Used Avail Use% Mounted on/dev/mapper/centos-root xfs 50G 50G 134M 100% /Devtmpfs devtmpfs 1.9G 0 1.9G 0% /devTmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmTmpfs tmpfs 1.9G 8.7M 1.9G 1% /runTmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/sda1 xfs 497M 123M 375M 25% /bootTmpfs tmpfs 378M 0 378M 0% /run/user/0
我们知道,Docker默认的存储目录是在/var/lib/docker/下,同时我们也知道,可以通过使用-g, --graph=”/var/lib/docker” 参数修改Docker 默认存放路径。知道了问题后,我们可以通过挂载一个大硬盘到系统,并将Docker的目录更改为新挂载到硬盘上:Filesystem Type Size Used Avail Use% Mounted on/dev/mapper/centos-root xfs 50G 50G 134M 100% /Devtmpfs devtmpfs 1.9G 0 1.9G 0% /devTmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmTmpfs tmpfs 1.9G 8.7M 1.9G 1% /runTmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/sda1 xfs 497M 123M 375M 25% /boot/dev/vdb xfs 300G 7G 293G 3% /dataTmpfs tmpfs 378M 0 378M 0% /run/user/0
我将Docker的存储目录设置到刚才新增加的/data目录下,但是原来的镜像和容器都找不到了,因为路径改了。原来的镜像是在/var/lib/docker/devicemapper/devicemapper/{data,metadata},转移文件后继续运行Docker服务,这样我们就有了一个300G的大房子给Docker们用了。
大家以为事情到了这里就完结了么?其实我也想,但是我顺便折腾了一下,于是又发生了接下来的事情。说我手贱也好,瞎折腾也罢,导入一堆容器镜像和运行一堆容器后,系统又光荣告诉我所有的容器根目录全部变成了只读,宿主机内核同样报磁盘I/O错误,一开始我以为data目录又被写满了,但是用df –Th命令查看后,发现目录还有很多空间:Filesystem Type Size Used Avail Use% Mounted on/dev/mapper/centos-root xfs 50G 4.7G 45.3 9% /Devtmpfs devtmpfs 1.9G 0 1.9G 0% /devTmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmTmpfs tmpfs 1.9G 8.7M 1.9G 1% /runTmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/sda1 xfs 497M 123M 375M 25% /boot/dev/vdb xfs 300G 145G 155G 48% /dataTmpfs tmpfs 378M 0 378M 0% /run/user/0
但是残酷的现实是,只用了不到一半的空间后,所有的容器就全部出现异常了,这是我祭出了经典三板斧:重启容器,重启Docker服务,重启服务器。然并卵,容器还是运行异常。通过在网上爬了一堆资料,在http://jpetazzo.github.io/2014/01/29/docker-device-mapper-resize/上查到,CentOS默认用的是Device Mapper作为容器的存储驱动的,大家可以用dockers info命令查看,Docker服务启动时默认会在/var/lib/docker/devicemapper/devicemapper/目录创建一个100G(由于1000和1024换算的关系,系统实际显示的是107.4G,其他数字亦同)的data文件,然后启动的容器的所有变更的数据全部保存到这个data文件中;也就是说当容器内产生的相关data数据超过100G后容器就再也没有多余的空间可用,从而导致所有容器的根目录变为只读!同时它会限制每个容器最大为 10GB。太坑爹了有木有,给了大房子只能用100G!
为了找到根本原因,我们需要了解devicemapper存储驱动的原理: Device Mapper存储驱动是以精简配置的方式运行的,它实际上是目标块设备的快照。Docker启动时会设置一个100G的sparse文件( /var/lib/docker/devicemapper/devicemapper/data,元数据为/var/lib/docker/devicemapper/devicemapper/metadata ),并将其作为Device Mapper的存储池,而所有容器都从该存储池中分配默认10G的存储空间使用,如下图所示:
当有实际读写后,这些存储块将在存储池中被标记为已使用(或者从池中拿走)。当实际读写的块容量大于池的容量时,容器的运行空间不足,所以报I/O错误。
Device Mapper存储驱动非常方便,你不需要做任何安装部署便可以使用:如创建额外的分区来存储 Docker 容器,或者建立LVM。然而它也有两个缺点:• 存储池会有一个默认 100GB 的容量,满足不了大存储的需求。• 它将会被稀疏文件所支持(精简配置,一开始基本不占用空间,只有当实际需要写的时候才会使用磁盘的存储块)但性能较差。
针对这些问题,有两个解决方案:1. 使用更大的文件/磁盘/逻辑卷创建data文件使用文件:dd if=/dev/zero of=/var/lib/docker/devicemapper/devicemapper/data bs=1G count=0 seek=1000这样将会创建一个虚拟的1000G大小的data文件,如果不加seek参数count直接为1000的话则是创建了一个结结实实的1000G的文件使用磁盘:ln -s /dev/sdb /var/lib/docker/devicemapper/devicemapper/data使用逻辑卷:ln -s /dev/mapper/centos-dockerdata /var/lib/docker/devicemapper/devicemapper/data
2. 通过Docker启动参数的--storage-opt选项来限制每个容器初始化的磁盘大小,如-storage-opt dm.basesize=80G 这样每个容器启动后,根目录的总空间就是80G。
但是我总觉得这样的解决方式不够优雅,需要多步操作才能满足需求,同时,容器的空间还是被限制的,只是限制的大小变化而已。那有没有更好的办法呢? 让我们继续来爬资料,在Docker的官方网站上:https://docs.docker.com/engine/reference/commandline/dockerd/
Docker在存储驱动方面支持 AUFS、Device Mapper、Btrfs、ZFS、 Overlay 、Overlay2等多址方式,现由于AUFS并未并入内核,目前只有Ubuntu系统上能够使用aufs作为docker的存储引擎,而在CentOS系统上默认使用Device Mapper,但是幸运的是,在Linux内核3.18.0以上的版本,是可以原生支持Overlay驱动方式的,Overlayfs跟AUFS很像,但是性能比AUFS好,有更好的内存利用。
Docker通过-s参数选择存储驱动, 通过-s=overlay,我们将存储驱动器设置为Overlay方式,再重启Docker应用。
大家可以看到,现在Docker已经是使用了OverlayFS(这里大家要注意,如果系统有存储的镜像和运行的容器,更改存储驱动后将都不可用,请先行备份)。
通过修改为OverlayFS,Device Mapper的存储池容量限制及单个容器运行最大空间限制统统没有了,同时Overlay的读写性能也好于Device Mapper,只需通过-s=overlay一个参数即可优雅的使用更好的文件系统来运行容器。
至此,容器运行时I/O错误的原因已经完美解决,希望这篇文章能帮到在使用过程中遇到相同问题的朋友。http://mp.weixin.qq.com/s?__biz=MzA3NzUwMDg1Mg==&mid=2651291797&idx=1&sn=178f6d7d9a390d588c817994659c095d&mpshare=1&scene=23&srcid=0218UnzuZTW6OWKzB5sy2RgH#rd
相关推荐
在Linux世界中,CentOS是一款广泛使用的开源操作系统,它基于Red Hat Enterprise Linux并提供免费的社区支持。在使用CentOS时,有时可能会遇到需要手动安装网卡驱动的情况,尤其是在新安装或者更新硬件后。本文将...
在 CentOS 6 系统中,对系统日志的分析和管理是进行故障诊断的关键步骤之一。本节将详细介绍 CentOS 6 中的主要日志文件类型、如何分析这些日志以及如何实施有效的日志管理策略。 ##### 9.1.1 主要日志文件 Linux ...
CENTOS 5.1 操作系统中,RTL8168网卡驱动的安装是非常重要的,因为这个驱动程序直接影响到计算机的网络连接。下面我们将详细介绍如何安装CENTOS 5.1 RTL8168网卡驱动。 一、下载驱动 首先,我们需要下载RTL8168网卡...
在Linux系统中,尤其是服务器级别的操作系统,如CentOS,网络驱动程序扮演着至关重要的角色,因为它们确保了操作系统能够正确地识别和与硬件设备通信,尤其是网卡这种基础的网络连接设备。标题“centos网卡驱动”所...
### Lenovo SR650 手动加载430-16iHBA驱动安装CentOS 6.5 指南 #### 环境配置 - **目标系统**: Lenovo SR650 服务器 - **硬件配置**: LOM-x722 + 430-16iHBA卡 - **操作系统**: CentOS 6.5 - **BIOS设置**: 使用...
对于CentOS 7.0这类广泛使用的Linux发行版而言,正确安装Nvidia驱动程序不仅能够提升系统的图形性能,还能解锁Nvidia GPU的全部功能。本文将详细介绍如何在CentOS 7.0系统中安装Nvidia驱动程序。 #### 二、准备工作...
在 CentOS 7 系统中安装 NVIDIA 驱动和 CUDA 是一个复杂的过程,需要一步步地完成。下面将详细介绍安装 NVIDIA 驱动和 CUDA 的步骤。 安装相关编译依赖 在安装 NVIDIA 驱动和 CUDA 之前,需要安装相关的编译依赖项...
在本文中,将详细讨论如何在CentOS 7.4操作系统上安装Intel I219-V网卡驱动。主要知识点将包括安装过程中的问题描述、驱动下载步骤、编译安装过程、以及可能遇到的问题和解决方法。 首先,问题描述部分提到,在戴尔...
### CentOS 6.9 安装英伟达显卡驱动详解 #### 一、准备工作与注意事项 在开始安装显卡驱动之前,请确保已准备好以下事项: 1. **卸载现有驱动**:确保系统中没有安装任何旧版或不兼容的显卡驱动。这一步非常重要...
CentOS7版本:CentOS Linux release 7.9.2009 (Core) 网卡版本:Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05) 安装步骤: 1.在BIOS中关闭Secure Boot,不关闭的情况...
### 网络安装CentOS系统详解 #### 一、前言 在IT领域中,CentOS作为一种广泛使用的Linux发行版,因其稳定性、安全性及开源性等特性深受用户喜爱。然而,对于那些需要频繁安装系统或者网络环境不佳的用户来说,下载...
在本指南中,我们将详细介绍如何在航天联志服务器上安装 CentOS 7.9 操作系统,并加载板载 RAID 驱动。整个过程分为以下几个步骤: 步骤 1:检查主板和下载驱动 首先,我们需要检查主板的型号。在本例中,主板型号...
在Redhat/CentOS 6操作系统环境中,安装过程可能会遇到硬件兼容性问题,特别是当涉及到存储设备如阵列卡时。传统的解决方案可能包括在安装媒介(如CD或DVD)上手动添加驱动,或者使用USB KEY来传递驱动。然而,本...
- Linux Centos系统安装完成后,还需要进行系统的更新和维护,包括安装必要的驱动、更新系统、安装常用软件等,以确保系统的正常运行和安全。 总的来说,Linux Centos系统安装手册主要介绍了Linux Centos系统的...
centos8安装容器.docx
在这样的背景下,exFAT(Extended File Allocation Table)应运而生,它是一种轻量级、高性能的文件系统,特别适合于闪存驱动器和移动存储设备。本文将详细介绍如何在 CentOS 7.4 上安装和挂载 exFAT 文件系统。 ...
centos 7.9 ARM平台容器镜像
CentOS作为一个开源社区项目,专注于提供与Red Hat Enterprise Linux (RHEL)高度兼容的免费操作系统。它的核心价值在于利用RHEL的源代码进行二次开发,通过重新编译生成与RHEL功能相似但免费的版本,为用户提供了...
通过这些步骤,我们可以成功地搭建一个 CentOS 容器使用 Docker。这个容器可以用于开发、测试和部署应用程序。 知识点: 1. Docker 是一个流行的容器化平台,允许开发人员快速构建、测试和部署应用程序。 2. 使用 ...