CentOS下安装Redis并设置密码外网访问

在windows下,下载redis直接运行redis-server.exe即可,方便快捷。

未分类
redis windows

Centos下安装redis稍微复杂一点。

redis的官网 https://redis.io/

先获取到redis

http://download.redis.io/releases/redis-4.0.9.tar.gz

然后解压编译安装

tar xzf redis-4.0.9.tar.gz
cd redis-4.0.9
make
make install

未分类

编译安装完成后启动Redis

redis-server

也可以通过初始化脚本启动Redis,在编译后的目录utils文件夹中有

redis_init_script

首先将初始化脚本复制到/etc/init.d 目录中,文件名为 redis_端口号(这个mv成了redis_6379),其中端口号表示要让Redis监听的端口号,客户端通过该端口连接Redis。然后修改脚本中的 REDISPORT 变量的值为同样的端口号。

未分类

然后建立存放Redis的配置文件目录和存放Redis持久化的文件目录

/etc/redis 存放Redis的配置文件

/var/redis/端口号 存放Redis的持久化文件(这里是 /var/redis/6379 )

修改配置文件

将配置文件模板 redis-4.0.9/redis.conf 复制到 /etc/redis 目录中,以端口号命名(如 6379.conf ),然后对其中的部分参数进行编辑。

daemonize yes 使Redis以守护进程模式运行
pidfile /var/run/redis_端口号.pid 设置Redis的PID文件位置
port 端口号 设置Redis监听的端口号
dir /var/redis/端口号 设置持久化文件存放位置
#requirepass foobared 若需要设置密码就把注释打开,改成你要设置的密码
bind 127.0.0.1   将其默认的127.0.0.1改为0.0.0.0(代表不做限制),这样外网就能访问了

现在也可以使用下面的命令来启动和关闭Redis了

/etc/init.d/redis_6379 start

/etc/init.d/redis_6379 stop

redis随系统自动启动

chkconfig redis_6379 on

通过上面的操作后,以后也可以直接用下面的命令对Redis进行启动和关闭了,如下

service redis_6379 start

service redis_6379 stop

这样系统重启,Redis也会随着系统启动自动启动起来。

那么怎么停止Redis呢?

上面的stop方法可以停止redis,但是考虑到 Redis 有可能正在将内存中的数据同步到硬盘中,强行终止 Redis 进程可能会导致数据丢失。正确停止Redis的方式应该是向Redis发送SHUTDOWN命令,方法为:

redis-cli SHUTDOWN

当Redis收到SHUTDOWN命令后,会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出。
Redis可以妥善处理 SIGTERM信号,所以使用 kill Redis 进程的 PID也可以正常结束Redis,效果与发送SHUTDOWN命令一样。

如果需要外网访问,首先检查是否被防火墙挡住

然后在配置文件中将bind配置项默认的127.0.0.1改为0.0.0.0

使用腾讯云可能需要在腾讯云控制台对端口进一步设置。

Centos-7安装zabbix

本例环境使用Centos7.3 64位

安装zabbix需要mysql的支持,下面是快速安装LNMP的方法(使用EZHTTP安装)

安装LNMP

首先创建一个目录存放下载文件:

[root@localhost ~]# mkdir /software
[root@localhost software]# cd /software/

安装wget工具:

[root@localhost software]# yum -y install wget

下载EZHTTP安装脚本:

[root@localhost software]# wget --no-check-certificate https://github.com/centos-bz/ezhttp/archive/master.zip?time=$(date +%s) -O ezhttp.zip

启动脚本:

[root@localhost software]# unzip ezhttp.zip
[root@localhost software]# cd ezhttp-master
[root@localhost ezhttp-master]# chmod +x start.sh
[root@localhost ezhttp-master]# ./start.sh

进去选择页面

除了数字选择项需要确认输入,其他的的按回车默认就行:

nginx 和 apache 都行,个人比较喜欢nginx
php版本5.5-7.1
mysql版本5.6

[root@localhost ezhttp-master]# ./start.sh
#############################################################################

You are welcome to use this script to deploy your linux,hope you like.
The script is written by Zhu Maohai.
If you have any question.
please visit http://devops.webres.wang/ezhttp/ and submit your issue.thank you.

############################################################################

1) LAMP LNMP LANMP Installation.
2) Some Useful Tools.
3) Upgrade Software
4) Exit.

please select: 1
you select LAMP LNMP LANMP Installation.
1) LNMP(Nginx MySQL PHP)
2) LAMP(Apache MySQL PHP)
3) LNAMP(Nginx Apache MySQL PHP)
4) back to main menu

please input the package you like to install: 1
#################### nginx setting ####################


1) nginx-1.8.0
2) tengine-2.1.0
3) openresty-1.9.7.3
4) custom_version
5) do_not_install

which nginx you do select(default do_not_install): 1
your selection: nginx-1.8.0
nginx-1.8.0 install location(default:/usr/local/nginx,leave blank for default): 
nginx-1.8.0 install location: /usr/local/nginx
the nginx-1.8.0 configure parameter is:
--prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/software/ezhttp-master/soft/openssl-1.0.2h  --with-http_sub_module --with-http_stub_status_module --with-pcre --with-pcre=/software/ezhttp-master/soft/pcre-8.33 --with-zlib=/software/ezhttp-master/soft/zlib-1.2.8 --with-http_secure_link_module


Would you like to change it?[N/y](default n): 
you select no,configure parameter will not be changed.

Do you need to install nginx module?[N/y](default n): 
#################### mysql setting ####################


1) mysql-5.1.73
2) mysql-5.5.54
3) mysql-5.6.35
4) mysql-5.7.17 (need about 2GB RAM when building,try mysql-5.6 if failed)
5) libmysqlclient18
6) custom_version
7) do_not_install

which mysql you'd select(default do_not_install): 3
your selection: mysql-5.6.35
mysql-5.6.35 install location(default:/usr/local/mysql,leave blank for default): 
mysql-5.6.35 install location: /usr/local/mysql
mysql data location(default:/usr/local/mysql/data,leave blank for default): 
mysql-5.6.35 data location: /usr/local/mysql/data
mysql port number(default:3306,leave blank for default): 
mysql port number: 3306
mysql server root password (default:root,leave blank for default): 123456
mysql-5.6.35 root password: 123456
the mysql-5.6.35 configure parameter is:
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/usr/local/mysql/etc -DMYSQL_UNIX_ADDR=/usr/local/mysql/data/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=complex -DENABLED_LOCAL_INFILE=1 


Would you like to change it?[N/y](default n): 
you select no,configure parameter will not be changed.
#################### php setting ####################


1) php-5.2.17
2) php-5.3.29
3) php-5.4.43
4) php-5.5.27
5) php-5.6.15
6) php-7.1.0
7) custom_version
8) do_not_install

which php you'd select(default do_not_install): 6
your selection: php-7.1.0
php-7.1.0 install location(default:/usr/local/php,leave blank for default): 
php-7.1.0 install location: /usr/local/php
the php-7.1.0 configure parameter is:
--prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --enable-bcmath=shared --with-pdo_sqlite --with-gettext=shared --with-iconv --enable-ftp=shared --with-sqlite --with-sqlite3 --enable-mbstring=shared --enable-sockets=shared --enable-zip --enable-soap=shared --with-openssl --with-zlib --with-curl=shared --with-gd=shared --with-jpeg-dir --with-png-dir --with-freetype-dir --with-mcrypt=shared,/opt/ezhttp/libmcrypt-2.5.8 --with-mhash=shared,/opt/ezhttp/mhash-0.9.9.9 --enable-opcache --with-mysql=mysqlnd --with-mysqli=shared,mysqlnd --with-pdo-mysql=shared,mysqlnd --without-pear --with-libdir=lib64 --disable-fileinfo


Would you like to change it?[N/y](default n): 
you select no,configure parameter will not be changed.
#################### PHP modules install ####################
php-7.1.0 version available modules:

#################### php_modules install ####################

1) fileinfo
2) php-gmp
3) php-swoole-1.7.20
4) do_not_install

please input one or more number between 1 and 4(default do_not_install)(ie.1 2 3): 
your selection do_not_install
#################### other_soft install ####################

1) memcached-1.4.24
2) pure-ftpd-1.0.41
3) phpMyAdmin-4.4.12-all-languages
4) redis-3.0.3
5) mongodb-linux-x86_64-2.4.9
6) phpRedisAdmin-1.1.0
7) memadmin-1.0.12
8) rockmongo-1.1.6-fix-auth
9) jdk1.7.0_79
10) jdk1.8.0_66
11) apache-tomcat-7.0.68
12) apache-tomcat-8.0.39
13) do_not_install

please input one or more number between 1 and 13(default do_not_install)(ie.1 2 3): 1 2 3 4 6 10 12
your selection memcached-1.4.24 pure-ftpd-1.0.41 phpMyAdmin-4.4.12-all-languages redis-3.0.3 phpRedisAdmin-1.1.0 jdk1.8.0_66 apache-tomcat-8.0.39
input memcached-1.4.24 location(default:/usr/local/memcached): 
memcached location: /usr/local/memcached
input pure-ftpd-1.0.41 location(default:/usr/local/pureftpd): 
pureftpd location: /usr/local/pureftpd
Would you like to install web user manager for pureftpd?[N/y](default n): 
you select not install web manager
input phpMyAdmin-4.4.12-all-languages location(default:/home/wwwroot/phpmyadmin): 
phpmyadmin location: /home/wwwroot/phpmyadmin
input redis-3.0.3 location(default:/usr/local/redis): 
redis location: /usr/local/redis
please input the max memory allowed for redis(ie.128M,512m,2G,4g): 128M
128M
input phpRedisAdmin-1.1.0 location(default:/home/wwwroot/redisadmin): 
phpRedisAdmin location: /home/wwwroot/redisadmin
input jdk1.8.0_66 location(default:/usr/local/jdk1.8.0_66): 
jdk8 location: /usr/local/jdk1.8.0_66
input apache-tomcat-8.0.39 location(default:/usr/local/tomcat8): 
tomcat8 location: /usr/local/tomcat8
#################### your choice overview ####################

Package: lnmp

*****Nginx Setting*****
Nginx: nginx-1.8.0
Nginx Location: /usr/local/nginx
Nginx Configure Parameter: --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/software/ezhttp-master/soft/openssl-1.0.2h  --with-http_sub_module --with-http_stub_status_module --with-pcre --with-pcre=/software/ezhttp-master/soft/pcre-8.33 --with-zlib=/software/ezhttp-master/soft/zlib-1.2.8 --with-http_secure_link_module
Nginx Modules: 


*****MySQL Setting*****
MySQL Server: mysql-5.6.35
MySQL Location: /usr/local/mysql
MySQL Data Location: /usr/local/mysql/data
MySQL Port Number: 3306
MySQL Root Password: 123456
MySQL Configure Parameter: -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/usr/local/mysql/etc -DMYSQL_UNIX_ADDR=/usr/local/mysql/data/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=complex -DENABLED_LOCAL_INFILE=1 

*****PHP Setting*****
PHP: php-7.1.0
PHP Location: /usr/local/php
PHP Configure Parameter: --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --enable-bcmath=shared --with-pdo_sqlite --with-gettext=shared --with-iconv --enable-ftp=shared --with-sqlite --with-sqlite3 --enable-mbstring=shared --enable-sockets=shared --enable-zip --enable-soap=shared --with-openssl --with-zlib --with-curl=shared --with-gd=shared --with-jpeg-dir --with-png-dir --with-freetype-dir --with-mcrypt=shared,/opt/ezhttp/libmcrypt-2.5.8 --with-mhash=shared,/opt/ezhttp/mhash-0.9.9.9 --enable-opcache --with-mysql=mysqlnd --with-mysqli=shared,mysqlnd --with-pdo-mysql=shared,mysqlnd --without-pear --with-libdir=lib64 --disable-fileinfo

*****Other Software Setting*****
Other Software:  memcached-1.4.24 pure-ftpd-1.0.41 phpMyAdmin-4.4.12-all-languages redis-3.0.3 phpRedisAdmin-1.1.0 jdk1.8.0_66 apache-tomcat-8.0.39
memcached location: /usr/local/memcached
pureftpd location: /usr/local/pureftpd
phpmyadmin_location: /home/wwwroot/phpmyadmin
redis_location: /usr/local/redis
phpRedisAdmin_location: /home/wwwroot/redisadmin
jdk8_location: /usr/local/jdk1.8.0_66
tomcat8_location: /usr/local/tomcat8
JAVA_HOME: /usr/local/jdk1.8.0_66

##############################################################

Are you ready to configure your Linux?[Y/n](default y):

安装过程等待即可:

..............................
..............................

安装成功:

start programs...
Starting nginx daemon: .
Starting MySQL.. SUCCESS! 
Warning: Using a password on the command line interface can be insecure.
Starting php-fpm  done
Starting memcached: 
Start pureftpd....  [OK] 
Starting Redis server...

使用EZHTTP安装成功后各服务已经打开,输入Linxu 机器IP 访问即可:

未分类

恭喜,安装成功了!

开始安装zabbix

配置源

Zabbix在CentOS基本源里不可获得,因此必须配置EPEL 和Zabbix 官方repository,因为需要一款名叫fping的软件(这款软件你下载源码编译安装貌似行不通!),然后其他的yum源将mysql全部识别为mariadb了,所以想yum安装mysql,请安装mysql社区版官方源,或者编译安装,上面的EZHTTP安装脚本就是编译安装

安装EPEL repository

[root@localhost software]# pwd
/software
[root@localhost software]# yum -y install epel-release

配置ZabbixZone package repository and GPG key

[root@localhost software]# rpm --import http://repo.zabbix.com/RPM-GPG-KEY-ZABBIX
[root@localhost software]# rpm --import http://repo.zabbix.com/RPM-GPG-KEY-ZABBIX-A14FE591
[root@localhost software]# yum -y install fping
[root@localhost software]# rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm

安装Zabbix server and agent(agent是可选的)

安装Zabbix server and agent:(配置自己监控自己,所以安装了zabbix-agent)

yum -y install zabbix-server-mysql zabbix-web-mysql zabbix-agent

可以上zabbix rpm包官网查看或下载相应包

http://repo.zabbix.com/

创建MySQL 数据库和用户

登录Mysql:

[root@localhost software]# mysql -uroot -p123456

创建一个数据库zabbix和数据库用户zabbix:

mysql> create database zabbix character set utf8;

mysql> grant all privileges on zabbix.* to 'zabbix'@'localhost' identified by 'zabbix';

mysql> flush privileges;

数据库导入zabbix template

看yum安装的zabbix-server-mysql-3.x.x 这个文件的版本是多少就改成多少

[root@localhost software]# zcat /usr/share/doc/zabbix-server-mysql-3.2.4/create.sql.gz |mysql -uzabbix -pzabbix -b zabbix

配置Zabbix server

vi /etc/zabbix/zabbix_server.conf

配置下面的几个参数
带#号的就去掉#号,并修改其值

ListenPort=10051
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=zabbix
DBSocket=/usr/local/mysql/data/mysql.sock
DBPort=3306

配置zabbix-agent

vi /etc/zabbix/zabbix_agentd.conf

配置zabbix server的ip

## Line 95 - Specify Zabbix server ##

Server=127.0.0.1

## Line 136 - Specify Zabbix server ##

ServerActive=127.0.0.1

## Line 147 - Specify Zabbix server Hostname or IP address

Hostname=127.0.0.1

修改PHP 设置

修改php.ini为zabbix 建议的设置
编辑文件 php.ini,

[root@localhost software]# vi /usr/local/php/etc/php.ini

设置下面的参数:

max_execution_time = 300

max_input_time = 300

memory_limit = 128M

post_max_size = 32M

upload_max_filesize = 2M

date.timezone = Asia/Shanghai

安装时可能缺少下面扩展,把下面内容添加到php.ini

extension=bcmath.so
extension=gettext.so
extension=sockets.so

安装扩展

[root@localhost ext]# cd /software/ezhttp-master/soft/php-7.1.0/ext
[root@localhost ext]# pwd
/software/ezhttp-master/soft/php-7.1.0/ext
[root@localhost ext]# cd sockets/
[root@localhost sockets]# /usr/local/php/bin/phpize
[root@localhost sockets]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost sockets]# cd ..
[root@localhost ext]# cd bcmath/
[root@localhost bcmath]# /usr/local/php/bin/phpize
[root@localhost bcmath]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost bcmath]# cd ..
[root@localhost ext]# cd gettext/
[root@localhost gettext]# /usr/local/php/bin/phpize
[root@localhost gettext]# ./configure --with-php-config=/usr/local/php/bin/php-config

使用下面命令可以看到有一个扩展存放的目录,我们需要的扩展模块在其中即安装成功

[root@localhost gettext]# make && make install

修改php-fpm运行的用户和组

[root@localhost software]# vi /usr/local/php/etc/php-fpm.d/www.conf
user = www
group = www

方法一:使用 apache 服务器

apache配置zabbix-web站点文件

[root@localhost etc]# cd /etc/httpd/

vi conf/httpd.conf
修改下面内容:

Listen 80

User www
Group wwww

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

vi conf.d/zabbix.conf
修改内容如下:

<IfModule mod_php5.c>
    php_value max_execution_time 300
    php_value memory_limit 128M
    php_value post_max_size 32M
    php_value upload_max_filesize 8M
    php_value max_input_time 300
    php_value always_populate_raw_post_data -1
    php_value date.timezone Asia/Shanghai
</IfModule>

然后重启apache、mysql、php、zabbix-server
浏览器输入ip/setup.php 即可进入zabbix初次web安装界面

方法二:使用 Nginx 服务器

配置zabbix-web站点文件

把zabbix程序文件拷贝到我们指定的目录,并修改属主和属组

[root@localhost software]# cp -r /usr/share/zabbix /var/www/
[root@localhost software]# chown -R www:www /var/www/zabbix
[root@localhost software]# chown -R www:www /etc/zabbix
[root@localhost software]# chown -R www:www /usr/share/zabbix
[root@localhost software]# chown -R www:www /usr/lib/zabbix
[root@localhost software]# chmod -R 755 /etc/zabbix/web

创建存放web站点配置文件的目录

[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# mkdir conf.d/

配置nginx.conf,把新建的目录包含进去

[root@localhost conf]# vi nginx.conf

listen 80 default_server;      ===> 改为 listen 90 default_server;
root /home/wwwroot/;      ===> 改为 # root /home/wwwroot/;
include vhost/*.conf;    ===> 改为 include /usr/local/nginx/conf/conf.d/*.conf;

配置zabbix.conf(zabiix站点的配置文件)

[root@localhost conf]# cd conf.d/
[root@localhost conf.d]# vi zabbix.conf

zabbix.conf 内容如下:

    server {
        listen 80;
        server_name localhost;
        root /var/www/zabbix;
        index index.php index.html index.htm;
        access_log  logs/zabbix.access.log;
        error_log   logs/zabbix.error.log;

        location / {
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ .*.(php)?$ {
            expires -1s;
            try_files $uri =404;
            fastcgi_split_path_info ^(.+.php)(/.+)$;
            include        fastcgi_params;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PHP_VALUE        open_basedir=$document_root:/tmp/:/proc/:/usr/share/zabbix/:/etc/zabbix/web/:/etc/zabbix/;
        }

    }

启动zabbix 和 各服务

启动zabbix-server 和zabbix-agent。并设置zabbix-server和zabbix-agent开机自动启动

systemctl start zabbix-server

systemctl start zabbix-agent

/etc/init.d/nginx restart

chkconfig nginx on

/etc/init.d/mysqld restart

chkconfig mysqld on

/etc/init.d/php-fpm restart

chkconfig php-fpm on

systemctl enable zabbix-server

systemctl enable zabbix-agent

修改Firewall 和SELinux 设置

开放zabbix端口10050 and 10051

firewall-cmd --permanent --add-port=10050/tcp

firewall-cmd --permanent --add-port=10051/tcp

重启firewall

systemctl restart firewalld

如果使用 SELinux, 运行以下命令使 Apache 可以和 Zabbix通信

setsebool -P httpd_can_connect_zabbix=1

如果是测试环境可以直接关闭防火墙和selinux

[root@localhost software]# systemctl stop firewalld
[root@localhost local]# chkconfig firewalld off

修改配置文件,禁用selinux

[root@localhost software]# setenforce 0
[root@localhost software]# vi /etc/selinux/config

SELINUX=disabled

输入ip/setup.php进入zabbix-web界面进行后续安装操作

未分类

确认状态都是ok

未分类

配置数据库信息(填写上面我们设置的数据库账户和密码:zabbix,zabbix,测试环境可以直接用root)

未分类

进入下一步,默认即可

未分类

如果出现下面错误

未分类

解决方法:

sed -i 's#cgi.fix_pathinfo=0#cgi.fix_pathinfo=1#' /usr/local/php/etc/php.ini
/etc/init.d/php-fpm restart

刷新浏览器, 一直下一步

登录,默认用户名: Admin , 默认密码:zabbix

未分类

使用php7.0版本初始化完成后页面有如下的报错:

未分类

这个是因为PHP 7.1.0类型强化,处理方法也很简单找到Zabbix WEB目录下include/func.inc.php文件,执行下面命令,并重启php服务:

sed -i ‘/$last = strtolower(substr($val, -1));/a$val = substr($val,0,-1);’ /var/www/zabbix/include/func.inc.php
/etc/init.d/php-fpm reload
然后刷新页面可以看到已经正常。

ok,初始化完毕。。。

解决图形中文乱码

未分类

这个问题是由于zabbix的web端没有中文字库,我们最需要把中文字库加上即可
解决办法如下
1.从windows下控制面板->字体->选择一种中文字库例如“楷体”

未分类

2.把它拷贝到zabbix的web端的fonts目录下例如:/var/www/html/zabbix/fonts,确认后缀为ttf

未分类

3.修改zabbix的web端/include/defines.inc.php
点击(此处)折叠或打开

//define('ZBX_FONT_NAME', 'graphfont');
define('ZBX_FONT_NAME', 'simkai');

//define('ZBX_GRAPH_FONT_NAME',     'graphfont'); // font file name
define('ZBX_GRAPH_FONT_NAME',       'simkai'); // font file name

其中simkai为字库名字,不包含ttf后缀
测试结果:

未分类

centos下使用yum 安装percona xtrabackup

配置percona的yum仓库

一、先安装依赖

yum install perl-DBI

yum install perl-DBD-MySQL

yum install perl-Time-HiRes

yum install perl-IO-Socket-SSL

二、配置yum源

方法1、自动安装percona的yum仓库(以下分别为x86_64和i386平台)

#rpm -ivh http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
#rpm -ivh http://www.percona.com/redir/downloads/percona-release/percona-release-0.0-1.i386.rpm

方法2、手动yum仓库

创建文件/etc/yum.repos.d/Percona.repo内容如下:

[percona]
name = CentOS $releasever - Percona
baseurl=http://repo.percona.com/centos/$releasever/os/$basearch/
enabled = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-percona
gpgcheck = 1

获取和保存key

#wget http://www.percona.com/redir/downloads/percona-release/RPM-GPG-KEY-percona

#cp RPM-GPG-KEY-percona /etc/pki/rpm-gpg/RPM-GPG-KEY-percona

安装 percona xtrabackup
下面我们就可以安装percona一系列工具了:

安装xtrabackup    
#yum -y install percona-xtrabackup    
安装toolkit
#yum -y install percona-toolkit

CentOS监控ssh免密登录

ssh免密登录在带来方便的同时也带来一些问题,那就是不知道什么时间什么人利用ssh免密通道登录服务器了,为此我们需要在sshd的配置文件里设置好详细日志,以便日后回溯。

在CentOS里,sshd的日志文件是保存在/var/log/secure里的,如果不进行特殊设置的话,它只记录一些最简单的信息,比如什么时间哪个账号被人用免密登录的方式登录了,如果这个账号的authorized_keys里有很多key的话,这样的log没有办法告诉你客户到底是用哪个key登录的。

所以,我们需要在sshd的配置文件/etc/ssh/sshd_config文件里找到以下项LogLevel并把它改成LogLevel VERBOSE,这一项的缺省值是INFO,不够详细,所以我们需要把它改成啰嗦模式,这样可以记录更多信息。

改成VERBOSE并重启sshd(service sshd restart)后,我们会在日志文件里看到类似于这样的记录:

Apr 1 10:37:06 hostname sshd[5903]: Found matching RSA key: 83:67:b5:c7:bb:17:4d:06:ca:dc:8b:ca:85:cc:0c:b1

但这样的信息明显不同于我们在authorized_keys里存放的信息,那该怎么办呢?实际上,在sshd的日志文件里存储的只是我们authorized_keys的指纹信息fingerprint,不是真正的key,必须从authorized_keys反算出fingerprint来,才能做对比:

ssh-keygen -E md5 -lf /home/someuser/.ssh/authorized_keys

但是这样依然很麻烦,有没有办法直接告诉我日志里到底是谁登录的呢?为此我们还需要引入一个用Perl写的小程序点击预览。(原作者写的略有问题,在新版的CentOS里必须要求附加md5参数,为此我做了一些小的修改):

#!/usr/bin/perl -w
use strict;
use diagnostics;
use File::Temp;

# Matches Fingerprints from sshd logs (sshd on loglevel VERBOSE) against
# authorized_keys for the respective user.

die "Please specify input file!n" unless ($ARGV[0]);

my $fingerprints;

my $nav = File::Navigate->new($ARGV[0]);
# Store publickey login events
my @lines = @{$nav->find(qr/sshd[d+]: Accepted publickey for .+ from .+ port d+/)};

# Process all publickey login events
foreach(@lines){
    $nav->cursor($_);
    my $line = $nav->get();
    $line =~ /^(.{15}).+sshd[(d+)]: Accepted publickey for (.+) from (.+) port (d+)/;
    my $date = $1;
    my $pid  = $2;
    my $user = $3;
    my $ip   = $4;
    my $port = $5;
    my $fp   = "unknown"; # (yet)
    # Seek backwards to find matching fingerprint line
    my $sought = 0;
    while ((my $seekline = $nav->getprev()) and ($sought++ < 1000)){
        if ($seekline =~ /sshd[$pid]: Found matching .+ key: (.+)/){
            $fp = $1;
            last;
        }elsif($line =~ /sshd[$pid]: Connection from $ip port $port/){
            last;
        }
    }
    my $key = get_key($fp, $user);
    print ""$date";"$user";"$fp";"$key"n";
}

sub get_key{
    my $fp   = shift;
    $fp = "MD5:" . $fp;
    my $user = shift;

    # See if FP is cached
    if ($fingerprints->{$user}){
        if ($fingerprints->{$user}->{$fp}){
            return $fingerprints->{$user}->{$fp};
        }else{
            return "No matching key found.";
        }
    }

    # Else, generate fingerprints from users authorized_keys
    print STDERR "------> Reading keys for user $usern";
    my $home = (getpwnam($user))[7];
    open my $fh_in, "<$home/.ssh/authorized_keys" or warn "No such file: $home/.ssh/authorized_keysn";
    while (<$fh_in>){
        chomp;
        next unless (/^ssh-/);
        my $out_fh = File::Temp->new();
        print $out_fh "$_n";
        close $out_fh;
        my $fp_raw = `ssh-keygen -E md5 -lf $out_fh`;
        # Second field of output has the fingerpring
        my $fp = (split /s+/, $fp_raw)[1];
        $fingerprints->{$user}->{$fp} = $_;
    }
    if ($fingerprints->{$user}->{$fp}){
        return $fingerprints->{$user}->{$fp};
    }else{
        return "No matching key found.";
    }
}

package File::Navigate;
use strict;
use warnings;

=head1 NAME

File::Navigate - Navigate freely inside a text file

=head1 DESCRIPTION

The module is a glorified wrapper for tell() and seek().

It aims to simplify the creation of logfile analysis tools by
providing a facility to jump around freely inside the contents
of large files without creating the need to slurp excessive
amounts of data.

=head1 SYNOPSIS

  use File::Navigate;
  my $nav = File::Navigate->new('/var/log/messages');

  # Read what's below the "cursor":
  my $first = $nav->get;

  # Advance the cursor before reading:
  my $second = $nav->getnext;
  my $third  = $nav->getnext;

  # Advance the cursor by hand:
  $nav->next;
  my $fourth = $nav->get;

  # Position the cursor onto an arbitrary line:
  $nav->cursor(10);
  my $tenth  = $nav->get;

  # Reverse the cursor one line backward:
  $nav->prev;
  my $ninth  = $nav->get;

  # Reverse the cursor before reading:
  my $eigth  = $nav->getprev;

  # Read an arbitrary line:
  my $sixth  = $nav->get(6);

=cut

our @ISA       = qw(Exporter);
our @EXPORT_OK = qw();
our $VERSION   = '1.0';

=head1 CLASS METHODS

=head2 I<new()>

Open the file and create an index of the lines inside of it.

  my $mapper = File::Navigate->new($filename);

=cut

sub new($){
    my $class = shift;
    my $file;
    unless ($file = shift){
        die "No file specifiedn";
    }
    unless (-e $file){
        die "File not found: $filen";
    }
    unless (-r $file){
        die "File not readable: $filen";
    }
    my $self = {};
       $self->{'cursor'}         = 1;
       $self->{'lineindex'}      = {};
       $self->{'lineindex'}->{1} = 0;
    open my $fh, "$file"
        or die "Can't open $file: $!n";
    while (<$fh>){
        my $thisline = $.;
        my $nextline = $thisline + 1;
        $self->{'lineindex'}->{$nextline} = tell $fh;
    }
    $self->{'length'} = scalar(keys %{$self->{'lineindex'}}) - 1 ;
    $self->{'fh'} = $fh;
    bless $self;
}

=head1 OBJECT METHODS

=head2 I<count()>

Returns the number of lines in the file ("wc -l")

  my $lines = $nav->count;

=cut

sub length(){
    my $self = shift;
    return $self->{'length'};
}

=head2 I<cursor()>

Returns the current cursor position and/or sets the cursor.

  my $cursor = $nav->cursor();   # Query cursor position.
  my $cursor = $nav->cursor(10); # Set cursor to line 10

=cut

sub cursor($){
    my $self = shift;
    if (my $goto = shift){
        $self->{'cursor'} = $goto;
    }
    return $self->{'cursor'};
}

=head2 I<get()>

Gets the line at the cursor position or at the given position.

  my $line = $nav->get();   # Get line at cursor
  my $line = $nav->get(10); # Get line 10

=cut

sub get($){
    my $self = shift;
    my $fh   = $self->{'fh'};

    my $getline;
    $getline = $self->{'cursor'} unless ($getline = shift);

    if ($getline < 1){
        warn "WARNING: Seek before first line.";
        return undef;
    }elsif($getline > $self->{'length'}){
        warn "WARNING: Seek beyond last line.";
        return undef;
    }
    seek ($fh, $self->{'lineindex'}->{$getline}, 0);
    my $gotline = <$fh>;
    chomp $gotline;
    return $gotline;
}

=head2 I<next()>

Advance the cursor position by one line. Returns the new cursor position.
Returns I<undef> if the cursor is already on the last line.

  my $newcursor = $nav->next();

=cut

sub next(){
    my $self = shift;
    if ($self->{'cursor'} == $self->{'length'}){
        return undef;
    }
    $self->{'cursor'}++;
    return $self->{'cursor'};
}

=head2 I<prev()>

Reverse the cursor position by one line. Returns the new cursor position.
Returns I<undef> if the cursor is already on line 1.

  my $newcursor = $nav->prev();

=cut

sub prev(){
    my $self = shift;
    if ($self->{'cursor'} == 1){
        return undef;
    }
    $self->{'cursor'}--;
    return $self->{'cursor'};
}

=head2 I<getnext()>

Advance to the next line and return it.
Returns I<undef> if the cursor is already on the last line.

  my $newcursor = $nav->getnext();

=cut

sub getnext(){
    my $self = shift;
    $self->next or return undef;
    return $self->get;
}

=head2 I<getprev()>

Reverse to the previous line and return it:
Returns I<undef> if the cursor is already on line 1.

  my $newcursor = $nav->getprev();

=cut

sub getprev(){
    my $self = shift;
    $self->prev or return undef;
    return $self->get;
}

=head2 I<find()>

Find lines containing given regex. Returns array with line numbers.

  my @lines = @{$nav->find(qr/foo/)};

=cut

sub find($){
    my $self = shift;
    my $regex = shift;

    my @results;
    for (my $lineno = 1; $lineno <= $self->{'length'}; $lineno++){
        my $line = $self->get($lineno);
            if ($line =~ $regex){
            push @results, $lineno;
        }
    }
    return @results;
}

sub DESTROY(){
    my $self = shift;
    close $self->{'fh'};
}

=head1 EXAMPLE

I<tac>, the opposite of I<cat>, in Perl using File::Navigate:

  #!/usr/bin/perl -w
  use strict;
  use File::Navigate;

  foreach my $file (reverse(@ARGV)){
          my $nav = File::Navigate->new($file);
          # Force cursor beyond last line
          $nav->cursor($nav->length()+1);
          print $nav->get()."n" while $nav->prev();
  }

=head1 BUGS

Seems to lack proper error handling.

=head1 LIMITATIONS

Works only on plain text files. Sockets, STDIO etc. are not supported.

=head1 PREREQUISITES

Tested on Perl 5.6.1.

=head1 STATUS

Mostly harmless.

=head1 AUTHOR

Martin Schmitt <mas at scsy dot de>

=cut

1;

为此我们给它起名叫match-ssh-keys,赋予它可执行权限(chmod +x match-ssh-keys),然后把它搬到/usr/local/bin里(mv match-ssh-keys /usr/local/bin/),这样我们以后再想查谁通过sshd免密登录过服务器就方便了,我们只需要执行:

match-ssh-keys /var/log/secure

就可以了。

详解Centos7扩展磁盘空间(LVM管理)

本文介绍了Centos7扩展磁盘空间(LVM管理),分享给大家,具体如下:

查看磁盘情况

# fdisk -l /dev/sda
Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00063fa6
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 1026047 512000 83 linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM
/dev/sda3 20971520 41943039 10485760 8e Linux LVM

现在,磁盘大小为 21.5 GB。磁盘占用情况为:

# df -h

Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 19G 8.1G 11G 44% /
devtmpfs 482M 0 482M 0% /dev
tmpfs 497M 88K 497M 1% /dev/shm
tmpfs 497M 7.0M 490M 2% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 497M 157M 341M 32% /boot
Share 103G 36G 67G 35% /media/sf_Share
tmpfs 100M 4.0K 100M 1% /run/user/42
tmpfs 100M 12K 100M 1% /run/user/0

试试看用 dd 命令创建一个大小为 1GB 的块文件:

# dd if=/dev/zero of=1.0G.img bs=1M count=1000
dd: writing `1.0G.img': No space left on device
1+0 records in
0+0 records out
8192 bytes (8.2 kB) copied, 0.00300509 s, 2.7 MB/s

提示磁盘空间不足,说明,虽然已给虚拟机分配了足够的空间,但是系统并不识别该空间。

下面调整虚拟机操作系统的文件系统,使之识别新增的空间

1、创建新的分区

# fdisk /dev/sda
n {new partition}
p {primary partition}
3 {partition number}
[这时会提示修改大小,选择默认直接回车即可]
t {change partition id}
3 {partition number}
8e {Linux LVM partition}
w

如果中间有设置大小之类的提示,就直接回车。

完成后,如果提示:
PS:经实际测试,无此提示,但还是要重启系统,看看是否已识别该磁盘空间。

WARNING: Re-reading the partition table failed with error 16: 设备或资源忙. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8)

就重启一下系统。

2、查看新增加的sda3是否标记为LVM,如果没有需要reboot
PS:经实际测试,sda3已经是LVM了,但系统还是不识别该磁盘空间。

3、调整LVM大小

查看Volume Group名称

# vgdisplay
--- Volume group ---
VG Name centos
System ID 
Format lvm2

4、为新分配的空间创建一个新的物理卷

#pvcreate /dev/sda3

5、使用新的物理卷来扩展 LVM 的 VolGroup

# vgextend centos /dev/sda3
No physical volume label read from /dev/sda3
Writing physical volume data to disk "/dev/sda3"
Physical volume "/dev/sda3" successfully created
Volume group "vg_aimin" successfully extended

6、扩展 LVM 的逻辑卷 centos-root

先查看逻辑卷:

# lvdisplay
--- Logical volume ---
LV Path /dev/centos/root
LV Name root
VG Name centos
# lvextend /dev/centos/root /dev/sda3

7、调整逻辑卷的大小

# xfs_growfs /dev/centos/root

PS:不知道是调整还是同步,经实际测试需要用xfs_growfs命令,而非resize2fs命令

8、查看结果

# lvscan
ACTIVE '/dev/centos/root' [18.46 GiB] inherit
ACTIVE '/dev/centos/swap' [1.00 GiB] inherit

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

CentOS从firewall切换为iptables防火墙

1、关闭firewall:

service firewalld stop
systemctl disable firewalld.service #禁止firewall开机启动

2、安装iptables防火墙

yum install iptables-services #安装

3、编辑iptables防火墙配置

vi /etc/sysconfig/iptables #编辑防火墙配置文件

下边是一个完整的配置文件:

Firewall configuration written by system-config-firewall

Manual customization of this file is not recommended.

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT

-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT

-A INPUT -m state –state NEW -m tcp -p tcp –dport 3306 -j ACCEPT

-A INPUT -j REJECT –reject-with icmp-host-prohibited

-A FORWARD -j REJECT –reject-with icmp-host-prohibited

COMMIT

:wq! #保存退出

service iptables start #开启
systemctl enable iptables.service #设置防火墙开机启动

CentOS 7 加速 docker源

对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

{
  "registry-mirrors": [
    "https://registry.docker-cn.com"
  ]
}

注意,一定要保证该文件符合 json 规范,否则 Docker 将不能启动。

之后重新启动服务。

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

注意:如果您之前查看旧教程,修改了 docker.service 文件内容,请去掉您添加的内容(–registry-mirror=https://registry.docker-cn.com),这里不再赘述。

centos7的服务治理-systemd

经常用到的高频命令小结

- 所有服务unit放在这里
ll /usr/lib/systemd/system

- 默认启动级别
[root@n1 ~]# ll /etc/systemd/system/default.target 
lrwxrwxrwx 1 root root 41 Mar  4 09:02 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target

- 开机启动的服务
ll /etc/systemd/system/multi-user.target.wants/

- 哪些服务开机会启动
[root@n1 ~]# systemctl list-unit-files --type service |grep enable
[email protected]                               enabled 
crond.service                                 enabled 
docker.service                                enabled 
[email protected]                                enabled 
ntpdate.service                               enabled 
rsyslog.service                               enabled 
sshd.service                                  enabled 
sysstat.service                               enabled 

- 目前哪些服务处于active状态
[root@n1 ~]# systemctl list-units --type service |grep active
crond.service                      loaded active running Command Scheduler
dbus.service                       loaded active running D-Bus System Message Bus
docker.service                     loaded active running Docker Application Container Engine
[email protected]                 loaded active running Getty on tty1

- 查看某个服务是否开机自启
systemctl is-enabled httpd.service 或
systemctl status httpd.service

systemd 有很多unit,其中service.unit是管理系统服务的.

未分类

unit的类型

/usr/lib/systemd/system

未分类

查看管理系统服务的相关的, 即 .service后缀的

[root@n1 system]# ls /usr/lib/systemd/system/*.service|more
/usr/lib/systemd/system/arp-ethers.service
/usr/lib/systemd/system/auditd.service
/usr/lib/systemd/system/[email protected]
/usr/lib/systemd/system/blk-availability.service
/usr/lib/systemd/system/brandbot.service
...

特点:
    不需要可执行权限,其内容也不能执行
    仅是systemd的调用的配置文件<img

src=”http://devops.webres.wang/wp-content/uploads/2018/03/3-20.png” alt=”” width=”388″ height=”443″ class=”alignnone size-full wp-image-19103″ />

centos6 chkconfig VS 使用systemd的service unit治理centos7服务

未分类

ls /usr/lib/systemd/system/*.service|more 下以service开头的文件,都是和系统服务有关的, 其下还有别的后缀的服务.是别的unit的配置文件.

未分类

serivice unit配置

未分类

target unit: 的含义是服务组,表示一组服务

将很多服务放在一坨, 开启启动时候加载这个文件.

启动级别

/usr/lib/systemd/system
/etc/systemd/system

runlevel0.target -> poweroff.target
runlevel2.target -> multi-user.target
runlevel3.target -> multi-user.target
runlevel4.target -> multi-user.target
runlevel5.target -> graphical.target
runlevel6.target -> reboot.target

注意: centos7里,运行级别234没区别.

查看在运行的服务

我们看ACTIVE就ok了,SUB这一列可以不用理会

[root@n1 system]# systemctl list-units --type=service
UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
crond.service                      loaded active running Command Scheduler
dbus.service                       loaded active running D-Bus System Message Bus
docker.service                     loaded active running Docker Application Container Engine
[email protected]                 loaded active running Getty on tty1
httpd.service                      loaded active running The Apache HTTP Server

查看开机是否会启动

[root@n1 system]# systemctl list-unit-files --type=service
UNIT FILE                                     STATE   
arp-ethers.service                            disabled
auditd.service                                disabled
[email protected]                               enabled #开机会启动
blk-availability.service                      disabled#开机不会启动
brandbot.service                              static  #这类不用管
conntrackd.service                            disabled

systemd管理服务入门http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html

设置开机自动启动细节

[root@n1 ~]# yum install psmisc -y
[root@n1 ~]# pstree
systemd─┬─agetty
        ├─crond
        ├─dbus-daemon
        ├─dockerd─┬─docker-containe─┬─docker-containe─┬─mysqld───20*[{mysqld}]
        │         │                 │                 └─8*[{docker-containe}]
        │         │                 └─9*[{docker-containe}]
        │         ├─docker-proxy───3*[{docker-proxy}]
        │         └─11*[{dockerd}]
        ├─httpd───8*[httpd]
        ├─lvmetad
        ├─polkitd───5*[{polkitd}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        └─systemd-udevd
[root@n1 system]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

相当于执行

ln -s /usr/lib/systemd/system/httpd.service /etc/systemd/system/multi-user.target.wants/httpd.service

disable相当于删除

[root@n1 system]# systemctl disable httpd
Removed symlink /etc/systemd/system/multi-user.target.wants/httpd.service.
[root@n1 system]# ll /etc/systemd/system/multi-user.target.wants
total 0
lrwxrwxrwx. 1 root root 37 Dec 27 04:44 crond.service -> /usr/lib/systemd/system/crond.service
lrwxrwxrwx  1 root root 38 Dec 26 21:05 docker.service -> /usr/lib/systemd/system/docker.service
lrwxrwxrwx  1 root root 37 Mar  4 03:39 httpd.service -> /usr/lib/systemd/system/httpd.service
lrwxrwxrwx. 1 root root 39 Dec 26 21:00 ntpdate.service -> /usr/lib/systemd/system/ntpdate.service
lrwxrwxrwx. 1 root root 40 Dec 27 04:44 remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
lrwxrwxrwx. 1 root root 39 Dec 27 04:44 rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root 36 Dec 27 04:44 sshd.service -> /usr/lib/systemd/system/sshd.service
lrwxrwxrwx. 1 root root 39 Dec 27 05:00 sysstat.service -> /usr/lib/systemd/system/sysstat.service

设置启动级别的命令

- 设置默认启动级别
[root@n1 ~]# systemctl set-default graphical.target 
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/graphical.target.

- 查看默认的启动级别
[root@n1 ~]# systemctl get-default 
graphical.target

- 手动修改启动级别(先将原来的rm了)
[root@n1 ~]# ln -sv /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target
ln: failed to create symbolic link ‘/etc/systemd/system/default.target’: File exists
[root@n1 ~]# rm -rf /etc/systemd/system/default.target
[root@n1 ~]# ln -sv /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target
‘/etc/systemd/system/default.target’ -> ‘/usr/lib/systemd/system/multi-user.target’
[root@n1 ~]# systemctl get-default 
multi-user.target

- 查看服务状态

[root@n1 ~]# systemctl is-enabled httpd.service 
disabled

使用centos系统中的crontab命令对mongodb定时备份恢复

通过centos脚本来执行备份操作,使用crontab命令实现定时备份与恢复功能,并删除指定天数前的备份

具体操作:

1、创建Mongodb数据库备份目录

mkdir -p /home/backup/mongod_bak/mongod_bak_now
mkdir -p /home/backup/mongod_bak/mongod_bak_list

2、新建Mongodb数据库备份脚本

vi /home/crontab/mongod_bak.sh #新建文件,输入以下代码
#!/bin/sh
DUMP=/usr/local/mongodb/bin/mongodump #mongodump备份文件执行路径
OUT_DIR=/home/backup/mongod_bak/mongod_bak_now #临时备份目录
TAR_DIR=/home/backup/mongod_bak/mongod_bak_list #备份存放路径
DATE=`date +%Y_%m_%d` #获取当前系统时间
DB_USER=username #数据库账号
DB_PASS=123456 #数据库密码
DAYS=7 #DAYS=7代表删除7天前的备份,即只保留最近7天的备份
TAR_BAK="mongod_bak_$DATE.tar.gz" #最终保存的数据库备份文件名
cd $OUT_DIR
rm -rf $OUT_DIR/*
mkdir -p $OUT_DIR/$DATE
$DUMP -u $DB_USER -p $DB_PASS -o $OUT_DIR/$DATE #备份全部数据库
tar -zcvf $TAR_DIR/$TAR_BAK $OUT_DIR/$DATE #压缩为.tar.gz格式
find $TAR_DIR/ -mtime +$DAYS -delete #删除7天前的备份文件

3、修改文件属性,使其可执行

chmod +x /home/crontab/mongod_bak.sh

4、修改/etc/crontab #添加计划任务

crontab -e

在下面添加

30 1 * * * root /home/crontab/mongod_bak.sh #表示每天凌晨1点30执行备份

5、重新启动crond使设置生效

/sbin/service crond reload #重新载入配置
chkconfig --level 35 crond on #加入开机自动启动:
/sbin/service crond start  #启动服务
crontab -l #列出crontab文件

每天在/home/backup/mongod_bak/mongod_bak_list目录下面可以看到mongod_bak_2017_02_28.tar.gz这样的压缩文件。

至此,Linux下自动备份Mongodb数据库并删除指定天数前的备份完成。

Mongodb定时恢复备份

恢复全部数据库:

mongorestore Cdrop Cdirectoryperdb 
/home/backup/mongod_bak/mongod_bak_now/2017_02_28/

恢复单个数据库:

mongorestore Cdrop -d dataname Cdirectoryperdb 
/home/backup/mongod_bak/mongod_bak_now/2017_02_28/dataname

Cdrop参数:恢复数据之前删除原来数据库数据,避免数据重复。

Cdirectoryperdb参数:数据库备份目录

-d参数:后面跟要恢复的数据库名称

crontab命令:

crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语 chronos(χρ?νο?),原意是时间。

通常,crontab储存的指令被守护进程激活, crond常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为cron jobs。

安装crontab:

[root@CentOS ~]# yum install vixie-cron
[root@CentOS ~]# yum install crontabs

说明:
vixie-cron软件包是cron的主程序;
crontabs软件包是用来安装、卸装、或列举用来驱动 cron 守护进程的表格的程序。

cron 是linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:

/sbin/service crond start #启动服务
/sbin/service crond stop #关闭服务
/sbin/service crond restart #重启服务
/sbin/service crond reload #重新载入配置

查看crontab服务状态:

service crond status

手动启动crontab服务:

service crond start

其他命令:

#查看crontab服务是否已设置为开机启动,执行命令:
ntsysv

#加入开机自动启动:
chkconfig --level 35 crond on

#列出crontab文件
crontab -l

#编辑crontab文件
crontab -e

#删除crontab文件
$ crontab -r

#恢复丢失的crontab文件
#假设你在自己的$HOME目录下还有一个备份,那么可以将其拷贝到/var/spool/cron/<username>,其中<username >是用户名
#或者使用如下命令其中,<filename>是你在$HOME目录中副本的文件名
crontab <filename>

在 CentOS 7 平台使用 cnpmjs.org 搭建 npm 私有仓储

一、安装系统并配置编译环境

1、下载 CentOS 7 系统镜像并安装,选择基本开发环境。

2、修改默认 yum 源为阿里云源,并添加 EPEL 源。

# 如提示 wget 不存在,可使用 curl 下载
# 备份默认源
sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
# 修改为阿里源
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 添加 EPEL 源
sudo wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

3、安装 gcc 编译环境

sudo yum install gcc-c++ make

4、验证安装结果

# 验证 g++ 版本
g++ -v

使用内建 specs。
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
目标:x86_64-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
线程模型:posix
gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)

# 验证 make 版本
make -v

GNU Make 3.82
Built for x86_64-redhat-linux-gnu
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

二、监测环境并安装 node.js

1、执行环境检测脚本,下载 node 在相应环境的已编译包

curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -

2、安装 node 和 npm

sudo yum -y install nodejs

3、验证安装结果

# 验证 node 版本
node -v
v8.9.4

# 验证 npm 版本
npm -v
5.6.0

三、安装并配置 cnpmjs.org

1、安装 cnpmjs.org依赖

# 安装 cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 安装 node-pre-gyp
cnpm install -g node-pre-gyp
# 安装 sqlite3 直接安装会报错 node-pre-gyp: 未找到命令
cnpm install -g sqlite3
# 安装 cnpmjs.org
cnpm install -g cnpmjs.org
# 创建配置目录 ~/.cnpmjs.org
cnpmjs.org start

2、验证安装结果

# 验证 cnpm 版本
cnpm -v

[email protected] (/usr/lib/node_modules/cnpm/lib/parse_argv.js)
[email protected] (/usr/lib/node_modules/cnpm/node_modules/npm/lib/npm.js)
[email protected] (/usr/bin/node)
[email protected] (/usr/lib/node_modules/cnpm/node_modules/npminstall/lib/index.js)
prefix=/usr 
linux x64 3.10.0-327.el7.x86_64 
registry=https://registry.npm.taobao.org

# 验证 node-pre-gyp 版本
node-pre-gyp -v
v0.6.39

# 验证 sqlite3 版本
sqlite3 -version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

# 验证 cnpmjs.org 版本
cnpmjs.org --version
2.19.4

3、添加防火墙例外

# 检查防火墙状态
systemctl status firewalld
# 启动防火墙,未启动会报错 FirewallD is not running
systemctl start firewalld
# 添加 7001 端口
firewall-cmd --zone=public --add-port=7001/tcp --permanent
# 添加 7002 端口
firewall-cmd --zone=public --add-port=7002/tcp --permanent
# 根据需要,关闭防火墙
systemctl stop firewalld

四、修改 cnpmjs.org 配置

1、修改 /root/.cnpmjs.org/config.json (实际使用中必须删除注释,否则 json 格式错误)

{
  "registryPort": 7001, // cnpmjs.org web 站点端口
  "webPort": 7002, // cnpmjs.org register 端口
  "bindingHost": "0.0.0.0", // 允许外部访问
  "handleSyncRegistry": "http://127.0.0.1:7001", // 同步源
  "registryHost": "registry.npm.xxxxxx.work", // cnpmjs.org register 域名
  "scopes": [
    "@xxxxxx" // 私有包 scope 名称
  ],
  "enablePrivate": false, // 允许所有登录用户发布私有包
  "syncModel": "none", // 不同步公共包
  "alwaysAuth": false, // 不强制用户认证
  "customReadmeFile": "/root/.cnpmjs.org/docs/web/readme.md", // 自定义首页
  "userService": "/root/.cnpmjs.org/services/custom_user_service.js", // 自定义用户认证
  "admins": {
    "admin": "[email protected]" // cnpmjs.org 管理员
  },
  "database": { // cnpmjs.org 数据库
    "db": "cnpmjs_test", // 数据库名称
    "username": "root", // 数据库用户名
    "password": "", // 数据库密码
    "dialect": "sqlite", // 数据库类型
    "host": "127.0.0.1", // 数据库 IP
    "port": 3306, // 数据库端口
    "storage": "/root/.cnpmjs.org/data.sqlite" // sqlite 数据库位置
  }
}

2、修改 cnpmjs.org 源码
/usr/lib/node_modules/cnpmjs.org/services/user.js

11 +  if(typeof(config.userService) === 'string') {
12 +    var CustomUserService = require(config.userService);
13 +    config.userService = new CustomUserService();
14 +  }

3、自定义首页 /root/.cnpmjs.org/docs/web/readme.md

# 公司 npm 私有仓储

[npm.xxxxxx.work](http://npm.xxxxxx.work) 基于 [cnpmjs.org](https://github.com/cnpm/cnpmjs.org) 搭建,使用 @xxxxxx 作为私有仓储的 [scope](https://docs.npmjs.com/getting-start)  
仅用于托管公司私有包,不同步公共包,可使用 npm 或 cnpm 客户端。  

## npm 或 cnpm 客户端配置

1. 拦截 @xxxxxx 作用域下所有操作至私有仓储,可安装公司私有包。  
``bash
# 或替换为 cnpm 命令
$ npm config set @xxxxxx:registry http://registry.npm.xxxxxx.work
``

2. 使用 [git.xxxxxx.work](http://git.xxxxxx.work) 用户名和[个人访问令牌](http://git.xxxxxx.work/profile/personal_access_tokens)登录,可发布公司私有包。  
``bash
# 或替换为 cnpm 命令
$ npm login --scope=@xxxxxx --registry=http://registry.npm.xxxxxx.work

Username: zhangsan # 用户名
Password: xxxxxxxxxxxxxxxxxxxx # 个人访问令牌(需勾选 Scopes 中 api 选项)
Email: (this IS public) [email protected] # 邮箱
``

## 更多信息请查看[使用说明](http://xxxxxx.wiki/pages/viewpage.action?pageId=8524381)

**此处粘贴 /usr/lib/node_modules/cnpmjs.org/docs/web/readme.md 文件内容**

4、自定义用户认证 /root/.cnpmjs.org/services/custom_user_service.js

const http = require('http');
const isAdmin = require('cnpmjs.org/lib/common').isAdmin;
const config = require('cnpmjs.org/config');

// User: https://github.com/cnpm/cnpmjs.org/wiki/Use-Your-Own-User-Authorization#user-data-structure
// {
//   "login": "fengmk2",
//   "email": "[email protected]",
//   "name": "Yuan Feng",
//   "html_url": "http://fengmk2.github.com",
//   "avatar_url": "https://avatars3.githubusercontent.com/u/156269?s=460",
//   "im_url": "",
//   "site_admin": false,
//   "scopes": ["@org1", "@org2"]
// }

const emailDomain = '@xxxx.com';
const defaultToken = 'xxxxxxxxxxxxxxxxxxxx';

function convertToUser(gitUser) {
  let user = {
    login: gitUser.username,
    email: gitUser.email || `${gitUser.username}${emailDomain}`,
    name: gitUser.name,
    html_url: gitUser.web_url,
    avatar_url: gitUser.avatar_url,
    im_url: '',
    site_admin: isAdmin(gitUser.username),
    scopes: config.scopes,
  };

  return user;
}

function gitHttp(api, token) {
  return new Promise((resolve, reject) => {
    let options = {
      method: 'GET',
      port: 80,
      hostname: 'git.xxxxxx.work',
      path: `/api/v4${api}`,
      headers: {
        'PRIVATE-TOKEN': token
      }
    };

    let req = http.request(options, (res) => {
      if (res.statusCode === 200) {
        res.setEncoding('utf8');

        let rawData = '';
        res.on('data', (chunk) =&gt; {
          rawData += chunk;
        });

        res.on('end', () => {
          try {
            let parsedData = JSON.parse(rawData);
            console.log(`[CustomUserService] [${api}] [${token}] JSON.parse: success`, parsedData);

            resolve(parsedData);
          } catch (e) {
            reject(`[CustomUserService] [${api}] [${token}] JSON.parse: ${e.message}`, e);
          }
        });
      }
      else {
        reject(`[CustomUserService] [${api}] [${token}] statusCode: ${res.statusCode}`);
      }
    });

    req.on('error', (e) => {
      reject(`[CustomUserService] [${api}] [${token}] error: ${e.message}`, e);
    });

    req.end();
  });
}

function* gitAuth(username, token) {
  let data = yield gitHttp('/user', token);

  let gitUser = null;
  if (data && data.username === username) {
    gitUser = data;
  }

  return gitUser;
}

function* gitGet(username) {
  let data = yield gitHttp(`/users?username=${encodeURIComponent(username)}`, defaultToken);

  let gitUser = null;
  if (data && data.length > 0 && data[0].username === username) {
    gitUser = data[0];
  }

  return gitUser;
}

function* gitList(usernames) {
  let gitUsers = [];

  if (usernames && usernames.length > 0) {
    for (let i = 0; i < usernames.length; i++) {
      let username = usernames[i];
      let gitUser = yield gitGet(username);
      if (gitUser) {
        gitUsers.push(gitUser);
      }
    }
  }

  return gitUsers;
}

function* gitSearch(query, limit) {
  let data = yield gitHttp(`/users?search=${encodeURIComponent(query)}&per_page=${limit}`, defaultToken);

  let gitUsers = [];
  if (data && data.length > 0) {
    gitUsers = data;
  }

  return gitUsers;
}

function CustomUserService() { }
const proto = CustomUserService.prototype;

/**
 * Auth user with login name and password
 * @param  {String} login    login name
 * @param  {String} password login password
 * @return {User}
 */
proto.auth = function* (login, password) {
  console.log(`[CustomUserService] [auth]`, login, password);

  let user = null;

  try {
    let gitUser = yield gitAuth(login, password);

    if (gitUser) {
      user = convertToUser(gitUser);
    }
  }
  catch (e) {
    console.log(`[CustomUserService] [auth]`, e);
  }

  return user;
};

/**
 * Get user by login name
 * @param  {String} login  login name
 * @return {User}
 */
proto.get = function* (login) {
  console.log(`[CustomUserService] [get]`, login);

  let user = null;

  try {
    let gitUser = yield gitGet(login);

    if (gitUser) {
      user = convertToUser(gitUser);
    }
  }
  catch (e) {
    console.log(`[CustomUserService] [get]`, e);
  }

  return user;
};

/**
 * List users
 * @param  {Array<String>} logins  login names
 * @return {Array<User>}
 */
proto.list = function* (logins) {
  console.log(`[CustomUserService] [list]`, logins);

  let users = [];

  try {
    let gitUsers = yield gitList(logins);

    gitUsers.forEach((gitUser) => {
      users.push(convertToUser(gitUser));
    });
  }
  catch (e) {
    console.log(`[CustomUserService] [list]`, e);
  }

  return users;
};

/**
 * Search users
 * @param  {String} query  query keyword
 * @param  {Object} [options] optional query params
 *  - {Number} limit match users count, default is `20`
 * @return {Array<User>}
 */
proto.search = function* (query, options) {
  console.log(`[CustomUserService] [search]`, query, options);

  let users = [];

  try {
    options = options || {};
    options.limit = parseInt(options.limit);
    if (!options.limit || options.limit < 0) {
      options.limit = 20;
    }

    let gitUsers = yield gitSearch(query, options.limit);

    gitUsers.forEach((gitUser) => {
      users.push(convertToUser(gitUser));
    });
  }
  catch (e) {
    console.log(`[CustomUserService] [search]`, e);
  }

  return users;
};

module.exports = CustomUserService;

5、验证自定义配置

export NODE_PATH=/usr/lib/node_modules && /usr/bin/cnpmjs.org start

Starting cnpmjs.org ...
cluster: false
admins: {"admin":"[email protected]"}
scopes: ["@xxxxxx"]
sourceNpmRegistry: https://registry.npm.taobao.org
syncModel: none
[Tue Mar 06 2018 17:05:20 GMT+0800 (CST)] [worker:8004] Server started, registry server listen at 0.0.0.0:7001, web listen at 0.0.0.0:7002, cluster: false

五、开机启动 cnpmjs.org 并配置域名和定期备份

1、创建服务并开机自启 /usr/lib/systemd/system/cnpmjs.org.service

[Unit]
Description=cnpmjs.org
After=network.target

[Service]
Type=simple
User=root
Environment=NODE_PATH=/usr/lib/node_modules
ExecStart=/usr/bin/cnpmjs.org start
ExecStop=/usr/bin/cnpmjs.org stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target

2、应用并启动 cnpmjs.org 服务

# 刷新服务守护进程
systemctl daemon-reload
# 启动 cnpmjs.org 服务
systemctl start cnpmjs.org.service
# 设置开机启动
systemctl enable cnpmjs.org.service
# 查看启动日志
journalctl -u cnpmjs.org.service

3、配置 nginx 反向代理

# cnpmjs.org registry
server {
    listen       80;
    server_name  registry.npm.xxxxxx.work;
    location / {
        #proxy_redirect off;
        proxy_pass http://192.168.21.23:7001;
    }
}

# cnpmjs.org web
server {
    listen       80;
    server_name  npm.xxxxxx.work;
    location / {
        #proxy_redirect off;
        proxy_pass http://192.168.21.23:7002;
    }
}

4、验证域名配置

curl npm.xxxxxx.work
curl registry.npm.xxxxxx.work

5、创建备份脚本 /root/.cnpmjs.org/backup/backup.sh
由于 cnpmjs.org 使用文件方式存放已发布的包,因此只用备份 sqlite 数据库即可。

#!/bin/sh

# 当前时间
var_dateTime=$(date +%Y%m%d%H%M)
# cnpmjs.org 配置目录
var_workDir="/root/.cnpmjs.org"
# 备份目录
var_backupDir=${var_workDir}"/backup/"${var_dateTime}
# 创建备份目录
mkdir -p ${var_backupDir}
# 数据库源位置
var_dataSource=${var_workDir}"/data.sqlite"
# 数据库目标位置
var_dataTarget=${var_backupDir}"/data.sqlite"
# 备份数据库
sqlite3 ${var_dataSource} ".backup ${var_dataTarget}"

6、验证备份脚本

# 修改备份脚本执行权限
chmod a+x /root/.cnpmjs.org/backup/backup.sh

# 执行备份脚本
/root/.cnpmjs.org/backup/backup.sh

# 检查是否已经生成备份
ls -l /root/.cnpmjs.org/backup/

7、配置定时任务

# 编辑定时任务文件 /var/spool/cron/root
crontab -e

# 每周日 00:00 执行备份
0 0 * * 0 /root/.cnpmjs.org/backup/backup.sh

# 如果未正常进行,检查以下文件
cat /var/log/cron
cat /var/spool/mail/root

六、【非服务端】npm 或 cnpm 客户端配置

1、拦截 @xxxxxx 作用域下所有操作至私有仓储,可安装公司私有包。

# 或替换为 cnpm 命令
npm config set @xxxxxx:registry http://registry.npm.xxxxxx.work

2、使用 git.xxxxxx.work 用户名和个人访问令牌登录,可发布公司私有包。

# 或替换为 cnpm 命令
npm login --scope=@xxxxxx --registry=http://registry.npm.xxxxxx.work

Username: zhangsan # 用户名
Password: xxxxxxxxxxxxxxxxxxxx # 个人访问令牌(需勾选 Scopes 中 api 选项)
Email: (this IS public) [email protected] # 邮箱