在以 CentOS7.6 为基础镜像的 Docker 容器中通过 NFS 将内存挂载成高速硬盘使用

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 在以 CentOS7.6 为基础镜像的 Docker 容器中通过 NFS 将内存挂载成高速硬盘使用一 背景这是最近项目中遇到的一个问题。在已知的部署在 docker 容器云上某个应用中,读写非常频繁,对磁盘的性能要求极高,但是又不能在同一个容器内进行高强度读写。

在以 CentOS7.6 为基础镜像的 Docker 容器中通过 NFS 将内存挂载成高速硬盘使用

一 背景

这是最近项目中遇到的一个问题。在已知的部署在 docker 容器云上某个应用中,读写非常频繁,对磁盘的性能要求极高,但是又不能在同一个容器内进行高强度读写。另外,该主机内存资源有冗余,允许使用特权模式运行容器,不要求该部分数据持久性存储。

通过对问题的分析,我采取了以下解决方案:

  • 通过把内存挂载成硬盘,可以大幅度提高磁盘的性能;
  • 由于不能在同一个容器内进行读写,可以使用 NFS 来解决;
  • 允许使用特权模式,可以在容器内部挂载磁盘;
  • 不要求数据持久存储,可以把内存当作告诉磁盘来使用;
  • 在同一台主机上,可以不考虑容器的跨主机互联。

在本文中已经对涉及到公司利益部分内容进行处理,例如:文中涉及到的镜像已经移除相关应用,直接以centos7.6.1810为基础镜像。

二 环境

2.1 宿主机OS

CentOS Linux release 7.6.1810 (Core)

2.2 硬件信息

内存:256GB

2.3 宿主机的初始化配置

#!/bin/bash
UserName='gysl'
PassWord='drh123'
# Install the Docker engine. This needs to be executed on every machine.
curl http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo>&/dev/null
if [ $? -eq 0 ] ;
    then
        yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-selinux \
                      docker-engine-selinux \
                      docker-engine>&/dev/null
        yum list docker-ce --showduplicates|grep "^doc"|sort -r
        yum -y install docker-ce-18.09.3-3.el7
        rm -f /etc/yum.repos.d/docker-ce.repo
        systemctl enable docker --now && systemctl status docker
    else
        echo "Install failed! Please try again! ";
        exit 110
fi
# Modify related kernel parameters.  
cat>/etc/sysctl.d/docker.conf<<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF  
sysctl -p /etc/sysctl.d/docker.conf>&/dev/null  
# Turn off and disable the firewalld.  
systemctl stop firewalld  
systemctl disable firewalld  
# Disable the SELinux.  
sed -i.bak 's/=enforcing/=disabled/' /etc/selinux/config  
# Disable the swap.  
sed -i.bak 's/^.*swap/#&/g' /etc/fstab
# Install EPEL/vim/git.  
yum -y install epel-release vim git
yum repolist
# Add a docker user.
useradd $UserName
echo $PassWord|passwd $UserName --stdin
usermod $UserName -aG docker  
# Reboot the machine.  
reboot

执行以上脚本重启服务器之后,以用户名 gysl 登录系统。

三 实施步骤

3.1 构建 NFS 服务镜像

3.1.1 准备阶段

Dockefile内容如下:

FROM centos:7.6.1810
ENV  SSD='/high-speed-storage' SIZE='10m'
COPY . /
RUN  yum -y install nfs-utils && \
     mkdir $SSD  
CMD  [ "/bin/bash","/start.sh" ]

start.sh脚本内容如下:

#!/bin/bash
echo "$SSD *(fsid=0,rw,no_root_squash,no_subtree_check)">>/etc/exports
mount -t tmpfs -o size=$SIZE tmpfs $SSD
/usr/sbin/exportfs -r
/usr/sbin/rpcbind
/usr/sbin/rpc.nfsd
/usr/sbin/rpc.mountd
/usr/sbin/rpc.rquotad
while true;
    do
        sleep 6000;
    done

3.1.2 构建阶段

新建一个目录,将上文中的 Dokcerfile 与 start.sh 放到该目录。

[gysl@gysl-dev ~]$ mkdir nfs
[gysl@gysl-dev ~]$ cd nfs
[gysl@gysl-dev nfs]$ docker build -t nfs:v1.0 .

3.1.3 启动 NFS 服务容器

启动容器内的 NFS 服务,命令如下:

[gysl@gysl-dev nfs]$ docker run -itd --privileged --rm nfs:v1.0
953dd0cf03e024447ba3a7f1be6dce6217226b25c13ffa2b9967941c96b73f4e

3.1.4 记下 NFS 服务容器的IP

[gysl@gysl-dev nfs]$ docker inspect 953|grep -w 'IPAddress'
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

3.2 修改应用镜像

3.2.1 在应用所在的镜像内添加 NFS 服务

修改 Dockerfile ,内容如下:

FROM centos:7.6.1810
ENV  SSD='/high-speed-storage' DATA='/data'
COPY . /
RUN  yum -y install nfs-utils && \
     mkdir $DATA
CMD  [ "/bin/bash","/start-client.sh" ]

添加 start-client.sh 脚本,脚本内容如下:

#!/bin/bash
mount -t nfs 172.17.0.2:$SSD $DATA
while true; do sleep 6000; done

3.2.2 重新构建应用镜像

新建一个目录,把修改后的 Dockerfile 和 start-client.sh 放到同一目录,执行命令如下:

[gysl@gysl-dev ~]$ mkdir nfs-client
[gysl@gysl-dev ~]$ cd nfs-client/
[gysl@gysl-dev nfs-client]$ vi Dockerfile
[gysl@gysl-dev nfs-client]$ vi start-client.sh
[gysl@gysl-dev nfs-client]$ docker run --privileged -itd --rm nfs-client:v1.0
7e01276f49815b76dd4dc3ae3ff9a80b8d4f32814f46c4e58f7cfab0d945cebf

3.3.3 验证是否挂载成功

进入应用容器,查看是否挂载成功:

[root@7e01276f4981 /]# df -h
Filesystem                      Size  Used Avail Use% Mounted on
overlay                         8.0G  2.6G  5.5G  32% /
tmpfs                            64M     0   64M   0% /dev
tmpfs                           455M     0  455M   0% /sys/fs/cgroup
/dev/mapper/centos-root         8.0G  2.6G  5.5G  32% /etc/hosts
shm                              64M     0   64M   0% /dev/shm
172.17.0.2:/high-speed-storage   10M     0   10M   0% /data
[root@7e01276f4981 /]# touch /data/test

成功!问题解决!

四 总结及拓展

4.1 本案例的缺点

  • 不符合一个容器一个进程的容器运用的主流标准;
  • 数据不能持久化保存,重启容器数据会被清除;
  • 容器存在依赖性,必须先启动提供 NFS 服务的容器;
  • 适用范围狭窄;
  • 不能通过 systemd 来管理服务;
  • 生产环境中不推荐使用此方案。

4.2 拓展知识

4.2.1 把内存挂载成高速硬盘有 tmpfs 和 ramdisk 两种方案

linux下的 ramdisk 是由内核提供的,mount 命令挂载即可使用。它会被视为块设备,使用时需要格式化该文件系统。ramdisk 一旦创建就会占用固定大小的物理内存,tmpfs则是动态分配。

4.2.2 Docker 容器的互联

在同一台主机的未指定网络方案的情况下,Docker 是通过 bridge 的方式进行桥接的。如果涉及到跨主机的互联,那么可能需要使用其他方案。

4.2.3 在容器中的其他 NFS 解决方案

nfs-ganesha 也是 NFS 在容器中的一个比较流行的解决方案。

相关文章
|
18天前
|
Ubuntu API 网络虚拟化
ubuntu22 编译安装docker,和docker容器方式安装 deepseek
本脚本适用于Ubuntu 22.04,主要功能包括编译安装Docker和安装DeepSeek模型。首先通过Apt源配置安装Docker,确保网络稳定(建议使用VPN)。接着下载并配置Docker二进制文件,创建Docker用户组并设置守护进程。随后拉取Debian 12镜像,安装系统必备工具,配置Ollama模型管理器,并最终部署和运行DeepSeek模型,提供API接口进行交互测试。
268 15
|
3月前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
322 78
|
2月前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
187 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
3月前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
3月前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
100 8
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
3月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
196 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
2月前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
257 11
|
3月前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
100 3
实战~如何组织一个多容器项目docker-compose
|
3月前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
83 5
|
3月前
|
数据建模 应用服务中间件 nginx
docker替换宿主与容器的映射端口和文件路径
通过正确配置 Docker 的端口和文件路径映射,可以有效地管理容器化应用程序,确保其高效运行和数据持久性。在生产环境中,动态替换映射配置有助于灵活应对各种需求变化。以上方法和步骤提供了一种可靠且易于操作的方案,帮助您轻松管理 Docker 容器的端口和路径映射。
194 3

热门文章

最新文章