NFS在docker环境下无法写入文件的问题解决、NFS文件共享查看挂载客户端列表、mount监控及使用script命令保存屏幕终端输出内容
一、NFS在docker环境下无法写入文件的问题解决
publish:December 25, 2019 -Wednesday 在使用docker搭建的服务器环境中,如果需要使用nfs来进行共享应用生成的比如缓存或者客户端上传的资源时,可能会遇到nfs文件虽然同步,但是却未映射到docker容器中。比如我们在docker环境中启动一个如下php容器,将php中的缓存目录cache_dir映射到宿主机中的/opt/data/cache_dir目录。然后我们开启nfs将多台服务器间的/opt/data/cache_dir目录进行同步。如下:
#192.168.162.26/27上的服务器在docker中启动php
docker run --name php-test -d -p 9000:9000 \
-v /opt/www-data/:/var/www \
-v /data/php/php-fpm.conf:/usr/local/etc/php-fpm.conf \
-v /data01/php/log:/var/log/php \
-v /opt/data/cache_dir:/home/cache_dir \
php
#nfs进行文件共享主机配置
/opt/data/cache_dir 192.168.162.27(rw,sync,no_root_squash,no_subtree_check)
#从服务器使用mount挂载相关目录
mount 192.168.162.26:/opt/data/cache_dir /opt/data/cache_dir
此时进行php程序处理,比如图片上传至2台服务器中的任何一台,可以看到NFS配置成功,2台服务器的nfs目录文件也同步成功,但在图片请求中只在其中一台上能加载出图片,排查发现虽然两边的文件同步成功,但通过docker exec进入docker容器查看并未将nfs同步的文件映射到容器中。这是为什么呢?为什么mount在宿主机中生效,但是不能在容器中生效?大概看到网上有一个提法叫做private mount和shared mount等等之分,详细介绍可见:https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt 默认使用的是private mount,通过mount命令也可以查看到有--make-shared等选项,可以设置mount模式。
#mount --help的选项信息
Operations:-B, --bind mount a subtree somewhere else (same as -o bind)-M, --move move a subtree to some other place-R, --rbind mount a subtree and all submounts somewhere else--make-shared mark a subtree as shared--make-slave mark a subtree as slave--make-private mark a subtree as private--make-unbindable mark a subtree as unbindable--make-rshared recursively mark a whole subtree as shared--make-rslave recursively mark a whole subtree as slave--make-rprivate recursively mark a whole subtree as private--make-runbindable recursively mark a whole subtree as unbindable
有什么解决办法呢?但我认为使用mount的--make-shared选项可以解决这个问题,不过我没有去尝试应用,我使用的是另一种比较简单省事的办法:就是先启动nfs,然后再启动docker, 我上面碰到了问题的情况正是因为先启动的docker然后再启动的nfs,这样nfs挂载将传播到容器中,这个方法我已经尝试使用并且验证成功。
以上两个方法应该够用,另外还有其它的一些方法,比如在启动docker容器的时候也可以使用:private来设置传播模式,不过我也未进行尝试验证。欢迎试验并反馈结果。
其它NFS无法写入文件的问题:需要排查NFS服务端的配置对host客户端主机是否设置了rw权限,并且使用no_root_squash选项,接着查看客户端的挂载命令,可以尝试给mount增加-o rw参数重新挂载。
二、NFS文件共享怎么查看挂载客户端列表及进行mount监控
在配置了NFS文件共享服务之后,怎么查看挂载客户端列表及进行mount监控呢,因为可能哪天挂载出了问题中止了,导致业务出现问题。这时可以使用showmount命令来查看挂载的情况。showmount主要有以下三个选项,publish:December 25, 2019 -Wednesday 其意义台使用过程如下:
#showmount命令选项
showmount -a 服务器ip #查看挂载的nfs客户端列表
showmount -d 服务器ip #查看nfs服务器的共享资源
showmount -e 服务器ip #查看nfs服务器的exports文件
#showmount查看共享文件资源
tuser@n17:~$ /sbin/showmount --help
Usage: /sbin/showmount [-adehv][--all] [--directories] [--exports][--no-headers] [--help] [--version] [host]
u07@mac5:/$ showmount -a
-bash: showmount: command not found
u07@mac5:/$ whereis showmount
showmount: /sbin/showmount /usr/share/man/man8/showmount.8.gz
u07@mac5:/$ /sbin/showmount -a
All mount points on n147-026-025:
192.117.19.27:/data00/www-data/test.04007.cn/share_dir/files
192.117.19.35:/data00/www-data/test.04007.cn/share_dir/files
192.117.19.39:/data00/www-data/test.04007.cn/share_dir/files
u07@mac5:/$ /sbin/showmount -e 192.117.19.25
Export list for 192.117.19.25:
/data00/www-data/test.04007.cn/share_dir/files 192.117.19.39,192.117.19.35,192.117.19.27
#通过监控mount客户端的数量来进行监控报警
tuser@n17:~$ /sbin/showmount -a 192.117.19.25 | grep -v 'All mount' | wc -l
能看到这些数据我们就可以方便地对挂载服务进行监控了。通过监控mount客户端的数量或者再细一点对IP进行过滤来进行监控报警。
三、服务器上使用script命令保存屏幕终端输出的内容
在服务器执行命令的时候,有时输出的内容会很多,像一般的secureCRT到是可以设置最多可以保留多少行的记录,但用鼠标去点选也是挺麻烦的,这时可以使用一下script工具了。script工具可以记录用户在当前终端的所有操作命令和已经输出到屏幕的内容,并将这些信息保存到指定的文本文件中。记录文件会存储为文本文件,可以很方便地用打开和编辑。
script和scriptreplay在Linux发行版上都自带,script工具使用起来也很简单。使用script命令开启屏幕输出记录,可以使用-f选项指定记录的文件名,默认文件名是typescript,在执行完毕后使用exit退出,此时会记录到typescript文件。有的地方提到scriptreplay的-f选项,但在使用时会报-f选项无效。
user@u19:/opt/nginx/logs$ script
Script started, file is typescript
user@u19:/opt/nginx/logs$ date
Thu Dec 26 15:32:39 CST 2019
user@u19:/opt/nginx/logs$ scriptreplay -f demo
scriptreplay: invalid option -- 'f'Usage:scriptreplay [-t] timingfile [typescript] [divisor]
Play back terminal typescripts, using timing information.
Options:-t, --timing <file> script timing output file-s, --typescript <file> script terminal session output file-d, --divisor <num> speed up or slow down execution with time divisor-m, --maxdelay <num> wait at most this many seconds between updates-V, --version output version information and exit-h, --help display this help and exit
For more details see scriptreplay(1).
user@u19:/opt/nginx/logs$ exit
exit
Script done, file is typescript
user@u19:/opt/nginx/logs$
user@u19:/opt/nginx/logs$ ll
total 3960
-rw-r--r-- 1 tiger tiger 3960 Dec 26 19:32 typescript
#屏幕录制和回放:
user@u19:/opt/nginx/logs$ script -t 2>kermit.time -a kermit.his
user@u19:/opt/nginx/logs$ scriptreplay kermit.time kermit.his
在使用script命令将终端的会话过程录制之后,可以使用scriptreplay将其给他人回放。这时需要将script输出到两个文件(可随便命名),如上kermit.time用于命令运行时间;kermit.his用于存储命令输出。-t选项用于将时序数据导入stderr。2>用于stderr重定向到kermit.time。exit退出录制之后就可以使用scriptreplay回放。