Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

3.9. 配置 Docker 存储

容器及其创建的镜像存储在 Docker 的存储后端中。这个存储是临时的,与分配用来满足应用程序需要的 持久性存储分开。使用 临时(Ephemeral)存储时,容器保存的数据会在容器被删除时丢失。使用 持久性存储 时,如果容器被删除,容器保存的数据会保留。

您必须为所有 master 和节点主机配置存储,因为默认每个系统都运行容器守护进程。对于容器化安装,您需要在 master 上存储。另外,默认情况下,需要存储的 Web 控制台和 etcd 在 master 上的容器中运行。容器在节点上运行,它们始终需要存储。

存储的大小取决于工作负载、容器数量、运行的容器大小以及容器的存储要求。

重要

如果您的主机使用 RHEL 7.5,且您想要接受 OpenShift Container Platform 的默认 docker 配置(使用 OverlayFS 存储和所有默认日志选项),请不要手动安装这些软件包。安装过程中运行 prerequisites.yml playbook 时会安装这些软件包。

如果您的主机使用 RHEL 7.4,或者使用 RHEL 7.5 且您要自定义 docker 配置,请安装这些软件包。

对于 RHEL 7 系统:

RHEL 7 上 Docker 的默认存储后端是回送设备的一个精简池,在生产环境中不被支持,仅适用于概念验证环境。对于生产环境,您必须创建一个精简池逻辑卷,并重新配置 Docker 来使用这个卷。

Docker 将镜像和容器存储在图形驱动程序中,它是一个可插入的存储技术,如 DeviceMapperOverlayFSBtrfs。它们都有各自的优缺点。例如,OverlayFS 在启动和停止容器时比 DeviceMapper 快,但因为联合文件系统的架构限制,OverlayFS 无法兼容 Unix(POSIX)的可移植操作系统接口。有关在您的 RHEL 版本中使用 OverlayFS 的详情,请查看 Red Hat Enterprise Linux 发行注记。

有关 DeviceMapper 和 OverlayFS 的优点和局限性的更多信息,请参阅 Choosing a Graph Driver

对于 RHEL Atomic Host 7 系统:

RHEL Atomic Host 上 Docker 的默认存储后端是一个精简逻辑卷,在生产环境中被支持。您必须确保根据系统要求中提到的 Docker 存储要求为这个卷分配足够空间。

如果您没有足够的空间,请参阅使用 Docker 格式化容器管理存储,以了解有关使用 docker-storage-setup 和 RHEL Atomic Host 中存储管理的基本说明。

3.9.1. 配置 OverlayFS

OverlayFS 是一种联合文件系统。它允许您在一个文件系统上使用另外一个文件系统。更改记录在上面的文件系统中,而下面的文件系统则未修改。

比较 Overlay 和 Overlay2 Graph Drivers 提供了更多与 overlayoverlay2 驱动程序相关的信息。

有关为 Docker 服务启用 OverlayFS 存储驱动程序的详情,请查看 Red Hat Enterprise Linux Atomic Host 文档

3.9.2. 配置精简池存储

您可以使用 Docker 中包含的 docker-storage-setup 脚本来创建精简池设备并配置 Docker 的存储驱动程序。安装 Docker 后,可以进行此操作,且必须在创建镜像或容器前进行此操作。该脚本从 /etc/sysconfig/docker-storage-setup 文件中读取配置选项,并支持 3 个创建逻辑卷的选项:

  • 使用附加块设备。
  • 使用一个已存在的指定的卷组。
  • 使用 root 文件系统所在卷组中的剩余空间。

使用附加块设备是最可靠的选项,但需要在配置 Docker 存储前向您的主机添加另一个块设备。其他选项都需要在置备主机时保留可用空间。使用 root 文件系统卷组中剩余的可用空间会导致一些应用程序出现问题,例如 Red Hat Mobile Application Platform(RHMAP)。

  1. 使用以下三个选项之一创建 docker-pool 卷:

    • 使用附加块设备:

      1. /etc/sysconfig/docker-storage-setup 中,将 DEVS 设置为要使用的块设备的路径。将 VG 设置为要创建的卷组名称,如 docker-vg。例如:

        # cat <<EOF > /etc/sysconfig/docker-storage-setup
        DEVS=/dev/vdc
        VG=docker-vg
        EOF
      2. 运行 docker-storage-setup 并查看输出以确保创建 docker-pool 卷:

        # docker-storage-setup                                                                                                                                                                                                                                [5/1868]
        0
        Checking that no-one is using this disk right now ...
        OK
        
        Disk /dev/vdc: 31207 cylinders, 16 heads, 63 sectors/track
        sfdisk:  /dev/vdc: unrecognized partition table type
        
        Old situation:
        sfdisk: No partitions found
        
        New situation:
        Units: sectors of 512 bytes, counting from 0
        
           Device Boot    Start       End   #sectors  Id  System
        /dev/vdc1          2048  31457279   31455232  8e  Linux LVM
        /dev/vdc2             0         -          0   0  Empty
        /dev/vdc3             0         -          0   0  Empty
        /dev/vdc4             0         -          0   0  Empty
        Warning: partition 1 does not start at a cylinder boundary
        Warning: partition 1 does not end at a cylinder boundary
        Warning: no primary partition is marked bootable (active)
        This does not matter for LILO, but the DOS MBR will not boot this disk.
        Successfully wrote the new partition table
        
        Re-reading the partition table ...
        
        If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
        to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
        (See fdisk(8).)
          Physical volume "/dev/vdc1" successfully created
          Volume group "docker-vg" successfully created
          Rounding up size to full physical extent 16.00 MiB
          Logical volume "docker-poolmeta" created.
          Logical volume "docker-pool" created.
          WARNING: Converting logical volume docker-vg/docker-pool and docker-vg/docker-poolmeta to pool's data and metadata volumes.
          THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
          Converted docker-vg/docker-pool to thin pool.
          Logical volume "docker-pool" changed.
    • 使用现有的、指定的卷组:

      1. /etc/sysconfig/docker-storage-setup 中,将 VG 设置为卷组。例如:

        # cat <<EOF > /etc/sysconfig/docker-storage-setup
        VG=docker-vg
        EOF
      2. 然后运行 docker-storage-setup 并查看输出以确保创建 docker-pool 卷:

        # docker-storage-setup
          Rounding up size to full physical extent 16.00 MiB
          Logical volume "docker-poolmeta" created.
          Logical volume "docker-pool" created.
          WARNING: Converting logical volume docker-vg/docker-pool and docker-vg/docker-poolmeta to pool's data and metadata volumes.
          THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
          Converted docker-vg/docker-pool to thin pool.
          Logical volume "docker-pool" changed.
    • 使用您的根文件系统所在卷组中的剩余空间:

      1. 验证 root 文件系统所在的卷组是否有所需可用空间,然后运行 docker-storage-setup 并查看输出以确保创建了 docker-pool 卷:

        # docker-storage-setup
          Rounding up size to full physical extent 32.00 MiB
          Logical volume "docker-poolmeta" created.
          Logical volume "docker-pool" created.
          WARNING: Converting logical volume rhel/docker-pool and rhel/docker-poolmeta to pool's data and metadata volumes.
          THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
          Converted rhel/docker-pool to thin pool.
          Logical volume "docker-pool" changed.
  2. 验证您的配置。确认 /etc/sysconfig/docker-storage 文件有 dm.thinpooldevdocker-pool 逻辑卷值:

    # cat /etc/sysconfig/docker-storage
    DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper --storage-opt dm.fs=xfs --storage-opt dm.thinpooldev=/dev/mapper/rhel-docker--pool --storage-opt dm.use_deferred_removal=true --storage-opt dm.use_deferred_deletion=true "
    
    # lvs
      LV          VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      docker-pool rhel twi-a-t---  9.29g             0.00   0.12
    重要

    在使用 Docker 或 OpenShift Container Platform 前,请验证 docker-pool 逻辑卷是否足够大,以满足您的需要。使 docker-pool 卷 60% 成为可用卷组,它将通过 LVM 监控来充满卷组。

  3. 启动或重启 Docker。

    • 如果 Docker 从未在主机上运行,请启用并启动该服务,然后验证它是否正在运行:

      # systemctl enable docker
      # systemctl start docker
      # systemctl is-active docker
    • 如果 Docker 已在运行:

      1. 重新初始化 Docker:

        警告

        这将破坏当前主机上的所有容器或镜像。

        # systemctl stop docker
        # rm -rf /var/lib/docker/*
        # systemctl restart docker
      2. 删除 /var/lib/docker/ 目录中的所有内容。

3.9.3. 配置 Docker 存储

如果您需要在创建 docker-pool 后重新配置 Docker 存储:

  1. 删除 docker-pool 逻辑卷。
  2. 如果您使用专用卷组,请删除卷组和任何关联的物理卷。
  3. 再次运行 docker-storage-setup

有关 LVM 管理的详情,请查看逻辑卷管理器管理

3.9.4. 启用镜像签名支持

OpenShift Container Platform 能够检查镜像是否来自可信源。容器安全指南介绍了相关内容。

您可以使用 atomic 命令行界面(CLI)版本 1.12.5 或更高版本来配置镜像签名验证。在 RHEL Atomic Host 系统中预先安装 atomic CLI。

注意

如需有关 atomic CLI 的更多信息,请参阅 Atomic CLI 文档

以下文件和目录组成主机的信任配置:

  • /etc/containers/registries.d/*
  • /etc/containers/policy.json

您可以直接管理每个节点上的信任配置,或者管理独立主机上的文件,或使用 Ansible 将这些文件分发到适当的节点。有关使用 Ansible 自动分发文件的实例,请参阅容器镜像签名集成指南

  1. 如果还没有安装,在主机系统中安装 atomic 软件包:

    $ yum install atomic
  2. 查看当前的信任配置:

    $ atomic trust show
    * (default)                         accept

    默认配置是将所有 registry 列入白名单,这代表没有配置签名验证。

  3. 自定义信任配置。在以下示例中,将一个 registry 或命名空间列入白名单,将不信任的 registry 列入黑名单(reject),这代表需要在供应商的 registry 中进行签名验证:

    $ atomic trust add --type insecureAcceptAnything 172.30.1.1:5000
    
    $ atomic trust add --sigstoretype atomic \
      --pubkeys pub@example.com \
      172.30.1.1:5000/production
    
    $ atomic trust add --sigstoretype atomic \
      --pubkeys /etc/pki/example.com.pub \
      172.30.1.1:5000/production
    
    $ atomic trust add --sigstoretype web \
      --sigstore https://access.redhat.com/webassets/docker/content/sigstore \
      --pubkeys /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \
      registry.redhat.io
    
    # atomic trust show
    * (default)                         accept
    172.30.1.1:5000                     accept
    172.30.1.1:5000/production          signed security@example.com
    registry.redhat.io                  signed security@redhat.com,security@redhat.com
  4. 您可以通过添加全局 reject(拒绝) 默认信任来进一步强化节点:

    $ atomic trust default reject
    
    $ atomic trust show
    * (default)                         reject
    172.30.1.1:5000                     accept
    172.30.1.1:5000/production          signed security@example.com
    registry.redhat.io                  signed security@redhat.com,security@redhat.com
  5. (可选)查看 atomic man page man atomic-trust 来获得更多配置选项。

3.9.5. 管理容器日志

为防止容器的日志文件(容器运行在的节点上的 /var/lib/docker/containers/<hash> /<hash>-json.log 文件)的大小增长到会出问题的大小,您可以配置 Docker 的 json-file 日志记录驱动程序来限制日志文件的大小和数量。

选项用途

--log-opt max-size

设置创建新日志文件的大小。

--log-opt max-file

设置每个主机要保留的日志文件的最大数量。

  1. 要配置日志文件,请编辑 /etc/sysconfig/docker 文件。例如:要将最大文件大小设定为 1MB,并且始终保留最后三个日志文件,在 OPTIONS= 行中附加 max-size=1Mmax-file=3,确保值使用单引号格式:

    OPTIONS='--insecure-registry=172.30.0.0/16 --selinux-enabled --log-opt max-size=1M --log-opt max-file=3'

    如需了解如何 配置日志记录驱动程序 的更多信息,请参阅 Docker 文档。

  2. 重启 Docker 服务:

    # systemctl restart docker

3.9.6. 查看可用的容器日志

您可以在容器运行的节点上的 /var/lib/docker/containers/<hash> / 目录中查看容器日志。例如:

# ls -lh /var/lib/docker/containers/f088349cceac173305d3e2c2e4790051799efe363842fdab5732f51f5b001fd8/
total 2.6M
-rw-r--r--. 1 root root 5.6K Nov 24 00:12 config.json
-rw-r--r--. 1 root root 649K Nov 24 00:15 f088349cceac173305d3e2c2e4790051799efe363842fdab5732f51f5b001fd8-json.log
-rw-r--r--. 1 root root 977K Nov 24 00:15 f088349cceac173305d3e2c2e4790051799efe363842fdab5732f51f5b001fd8-json.log.1
-rw-r--r--. 1 root root 977K Nov 24 00:15 f088349cceac173305d3e2c2e4790051799efe363842fdab5732f51f5b001fd8-json.log.2
-rw-r--r--. 1 root root 1.3K Nov 24 00:12 hostconfig.json
drwx------. 2 root root    6 Nov 24 00:12 secrets

3.9.7. 阻塞使用本地卷

当使用 Dockerfile 中的 VOLUME 指令置备卷或使用 docker run -v <volumename> 命令时,会使用主机的存储空间。使用这个存储会导致意外地出现存储空间的问题,并可能导致主机关闭。

在 OpenShift Container Platform 中,试图运行自己的镜像可能会导致占用完节点主机上的所有存储空间。解决这个问题的一种方法是防止用户使用卷运行镜像。这样,用户唯一可以访问的存储会被限制,集群管理员可以分配存储配额。

使用 docker-novolume-plugin 可通过禁止使用定义的本地卷启动容器来解决这个问题。特别是,插件块 docker run 命令包含以下内容:

  • --volumes-from 选项
  • 定义了 VOLUME 的镜像
  • 对已存在的、由 docker volume 命令置备的卷的引用

该插件不会阻止对绑定挂载的引用。

要启用 docker-novolume-plugin,在每个节点主机上执行以下步骤:

  1. 安装 docker-novolume-plugin 软件包:

    $ yum install docker-novolume-plugin
  2. 启用并启动 docker-novolume-plugin 服务:

    $ systemctl enable docker-novolume-plugin
    $ systemctl start docker-novolume-plugin
  3. 编辑 /etc/sysconfig/docker 文件并在 OPTIONS 列表中附加以下内容:

    --authorization-plugin=docker-novolume-plugin
  4. 重启 docker 服务:

    $ systemctl restart docker

启用此插件后,定义了本地卷的容器无法启动并显示以下错误消息:

runContainer: API error (500): authorization denied by plugin
docker-novolume-plugin: volumes are not allowed