使用fluentd实时收到nginx日志到mysql数据库

前言

本篇介绍如何使用fluentd把nginx的log日志读取,并且解析成为一个一个MySQL的字段,最后存储到mysql的数据库中。

环境

我用的是aws的ec2,操作系统是amazon定制的Amazon Linux AMI

安装fluentd

使用root用户

curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh

安装完毕后,在/usr/sbin/下会有td-agent , td-agent-gem ,td-agent-ui三个可执行文件。其中td-agent-gem用来安装之外的fluent的插件。

配置文件在/etc/td-agent/td-agent.conf

启动fluentd命令集合

/etc/init.d/td-agent start
/etc/init.d/td-agent stop
/etc/init.d/td-agent restart
/etc/init.d/td-agent status

log可以在/var/log/td-agent/td-agent.log查看

编辑fluentd配置文件

定义一个source,读取nginx的log文件

<source>
  @type tail
  path /tmp/nginx.log
  pos_file /var/log/td-agent/nginx.log.pos
  tag nginx.access
  format /^(?<remote>[^ ]*) - (?<user>[^ ]*) [(?<time>[^]]*)] "(?<method>S+)(?: +(?<path>[^"]*) +S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^"]*)" "(?<agent>[^"]*)" "(?<http_x_forwarded_for>[^"]*)" "(?<host>[^"]*)" "(?<country>[^"]*)" "(?<city>[^"]*)")?$/
  time_format %d/%b/%Y:%H:%M:%S %z
</source>

注意:format的地方需要根据自己的nginx的log的格式进行相应的调整

接下去定义一个写入到mysql的match。

<match nginx.access>
  @type mysql_bulk
  host your_host
  database your_db
  username your_username
  password your_password
  column_names remote,host,user,method,path,code,size,referer,agent,country,city,http_x_forwarded_for,log_time
  key_names remote,host,user,method,path,code,size,referer,agent,country,city,http_x_forwarded_for,${time}
  table nginx_access
  flush_interval 10s
</match>

附上mysql的建表语句

CREATE TABLE `nginx_access` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `remote` text,
  `host` text,
  `user` text,
  `method` text,
  `path` text,
  `code` text,
  `size` text,
  `referer` text,
  `agent` text,
  `country` text,
  `city` text,
  `http_x_forwarded_for` text,
  `log_time` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

安装mysql_bulk的插件

从https://github.com/tagomoris/fluent-plugin-mysql克隆下项目。由于我用的fluentd是0.12版本,所以对应的fluent-plugin-mysql的版本是v0.1.5,所以Git checkout v0.1.5。

进行gem build fluent-plugin-mysql.gemspec生成.gem文件。
然后用/usr/sbin/td-agent-gem install fluent-plugin-mysql-0.1.5.gem命令来安装插件。

如果安装插件失败的话,很大可能是没有mysql-devel。

mysql client is missing. You may need to 'apt-get install libmysqlclient-dev' or 'yum install mysql-devel', and try again.

所以先执行yum install mysql-devel。

[root@x fluent-plugin-mysql]# /usr/sbin/td-agent-gem install fluent-plugin-mysql-0.1.5.gem
Building native extensions.  This could take a while...
Successfully installed mysql2-0.4.9
Fetching: mysql2-cs-bind-0.0.6.gem (100%)
Successfully installed mysql2-cs-bind-0.0.6
Fetching: jsonpath-0.8.7.gem (100%)
Successfully installed jsonpath-0.8.7
Successfully installed fluent-plugin-mysql-0.1.5
Parsing documentation for mysql2-0.4.9
Installing ri documentation for mysql2-0.4.9
Parsing documentation for mysql2-cs-bind-0.0.6
Installing ri documentation for mysql2-cs-bind-0.0.6
Parsing documentation for jsonpath-0.8.7
Installing ri documentation for jsonpath-0.8.7
Parsing documentation for fluent-plugin-mysql-0.1.5
Installing ri documentation for fluent-plugin-mysql-0.1.5
Done installing documentation for mysql2, mysql2-cs-bind, jsonpath, fluent-plugin-mysql after 0 seconds
4 gems installed

结语

可能遇到的坑总结一下:

  • gem命令的时候,需要使用/usr/sbin/td-agent-gem,td-agent使用的是这个环境的gem依赖
  • ruby安装mysql的插件的时候,需要mysql-devel,否则会报错
  • nginx的log format可能根据自己的情况调整
  • source文件的tail需要该输入文件的目录权限是755

使用nginx ngx_http_referer_module模块配置防盗链

nginx referer简介

nginx模块ngx_http_referer_module通常用于阻挡来源非法的域名请求.我们应该牢记,伪装Referer头部是非常简单的事情,所以这个模块只能用于阻止大部分非法请求。我们应该记住,有些合法的请求是不会带referer来源头部的,所以有时候不要拒绝来源头部(referer)为空的请求.

图片防盗链配置示例如下

location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked *.91linux.org 91linux.org server_names ~.google. ~.baidu.;
    if ($invalid_referer) {
    return 403;
    #rewrite ^/ https://www.91linux.org/403.jpg;
    }
}

以上所有来至91linux.org和域名中包含google和baidu的站点都可以访问到当前站点的图片,如果来源域名不在这个列表中,那么$invalid_referer等于1,在if语句中返回一个403给用户,这样用户便会看到一个403的页面,如果使用下面的rewrite,那么盗链的图片都会显示403.jpg。如果用户直接在浏览器输入你的图片地址,那么图片显示正常,因为它符合none这个规则.

示例解析

第一行:

location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$

其中“gif|jpg|jpeg|png|bmp|swf”设置防盗链文件类型,自行修改,每个后缀用“|”符号分开!

第二行:

valid_referers none blocked *.91linux.org 91linux.org server_names ~.google. ~.baidu.;

就是白名单,允许文件链出的域名白名单,自行修改成您的域名! *.91linux.org这个指的是子域名,域名与域名之间使用空格隔开!baidu和google是搜索引擎。

第五行:

rewrite ^/ https://www.91linux.org/403.jpg;

这个图片是盗链返回的图片,也就是替换盗链网站所有盗链的图片。这个图片要放在没有设置防盗链的网站上,因为防盗链的作用,这个图片如果也放在防盗链网站上就会被当作防盗链显示不出来了,盗链者的网站所盗链图片会显示X符号;当然你也可以直接返回403

扩展

这样设置差不多就可以起到防盗链作用了,上面说了,这样并不是彻底地实现真正意义上的防盗链!

我们来看第三行:

valid_referers none blocked *.91linux.org 91linux.org server_names ~.google. ~.baidu.;

valid_referers 里多了“none blocked”

我们把“none blocked”删掉,改成

valid_referers *.91linux.org 91linux.org server_names ~.google. ~.baidu.;
  • none
    “Referer” 来源头部为空的情况

  • blocked
    “Referer”来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以http://或者https://开头.

nginx彻底地实现真正意义上的防盗链完整的代码应该是这样的:

location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers *.91linux.org 91linux.org server_names ~.google. ~.baidu.;
    if ($invalid_referer) {
    return 403;
    #rewrite ^/ https://www.91linux.org/403.jpg;
    }
}

这样您在浏览器直接输入图片地址就不会再显示图片出来了,也不可能会再右键另存什么的。

我们应该记住,有些合法的请求是不会带referer来源头部的,所以有时候不要拒绝来源头部(referer)为空的请求.

Ubuntu系统安装Nginx web服务器

在QQ群很多朋友问阿里云服务器怎么安装LNMP环境,怎么把项目放到服务器上面去,在这里,我就从头开始教大家怎么在阿里云服务器安装LNMP环境。

在这之前,我们先要知道什么是LNMP。

  • L: 表示的是Linux系统, 包括Ubuntu、Centos但不限于以上两种的系统版本。
  • N: 表示的是Nginx,这是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。
  • M: 表示的是Mysql,Mysql是一个小型关系型数据库管理系统。
  • P: 表示的是PHP,PHP是一种在服务器端执行的嵌入HTML文档的脚本语言。

首先, 我们使用ssh连接到服务器:

$  ssh [email protected]

接着我们需要更新一下apt管理工具包:

$ apt update

更新完之后,使用包管理工具直接下载Nginx:

$ apt install -y nginx

这个时候可以看一下外面安装的nginx在放在哪里:

$ whereis nginx
nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx

现在我们先不管配置, 打开浏览器, 输入服务器IP地址访问, 如果出现:

Welcome to nginx!

那就证明已经安装成功了Nginx。

先简单说一下配置:

现在我使用的nginx版本是1.10.3

$ nginx -v
nginx version: nginx/1.10.3 (Ubuntu)

这个版本的配置在/etc/nginx/sites-enabled/default

$ cd /etc/nginx/sites-enabled/
$ ls
default

这个default里面就有我们一会要配置的东西.

还有就是关于Nginx的错误日志的路径/var/log/nginx, 很多时候我们找错误都是从错误日志中找到问题的解决方法,所以这个路径还是要记住的。

$ cd /var/log/nginx
$ ls
access.log  error.log

通过NGINX配置文件防止XMLRPC.PHP攻击

最近在博客后台发现有一些ip的访问量特别大,排查nginx日志发现基本都是xmlrpc攻击

xmlrpc.php攻击可以绕过使用用户名登陆限制,进行暴力破解。在不想修改wordpress代码的情况下,使用nginx限制是最好的办法。

不建议删除xmlrpc.php文件,因为可能造成莫名其妙的错误

  • 方法1

nginx直接禁止访问该文件

location ~* /xmlrpc.php {
  deny all;
}
  • 方法2

通过跳转或重定向转移流量,这样可以引流到你希望引流到目标的网址或者ip

location ~* /xmlrpc.php {
  proxy_pass https://www.baidu.com;
}

使用nginx replace-filter-nginx-module模块替换网页中的http链接为https

首先不知道openresty为何物的,可自行google!

问题:我们有一个网站,开始用的是http协议的,由于历史原因,路径写在各个地方,比较混乱。现在想启用https协议,可是现在的浏览器不充计https协议下加载http协议的样式,脚本等。

方案1: 将代码中的http全部修改成https,工作量比较大,并且风险太高

方案2: 在程序的输出到时,统一替换,这个虽然相对不错,不过感觉还是有点麻烦,把不属于业务的功能放到了业务代码上

方案3: 在web服务器上做统一替换,这也是我们最终决定的方案,我们选用openresty来做统一替换功能.

安装:

cd /opt/
yum install readline-devel pcre-devel openssl-devel gcc
wget https://openresty.org/download/ngx_openresty-1.9.7.1.tar.gz
git clone https://github.com/openresty/sregex.git
git clone https://github.com/openresty/replace-filter-nginx-module.git
cd  sregex
make
make install
cd ..
tar -zxvf ngx_openresty-1.9.7.1.tar.gz
cd ngx_openresty-1.9.7.1
./configure --with-luajit --add-module=/opt/replace-filter-nginx-module/ --with-debug
gmake
gmake install

这样openresty就算安装完毕,默认安装在/usr/local/openresty。

配置如下:

mkdir /usr/local/openresty/test
cd /usr/local/openresty/test
mkdir logs/ conf/

//在conf目录下创建一个文本文件作为配置文件,命名为nginx.conf

worker_processes  1;
error_log logs/error.log debug;
events {
    worker_connections 1024;
}
http {
    server {
        root            /alidata/www/test;
        index           index.php;
        charset         utf-8;
        server_name     test.xxx.com;
        listen          80;

        rewrite ^/(.*) https://$server_name/$1 permanent;    #跳转到Https

    }
    server {
        root            /alidata/www/test;
        index           index.php;
        charset         utf-8;
        server_name     test.xxx.com;
        listen          443;

        replace_filter 'http://test.xxx.com' 'https://test.xxx.com' 'ig';
        replace_filter 'http://(d+).gravatar.com' 'https://$1.gravatar.com' 'ig';
    }
}

写一shell来start,stop,reload

start.sh

#!/bin/bash
/usr/local/openresty/nginx/sbin/nginx -p /usr/local/openresty/test -c conf/nginx.conf

stop.sh

#!/bin/bash
/usr/local/openresty/nginx/sbin/nginx -p /usr/local/openresty/test -c conf/nginx.conf -s stop

reload.sh

#!/bin/bash
/usr/local/openresty/nginx/sbin/nginx -p /usr/local/openresty/test -c conf/nginx.conf -s stop

总结:

通过这样简单的配置,我们就成功实现了将响应中的内容替换了,还是蛮方便的!

Ubuntu14.04系统安装配置Nginx+PHP+MySQL+EduSoho

注意: 本教程基于Ubuntu系统 14.04版本并且需要以root用户操作机器,请在确保您的环境是否符合以上两个条件之后,再进行后续的操作。

切记:我们的edusoho访问目录是edusoho/web,只有在nginx或者Apache配
置里面把根目录定位到web目录下,才不会出现奇怪的问题,否则就会出现图片不能显示或者文件无法上传的问题。

本教程主要分为一下几个步骤:更新系统、安装并配置Nginx、安装MySQL、安装并配置PHP、 安装并配置EduSoho,测试Edusoho。

一、更新系统

sudo apt-get update
sudo apt-get upgrade

二、安装Nginx

1、安装nginx

sudo apt-get install nginx

2、配置Nginx

sudo vim /etc/nginx/nginx.conf 
然后 在http{} 字段里添加
client_max_body_size 1024M;

三、安装并配置MySQL

1、安装mysql

apt-get install mysql-server

在这个过程过程中会要求您输入MySQL数据库的root密码,请认真填写。

2、创建数据库

mysql -uroot -p 

然后你需要输入MySQL数据库的root密码。

进入数据库命令行模式后,创建edusoho数据库,执行:

CREATE DATABASE `edusoho` DEFAULT CHARACTER SET utf8 ; 
GRANT ALL PRIVILEGES ON `edusoho`.* TO 'esuser'@'localhost' IDENTIFIED BY 'edusoho';
quit;

注意:这里为edusoho数据库创建了一个用户名,用户名为:esuser,密码为edusoho,在后面安装的第三步需要用到,不建议直接填写root账户。

四、安装PHP

1、安装PHP

sudo apt-get install php5 php5-cli php5-curl php5-fpm php5-intl php5-mcrypt php5-mysqlnd php5-gd

2、修改PHP上传文件的大小限制

sudo vim /etc/php5/fpm/php.ini

添加一下三行配置文字

post_max_size = 1024M 
memory_limit = 1024M
upload_max_filesize = 1024M

3、配置PHP-FPM

编辑配置文件: vim /etc/php5/fpm/pool.d/www.conf,找到:

;listen.owner = www-data
;listen.group = www-data
;listen.mode = 0660
去除最前面的分号。

然后重启PHP-FPM:
sudo /etc/init.d/php5-fpm restart

五、配置安装EduSoho

1、下载/解压程序

mkdir /var/www
cd /var/www
wget http://download.edusoho.com/edusoho-VERSION.tar.gz  (注:将VERSION替换为当前EduSoho最新版本号,可从官网www.edusoho.com查询获取)
tar -zxvf edusoho-VERSION.tar.gz
chown www-data:www-data edusoho/ -Rf
注:这里的下载地址可以在http://www.edusoho.com/中可以获取到,VERSION为下载来之后压缩包后面的版本号。

2、配置nginx的虚拟主机

sudo vim /etc/nginx/sites-enabled/edusoho

输入以下内容:

server {
    listen 80;

    # [改] 网站的域名
    server_name www.example.com example.com;

    #301跳转可以在nginx中配置

    # 程序的安装路径
    root /var/www/edusoho/web;

    # 日志路径
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

    location / {
        index app.php;
        try_files $uri @rewriteapp;
    }

    location @rewriteapp {
        rewrite ^(.*)$ /app.php/$1 last;
    }

    location ~ ^/udisk {
        internal;
        root /var/www/edusoho/app/data/;
    }

    location ~ ^/(app|app_dev).php(/|$) {
        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  HTTPS              off;
        fastcgi_param HTTP_X-Sendfile-Type X-Accel-Redirect;
        fastcgi_param HTTP_X-Accel-Mapping /udisk=/var/www/edusoho/app/data/udisk;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 8 128k;
    }

    # 配置设置图片格式文件
    location ~* .(jpg|jpeg|gif|png|ico|swf)$ {
        # 过期时间为3年
        expires 3y;

        # 关闭日志记录
        access_log off;

        # 关闭gzip压缩,减少CPU消耗,因为图片的压缩率不高。
        gzip off;
    }

    # 配置css/js文件
    location ~* .(css|js)$ {
        access_log off;
        expires 3y;
    }

    # 禁止用户上传目录下所有.php文件的访问,提高安全性
    location ~ ^/files/.*.(php|php5)$ {
        deny all;
    }

    # 以下配置允许运行.php的程序,方便于其他第三方系统的集成。
    location ~ .php$ {
        # [改] 请根据实际php-fpm运行的方式修改
        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  HTTPS              off;
        fastcgi_param  HTTP_PROXY         "";
    }
}

配置文件中的example.com 为您需要指定的域名,为了确保您的域名能被他人访问得到, 您需要将这个域名和您当前的机器IP地址做DNS解析工作。

3、重启nginx

sudo /etc/init.d/nginx restart

最后一步:

浏览器中打开:http://YOU_DOMAIN 安装,当然这里的YOU_DOMAIN是您的域名。

Nginx下配置ThinkPHP URL的PATHINFO与REWRITE

尝试了下 ThinkPHP 框架, 版本为 3.2.3, 测试环境为 Windows 下 Nginx 1.6 + PHP 5.5。本文内容为解决 Nginx 下 ThinkPHP URL 模式中所用到的 PATHINFO 与 REWRITE 模式的配置问题。并在 Mac OS X 10.10 下 Nginx 1.8.0 + PHP 5.6.8 下测试通过。理论同样适用于各版本的 Linux 系统中。

PATHINFO 与 REWRITE 模式在表现上的不同在于浏览器的 URL 地址栏中, 以访问 Home 模块, User 控制器, login 操作为例:

PATHINFO 下的 URL: http://localhost/index.php/Home/User/login
REWRITE 下的 URL: http://localhost/Home/User/login

Nginx 开启 PATHINFO

在这之前, 笔者也到搜索引擎上看了几篇关于 Nginx 配置 PATHINFO 的方法, 感觉有点乱, 乱的原因主要是由于 Nginx 没有给予像 Apache 那样一个参数即可开启 PATHINFO 的良好支持, 因此出现了各种 Nginx 下开启 PATHINFO 的解法。

这里提供的是参阅 Nginx 官方文档并结合实测可用后的 PATHINFO 的方案。去除不必须的注释, Nginx 开启 PATHINFO 的 server 部分配置如下:

server {
 listen       80;
 server_name  localhost;
 location / {
   root   D:/Projects/Demo/thinkphp;   # 你的 TP 框架 index.php 所在目录, 记得用 / 分割路径
   index index.php index.html index.htm;
 }
 # ...
 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
 #
 location ~ ^(.+.php)(.*)$ {
   root   D:/Projects/Demo/thinkphp;   # 你的 TP 框架 index.php 所在目录, 记得用 / 分割路径
   fastcgi_split_path_info ^(.+.php)(.*)$;
   fastcgi_param PATH_INFO $fastcgi_path_info;
   fastcgi_pass   127.0.0.1:9000;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
 }
}

这种做法的原理是当请求的访问路径中含有 .php 时, 通过正则表达式构造出 PATHINFO, 并设置到 fastcgi 的参数 PATH_INFO 中。

代码中匹配 PATH_INFO 的正则表达式来源于 Nginx 官方文档中的写法。参见: http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info

PATHINFO 模式是 ThinkPHP 默认的 URL 模式, 因此不需要修改 ThinkPHP 的默认配置即可使用 http://serverName/index.php/模块/控制器/操作 方式访问。

URL REWRITE 模式

REWRITE 模式也称 URL重写, 可用于隐藏 PATHINFO 模式路径中的 index.php, 开启 REWRITE 模式的 Nginx 配置为:

server {
 listen       80;
 server_name  localhost;
 location / {
   root   D:/Projects/Demo/thinkphp;   # 你的 TP 框架 index.php 所在目录, 记得用 / 分割路径
   index index.php index.html index.htm;
   try_files $uri $uri/ /index.php?s=$uri; # 核心
 }
 # ...
 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
 #
 location ~ .php$ {
   root   D:/Projects/Demo/thinkphp;   # 你的 TP 框架 index.php 所在目录, 记得用 / 分割路径
   fastcgi_pass   127.0.0.1:9000;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
 }
}

配置完成后修改 ThinkPHP 的 URL 模式为 REWRITE, 编辑配置文件 ThinkPHP/Conf/convention.php 中修改 URL_MODEL 参数值为 2 (REWRITE 模式)即可通过 http://serverName/模块/控制器/操作 方式访问。

gitlab的备份、备份还原测试及zabbix监控

说明

备份很重要,我们使用一台备份服务器来对gitlab服务器数据进行备份,而测试备份文件是否可用也很重要,要不然用到备份文件,而此文件无法正常还原就损失大了。所以我们还对备份文件进行还原测试及使用zabbix监控备份和还原是否成功。
备份服务器系统使用centos7。下面是备份服务器的配置过程。

配置备份服务器环境

安装docker

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager 
    --add-repo 
    https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce    
systemctl start docker

拉取gitlab镜像

docker pull hub-mirror.c.163.com/gitlab/gitlab-ce:8.17.2-ce.0
docker tag hub-mirror.c.163.com/gitlab/gitlab-ce:8.17.2-ce.0 gitlab/gitlab-ce:8.17.2-ce.0

配置密钥免密码登录gitlab服务器

ssh-keygen
ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.93.5

关闭selinux

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
setenforce 0

安装zabbix-agent

rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm 
yum -y install zabbix-agent zabbix-sender
service zabbix-agent start
chkconfig zabbix-agent on

配置agent

server_ip=192.168.93.202
sed -i "s/Server=.*/Server=$server_ip/"  /etc/zabbix/zabbix_agentd.conf
sed -i "s/ServerActive=.*/Server=$server_ip/"  /etc/zabbix/zabbix_agentd.conf
service zabbix-agent restart

导入模板

<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>3.2</version>
    <date>2017-09-06T15:39:00Z</date>
    <groups>
        <group>
            <name>Templates</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template Gitlab Backup</template>
            <name>Template Gitlab Backup</name>
            <description/>
            <groups>
                <group>
                    <name>Templates</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>gitlab-backup</name>
                </application>
            </applications>
            <items>
                <item>
                    <name>gitlab backup result</name>
                    <type>7</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>gitlab-backup</key>
                    <delay>86400</delay>
                    <history>90</history>
                    <trends>0</trends>
                    <status>0</status>
                    <value_type>4</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description/>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>gitlab-backup</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
            </items>
            <discovery_rules/>
            <httptests/>
            <macros/>
            <templates/>
            <screens/>
        </template>
    </templates>
    <triggers>
        <trigger>
            <expression>{Template Gitlab Backup:gitlab-backup.strlen()}&lt;&gt;0</expression>
            <recovery_mode>0</recovery_mode>
            <recovery_expression/>
            <name>gitlab backup failed</name>
            <correlation_mode>0</correlation_mode>
            <correlation_tag/>
            <url/>
            <status>0</status>
            <priority>2</priority>
            <description/>
            <type>0</type>
            <manual_close>0</manual_close>
            <dependencies/>
            <tags/>
        </trigger>
        <trigger>
            <expression>{Template Gitlab Backup:gitlab-backup.nodata(25h)}=1</expression>
            <recovery_mode>0</recovery_mode>
            <recovery_expression/>
            <name>no gitlab backup message</name>
            <correlation_mode>0</correlation_mode>
            <correlation_tag/>
            <url/>
            <status>0</status>
            <priority>2</priority>
            <description/>
            <type>0</type>
            <manual_close>0</manual_close>
            <dependencies/>
            <tags/>
        </trigger>
    </triggers>
</zabbix_export>

配置备份脚本

mkdir -p /data/sh
vi /data/sh/backup-gitlab.sh

脚本内容:

#!/bin/bash
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"

GITLAB_HOST="192.168.93.5"
ZABBIX_SERVER="192.168.93.202"
BACKUP_SERVER_HOST_NAME="backup server"

# 开始ssh远程执行备份
echo "开始ssh远程执行备份"
if ! msg=`ssh $GITLAB_HOST gitlab-rake gitlab:backup:create 2>&1`;then
    zabbix_sender -z $ZABBIX_SERVER -s "$BACKUP_SERVER_HOST_NAME" -k gitlab-backup -o "backup failed: $msg"
    exit 1
fi
# 获取备份文件名
echo "获取备份文件名"
backup_filename=`ssh $GITLAB_HOST ls -t /var/opt/gitlab/backups/ | head -1`
mkdir -p /data/backup/gitlab/

# 拉取备份文件
echo "拉取备份文件"
if ! msg=`scp $GITLAB_HOST:/var/opt/gitlab/backups/$backup_filename /data/backup/gitlab/ 2>&1`;then
    zabbix_sender -z $ZABBIX_SERVER -s "$BACKUP_SERVER_HOST_NAME" -k gitlab-backup -o "scp backup file failed: $msg"
    exit 1  
fi

# 拉取配置文件
echo "拉取配置文件"
mkdir -p /data/backup/gitlab/etc/
if ! msg=`scp -r $GITLAB_HOST:/etc/gitlab/* /data/backup/gitlab/etc/ 2>&1`;then
    zabbix_sender -z $ZABBIX_SERVER -s "$BACKUP_SERVER_HOST_NAME" -k gitlab-backup -o "scp etc file failed: $msg"
    exit 1  
fi
# 备份.ssh
mkdir -p /data/backup/gitlab/etc/ssh/
scp -r $GITLAB_HOST:/var/opt/gitlab/.ssh/ /data/backup/gitlab/etc/ssh/

timestamp=`echo $backup_filename  | sed 's/_gitlab_backup.tar//'`
# 启动一个gitlab容器进行还原测试
echo "启动一个gitlab容器进行还原测试"
docker run --detach 
    --hostname gitlab.example.com 
    --name gitlab 
    --restart always 
    -p 443:443 
    -p 80:80 
    --volume /data/backup/gitlab/etc:/etc/gitlab 
    -v /data/backup/gitlab:/var/opt/gitlab/backups/ 
    gitlab/gitlab-ce:8.17.2-ce.0

# 停止unicorn和sidekiq
echo "等待gitlab启动"
while true;do
    if [[ `docker exec gitlab gitlab-ctl status | grep -c ^run` -eq 7  ]];then
        break
    fi
    sleep 5    
done
echo "重新配置"
docker exec gitlab gitlab-ctl reconfigure
docker exec gitlab gitlab-ctl restart
echo "停止unicorn和sidekiq"
docker exec gitlab gitlab-ctl stop unicorn
docker exec gitlab gitlab-ctl stop sidekiq
chmod -R 777 /data/backup/gitlab/

# 开始还原备份
echo "开始还原备份"
if ! msg=`docker exec gitlab gitlab-rake gitlab:backup:restore BACKUP=$timestamp force=yes 2>&1`;then
    zabbix_sender -z $ZABBIX_SERVER -s "$BACKUP_SERVER_HOST_NAME" -k gitlab-backup -o "rescore failed: $msg"
    exit 1
fi
docker exec gitlab gitlab-ctl start
docker stop gitlab
docker rm gitlab

# 清除备份
find /data/backup/gitlab/*.tar -mtime +7 -exec rm -f {} ;
zabbix_sender -z $ZABBIX_SERVER -s "$BACKUP_SERVER_HOST_NAME" -k gitlab-backup -o ""

加定时任务

01 03 * * * /data/sh/backup-gitlab.sh

CentOS下NFS共享存储环境搭建

在CentOS 6.9环境下搭建NFS共享,使用Yum安装

yum install nfs-utils -y

修改服务端配置文件/etc/exports如下:

# 格式:
# 作为共享的本地目录  主机A(权限)  主机B(权限)
# fsid=0表示客户端挂载时将/data/share映射为/根目录
/data/share 192.168.1.111(rw,sync,fsid=0,no_root_squash) 192.168.1.112(rw,sync,fsid=0,no_root_squash)

设置开机启动并启动服务

chkconfig rpcbind on
chkconfig nfs on
service rpcbind start
service nfs start

客户端也需要安装nfs-utils

yum install nfs-utils -y

客户端挂载直接使用mount命令即可,也可以加入/etc/fstab

不过还是建议放在/etc/rc.local,防止客户端服务器重启时
如果访问NFS服务器超时会导致客户端服务器启动慢或者无法启动

挂载命令

mount -t nfs4 -o rw,intr,hard,proto=tcp,noatime,nodev,noexec,nosuid 192.168.1.22:/ /data/web/wwwroot/upload/

客户端使用NFSv4协议挂载时,访问共享文件会特别慢,查看日志/var/log/message会报以下错误:

Aug 25 16:19:13 localhost nfsidmap[5617]: nss_getpwnam: name 'root@localhost' does not map into domain 'localdomain'
Aug 25 16:19:13 localhost nfsidmap[5619]: nss_name_to_gid: name 'root@localhost' does not map into domain 'localdomain'

如使用chown修改共享文件权限时会报以下错误:

idmapd errors about "localdomain", or chown failing on nfs4 mount, with "invalid argument"

Google后,找到问题解决办法:https://www.novell.com/support/kb/doc.php?id=7014266

原文摘录如下:

NFSv4 handles user identities differently than NFSv3. In v3, an nfs client would simply pass a UID number in chown (and other requests) and the nfs server would accept that (even if the nfs server did not know of an account with that UID number). However, v4 was designed to pass identities in the form of @. To function correctly, that normally requires idmapd (id mapping daemon) to be active at client and server, and for each to consider themselves part of the same id mapping domain.

Chown failures or idmapd errors like the ones documented above are typically a result of either:
1. The username is known to the client but not known to the server, or
2. The idmapd domain name is set differently on the client than it is on the server.

Therefore, this issue can be fixed by insuring that the nfs server and client are configured with the same idmapd domain name (/etc/idmapd.conf) and both have knowledge of the usernames / accounts in question.

However, it is often not convenient to insure that both sides have the same user account knowledge, especially if the nfs server is a filer. The NFS community has recognized that this idmapd feature of NFSv4 is often more troublesome that it is worth, so there are steps and modifications coming into effect to allow the NFSv3 behavior to work even under NFSv4.

SUSE NFS clients on SLES 11 SP2 or higher have this ability, but it is not necessarily always the default behavior. Setting the kernel module parameter as described in the "Resolution" section of this document is needed. In mainstream Linux, the default behavior changes in kernel 3.3, i.e. to already have nfs4_disable_idmapping set to 1. So eventually (as newer kernels come into SUSE products) setting this manually will not be needed.

NOTE: Some NFSv4 servers may not be prepared to accept this behavior, either. Both sides need to understand this change. If using a Linux NFSv4 server, it may be necessary to use a distribution with kernel 3.4 or higher (for example, openSUSE 12.2 or higher, or upcoming SLES 12). For 3rd party filers, check the nfs configuration for settings related to idmap, uids, etc.

原来是因为NFv4使用了idmapd来传递确保用户身份,必须确保服务器和客户度必须具有相同的idmapd域名(/etc/idmapd.conf),但通常服务端是不可控的
因此解决办法就是降级到NFSv3协议,或者是修改NFS服务器端参数nfs4_disable_idmapping改为True

在服务端执行关闭NFSv4的idmapping用户映射的命令,并将其添加到/etc/rc.local里以便下次开机自动关闭,问题解决

echo 1 > /sys/module/nfsd/parameters/nfs4_disable_idmapping

MySQL忘记root密码重置步骤

刚在Linux装完MySQL,然而登录的时候发现不知道root密码。更坑爹的是这个版本没有生成my.cnf的文件。所以不知道如何设置登录的时候跳过密码,so google 了一下,发现可以用安全模式登录修改。操作如下:

$mysqld_safe --skip-grant-tables
> mysql
> use mysql
> update user set authentication_string = PASSWORD('123456') where user = 'root';
flush privileges;

然后用exit,重启mysql,用刚才设置的密码重新登录。

$mysql -u root -p
> show database;

发现报错:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

> SET PASSWORD = PASSWORD('123456');