通过给EBS类型的根设备扩容解决AWS磁盘容量已满

问题描述

  • 在EC2实例上执行df -h命令不断的报错说no space
  • 根据指令执行结果/dev/xvda1目录的使用Use% 占了100%
  • 首先采取删除不需要的文件,可以维持一会,但是由于不断的运行jenkins job所以导致该目录的占用率又达到100%
问题推理过程:
  • Q1:使用了指令df -h发现一个目录已经满了,那么这个指令到底是什么作用?使用它log出的那些文件都是什么?这个满了的目录又是什么?
  • A1:
    • 首先关于命令的解释:
      - df显示现有磁盘空间使用率,或者显示Linux文件系统上总空间以及可用空间的信息(显示的是所有已经安装到该机器上的文件系统或者说已经安装到该文件系统的物理磁盘(存储卷))以及在当前Linux文件系统中的挂载点。
      - df -h: log出来的
      - Filesystem 代表这块存储卷的名字
      - Mounted on 代表这个存储卷挂载到了实例文件系统的位置
      Linux文件系统将所有物理硬盘统一到一个目录结构中(就是这个实例的文件系统)。这一切都是从顶部(/)目录开始的
      - df .显示当前目录所在的文件系统(物理磁盘或者存储卷)的相关信息
      - 因此可得出挂载到ec2实例上的某一个存储卷已经被占满了,接着发现指令输出的该文件的mounted on属性是'/' 说明该存储卷挂载到了实例的根目录上。说明此时根目录对应的磁盘空间不足了,当然也就意味着实例的文件系统都满了,直接导致实例不能正常工作了
      - 补一张Linux文件系统很low的示意图
      通过给EBS类型的根设备扩容解决AWS磁盘容量已满
      文章图片
      image.png
  • Q2:对于EC2实例而言挂载在根目录的存储卷是什么呢?
  • A2:对于一个EC2实例文件系统的使用的存储卷分成两类:实例存储卷和EBS存储卷。在前者中存储的数据会随着实例的删除而丢失,后者存储的数据是独立于实例的,因此删除实例并不影响EBS存储卷上存储的数据,它可以被看做安装在实例上的硬盘。
    • 如何查询根目录的存储卷类型:打开aws ec2 ui界面,查看某一个正在运行的ec2实例

      通过给EBS类型的根设备扩容解决AWS磁盘容量已满
      文章图片
      image.png
可以看到根设备类型以及根设备:可知根目录挂载的是一个EBS存储卷,并且存储卷的Filesystem是/dev/sda1
- ps:大多数的AMI(镜像)的跟设备都是EBS,当启动一个跟设备是EBS存储卷的实例时,会自动创建一个EBS存储卷挂载在实例的跟目录。 - EBS存储卷是一种块存储设备

  • Q3:根据df结果可以看到挂载的EBS存储卷被使用了100%,那么该如何处理呢?
  • A3:首先我们可以先去了解一下这个EBS存储卷的情况

    通过给EBS类型的根设备扩容解决AWS磁盘容量已满
    文章图片
    image.png
点击EBS ID即可跳转至

通过给EBS类型的根设备扩容解决AWS磁盘容量已满
文章图片
image.png 可以看到这个EBS存储卷的大小,对比df指令输出的结果,发现挂载到根目录的卷占用size就是256GB,因此我们可以采用两种方案:
  • 重启一个其他类型的实例(该跟设备容量大)
  • 给当前的ebs扩容(nice)
  • Q4:如何给当前跟设备对应的EBS扩容呢?
  • A4:
    • 给EBS扩容之前,一定要先创建一个EBS快照!!!!!
    • 接着按照如下扩容即可

      通过给EBS类型的根设备扩容解决AWS磁盘容量已满
      文章图片
      image.png
  • 当EBS状态变成

    通过给EBS类型的根设备扩容解决AWS磁盘容量已满
    文章图片
    image.png
!!请注意:对于EBS的扩容就完成了
  • 此时使用df -h发现根存储卷size没变
  • Q4:为什么挂载在根目录下的EBS存储卷容量都变大了,但是实例文件系统的表现好像没有发现EBS扩大?如何同时扩大实例的文件系统
  • A4: 调整完EBS存储卷大小之后,必须要对实例的文件系统进行扩展可以理解为实例的文件系统没有感知到EBS的扩大,所以还没有给扩大的容量分配地址。
    • 首先使用lsblk可以查看附加到实例上的所有存储卷的真实size以及分区情况

      通过给EBS类型的根设备扩容解决AWS磁盘容量已满
      文章图片
      image.png
      - xvda是一个存储卷,xvda1是存储卷上的一个分区,但是发现并不是一个存储卷被挂载到根而是存储卷上的一个分区被挂在跟上

分区的解释: - 如果您将EBS存储卷视为容器,则分区是卷中的另一个容器,并且数据位于分区上。 - 增大EBS存储卷大小并不会增大分区;如果根目录要利用较大存储卷,分区必须扩展为新大小 - 由于数据是存在分区上的,因此如果存储卷size大于分区的,那么大出的size就是没有被使用的,也就是浪费的。 - 因此最佳实践应该将分区(如果卷上只有一个分区)大小扩大的和存储卷一样

  • 如果分区的size小于卷size此时先将该分区size扩大,使用sudo growpart /dev/xvda 1将/dev/xvda上的1分区扩容到和卷一样大小(请注意将设备名称与分区名称分隔开)
    • 可以通过lsblk再次查看.可以确认分区 /dev/xvda1 现已填充卷 /dev/xvda 上的可用空间
    • 最后对实例的文件系统进行扩容:sudo resize2fs /dev/xvda1resize2fs后面跟着EBS存储卷名称
    • 执行df -h发现已经扩容
  • 最后:要记住挂载在根目录上的是EBS存储卷上的分区而不是这个卷,而且卷被扩容但是分区大小不变依旧不能扩容
  • Q5:在哪里可以选择包含大一点的根设备AMI?
  • A5:通过查看实例类型,不同的实例类型对应不同cpu、内存。。。。
写在最后
【通过给EBS类型的根设备扩容解决AWS磁盘容量已满】感觉EC2上的概念和机器一样:
  • 实例存储(实例停止数据就丢失,速度快) --- 内存 (断电数据丢失,读取速度是硬盘的好几倍)
  • EBS --- 物理磁盘
    独立存在不会因为挂载的实例而导致丢失数据

    推荐阅读