ubuntu 16.04升级nginx版本

因为刚刚在 V2EX 看到的 nginx 爆出了中度危险漏洞,于是决定将正在用的nginx服务都升个级喵~

默认 Ubuntu 自带的 nginx 都比较 out, 正确的姿势是从官方源安装

  • 在 /etc/apt/sources.list.d/ 下添加一个 nginx.list 文件,内容如下:
deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx  
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx  
  • 添加 nginx 的 key,并更新 apt
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add  
sudo apt update  
需要注意的是,Ubuntu 自带的 nginx 系列模组会干扰nginx本体安装,所以先备份配置文件,删除ubuntu的默认模组,再重装nginx
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak  
sudo apt remove nginx nginx-common nginx-full nginx-core  
sudo apt install nginx  
sudo rm /etc/nginx/nginx.conf  
sudo cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf  

另外一点是此时 nginx 被 mask 了……解除并重启它:

sudo systemctl unmask nginx  
sudo systemctl start nginx  

测试无误后,加上重启自启动

sudo systemctl enable nginx  

NGINX编译安装动态模块(不需重新编译nginx)

虽然我一贯会自行编译Nginx,而且我多会选用阿里的Tengine或者YiChun Zhang的OpenResty,可难免会遇到一些特殊情况。

例如:我最近接手的一个小项目。其官方运维偏偏选择的是RPM包。如果是Nginx 1.9.11版本之前,我只能选择跟他们的运维商量:“hi,哥们!我需要用到的一些第三方模块必须重新编译安装Nginx呢!” 所幸,他们用的Centos 7.0,而官方的RPM仓库自带的版本已经支持到Nginx 1.10.2啦。我深呼吸一下,考虑到他们的使用习惯,我作出了第二个选择:Nginx动态模块。

可是。。。我真的是第一次操作动态模块的编译和加载。所以,我才会写下这则手记。

我主要参考的三篇文章如下:

  • https://www.nginx.com/blog/compiling-dynamic-modules-nginx-plus/
  • https://www.nginx.com/resources/wiki/extending/new_config/
  • https://www.nginx.com/resources/wiki/extending/converting/

我这里记录一下ngx_cache_purge的动态编译过程。

cd /usr/local/src #养成源码统一放置的位置,方便你我他。这家在职运维是到处乱丢的,吐槽一下!
nginx -v #返回的是nginx version: nginx/1.10.2, 确保下一步源码版本一致哟
wget -c http://nginx.org/download/nginx-1.10.2.tar.gz
wget -c https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz -O ngx_cache_purge_2.3.tar.gz
tar zxf nginx-1.10.2.tar.gz
tar zxf ngx_cache_purge_2.3.tar.gz

转化动态模块的config文件

因为这个模块比较老,作者并没有对它做config配置的更新。换言之,源码下载后并不能支持编译为动态模块,我们参考官方文档(见上列表),试试看。

cd ./ngx_cache_purge-2.3/
cp config config.bk
vim config
###
if [ "$HTTP_PROXY" = "YES" ]; then
    have=NGX_HTTP_PROXY . auto/have
fi

if [ "$HTTP_FASTCGI" = "YES" ]; then
    have=NGX_HTTP_FASTCGI . auto/have
fi

if [ "$HTTP_SCGI" = "YES" 2]; then
    have=NGX_HTTP_SCGI . auto/have
fi

if [ "$HTTP_UWSGI" = "YES" ]; then
    have=NGX_HTTP_UWSGI . auto/have
fi

ngx_addon_name=ngx_http_cache_purge_module
CACHE_PURGE_SRCS="$ngx_addon_dir/ngx_cache_purge_module.c"

if [ -n "$ngx_module_link" ]; then
    ngx_module_type=HTTP
    ngx_module_name="$ngx_addon_name"
  /  ngx_module_srcs="$CACHE_PURGE_SRCS"

    . auto/module
else
    HTTP_MODULES="$HTTP_MODULES $ngx_addon_name"
    NGX_ADDON_SRCS="$NGX_ADDON_SRCS $CACHE_PURGE_SRCS"
fi

have=NGX_CACHE_PURGE_MODULE . auto/have
###

现在,我们可以进行动态模块的编译啦。

cd ../nginx-1.10.2
nginx -V
./configure --add-dynamic-module=../ngx_cache_purge-2.3/ ##这一步要注意:必须将之前的配置指令都拷贝过来,否则会有binary不兼容错误。
make modules
ls objs/

一切正常的话,输出会提示将so文件输出到了objs目录下。 他们这台服务器也没有SUDO相关配置,所以我以上都是以root身份直接运行的。您可能需要su指令。

最后,我们加载动态模块测试。

cp objs/ngx_http_cache_purge_module.so /usr/lib64/nginx/modules/
vim /usr/share/nginx/modules/mod-http-cache-purge.conf #该服务器是CENTOS 7.0,我看到nginx.conf中已经存在载入动态模块的include语句,所以就按照约定执行
###
load_module "/usr/lib64/nginx/modules/ngx_http_cache_purge_module.so";
###
systemctl restart nginx

Nginx平滑升级到最新版本

(一)简述:

早上收到nginx最新漏洞的通知,Nginx官方发布最新的安全公告,在Nginx范围过滤器中发现了一个安全问题(CVE-2017-7529),通过精心构造的恶意请求可能会导致整数溢出并且不正确处理范围,从而导致敏感信息泄漏。
当使用Nginx标准模块时,如果文件头从缓存返回响应,允许攻击者获取缓存文件头。在某些配置中,缓存文件头可能包含后端服务器IP地址或其他敏感信息。此外,如果使用第三方模块有潜在的可能导致拒绝服务。

影响版本
Nginx 0.5.6-1.13.2
漏洞等级
中危
Nginx 在官方公告中称发现了一个范围过滤器中的安全问题。通过精心构造的恶意请
求能造成整数溢出,对范围的不当处理会导致敏感信息泄漏。
No. 漏洞名称 漏洞危害
CVE-2017-7529 Nginx range 过滤器整形溢出漏洞 高危

针对 CVE–2017–7529 修复建议
针对 Nginx range 过滤器整形溢出漏洞的修复建议

  1. 下面的配置可以作为暂时的解决办法:
    max_ranges 1;
  2. 建议受影响用户尽快升级至 1.13.3, 1.12.1
  3. 及时安装官方补丁。

虽然临时可以解决,不过还是建议升级到最新的版本,官方建议升级到1.12.1。

(二)具体的升级步骤:

(1)升级和安装nginx第三方模块一样,需要查看原来安装nginx的版本以及编译的参数:

[root@ittestserver1 opt]# /usr/local/nginx2/sbin/nginx -V
nginx version: nginx/1.10.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) 
built with OpenSSL 1.1.0e  16 Feb 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx2 --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_stub_status_module --with-http_v2_module --with-openssl=/tmp/install/openssl-1.1.0e --with-http_v2_module

(2)下载要升级的nginx版本

[root@ittestserver1 soft]# wget http://nginx.org/download/nginx-1.12.1.tar.gz
--2017-07-17 15:41:24--  http://nginx.org/download/nginx-1.12.1.tar.gz
正在解析主机 nginx.org... 206.251.255.63, 95.211.80.227, 2001:1af8:4060:a004:21::e3, ...
正在连接 nginx.org|206.251.255.63|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:981093 (958K) [application/octet-stream]
正在保存至: “nginx-1.12.1.tar.gz”
90% [=================================================>     ] 892,302      265K/s eta(英国中部时100%[======================================================>] 981,093      291K/s   in 3.3s    
2017-07-17 15:41:28 (291 KB/s) - 已保存 “nginx-1.12.1.tar.gz” [981093/981093])

(3)解压ningx下载的压缩包编译make,切记不要make install。

[root@ittestserver1 soft]# tar xf nginx-1.12.1.tar.gz 
[root@ittestserver1 soft]# cd nginx-1.12.1
[root@ittestserver1 nginx-1.12.1]# ls
auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src
[root@ittestserver1 nginx-1.12.1]# ./configure  --prefix=/usr/local/nginx2 
--with-http_stub_status_module 
--with-http_ssl_module 
--with-http_realip_module 
--with-http_gzip_static_module 
--with-http_stub_status_module 
--with-http_stub_status_module 
--with-http_v2_module 
--with-openssl=/tmp/install/openssl-1.1.0e 
--with-http_v2_module
checking for OS
 + Linux 2.6.32-358.el6.x86_64 x86_64
checking for C compiler ... found
 + using GNU C compiler
 + gcc version: 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 
checking for gcc -pipe switch ... found
checking for -Wl,-E switch ... found
checking for gcc builtin atomic operations ... found
checking for C99 variadic macros ... found
checking for gcc variadic macros ... found
checking for gcc builtin 64 bit byteswap ... found
checking for unistd.h ... found
checking for inttypes.h ... found
checking for limits.h ... found
checking for sys/filio.h ... not found
checking for sys/param.h ... found
checking for openat(), fstatat() ... found
checking for getaddrinfo() ... found
checking for PCRE library ... found
checking for PCRE JIT support ... found
checking for zlib library ... found
creating objs/Makefile
Configuration summary
  + using system PCRE library
  + using OpenSSL library: /tmp/install/openssl-1.1.0e
  + using system zlib library
  nginx path prefix: "/usr/local/nginx2"
  nginx binary file: "/usr/local/nginx2/sbin/nginx"
  nginx modules path: "/usr/local/nginx2/modules"
  nginx configuration prefix: "/usr/local/nginx2/conf"
  nginx configuration file: "/usr/local/nginx2/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx2/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx2/logs/error.log"
  nginx http access log file: "/usr/local/nginx2/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"
[root@ittestserver1 nginx-1.12.1]# make

由于make的时间比较长,需要稍等下。

(4)make编译完后会在安装目录下生成一个objs目录且在该目录下有一个nginx执行文件。

[root@ittestserver1 nginx-1.12.1]# ls
auto     CHANGES.ru  configure  html     Makefile  objs    src
CHANGES  conf        contrib    LICENSE  man       README
[root@ittestserver1 nginx-1.12.1]# ll objs/
总用量 7124
-rw-r--r-- 1 root root   17459 7月  17 15:48 autoconf.err
-rw-r--r-- 1 root root   43530 7月  17 15:48 Makefile
-rwxr-xr-x 1 root root 7152312 7月  17 15:51 nginx
-rw-r--r-- 1 root root    5345 7月  17 15:51 nginx.8
-rw-r--r-- 1 root root    7066 7月  17 15:48 ngx_auto_config.h
-rw-r--r-- 1 root root     657 7月  17 15:48 ngx_auto_headers.h
-rw-r--r-- 1 root root    6242 7月  17 15:48 ngx_modules.c
-rw-r--r-- 1 root root   38232 7月  17 15:51 ngx_modules.o
drwxr-xr-x 9 root root    4096 7月  17 15:48 src

(5)备份原来老的nginx文件

[root@ittestserver1 nginx-1.12.1]# mv /usr/local/nginx2/sbin/nginx /usr/local/nginx2/sbin/nginx.bak
[root@ittestserver1 nginx-1.12.1]# cp objs/nginx
nginx    nginx.8  
[root@ittestserver1 nginx-1.12.1]# cp objs/nginx  /usr/local/nginx2/sbin/

[root@ittestserver1 nginx-1.12.1]# /usr/local/nginx2/sbin/nginx -t
nginx: the configuration file /usr/local/nginx2/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx2/conf/nginx.conf test is successful

(6)使用make upgrade替换老的nginx进程

[root@ittestserver1 nginx-1.12.1]# make upgrade
/usr/local/nginx2/sbin/nginx -t
nginx: the configuration file /usr/local/nginx2/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx2/conf/nginx.conf test is successful
kill -USR2 `cat /usr/local/nginx2/logs/nginx.pid`
sleep 1
test -f /usr/local/nginx2/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx2/logs/nginx.pid.oldbin`

(7)执行/usr/local/nginx2/sbin/nginx -V查看nginx最新的版本及编译的参数

[root@ittestserver1 nginx-1.12.1]# /usr/local/nginx2/sbin/nginx -V
nginx version: nginx/1.12.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 
built with OpenSSL 1.1.0e  16 Feb 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx2 --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_stub_status_module --with-http_v2_module --with-openssl=/tmp/install/openssl-1.1.0e --with-http_v2_module

至此升级完成。

centos7.1安装配置NFS共享文件系统

环境:centos7.1
server:192.168.0.63
client:192.168.0.64 (centos7.1 客户端)
共享文件的目录用户为:web(uid:1000,gid:1000)

一、安装

yum -y install nfs-utils rpcbind

nfs 的配置文件 /etc/expots
共享目录赋予权限:chmod 755 /home/data
vim /etc/exports
/home/data 192.168.0.0/24(rw,async,insecure,anonuid=1000,anongid=1000,no_root_squash)

二、使配置生效

exportfs -rv

配置文件说明:

/opt/test 为共享目录

  • 192.168.1.0/24 可以为一个网段,一个IP,也可以是域名,域名支持通配符 如: *.com
  • rw:read-write,可读写;
  • ro:read-only,只读;
  • sync:文件同时写入硬盘和内存;
  • async:文件暂存于内存,而不是直接写入内存;
  • no_root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的。
  • root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用nobody或nfsnobody身份;
  • all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;
  • anonuid:匿名用户的UID值
  • anongid:匿名用户的GID值。备注:其中anonuid=1000,anongid=1000,为此目录用户web的ID号,达到连接NFS用户权限一致。
  • defaults 使用默认的选项。默认选项为rw、suid、dev、exec、auto nouser与async。
  • atime 每次存取都更新inode的存取时间,默认设置,取消选项为noatime。
  • noatime 每次存取时不更新inode的存取时间。
  • dev 可读文件系统上的字符或块设备,取消选项为nodev。
  • nodev 不读文件系统上的字符或块设备。
  • exec 可执行二进制文件,取消选项为noexec。
  • noexec 无法执行二进制文件。
  • auto 必须在/etc/fstab文件中指定此选项。执行-a参数时,会加载设置为auto的设备,取消选取为noauto。
  • noauto 无法使用auto加载。
  • suid 启动set-user-identifier设置用户ID与set-group-identifer设置组ID设置位,取消选项为nosuid。
  • nosuid 关闭set-user-identifier设置用户ID与set-group-identifer设置组ID设置位。
  • user 普通用户可以执行加载操作。
  • nouser 普通用户无法执行加载操作,默认设置。
  • remount 重新加载设备。通常用于改变设备的设置状态。
  • rsize 读取数据缓冲大小,默认设置1024。–影响性能
  • wsize 写入数据缓冲大小,默认设置1024。
  • fg 以前台形式执行挂载操作,默认设置。在挂载失败时会影响正常操作响应。
  • bg 以后台形式执行挂载操作。
  • hard 硬式挂载,默认设置。如果与服务器通讯失败,让试图访问它的操作被阻塞,直到服务器恢复为止。
  • soft 软式挂载。服务器通讯失败,让试图访问它的操作失败,返回一条出错消息。这项功能对于避免进程挂在无关紧要的安装操作上来说非常有用。
  • retrans=n 指定在以软方式安装的文件系统上,在返回一条出错消息之前重复发出请求的次数。
  • nointr 不允许用户中断,默认设置。
  • intr 允许用户中断被阻塞的操作并且让它们返回一条出错消息。
  • timeo=n 设置请求的超时时间以十分之一秒为单位。
  • tcp 传输默认使用udp,可能出现不稳定,使用proto=tcp更改传输协议。客户端参考mountproto=netid

(以上内容:参考:man nfs)

三、启动nfs

systemctl enable rpcbind
systemctl start rpcbind
systemctl enable nfs-server
systemctl start nfs-server

确认NFS服务器启动成功:

rpcinfo -p
查看具体目录挂载权限
cat /var/lib/nfs/etab

四、客户端挂载:

1、linux客户端挂载:

在从机上安装NFS 客户端

首先是安裝nfs,然后启动rpcbind服务

systemctl enable rpcbind.service

systemctl start rpcbind.service

注意:客户端不需要启动nfs服务

检查 NFS 服务器端是否有目录共享:

showmount -e nfs服务器的IP
showmount -e 192.168.0.63     

客户端挂载#开机自动挂载

vim /etc/fstab  
192.168.0.63:/home/data    /home/data     nfs4 rw,hard,intr,proto=tcp,port=2049,noauto    0  0
手工挂载:
mount -t nfs 192.168.0.63:/home/data /home/data
#查看是否挂载成功。
df -h 
NFS默认是用UDP协议,换成TCP协议达到稳定传输目的:
mount -t nfs 192.168.0.63:/home/data /home/data -o proto=tcp -o nolock

2、windows客户端挂载:

  • Win7自带的NFS客户端可以在“控制面板”->“程序”->“WIndows 功能”找到->nfs-安装。

  • 由于自带的客户端功能少,缺少用户名映射,功能,所以必然会遇到权限的问题。所以需要自行配置权限问题

获取nfs server 用户web的gid和uid,并记录uid和gid,当前为:1000

打开注册表编辑器,找到HKEY_LOCAL_MACHINESOFTWAREMicrosoftClientForNFSCurrentVersionDefault,添加两个REG_DWORD值,填上uid和gid(10进制)完成后重启电脑

注册表导出是如下格式 :

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftClientForNFSCurrentVersionDefault]
"AnonymousGid"=dword:000003e8
"AnonymousUid"=dword:000003e8
  • 挂载到Z盘
mount -o anon mtype=soft lang=ansi  \192.168.0.63homedata  Z:

事项:一定要用软装载模式(mtype=soft),防止资源管理器停止响应,不能用utf-8

参考:http://nfs.sourceforge.net/nfs-howto/index.html

Nginx负载均衡NFS配置

Nginx配置

首先在两台服务器上部署同一个项目,例如下:
测试网站节点1: http://192.168.168.61/nfstest/
测试网站节点2: http://192.168.64.145/nfstest/

在主站进行nginx配置

upstream nfstest {
    server 192.168.64.145:9575 weight=5;
    server 192.168.168.61:80 weight=5; 
    fair;                           
}

现在负载均衡初步完成了。upstream按照轮询(默认)方式进行负载,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。虽然这种方式简便、成本低廉。但缺点是:可靠性低和负载分配不均衡。适用于图片服务器集群和纯静态页面服务器集群。

upstream还有其它的分配策略,分别如下:

weight(权重)

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。如下所示,10.0.0.88的访问比率要比10.0.0.77的访问比率高一倍。

upstream linuxidc{ 
      server 10.0.0.77 weight=5; 
      server 10.0.0.88 weight=10; 
}

ip_hash(访问ip)

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

upstream favresin{ 
      ip_hash; 
      server 10.0.0.10:8080; 
      server 10.0.0.11:8080; 
}

fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。与weight分配策略类似。

 upstream favresin{      
      server 10.0.0.10:8080; 
      server 10.0.0.11:8080; 
      fair; 
}

url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
注意:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。

 upstream resinserver{ 
      server 10.0.0.10:7777; 
      server 10.0.0.11:8888; 
      hash $request_uri; 
      hash_method crc32; 
}

upstream还可以为每个设备设置状态值,这些状态值的含义分别如下:

  • down 表示单前的server暂时不参与负载.
  • weight 默认为1.weight越大,负载的权重就越大。
  • max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误.
  • fail_timeout : max_fails次失败后,暂停的时间。
  • backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
upstream bakend{ #定义负载均衡设备的Ip及设备状态 
      ip_hash; 
      server 10.0.0.11:9090 down; 
      server 10.0.0.11:8080 weight=2; 
      server 10.0.0.11:6060; 
      server 10.0.0.11:7070 backup; 
}

NFS配置

环境:
两台服务器之间能正常通信
192.168.64.145 A服务器(文件实际保存)
192.168.168.61 B服务器

一、A服务器配置

1、安装NFS

使用rpm -qa | grep nfs 与 rpm -qa | grep rpcbind 可以查看是否有安装。
在CentOS内可以使用『yum install nfs-utils 』来安装。

2、设置服务机上的共享目录

  [root@www ~]# vi /etc/exports 
  /chroot/www/nfstest/WebContent/source 192.168.168.61(rw)
  #为192.168.168.61读写操作source目录权限
  /chroot/www/nfstest/WebContent/source *(rw,no_root_squash) 
  #任何人都可以应用source目录

3、启动NFS

设定文档后,开始启动, NFS启动之前需要先启动rpcbind才行。

  #如果rpcbind本来就已经在执行了,那就不需要启动啊!
  [root@www ~]# /etc/init.d/rpcbind start 
  #启动nfs
  [root@www ~]# /etc/init.d/nfs start 
  #启动nfslock
  [root@www ~]# /etc/init.d/nfslock start 
  [root@www ~]# chkconfig rpcbind on 
  [root@www ~]# chkconfig nfs on 
  [root@www ~]# chkconfig nfslock on

4、NFS 的连线观察

[root@www ~]# showmount [-ae] [hostname|IP]
选项与参数:

-a :显示目前主机与用户端的NFS 连线分享的状态;
-e :显示某部主机的/etc/exports 所分享的目录资料。

显示出刚刚所设定好的相关exports分享目录资讯

  [root@iZuf6ixy03u72vzno4jsiuZ ~]# showmount -e localhost
  Export list for localhost:
  /chroot/www/nfstest/source (everyone)
  /tmp                       (everyone)

二、B服务器配置

1.启动必备的服务
若没有启动才启动,有启动则保持原样不动

[root@clientlinux ~]# /etc/init.d/rpcbind start 
[root@clientlinux ~]# /etc/init.d/nfslock start 

2.查询A服务器提供哪些资源供使用

[root@jstu565zbb65jg ~]# showmount -e 192.168.64.145
Export list for 192.168.64.145:
/chroot/www/nfstest/source (everyone)<==这是等一下要挂载的目录
/tmp
                       (everyone)

3.建立挂载点

[root@clientlinux ~]# mkdir -p /chroot/www/nfstest/source 
[root@clientlinux ~]# mount -t nfs 192.168.64.145:/chroot/www/nfstest/source  /chroot/www/nfstest/source

4.卸载挂载点

[root@clientlinux ~]# umount /chroot/www/nfstest/source

推荐文档:
http://linux.vbird.org/linux_server/0330nfs.php#nfsserver_need

Linux NFS共享文件系统安装配置

一、NFS服务简介

NFS 是Network File System的缩写,即网络文件系统。一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布。功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。

NFS 的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,容许不同硬件及操作系统的系统共同进行文件的分享。

NFS在文件传送或信息传送过程中依赖于RPC协议。RPC,远程过程调用 (Remote Procedure Call) 是能使客户端执行其他系统中程序的一种机制。NFS本身是没有提供信息传输的协议和功能的,但NFS却能让我们通过网络进行资料的分享,这是因为NFS使用了一些其它的传输协议。而这些传输协议用到这个RPC功能的。可以说NFS本身就是使用RPC的一个程序。或者说NFS也是一个RPC SERVER。所以只要用到NFS的地方都要启动RPC服务,不论是NFS SERVER或者NFS CLIENT。这样SERVER和CLIENT才能通过RPC来实现PROGRAM PORT的对应。可以这么理解RPC和NFS的关系:NFS是一个文件系统,而RPC是负责负责信息的传输。

二、系统环境

系统平台:CentOS release 6.6
NFS Server IP:192.168.11.100

NFS Client IP:192.168.11.110
防火墙已关闭/iptables
SELINUX=disabled

三、安装NFS服务

NFS的安装是非常简单的,只需要两个软件包即可,而且在通常情况下,是作为系统的默认包安装的。
nfs-utils-* :包括基本的NFS命令与监控程序
rpcbind-* :支持安全NFS RPC服务的连接

1、查看系统是否已安装NFS

未分类

2、如果没有安装NFS软件包,则可以手动安装

# yum -y install nfs-utils rpcbind

3、安装完成后启动服务。

 注:启动时要先启动rpcbind在启动nfs

未分类

4、停止服务时也要先停止nfs在停止rpcbind

四、NFS配置文件

NFS的常用目录

  • /etc/exports NFS服务的主要配置文件

  • /usr/sbin/exportfs NFS服务的管理命令

  • /usr/sbin/showmount 客户端的查看命令

  • /var/lib/nfs/etab 记录NFS分享出来的目录的完整权限设定值

  • /var/lib/nfs/xtab 记录曾经登录过的客户端信息

4.1、NFS服务的配置文件为 /etc/exports,这个文件是NFS的主要配置文件,不过系统并没有默认值,所以这个文件不一定会存在,可能要使用vim手动建立,然后在文件里面写入配置内容。
/etc/exports文件内容格式:

[客户端1 选项(访问权限,用户映射,其他)] [客户端2 选项(访问权限,用户映射,其他)]

例:

vim /etc/exports

/home/data 192.168.11.0/24(rw,sync,no_root_squash)

4.2、常用配置项说明

访问权限选项
设置输出目录只读:ro
设置输出目录读写:rw

用户映射选项

  • all_squash:将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody);

  • no_all_squash:与all_squash取反(默认设置);

  • root_squash:将root用户及所属组都映射为匿名用户或用户组(默认设置);

  • no_root_squash:与rootsquash取反;

  • anonuid=xxx:将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx);

  • anongid=xxx:将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GID=xxx);

其它选项

  • secure:限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);

  • insecure:允许客户端从大于1024的tcp/ip端口连接服务器;

  • sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;

  • async:将数据先保存在内存缓冲区中,必要时才写入磁盘;

  • wdelay:检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置);

  • no_wdelay:若有写操作则立即执行,应与sync配合使用;

  • subtree:若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);

  • no_subtree:即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;

五、重启服务

 修改过配置文件后需要重启相关服务
#service rpcbind resatrt
#service nfs restart

六、客户端配置

6.1、客户端可通过showmount -e IP来查看NFS共享状态

未分类

6.2、客户端通过mount挂载

未分类

6.3、客户端取消挂载

umount /home/data
注:如遇到umount.nfs: /home/data: device is busy可使用-l参数来取消挂载
umount -l /home/data

6.4、挂载完成后,客户端和服务端做的修改都会及时同步

七、配置自动挂载nfs文件系统

 vim /etc/fstab

未分类

保存重启

八、有关权限的介绍

  1. 客户端连接时候,对普通用户的检查

    a. 如果明确设定了普通用户被压缩的身份,那么此时客户端用户的身份转换为指定用户;

    b. 如果NFS server上面有同名用户,那么此时客户端登录账户的身份转换为NFS server上面的同名用户;

    c. 如果没有明确指定,也没有同名用户,那么此时 用户身份被压缩成nfsnobody;

  2. 客户端连接的时候,对root的检查

    a. 如果设置no_root_squash,那么此时root用户的身份被压缩为NFS server上面的root;

    b. 如果设置了all_squash、anonuid、anongid,此时root 身份被压缩为指定用户;

    c. 如果没有明确指定,此时root用户被压缩为nfsnobody;

    d. 如果同时指定no_root_squash与all_squash 用户将被压缩为 nfsnobody,如果设置了anonuid、anongid将被压缩到所指定的用户与组;

九、相关命令

1、exportfs
如果我们在启动了NFS之后又修改了/etc/exports,是不是还要重新启动nfs呢?这个时候我们就可以用exportfs 命令来使改动立刻生效,该命令格式如下:

  • exportfs [-aruv]

  • -a 全部挂载或卸载 /etc/exports中的内容

  • -r 重新读取/etc/exports 中的信息 ,并同步更新/etc/exports、/var/lib/nfs/xtab

  • -u 卸载单一目录(和-a一起使用为卸载所有/etc/exports文件中的目录)

  • -v 在export的时候,将详细的信息输出到屏幕上。

具体例子:

  • exportfs -au 卸载所有共享目录

  • exportfs -rv 重新共享所有目录并输出详细信息

2、nfsstat
查看NFS的运行状态,对于调整NFS的运行有很大帮助。

3、rpcinfo
查看rpc执行信息,可以用于检测rpc运行情况的工具,利用rpcinfo -p 可以查看出RPC开启的端口所提供的程序有哪些。

4、showmount

  • -a 显示已经于客户端连接上的目录信息

  • -e IP或者hostname 显示此IP地址分享出来的目录

5、netstat

  • 可以查看出nfs服务开启的端口,其中nfs 开启的是2049,portmap 开启的是111,其余则是rpc开启的。

  • 最后注意两点,虽然通过权限设置可以让普通用户访问,但是挂载的时候默认情况下只有root可以去挂载,普通用户可以执行sudo。

  • NFS server 关机的时候一点要确保NFS服务关闭,没有客户端处于连接状态!通过showmount -a 可以查看,如果有的话用kill killall pkill 来结束,(-9 强制结束)

使用Nagios中监控进程最大线程数

最近在刚好一些业务经常把线程跑满,导致服务器资源用完,所以就写了一个脚本用于Nagios下相关进程的最大线程数的监控,Unix的服务器上最大的线程数默认的是1024,当然在业务繁忙的服务器中这样肯定是不够用的,当然在实际生产环境中做初始化调优时一般都会有做过修改,如开启打开文件的最大句柄数等等,一般情况下我们都是修改/etc/security/limits.conf文件,但是要修改最大线程数就要修改/etc/security/limits.d/90-nproc.conf文件了,修改就和修改limits.conf文件文件的方式一样,在此就不做过多的解释,我一般把所有用户的最大的线程数都调大

*          soft    nproc     65535

在调整好后线程数的预警值可以根据实际情况调整,脚本实现也很简单,如下:

#!/bin/bash
#check_pstree.sh
#Used for pstree process monitoring
#writer jim
#history 2017.07.01

# Nagios 返回值
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
#对传递进来的参数判断
if [ $# -lt 1 ];then
    echo "Please enter the process string"
    echo "ex> $0 java"
    exit $STATE_UNKNOWN
fi

if [ $# -gt 1 ]; then
        echo "The input parameters are too much"
    echo "ex> $0 java"
    exit $STATE_UNKNOWN
fi

reg_name=$1
process_pid=$(ps -ef | grep "$reg_name " | grep -v grep | awk '{print $2}')
declare -i max_process_num=$(ulimit -an | grep "max user processes" | awk '{print $5}')
declare -i warning_num=$max_process_num/2
#在此预警值取最大线程数的50%,具体可以根据实际生产环境修改
pstree_num=$(pstree -p $process_pid | wc -l)

if [ $pstree_num -le $warning_num ];then
        echo "$reg_name pstree number is:$pstree_num;warning_num is:$warning_num;max user processes is:$max_process_num,OK"
        exit $STATE_OK
else 
        echo "error!!!The number of pstree is too much.the number is:$pstree_num"
        exit $STATE_CRITICAL
fi

当然在这个脚本也可以修改后用cron任务中做定时检查,不过在Nagios中不知为何线程数的值在Nagios的监控页面下显示总有异常,不过直接执行是没有问题的。

Ganglia监控Hadoop集群 使用Nagios发送告警邮件

基本介绍

Ganglia:是UC Berkeley发起的一个开源集群监视项目,设计用于测量数以千计的节点。Ganglia的核心包含gmond、gmetad以及一个Web前端。主要是用来监控系统性能,如:cpu 、mem、硬盘利用率, I/O负载、网络流量情况、系统负载等,通过曲线很容易见到每个节点的工作状态,对合理调整、分配系统资源,提高系统整体性能起到重要作用。
更重要的是,HDFS、YARN、HBase等已经支持其守护进程的资源情况发送给Ganglia进行监控。

Nagios:是一款开源的电脑系统和网络监视工具,能有效监控Windows、Linux和Unix的主机状态,交换机路由器等网络设置,打印机等。尤其有用的是,在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员,在状态恢复后发出正常的邮件或短信通知。

我们这次的架构设计:

  1. Ganglia的优势在于监控数据的实时性和丰富的图形化界面,同时对Mobile端支持的很好,但是在出现问题的时候报警提示功能,相对较弱。

  2. Nagios的优势在于出现问题和问题恢复时可以提供强大的报警提示功能,但是在实时监控和图形化展示上功能较弱,对大规模集群支持较差。

  3. 要对数据平台中支持的Hadoop集群(HDFS、YARN)对资源的使用情况进行监控。

所以我们将3者结合起来,架构如下:

监控

相关版本:Ubuntu 16.04 LTS、Ganglia 3.6.1、Nagios 4.1.1、Hadoop 2.7.3

部署Ganglia:

在需要进行Web展示的节点上安装:

sudo apt-get update
sudo apt install apache2 php libapache2-mod-php 
sudo apt-get install rrdtool
sudo apt-get install gmetad ganglia-webfrontend
#过程中出现apache2重启的对话框,选择yes即可

在需要被监控的节点上安装:

sudo apt-get update
sudo apt install php libapache2-mod-php 
sudo apt-get install ganglia-monitor
#过程中出现apache2重启的对话框,选择yes即可

下述操作过程,在主节点上进行:

#复制 Ganglia webfrontend Apache 配置:
sudo cp /etc/ganglia-webfrontend/apache.conf /etc/apache2/sites-enabled/ganglia.conf

#编辑gmetad配置文件 
sudo vi /etc/ganglia/gmetad.conf
#更改数据源 data_source “my cluster” localhost 修改为:
data_source "bigdata cluster" 10  wl1:8649 wl2:8649 wl3:8649
setuid_username "nobody"
gridname "bigdata cluster"
case_sensitive_hostnames 1
all_trusted on

#主节点上执行:
sudo ln -s /usr/share/ganglia-webfrontend/ /var/www/ganglia

下述操作过程,在所有被监控节点上进行:

#编辑gmond配置文件 
sudo vi /etc/ganglia/gmond.conf
globals {
  daemonize = yes
  setuid = yes
  user = ganglia
  debug_level = 0
  max_udp_msg_len = 1472
  mute = no
  deaf = no
  host_dmax = 0 /*secs */
  cleanup_threshold = 300 /*secs */
  gexec = no
  send_metadata_interval = 10
}
/* If a cluster attribute is specified, then all gmond hosts are wrapped inside
 * of a <CLUSTER> tag.  If you do not specify a cluster tag, then all <HOSTS> will
 * NOT be wrapped inside of a <CLUSTER> tag. */
cluster {
  name = "bigdata cluster"
  owner = "ganglia"
  latlong = "unspecified"
  url = "unspecified"
}

/* The host section describes attributes of the host, like the location */
host {
  location = “wl1"  #每个节点写自己的主机名
}

/* Feel free to specify as many udp_send_channels as you like.  Gmond
   used to only support having a single channel */
udp_send_channel {
  #mcast_join = 239.2.11.71
  host = wl1  #每个节点都指向gmetad主机
  port = 8649
  ttl = 1
}

/* You can specify as many udp_recv_channels as you like as well. */
udp_recv_channel {
  #mcast_join = 239.2.11.71
  port = 8649
  #bind = 239.2.11.71
}


/* You can specify as many tcp_accept_channels as you like to share
   an xml description of the state of the cluster */
tcp_accept_channel {
  port = 8649
}

收集Hadoop集群的HDFS、YARN metric源:

下述操作过程,在所有Hadoop集群节点上进行:

#编辑hadoop-metrics2.properties
vi hadoop-2.7.3/etc/hadoop/hadoop-metrics2.properties
#注释掉所有原来的内容,增加如下内容:
*.sink.ganglia.class=org.apache.hadoop.metrics2.sink.ganglia.GangliaSink31
*.sink.ganglia.period=10

*.sink.ganglia.slope=jvm.metrics.gcCount=zero,jvm.metrics.memHeapUsedM=both
*.sink.ganglia.dmax=jvm.metrics.threadsBlocked=70,jvm.metrics.memHeapUsedM=40

namenode.sink.ganglia.servers=wl1:8649
resourcemanager.sink.ganglia.servers=wl1:8649

datanode.sink.ganglia.servers=wl1:8649
nodemanager.sink.ganglia.servers=wl1:8649

jobhistoryserver.sink.ganglia.servers=wl1:8649

maptask.sink.ganglia.servers=wl1:8649
reducetask.sink.ganglia.servers=wl1:8649

重启Hadoop集群、重启gmond、gmetad、gweb:

hadoop-2.7.3/sbin/stop-all.sh
hadoop-2.7.3/sbin/start-all.sh
sudo /etc/init.d/ganglia-monitor restart (所有节点) gmond服务 
sudo /etc/init.d/gmetad restart    (gmetad节点)   gmetad服务
sudo /etc/init.d/apache2 restart  (gweb节点)    web服务(包含gweb服务)

然后在安装了gweb的节点上使用主机ip/ganglia即可登录Web:

监控

选择某个Node具体观察,可以看到已经收集到了HDFS和YARN的度量数据:

监控

监控

选择Mobile标签页,可以看到对移动终端的展示支持的很好:

监控

部署Nagios:

  • 为了Nagios能正常发送告警邮件,先要安装sendmail工具:
sudo apt-get install sendmail  
sudo apt-get install sendmail-cf
sudo apt-get install mailutils  
sudo apt-get install sharutils
#终端输入命令:
ps aux |grep sendmail
#输出如下:说明sendmail 已经安装成功并启动了
root     20978  0.0  0.3   8300  1940 ?        Ss   06:34   0:00 sendmail: MTA: accepting connections          
root     21711  0.0  0.1   3008   776 pts/0    S+   06:51   0:00 grep sendmail
  • 配置sendmail:
#打开sendmail的配置文件 /etc/mail/sendmail.mc
vi  /etc/mail/sendmail.mc
#找到如下行:
DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp, Addr=127.0.0.1')dnl
#将Addr=127.0.0.1修改为Addr=0.0.0.0,表明可以连接到任何服务器。
DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp, Addr=0.0.0.0')dnl

#生成新的配置文件:
cd /etc/mail  
mv sendmail.cf sendmail.cf~      #做一个备份  
m4 sendmail.mc &gt; sendmail.cf  #&gt;的左右有空格
#修改sendmail.cf
vi /etc/mail/sendmail.cf
#新增
Dj$w. #注意最后面有一个点

#修改hosts,否则发送邮件的过程会非常慢,因为sendmail
#以wl1作为域名加到主机名wl1后组成完整的长名wl1.wl1来访问,
#会提示找不到域名
vi /etc/hosts
x.x.x.x       wl1 wl1.localdomain wl1.wl1
#重启sendmail服务:
service sendmail restart
#测试发送邮件,看看能否收得到:
echo "test" | mail -s test [email protected]
  • 安装Nagios:

参考Ubuntu 16.04 安装 Nagios Core:

Ubuntu 16.04 安装 Nagios Core

其中下载Nagios插件那一步时,nagios-plugins-2.1.1官网下载太慢,先从下面的链接下载好,然后编译安装

nagios-plugins-2.1.1下载:
http://download.csdn.net/download/u014722463/9288011

使用http://主机IP/nagios/ 登录,需要输入安装时设置的用户名nagiosadmin及其密码,然后就可以看到主页了:

监控

  • 主要说一下如何用Nagios监控Ganglia数据,并根据阀值发出告警:
#新生成一个监控ganglia的插件check_ganglia.py
cd /usr/local/nagios/libexec
vi check_ganglia.py #内容如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
import getopt
import socket
import xml.parsers.expat

class GParser:
  def __init__(self, host, metric):
    self.inhost =0
    self.inmetric = 0
    self.value = None
    self.host = host
    self.metric = metric

  def parse(self, file):
    p = xml.parsers.expat.ParserCreate()
    p.StartElementHandler = parser.start_element
    p.EndElementHandler = parser.end_element
    p.ParseFile(file)
    if self.value == None:
      raise Exception('Host/value not found')
    return float(self.value)

  def start_element(self, name, attrs):
    if name == "HOST":
      if attrs["NAME"]==self.host:
        self.inhost=1
    elif self.inhost==1 and name == "METRIC" and attrs["NAME"]==self.metric:
      self.value=attrs["VAL"]

  def end_element(self, name):
    if name == "HOST" and self.inhost==1:
      self.inhost=0

def usage():
 print """Usage: check_ganglia 
-h|--host= -m|--metric= -w|--warning= 
-c|--critical= [-o|--opposite=] [-s|--server=] [-p|--port=] """
 sys.exit(3)

if __name__ == "__main__":
##############################################################
 ganglia_host = 'x.x.x.x'  #修改为你的gmetad主机的ip
 ganglia_port = 8651
 host = None
 metric = None
 warning = None
 critical = None
 opposite = 0  ##增加一个参数,表示设定值取反,也就是当实际值小于等于设定值报警

 try:
   options, args = getopt.getopt(sys.argv[1:],
     "h:m:w:c:o:s:p:",
     ["host=", "metric=", "warning=","critical=","opposite=", "server=","port="],
     )
 except getopt.GetoptError, err:
   print "check_gmond:", str(err)
   usage()
   sys.exit(3)

 for o, a in options:
   if o in ("-h", "--host"):
      host = a
   elif o in ("-m", "--metric"):
      metric = a
   elif o in ("-w", "--warning"):
      warning = float(a)
   elif o in ("-c", "--critical"):
      critical = float(a)
   elif o in ("-o", "--opposite"):
      opposite = int(a)
   elif o in ("-p", "--port"):
      ganglia_port = int(a)
   elif o in ("-s", "--server"):
      ganglia_host = a


 if critical == None or warning == None or metric == None or host ==None:
   usage()
   sys.exit(3)

 try:
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.connect((ganglia_host,ganglia_port))
   parser = GParser(host, metric)
   value = parser.parse(s.makefile("r"))
   s.close()
 except Exception, err:
   #import pdb
   #pdb.set_trace()
   print "CHECKGANGLIA UNKNOWN: Error while getting value"%s"" % (err)
   sys.exit(3)

 if opposite == 1: ###根据传入参数做判断,等于1时,表示取反,等于0,不取反
      if value &lt;= critical:
        print &quot;CHECKGANGLIA CRITICAL: %s is %.2f&quot; % (metric, value)
        sys.exit(2)
      elif value = critical:
        print "CHECKGANGLIA CRITICAL: %s is %.2f" % (metric, value)
        sys.exit(2)
      elif value &gt;= warning:
          print "CHECKGANGLIA WARNING: %sis %.2f" % (metric, value)
          sys.exit(1)
      else:
        print "CHECKGANGLIA OK: %s is %.2f" % (metric, value)
        sys.exit(0)

修改该脚本为可读写、操作权限:

 chmod 755 check_ganglia.py

在如下目录,新建文件:(注意啊,里面最好不要有注释,可能会引起功能不可用,原因我没时间去分析)

#在/usr/local/nagios/etc/objects/下新建一个services.cfg
cd /usr/local/nagios/etc/objects/
vi services.cfg #内容如下:
define host {
    use linux-server
    host_name wl1
    address   x.x.x.1
}

define host {
    use linux-server
    host_name wl2
    address   x.x.x.2
}

define host {
    use linux-server
    host_name wl3
    address   x.x.x.3
}

define hostgroup {
    hostgroup_name ganglia-servers
    alias   nagios server
    members *
}

define servicegroup {
  servicegroup_name ganglia-metrics
  alias Ganglia Metrics
}

define command {
  command_name check_ganglia
  command_line $USER1$/check_ganglia.py -h $HOSTNAME$ -m $ARG1$ -w $ARG2$ -c $ARG3$ -o $ARG4$
}

define service {
    use generic-service
    name ganglia-service
    hostgroup_name ganglia-servers
    service_groups ganglia-metrics
    notifications_enabled 1
    notification_interval 10
    register  0
}

define service{
        use                             ganglia-service
        service_description             内存空闲
        check_command                   check_ganglia!mem_free!200!50!1
        contact_groups admins
}

define service{
        use                             ganglia-service
        service_description             load_one
        check_command                   check_ganglia!load_one!4!5!0
        contact_groups admins
}
define service{
        use                             ganglia-service
        service_description             disc_free
        check_command                   check_ganglia!disk_free!40!50!0
        contact_groups admins
}
define service{
        use                             ganglia-service
        service_description             yarn.NodeManagerMetrics.AvailableGB
        check_command                   check_ganglia!yarn.NodeManagerMetrics.AvailableGB!8!4!1
        contact_groups admins
}

需要注意的是,这个services.cfg文件就是用来你的Nagios自动去Ganglia里面取数据的,里面定义的需要关注的Ganglia的项目越多,Nagios里面显示的越多,我这里仅仅是一个范本,只举例了几个简单的数据,如果有需要,请自行增加。

修改该配置文件为可读写、操作权限:

chown nagios:nagios services.cfg
chmod 664 services.cfg

修改Nagios主配置文件:

vi /usr/local/nagios/etc/nagios.cfg
#cfg_file=/usr/local/nagios/etc/objects/localhost.cfg

#add by wangliang for ganglia
cfg_file=/usr/local/nagios/etc/objects/services.cfg

修改和发送告警邮件相关的配置:

vi /usr/local/nagios/etc/objects/commands.cfg
#将其中的/bin/mail替换为mail
# 'notify-host-by-email' command definition
define command{
        command_name    notify-host-by-email
        command_line    /usr/bin/printf "%b" "***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nHost: $HOSTNAME$nState: $HOSTSTATE$nAddress: $HOSTADDRESS$nInfo: $HOSTOUTPUT$nnDate/Time: $LONGDATETIME$n" | mail -s "** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$
        }

# 'notify-service-by-email' command definition
define command{
        command_name    notify-service-by-email
        command_line    /usr/bin/printf "%b" "***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nnService: $SERVICEDESC$nHost: $HOSTALIAS$nAddress: $HOSTADDRESS$nState: $SERVICESTATE$nnDate/Time: $LONGDATETIME$nnAdditional Info:nn$SERVICEOUTPUT$n" | mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$
        }

#修改发送的邮件地址和收件人:
vi /usr/local/nagios/etc/objects/contacts.cfg
###############################################################################
# CONTACTS.CFG - SAMPLE CONTACT/CONTACTGROUP DEFINITIONS
#
#
# NOTES: This config file provides you with some example contact and contact
#        group definitions that you can reference in host and service
#        definitions.
#
#        You don't need to keep these definitions in a separate file from your
#        other object definitions.  This has been done just to make things
#        easier to understand.
#
###############################################################################



###############################################################################
###############################################################################
#
# CONTACTS
#
###############################################################################
###############################################################################

# Just one contact defined by default - the Nagios admin (that's you)
# This contact definition inherits a lot of default values from the 'generic-contact'
# template which is defined elsewhere.

define contact{
        contact_name                    nagiosadmin        ; Short name of user
    use                generic-contact        ; Inherit default values from generic-contact template (defined above)
        alias                           Nagios Admin        ; Full name of user

        email                           [email protected]    ; &lt;&lt;***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
        }

define contact{
        contact_name                    nagiosadmin2           ; Short name of user
        use                             generic-contact         ; Inherit default values from generic-contact template (defined above)
        alias                           Nagios Admin2            ; Full name of user

        email                           [email protected]     ; &lt;&lt;***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
        }

define contact{
        contact_name                    nagiosadmin3             ; Short name of user
        use                             generic-contact         ; Inherit default values from generic-contact template (defined above)
        alias                           Nagios Admin3            ; Full name of user

        email                          [email protected]     ; &lt;&lt;***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
        }
###############################################################################
###############################################################################
#
# CONTACT GROUPS
#
###############################################################################
###############################################################################

# We only have one contact in this simple configuration file, so there is
# no need to create more than one contact group.

define contactgroup{
        contactgroup_name       admins
        alias                   Nagios Administrators
        members            *
        }

利用如下命令,判断修改是否成功:

/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
Total Warnings: 0
Total Errors:   0

按顺序重启相关服务:

sudo /etc/init.d/ganglia-monitor restart  (所有节点)
sudo /etc/init.d/gmetad restart       (gmetad节点)
sudo /etc/init.d/apache2 restart      (gweb节点)
service nagios restart    (nagios节点)
service sendmail restart  (nagios节点)

最后的效果图如下:
(nagios采集数据的过程略慢,有的时候会短暂的显示service status是unknown或者pending,过一会就会好的,不用着急)

监控

收到的邮件告警的图示:

监控

下一步工作是把这几个组件做成docker镜像,用k8s调度,具体过程不在详述,参考我前面的文章就可以完成。

需要注意的地方:

  1. 如果你想在Ganglia Web上显示各节点的主机名,则需要提前在
    gmetad节点的/etc/hosts里面配置好ip和hostname的映射关系,ganglia会在收到各节点数据时,先按照ip查找hosts里面的hostname,如果没有,则rrd中就按照ip存储;如果有,则rrd中按照查到的名字存储,Web显示数据时,是根据rrd中的记录的名字或者Ip来显示的。

  2. 如果你以前是按照ip显示,后来想改成hostname,则先要把rrd的内容清空,反之亦然。

  3. 记得rrd的权限是:
    drwxr-xr-x nobody nogroup rrds/
    否则网页会提示拒绝连接

  4. 由于sendmail使用的是smtp协议,而有的公司用的是esmtp协议的服务器,所以用本文描述的sendmail发送告警邮件可能邮箱会收不到。后来我使用了sendEmail的工具,它可以使用esmtp协议,如下格式:sendEmail -f [email protected] -t [email protected] -s smtp.exmail.qq.com -xu [email protected] -xp xxx -m “test”
    进行测试,就可以发送成功啦,
    安装很简单,参考此处:http://www.linuxidc.com/Linux/2011-12/49699.htm
    需要同步修改nagios的/usr/local/nagios/etc/objects/commands.cfg

define command{
        command_name    notify-host-by-email
        command_line    /usr/bin/printf &quot;%b&quot; &quot;***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nHost: $HOSTNAME$nState: $HOSTSTATE$nAddress: $HOSTADDRESS$nInfo: $HOSTOUTPUT$nnDate/Time: $LONGDATETIME$n&quot; | /usr/local/bin/sendEmail -f [email protected] -t $CONTACTEMAIL$ -s smtp.exmail.qq.com -u &quot;** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **&quot; -xu [email protected] -xp xxxx
        }

# 'notify-service-by-email' command definition
define command{
        command_name    notify-service-by-email
        command_line    /usr/bin/printf &quot;%b&quot; &quot;***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nnService: $SERVICEDESC$nHost: $HOSTALIAS$nAddress: $HOSTADDRESS$nState: $SERVICESTATE$nnDate/Time: $LONGDATETIME$nnAdditional Info:nn$SERVICEOUTPUT$n&quot; | /usr/local/bin/sendEmail -f [email protected] -t $CONTACTEMAIL$ -s smtp.exmail.qq.com -u &quot;** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **&quot; -xu [email protected] -xp xxx
        }

Linux CentOS 7.2 MySQL的root密码忘记时重置方法

验证环境:

[root@~~/]# rpm -qa | grep mysql
mysql-5.6.28-1.el6.x86_64
[root@~~/]# lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.2.1511 (Core)
Release:        7.2.1511
Codename:       Core
[root@~~/]# uname -r
3.10.0-327.22.2.el7.x86_64

首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。
因为在重新设置mysql的root密码的期间,MySQL数据库完全出于没有密码保护的状态下,其他的用户也可以任意地登录和修改MySQL的信息。可以采用将MySQL对外的端口封闭,并且停止Apache以及所有的用户进程的方法实现服务器的准安全状态。最安全的状态是到服务器的Console上面操作,并且拔掉网线。

修改MySQL的登录设置:

在[mysqld]的段中加上一句:skip-grant-tables
[root@~~/]# vi /etc/my.cnf
例如: 
[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
skip-grant-tables 
保存并且退出vi。

重新启动mysqld

[root@~~/]# /etc/init.d/mysqld restart 
Stopping MySQL: [ OK ] 
Starting MySQL: [ OK ]

登录并修改MySQL的root密码

[root@~~/]# mysql
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 1
Server version: 5.6.28-log Source distribution
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> use mysql;
mysql> update user set password=password("test") where user='root';
mysql> flush privileges;
mysql> exit; 
Bye

将MySQL的登录设置修改回来

将刚才在[mysqld]的段中加上的skip-grant-tables删除,保存并且退出vi;

[root@~~/]# vi /etc/my.cnf
保存并且退出vi。

再次重新启动mysqld

[root@~~/]# /etc/init.d/mysqld restart 
Stopping MySQL: [ OK ] 
Starting MySQL: [ OK ]

使用新的密码登录,正常登录

如果外网不能访问数据库,可以进行如下操作:

[root@~~/]# firewall-cmd --permanent --zone=public --add-port=3306/tcp  
success
[root@~~/]# firewall-cmd --reload
success

linux常用命令介绍

  1. 查看当前终端名:tty 或who am i

    查看当前所有登录的终端信息:who

    查看当前所有登录的终端的详细信息 w

  2. 编辑器

Gedit 只能在图形化界面编辑,不能远程编辑。

Nano 可以远程登陆后编辑

(开机后自动登录图形化界面:/etc/gdm/custom.conf

           [damon]

            AutomaticLoginEnable=True

       AutomaticLogin=root)

系统管理

修改登录前的信息 /etc/issue 完成后ctrl+x退出

系统管理

修改登陆后的信息 /etc/motd (佛祖保佑,永不死机:先在图形化界面安装光盘,然后把motd放在一个目录下,在终端敲rz(把物理机里的文件拷到虚拟机目录下

sz与此相反),找到motd文件,然后敲ls查看文件,如果有motd文件名说明拷贝成功,然后cp motd /etc/motd/(把etc下的motd 文件覆盖一下),敲y,然后cat /etc/motd就完成了。就会出现如图所示的效果:

系统管理

  • 内部命令与外部命令
    判断命令的类型: tupe +命令
    

系统管理

    显示所有启动的内部命令: enable

系统管理

统计启动的内部命令的个数:enable |wc -l

系统管理

  • Enable -n 显示被禁用的内部命令

  • Enable -n 命令名 禁用这个命令

  • Enable -n |wc -l 统计禁用的内部命令的个数

  • Enable -n command 仅用一个内部命令

  • alias 内部命令 > hsah >
    PATH > command not find

       Alias  显示当前已定义的别名
    

系统管理

Alias aliasname=’command[-x]
[….]’ 定义别名

Unlias aliname 取消定义别名

Unalias -a 取消所有的别名

(cp + -i 覆盖文件时才会提示,rm删除文件时也一样。)

  • Hwcolock 查看硬时间

  • Hwclock -s 将硬时间写入软时间(系统时间)

  • Hwclock -w 将软时间写入硬时间

  • Clock= hwclock

  • 修改时区

     Centos6    ln  -f /usr/share/zoneinfo /America/New _York/etc/localtime
    
                Ln -f /usr/share/zoneinfo
    

    /Asia/Shanghai/etc/localtime

     Centos7
    
                Timedatectl 查看当前时区
    

系统管理

                Timedatectl

list-timezone 查看所有的时区

    修改时区    Timedatectl

set-timezone America/New_York

                Timedatectl set-timezone

Asia/Shanghai

系统管理

  • Screen
      Screen 进入screen 名字以当前终端名.主机名前缀
    
      Screen
    

    -S screenname 创建会话

      Screen
    

    -ls 或–list 查看当前所有的screen

系统管理

      Screen

-r screenname 进入一个screen

       Ctrl +c 或exit退出screen

       Screen 恢复screen页面

       Screen +x screenname  加入会话

       Ctrl

+a同时按松手后按d 剥离会话

  • $的用法
        $变量名 引用变量的值
    
        $()或‘’引用命令执行的结果
    
        $[]运算
    
        ${变量名}或“$变量名”当变量名的起止不分明时,用来划定变量名的范围,同时引用变量。
    
  • {}的用法

    {a..z}表示引用指定范围的字母

    {1..9990}表示引用指定范围的数字

    {1,3,5}表示分别引用每一个字符

  • Tab

    补齐

    2tab 把根下所有的文件列出

    ~2tab 家目录下的所有文件列出

系统管理

 .2tab 当前目录下的所有文件列出,包含隐藏文件

 *2tab当前目录下的所有文件列出,不包含隐藏文件

 $2tab 显示当前所有的环境变量

系统管理

 =2tab=ls -A 显示上一级命令