postgresql设置主键自增的方法

一 :

CREATE TABLE customers  

(  

  customerid SERIAL primary key ,  

  companyname character varying,  

  contactname character varying,  

  phone character varying,  

 country character varying  

)  

二 :

CREATE SEQUENCE event_id_seq  

START WITH 1  

INCREMENT BY 1  NO MINVALUE  NO MAXVALUE  

CACHE 1;

alter table event alter column id set default nextval('event_id_seq'); 

CentOS 7系统使用firewalld管理防火墙端口

1、firewalld的基本使用

启动: systemctl start firewalld
查看状态: systemctl status firewalld 
停止: systemctl disable firewalld
禁用: systemctl stop firewalld

2、systemctl是CentOS7的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体。

启动一个服务:systemctl start firewalld.service
关闭一个服务:systemctl stop firewalld.service
重启一个服务:systemctl restart firewalld.service
显示一个服务的状态:systemctl status firewalld.service
在开机时启用一个服务:systemctl enable firewalld.service
在开机时禁用一个服务:systemctl disable firewalld.service
查看服务是否开机启动:systemctl is-enabled firewalld.service
查看已启动的服务列表:systemctl list-unit-files|grep enabled
查看启动失败的服务列表:systemctl --failed

3、配置firewalld-cmd

查看版本: firewall-cmd --version
查看帮助: firewall-cmd --help
显示状态: firewall-cmd --state
查看所有打开的端口: firewall-cmd --zone=public --list-ports
更新防火墙规则: firewall-cmd --reload
查看区域信息:  firewall-cmd --get-active-zones
查看指定接口所属区域: firewall-cmd --get-zone-of-interface=eth0
拒绝所有包:firewall-cmd --panic-on
取消拒绝状态: firewall-cmd --panic-off
查看是否拒绝: firewall-cmd --query-panic

那怎么开启一个端口呢

添加

firewall-cmd --zone=public --add-port=80/tcp --permanent    (--permanent永久生效,没有此参数重启后失效)

重新载入

firewall-cmd --reload

查看

firewall-cmd --zone= public --query-port=80/tcp

删除

firewall-cmd --zone= public --remove-port=80/tcp --permanent

GlusterFS和Ceph各方面的对比

存储世界最近发生了很大变化。十年前,Fibre Channel SAN文件管理器是企业存储的标准。而在目前的环境中,受到基础架构即服务云的影响,数据存储需要更加灵活。

GlusterFS和Ceph是两个灵活的存储系统,在云环境中表现非常出色。

在尝试了解GlusterFS与Ceph之间的相似之处和不同之处之前,让我们来讨论在云环境中对灵活存储的一些要求。

  • 纵向扩展和横向扩展。在云环境中,必须可以很容易地向服务器添加更多存储空间以及扩展可用存储池。Ceph和GlusterFS都可以通过轻松将新存储设备集成到现有存储产品中来满足这一要求。

  • 高可用性。GlusterFS和Ceph的复制是同时将数据写入不同的存储节点。这样做的结果是,访问时间增加,数据可用性也提高。在Ceph中,默认情况下将数据复制到三个不同的节点,这确保备份始终可用。

  • 商品化硬件。GlusterFS和Ceph是在Linux操作系统之上开发的。因此,对硬件唯一的要求是这些产品具有能够运行Linux的硬件。任何商品化硬件都可以运行Linux操作系统,结果是使用这些技术的公司可以大大减少在硬件上的投资——如果他们这样做的话。然而,实际上,许多公司正在投资专门用于运行GlusterFS或Ceph的硬件,因为更快的硬件可以更快地访问存储。

  • 去中心化。在云环境中,永远不应该有中心点故障。对于存储,这意味着不应该用一个中央位置存储元数据。GlusterFS和Ceph实现了元数据访问去中心化的解决方案,从而降低了存储访问的可用性和冗余性。

现在来谈谈GlusterFS与Ceph的差异。顾名思义,GlusterFS是来自Linux世界的文件系统,并且遵守所有Portable Operating System Interface标准。尽管你可以将GlusterFS轻松集成到面向Linux的环境中,但在Windows环境中集成GlusterFS很难。

Ceph是一种全新的存储方法,对应于Swift对象存储。在对象存储中,应用程序不会写入文件系统,而是使用存储中的直接API访问写入存储。因此,应用程序能够绕过操作系统的功能和限制。如果已经开发了一个应用程序来写入Ceph存储,那么使用哪个操作系统无关紧要。结果是,Ceph存储在Windows环境中像在Linux环境中一样容易集成。

基于API的存储访问并不是应用程序可以访问Ceph的唯一方式。为了最佳的集成,还有一个Ceph块设备,它可以在Linux环境中用作常规块设备,使你可以像访问常规Linux硬盘一样来使用Ceph。Ceph还有CephFS,它是针对Linux环境编写的Ceph文件系统。

最近,SUSE添加了一个iSCSI接口,使得运行iSCSI客户端的客户端能像任何其他iSCSI目标一样访问Ceph存储。

所有这些功能使得Ceph成为异构环境的更好选择,而不仅仅是使用Linux操作系统。

所以Ceph是一个更灵活的产品,更容易集成到非Linux环境中。对于许多公司来说,这足以让它们在Ceph而不是GlusterFS上构建存储产品。对于仅运行Linux的环境,此功能不够有说服力,所以来谈谈另一个非常重要的事情:速度。

为了比较GlusterFS与Ceph哪个更快已经进行了几项测试,但迄今为止没有确切的结论。GlusterFS存储算法更快,并且由于GlusterFS以砖组织存储的方式实现了更多的分层,这在某些场景下(特别是使用非优化Ceph的话)可能导致更快的速度。另一方面,Ceph提供了足够的定制功能来使其与GlusterFS一样快——结果是两者的性能都不够令人信服一个比另一个更强。

然而,现实表明,Ceph访问存储的不同方法使其成为更流行的技术。事实证明,更多的公司正在考虑Ceph技术而不是GlusterFS,而且GlusterFS仍然与Red Hat密切相关。例如,SUSE还没有GlusterFS的商业实施,而Ceph已经被开源社区广泛采用,市场上有各种不同的产品。可以说,Ceph确实已经胜过GlusterFS。

Ubuntu下安装MySQL-python模块遇到的问题及解决方法

今天把工作台转移到ubuntu上面,因为之前用win开发的时候用的一直都是 sqlite,这货,个人认为 不太好用,先不说它为啥不好用,先来说说今天遇到的问题吧,Python – Flask + Mysql

Error: No module named MySQLdb

在 安装各种依赖的时候 ,出现了这么一个错误

俺 无意识的就直接 pip install MySQLdb ,但是很不幸,并没有,于是 pip install MySQL-python,

(env)xxx@xxx:~/xxx$ pip install MySQL-python
Collecting MySQL-python

  Downloading MySQL-python-1.2.5.zip (108kB)
    100% |████████████████████████████████| 112kB 15kB/s 
    Complete output from command python setup.py egg_info:
    sh: 1: mysql_config: not found
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-ezVWsX/MySQL-python/setup.py", line 17, in <module>
        metadata, options = get_config()
      File "setup_posix.py", line 43, in get_config
        libs = mysql_config("libs_r")
      File "setup_posix.py", line 25, in mysql_config
        raise EnvironmentError("%s not found" % (mysql_config.path,))
    EnvironmentError: mysql_config not found

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-ezVWsX/MySQL-python/

很不幸提示找不到 mysql_config这个配置文件,于是俺 find 了一下 mysql_config,看看有没有这个文件

$ sudo find / -name mysql_config
$ 

没有任何结果数据,于是问题貌似就很明显了,Google了一下,看到有人说是

使用apt-get安装的MySQL是没有mysql_config这个文件的

简单回忆了一下,好像确实是这样,于是俺 准备重新装一下sudo apt-get install libmysqld-dev:

然后再find一下,果然

$ sudo find / -name mysql_config
/usr/bin/mysql_config

然后重新pip 安装一下就ok,

看到也有很多网友用源码安装的时候也是出现这个问题,于是俺也照着做了一遍,

$ wget http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz
$ tar zxvf MySQL-python-1.2.3.tar.gz
$ cd MySQL-python-1.2.3/

再到 MySQL-python-1.2.3下面 把 setup_posix.py 和 site.cfg 两个文件里的 mysql_config 对应值修改为/usr/bin/mysql_config ,保存后,再次运行 python setup.py build 就OK 。

$ python setup.py build build
$ python setup.py install 

这样以来,MySQLdb 的问题 就完美解决了 。

CentOS 6.7与CentOS 7.3内存查看命令free、top的差异对比

本文是作者学习及应用笔记,以CentOS 6.7和CentOS 7.X为例,介绍Linux中查看内存占用情况的free、top命令的常见用法及对比。

  • CENTOS 6.7 free -mlt(看buffers/cache free可知真正可用的空闲内存)
  • CENTOS 7.3 free -mlht(看available可知真正可用的空闲内存)
  • CENTOS 6.7 top -bn1 -a(按当前各个进程占用内存倒序)
  • CENTOS 7.3 top -bn1 -o “%MEM” (按当前各个进程占用内存倒序)
  • CENTOS 7.3 top -bn1 -o “%CPU” (按当前各个进程占用CPU倒序)

以CENTOS 6.7为例,解释命令及查看要点,并对照给出CENTOS7.3的差异

[ ~]# cat /etc/redhat-release 
CentOS release 6.7 (Final)
[ ~]# 
[ ~]# uname -a                
Linux  2.6.32-573.8.1.el6.x86_64 #1 SMP Tue Nov 10 18:01:38 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
[ ~]# 

free

[ ~]# free -mlt 
             total       used       free     shared    buffers     cached
Mem:           994        866        128          0        207        387
Low:           994        866        128
High:            0          0          0
-/+ buffers/cache:        271        723
Swap:            0          0          0
Total:         994        866        128
[ ~]# 
  • 上例为CENTOS 6.7,重点关注buffers/cache中的free = 723那项,表示可用的空余内存为723MB,其余的项都可以不管。

  • CENTOS7.3的free命令已有变化,请参见本文末尾附录CENTOS 7.3,free直接给出了空余内存available = 61,即61GB空余。同时,新版本的free增加了-h选项,支持以人性化的单位(K/M/G)显示各个数值。

top

[ ~]# top -bn1 -a | head -n 10       
top - 22:37:24 up 154 days,  4:57,  1 user,  load average: 0.02, 0.03, 0.00
Tasks:  93 total,   1 running,  92 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.1%us,  0.1%sy,  0.0%ni, 99.5%id,  0.2%wa,  0.0%hi,  0.0%si,  0.1%st
Mem:   1018508k total,   887376k used,   131132k free,   212380k buffers
Swap:        0k total,        0k used,        0k free,   396972k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                
25136 mongodb   20   0  645m  53m 7388 S  0.0  5.4 205:33.86 mongod                                                                 
18729 root      20   0  103m  34m  828 S  0.0  3.4  24:46.64 redis-server                                                           
22333 mysql     20   0  695m  29m 3296 S  0.0  3.0  17:54.86 mysqld   
  • 在CENTOS 6.7中,top支持-a选项,不支持-o选项。-a选项可以按各进程内存占用从大到小排序。

  • 在CENTOS 7.3中,top不支持-a选项,支持-o选项。-o “%CPU”是按CPU使用率排序;-o “%MEM”是按内存占用排序,这个与6.7版本的-a含义相同。具体请参见如下附录。

附录:CENTOS 7.3

[CENTOS73 ~]# cat /etc/redhat-release 
CentOS Linux release 7.3.1611 (Core) 
[CENTOS73 ~]# 
[CENTOS73 ~]# uname -a
Linux CENTOS73 3.10.0-514.21.2.el7.x86_64 #1 SMP Tue Jun 20 12:24:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[CENTOS73 ~]# 
[CENTOS73 ~]# 
[CENTOS73 ~]# top -bn1 -o "%MEM" | head
top - 22:42:44 up 39 days,  1:30,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 293 total,   1 running, 292 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 65798332 total, 63365896 free,  1111540 used,  1320896 buff/cache
KiB Swap: 33030140 total, 33030140 free,        0 used. 64057156 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3512 root      20   0 2319720 225432  49512 S   0.0  0.3  23:43.69 gnome-shell
 3739 root      20   0 1515744  65180  21744 S   0.0  0.1   0:00.86 evolution-calen
 3653 root      39  19 1308088  40700   7832 S   0.0  0.1   0:00.39 tracker-extract
[CENTOS73 ~]# 
[CENTOS73 ~]# top -bn1 -o "%CPU" | head   
top - 22:42:49 up 39 days,  1:30,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 293 total,   1 running, 292 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 65798332 total, 63366392 free,  1111044 used,  1320896 buff/cache
KiB Swap: 33030140 total, 33030140 free,        0 used. 64057652 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0  196468   7572   3972 S   0.0  0.0   2:33.80 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:01.12 kthreadd
    3 root      20   0       0      0      0 S   0.0  0.0   0:06.62 ksoftirqd/0
[CENTOS73 ~]# 
[CENTOS73 ~]# 
[CENTOS73 ~]# free -mlht
              total        used        free      shared  buff/cache   available
Mem:            62G        1.1G         60G         73M        1.3G         61G
Low:            62G        2.3G         60G
High:            0B          0B          0B
Swap:           31G          0B         31G
Total:          94G        1.1G         91G
[CENTOS73 ~]# 

附录:top的-n和-b选项

    -b  :Batch-mode operation
            Starts top in Batch mode, which could be useful for sending output from top to other programs or to a file.  In this
            mode,  top will not accept input and runs until the iterations limit you've set with the `-n' command-line option or
            until killed.
       -n  :Number-of-iterations limit as:  -n number
            Specifies the maximum number of iterations, or frames, top should produce before ending.

centos 7系统下重置mysql 5.7 root密码的步骤

mysql5.7版本之后,与mariadb不同,在安装之后,在启动之时,会进行自动随机密码的设定,所以在systemctl start mysqld之后,会出现mysql -uroot -p无法登陆的情况

mysql root原始密码查看

实际上mysqld在启动时,会自动设定root密码的,可以在其相关日志里面查看到,如下:

[root@bogon ~]# grep password /var/log/mysqld.log
2017-07-31T10:31:57.368883Z 1 [Note] A temporary password is generated for root@localhost: TjcrBm.j,7eU
2017-07-31T10:32:30.201882Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2017-07-31T10:34:40.233539Z 0 [Note] Shutting down plugin 'validate_password'
2017-07-31T10:34:41.483983Z 0 [Note] Shutting down plugin 'sha256_password'
2017-07-31T10:34:41.483990Z 0 [Note] Shutting down plugin 'mysql_native_password'

mysql root的初始密码为TjcrBm.j,7eU(每人情况不一样,具体值在mysql日志中查看)

mysql密码重置

当然有些人可能是root密码真忘记了,那样可以通过mysql免密码登陆

在其配置文件/etc/my.cnf中加入skip-grant-tables=1即可

[root@bogon ~]# grep -v ^# /etc/my.cnf | grep -v ^$
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
skip-grant-tables=1

然后重启mysql,使用mysql命令即可进入

[root@bogon ~]# systemctl restart mysqld
[root@bogon ~]# ss -tnl
State      Recv-Q Send-Q             Local Address:Port                            Peer Address:Port              
LISTEN     0      128                    127.0.0.1:9000                                       *:*                  
LISTEN     0      128                            *:111                                        *:*                  
LISTEN     0      128                            *:80                                         *:*                  
LISTEN     0      128                            *:22                                         *:*                  
LISTEN     0      100                    127.0.0.1:25                                         *:*                  
LISTEN     0      80                            :::3306                                      :::*                  
LISTEN     0      128                           :::111                                       :::*                  
LISTEN     0      128                           :::22                                        :::*                  
LISTEN     0      100                          ::1:25                                        :::*  
[root@bogon ~]# mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 4
Server version: 5.7.19

Copyright (c) 2000, 2017, 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> 

修改mysql root密码

mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> update user set authentication_string = password("123456") where user="root";
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 1

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

然后将/etc/my.cnf中的skip-grant-tables=1注释掉,重启mysql服务即可。

在此要注意的是,之前版本密码修改字段为password,在5.7版本之后字段为authentication_string

mysql密码难度修改

mysql密码修改为123456之后,有人发现使用123456能进入mysql,但是却不能使用mysql的任何功能。会出现如下情况:

[root@bogon ~]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 4
Server version: 5.7.19

Copyright (c) 2000, 2017, 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> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

实际上,在初始更改root密码时,并不能直接使用update来更改,需要使用alter user命令来更改

mysql> alter user 'root'@'localhost' identified by '123456';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
## mysql在5.7版本中加了密码安全等级,弱密码不能使用

mysql> alter user 'root'@'localhost' identified by 'QWEqwe123!@#';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql 安全策略以及root密码清空

在上述修改密码之后,可查看mysql的密码安全策略

[root@bogon ~]# mysql -uroot -p'QWEqwe123!@#'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 6
Server version: 5.7.19 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, 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> show variables like '%password%';
+---------------------------------------+--------+
| Variable_name                         | Value  |
+---------------------------------------+--------+
| default_password_lifetime             | 0      |
| disconnect_on_expired_password        | ON     |
| log_builtin_as_identified_by_password | OFF    |
| mysql_native_password_proxy_users     | OFF    |
| old_passwords                         | 0      |
| report_password                       |        |
| sha256_password_proxy_users           | OFF    |
| validate_password_check_user_name     | OFF    |
| validate_password_dictionary_file     |        |
| validate_password_length              | 8      |
| validate_password_mixed_case_count    | 1      |
| validate_password_number_count        | 1      |
| validate_password_policy              | MEDIUM |
| validate_password_special_char_count  | 1      |
+---------------------------------------+--------+
14 rows in set (0.00 sec)

其中可以看到validate有很多参数:

  • validate_password_dictionary_file:插件用于验证密码强度的字典文件路径。

  • validate_password_length:密码最小长度。

  • validate_password_mixed_case_count:密码至少要包含的小写字母个数和大写字母个数。

  • validate_password_number_count:密码至少要包含的数字个数。

  • validate_password_policy:密码强度检查等级,0/LOW、1/MEDIUM、2/STRONG。

  • validate_password_special_char_count:密码至少要包含的特殊字符数。

其中,关于validate_password_policy-密码强度检查等级:

  • 0/LOW:只检查长度。

  • 1/MEDIUM:检查长度、数字、大小写、特殊字符。

  • 2/STRONG:检查长度、数字、大小写、特殊字符字典文件。

可以直接在mysql中进行参数的修改

mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)

mysql> set global validate_password_special_char_count=0;
Query OK, 0 rows affected (0.00 sec)

mysql> set global validate_password_number_count=0;
Query OK, 0 rows affected (0.00 sec)

mysql> set global validate_password_mixed_case_count=0;
Query OK, 0 rows affected (0.00 sec)

mysql> set global validate_password_length=0;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%password%';
+---------------------------------------+-------+
| Variable_name                         | Value |
+---------------------------------------+-------+
| default_password_lifetime             | 0     |
| disconnect_on_expired_password        | ON    |
| log_builtin_as_identified_by_password | OFF   |
| mysql_native_password_proxy_users     | OFF   |
| old_passwords                         | 0     |
| report_password                       |       |
| sha256_password_proxy_users           | OFF   |
| validate_password_check_user_name     | OFF   |
| validate_password_dictionary_file     |       |
| validate_password_length              | 0     |
| validate_password_mixed_case_count    | 0     |
| validate_password_number_count        | 0     |
| validate_password_policy              | LOW   |
| validate_password_special_char_count  | 0     |
+---------------------------------------+-------+
14 rows in set (0.00 sec)

当然,此种变更,只能在当前环境下生效,重启mysql后会失效

想要长期生效,需要将更改写入配置文件中才可永久生效

也可以直接在配置文件中进行修改禁用validate-password功能

编辑my.cnf配置文件,在mysqld下面加入“validate-password=0”,然后重启mysql即可。

[root@bogon ~]# grep -v ^# /etc/my.cnf  | grep -v ^$
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
validate-password=0
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

将mysql的密码安全等级降低之后,可以将root密码修改回来

mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update user set authentication_string = password("") where user="root";
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit

以上密码root即清除为空了。使用mysql即可直接进入mysql。当然生产环境中不推荐此种做法。

Centos 6.5安装PDO PHP扩展

PHP 数据对象PDO扩展为PHP访问数据库定义了一个轻量级的一致接口。PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。最近在我们的建站和OA系统交流群中,有对服务器运维不熟悉的朋友问到关于PHP的PDO扩展安装的问题。本文我们将和大家一起分享如何在服务器上安装PDO扩展。

环境

  • 服务器系统:Centos6.5 (虚拟机演示)

  • PHP软件包存放目录:/data/php-5.6.14/

  • PHP安装目录:/usr/local/php/
  • mysql安装目录:/usr/local/mysql/

操作流程

通过phpinfo()函数我们可以检查服务器是否安装了PDO扩展。如果没有找到PDO扩展信息,那我们通过如下步骤来进行安装:

找到你的PHP的安装包(我的放在/data/php-5.6.14/目录下),并进入PHP扩展的pdo_mysql目录,运行下面命令:

/usr/local/php/bin/phpize

(/usr/local/php/是我的PHP安装目录,大家根据实际情况修改即可)

未分类

执行完上面命令后,我们就会发现当前pdo_msyql目录下就出现了configure文件。

未分类

然之我们执行下面命令:

./configure --with-php-config=/usr/local/php/bin/php-config --with-pdo-mysql=/usr/local/mysql/

参数说明:

  • –with-php-config=/usr/local/php/bin/php-config 指定安装 PHP 的时候的配置
  • –with-pdo-MySQL=/usr/local/mysql/ 指定 MySQL 数据库的安装目录位置
    (这里具体PHP和msyql的安装目录大家根据自己实际情况而定)

继续编译安装:

make && make install

命令执行完毕,效果如下:

未分类

足以最后一行的那个目录,后面会用到,此时生成的pdo_mysql.so文件就在该目录下:

未分类

接下来我们修改PHP配置文件,打开的你的php.ini文件,并添加一行代码:

extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/pdo_mysql.so

(这里是我演示的pdo_mysql.so目录,大家设置时根据自己的实际目录添加)

未分类

最后保存推出,并重启服务。然后使用phpinfo()函数检查一下PDO扩展安装是否成功,结果如下,说明PDO扩展安装成功。

未分类

本文我们和大家一起分享了如何在linux系统中,安装PHP的PDO扩展,如果大家在实际操作中有什么问题,欢迎一起交流讨论,我们共同学习,共同进步。

centOS 6.9安装配置本地yum服务器

准备工作

关闭防火墙

  • 关闭防火墙service iptables stop

  • 设置防火墙开机不启动chkconfig iptables off

  • 查看一下防火墙状态 iptables -vnL 如下图,可以看到已经关闭

未分类

关闭SElinux

使用命令 vim /etc/selinux/config 将SELINUX=enable改为SELINUX=permissive 如下图:

未分类

  • 使用命令setenforce 0让修改生效

  • 使用命令getenforce查看一下,如下图,确实已经生效

未分类

安装ftp服务包

  • 使用命令rpm -ivh /media/CentOS_6.9_Final/Packages/vsftpd-2.2.2-24.el6.x86_64.rpm 如下图:

未分类

  • 启用ftp服务service vsftpd start

  • 将其设为开机启动chkconfig vsftpd on

  • 利用命令ss -tnl 可以看到21端口已经打开

未分类

准备yum系统安装包

  • 创建目录作为yum包的地址mkdir -p /var/ftp/pub/centos/6

  • 由于现阶段不具备大量yum包,笔者用本地光盘内的yum包代替

  • 利用命令mount /dev/sr0  /var/ftp/pub/centos/6将光盘挂载到我们的yum包目录上

未分类

进行测验

我们可以登陆一下,可以看到yum包服务器已经成功搭建

未分类

生成脚本

对于运维来说,自动化才是最重要的,对于配置服务器更是如此,因此本人进行了脚本编辑,如下:

未分类

centos 7使用supervisor管理laravel队列

supervisor使用python开发的一个client/server服务,是linux/unix系统下的一个进程管理工具。它可以很方便的监听、停止、重启一个或多个进程。用supervisor管理的进程,打你个进程意外被杀死,supervisor监听到进程死后,会自动将它重新拉起,很方便的做到自动恢复的功能,不再需要自己写shell脚本控制。

安装supervisor

sudo pip install supervisor

或者

easy_install supervisor

还有其他安装方式,请参考官网

supervisor安装完成后会生成三个执行程序:

  • supervisord:守护进程服务(用于接收进程管理命令)

  • supervisorctl:客户端(用于和守护进程通信,发送管理进程的指令)

  • echo_supervisord_conf:生成初始配置文件程序

配置

运行supervisord服务的时候,需要指定supervisor配置文件,如果没有显示指定,默认在以下目录查找:

/etc/supervisord.conf
/etc/supervisor/supervisord.conf 
//默认是没有这些配置文件的

可以通过echo_supervisord_conf程序生成supervisor的初始化配置文件,如下所示:

mkdir /etc/supervisor
echo_supervisor_conf > /etc/supervisor/supervisord.conf

配置文件说明

supervisor的配置参数较多,下面介绍一下常用的参数配置,详细的配置及说明,请参考官方文档介绍。

[unix_http_server]
file=/tmp/supervisor.sock   ;UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ;socket文件的mode,默认是0700
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid

;[inet_http_server]         ;HTTP服务器,提供web管理界面
;port=127.0.0.1:9001        ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user              ;登录管理后台的用户名
;password=123               ;登录管理后台的密码

[supervisord]
logfile=/tmp/supervisord.log ;日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小
logfile_backups=10           ;日志文件保留备份数量默认10,设为0表示不备份
loglevel=info                ;日志级别,默认info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 文件
nodaemon=false               ;是否在前台启动,默认是false,即以 daemon 的方式启动
minfds=1024                  ;可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ;可以打开的进程数的最小值,默认 200

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord

; [program:xx]是被管理的进程配置参数,xx是进程的名称
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程序启动命令
autostart=true       ; 在supervisord启动的时候也自动启动
startsecs=10         ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
autorestart=true     ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
startretries=3       ; 启动失败自动重试次数,默认是3
user=tomcat          ; 用哪个用户启动进程,默认是root
priority=999         ; 进程启动优先级,默认999,值小的优先启动
redirect_stderr=true ; 把stderr重定向到stdout,默认false
stdout_logfile_maxbytes=20MB  ; stdout 日志文件大小,默认50MB
stdout_logfile_backups = 20   ; stdout 日志文件备份数,默认是10
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false     ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=false     ;默认为false,向进程组发送kill信号,包括子进程

;包含其它配置文件
[include]
files = relative/directory/*.ini    ;可以指定一个或多个以.ini结束的配置文件
include示例:

配置管理进程

进程管理配置参数,不建议全都写在supervisord.conf文件中,应该每个进程写一个配置文件放在include指定的目录下包含进supervisord.conf文件中。

打开最后的include注释:

 [include]
files=/etc/supervisor/conf.d/*.conf
//新增的 Supervisor 配置文件放在 /etc/supervisor/conf.d/ 目录下,并且以 conf 结尾。

这个时候就可以启动了服务了

supervisord -c /etc/supervisor/supervisord.conf

使用supervisor 管理 laravel 队列进程

我们使用 Laravel 队列,会用到 php artisan queue:work 命令,让它监听队列,我们可以通过 nohup 方式让它在后台运行,但是进程如果意外中断是不会自动重启的,所以使用 Supervisor 来监控进程是个很好的方式。

首先在 /etc/supervisor/conf.d/ 目录下新增一个 Supervisor 的配置文件,如下:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /www/artisan queue:work --tries=3
autostart=true
autorestart=true
user=nginx
numprocs=8
redirect_stderr=true
stdout_logfile=/var/log/supervisor/laravel-queue.log

这里 user 填写网站运行进程的用户,如nginx,numprocs 表示启动多少个进程来监听 Laravel 队列。

一切就绪后,我们使用如下命令就可以启动队列进程的监听了:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start laravel-worker:*

这里值得注意的是,如果 Laravel 处理队列的代码更改了,需要重启 Supervisor 的队列管理才能生效。

web 管理界面

未分类

出于安全考虑,默认配置是没有开启web管理界面,需要修改supervisord.conf配置文件,打开http访权限:

[inet_http_server]         ; inet (TCP) server disabled by default
port=127.0.0.1:9001          ; (ip_address:port specifier, *:port for all iface)
username=user              ; (default is no username (open server))
password=123               ; (default is no password (open server))
port:绑定访问IP和端口,这里是绑定的是本地IP和9001端口 
username:登录管理后台的用户名

CentOS 7上搭建安全、容灾、高可用的etcd集群

【编者的话】etcd 是 CoreOS 团队发起的开源项目,基于 Go 语言实现,做为一个分布式键值对存储,通过分布式锁,leader选举和写屏障(write barriers)来实现可靠的分布式协作。

本文目标是部署一个基于TLS(Self-signed certificates)的安全、快速灾难恢复(Disaster Recovery, SNAPSHOT)的高可用(High Availability)的etcd集群。

准备工作

版本信息:

  • OS: CentOS Linux release 7.3.1611 (Core)
  • etcd Version: 3.2.4
  • Git SHA: c31bec0
  • Go Version: go1.8.3
  • Go OS/Arch: linux/amd64

机器配置信息

CoreOS官方推荐集群规模5个为宜,为了简化本文仅以3个节点为例:

NAME       ADDRESS             HOSTNAME                    CONFIGURATION
infra0  192.168.16.227  bjo-ep-kub-01.dev.fwmrm.net  8cpus, 16GB内存, 500GB磁盘
infra1  192.168.16.228  bjo-ep-kub-02.dev.fwmrm.net  8cpus, 16GB内存, 500GB磁盘
infra2  192.168.16.229  bjo-ep-kub-03.dev.fwmrm.net  8cpus, 16GB内存, 500GB磁盘

官方建议配置

硬件            通常场景                    重负载
CPU           2-4 cores                 8-18 cores 
Memory        8GB                       16GB-64GB
Disk          50 sequential IOPS        500 sequential IOPS
Network       1GbE                      10GbE

注:重负载情况以CPU为例,每秒处理数以千计的client端请求。AWS、GCE推荐配置请参考:Example hardware configurations on AWS and GCE

搭建etcd集群

搭建etcd集群有3种方式,分别为Static, etcd Discovery, DNS Discovery。Discovery请参见官网https://coreos.com/etcd/docs/l … .html,在此不再敖述。本文仅以Static方式展示一次集群搭建过程。
每个node的etcd配置分别如下:

$ /export/etcd/etcd --name infra0 --initial-advertise-peer-urls http://192.168.16.227:2380 
--listen-peer-urls http://192.168.16.227:2380 
--listen-client-urls http://192.168.16.227:2379,http://127.0.0.1:2379 
--advertise-client-urls http://192.168.16.227:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=http://192.168.16.227:2380,infra1=http://192.168.16.228:2380,infra2=http://192.168.16.229:2380 
--initial-cluster-state new
$ /export/etcd/etcd --name infra1 --initial-advertise-peer-urls http://192.168.16.228:2380 
--listen-peer-urls http://192.168.16.228:2380 
--listen-client-urls http://192.168.16.228:2379,http://127.0.0.1:2379 
--advertise-client-urls http://192.168.16.228:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=http://192.168.16.227:2380,infra1=http://192.168.16.228:2380,infra2=http://192.168.16.229:2380 
--initial-cluster-state new
$ /export/etcd/etcd --name infra2 --initial-advertise-peer-urls http://192.168.16.229:2380 
--listen-peer-urls http://192.168.16.229:2380 
--listen-client-urls http://192.168.16.229:2379,http://127.0.0.1:2379 
--advertise-client-urls http://192.168.16.229:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=http://192.168.16.227:2380,infra1=http://192.168.16.228:2380,infra2=http://192.168.16.229:2380 
--initial-cluster-state new

TLS

etcd支持通过TLS加密通信,TLS channels可被用于集群peer间通信加密,以及client端traffic加密。Self-signed certificates与Automatic certificates两种安全认证形式,其中Self-signed certificates:自签名证书既可以加密traffic也可以授权其连接。本文以Self-signed certificates为例,使用Cloudflare的cfssl很容易生成集群所需证书。
首先,安装go以及设置环境变量GOPATH

$ cd /export
$ wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz
$ tar -xzf go1.8.3.linux-amd64.tar.gz

$ sudo vim ~/.profile
$ export GOPATH=/export/go_path
$ export GOROOT=/export/go/
$ export CFSSL=/export/go_path/
$ export PATH=$PATH:$GOROOT/bin:$CFSSL/bin

$ source ~/.profile

下载并build CFSSL工具, 安装路径为$GOPATH/bin/cfssl, eg. cfssl, cfssljson会被安装到/export/go_path目录。

$ go get -u github.com/cloudflare/cfssl/cmd/cfssl
$ go get -u github.com/cloudflare/cfssl/cmd/cfssljson

初始化certificate authority

$ mkdir ~/cfssl
$ cd ~/cfssl
$ cfssl print-defaults config > ca-config.json
$ cfssl print-defaults csr > ca-csr.json

配置CA选项, ca-config.json文件内容如下

{
"signing": {
    "default": {
        "expiry": "43800h"
    },
    "profiles": {
        "server": {
            "expiry": "43800h",
            "usages": [
                "signing",
                "key encipherment",
                "server auth"
            ]
        },
        "client": {
            "expiry": "43800h",
            "usages": [
                "signing",
                "key encipherment",
                "client auth"
            ]
        },
        "peer": {
            "expiry": "43800h",
            "usages": [
                "signing",
                "key encipherment",
                "server auth",
                "client auth"
            ]
        }
    }
}

ca-csr.json Certificate Signing Request (CSR)文件内容如下

{
"CN": "My own CA",
"key": {
    "algo": "rsa",
    "size": 2048
},
"names": [
    {
        "C": "US",
        "L": "CA",
        "O": "My Company Name",
        "ST": "San Francisco",
        "OU": "Org Unit 1",
        "OU": "Org Unit 2"
    }
]

用已定义的选项生成CA:cfssl gencert -initca ca-csr.json | cfssljson -bare ca –

$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2017/08/02 00:56:03 [INFO] generating a new CA key and certificate from CSR
2017/08/02 00:56:03 [INFO] generate received request
2017/08/02 00:56:03 [INFO] received CSR
2017/08/02 00:56:03 [INFO] generating key: rsa-2048
2017/08/02 00:56:04 [INFO] encoded CSR
2017/08/02 00:56:04 [INFO] signed certificate with serial number 81101109133309828380726760425799837279517519090

会在当前目录下生成如下文件

ca-key.pem
ca.csr
ca.pem

注:保存好ca-key.pem文件。

生成server端证书:

$ cfssl print-defaults csr > server.json

server.json内容如下:

{
"CN": "server",
"hosts": [
    "127.0.0.1",
    "192.168.16.227",
    "192.168.16.228",
    "192.168.16.229",
    "bjo-ep-kub-01.dev.fwmrm.net",
    "bjo-ep-kub-02.dev.fwmrm.net",
    "bjo-ep-kub-03.dev.fwmrm.net"
],
"key": {
    "algo": "ecdsa",
    "size": 256
},
"names": [
    {
        "C": "US",
        "L": "CA",
        "ST": "San Francisco"
    }
]

}

接下来生成server端证书以及private key

$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
2017/08/02 00:57:12 [INFO] generate received request
2017/08/02 00:57:12 [INFO] received CSR
2017/08/02 00:57:12 [INFO] generating key: ecdsa-256
2017/08/02 00:57:12 [INFO] encoded CSR
2017/08/02 00:57:12 [INFO] signed certificate with serial number 138149747694684969550285630966539823697635905885

将会生成如下文件:

server-key.pem
server.csr
server.pem

生成peer certificate

$ cfssl print-defaults csr > member1.json

替换 CN和hosts值,如下:

{
"CN": "member1",
"hosts": [
    "127.0.0.1",
    "192.168.16.227",
    "192.168.16.228",
    "192.168.16.229",
    "bjo-ep-kub-01.dev.fwmrm.net",
    "bjo-ep-kub-02.dev.fwmrm.net",
    "bjo-ep-kub-03.dev.fwmrm.net"
],
"key": {
    "algo": "rsa",
    "size": 2048
},
"names": [
    {
        "C": "US",
        "ST": "CA",
        "L": "San Francisco"
    }
]

}

生成 member1 certificate与private key

$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer member1.json | cfssljson -bare member1
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer member1.json | cfssljson -bare member1
2017/08/02 00:59:12 [INFO] generate received request
2017/08/02 00:59:12 [INFO] received CSR
2017/08/02 00:59:12 [INFO] generating key: rsa-2048
2017/08/02 00:59:13 [INFO] encoded CSR
2017/08/02 00:59:13 [INFO] signed certificate with serial number 222573666682951886940627822839805508037201209158

得到如下文件:

member1-key.pem
member1.csr
member1.pem

在集群其他节点上重复如上步骤。

生成 client certificate

$ cfssl print-defaults csr > client.json

client.json内容如下:

{
"CN": "client",
"hosts": [
    "127.0.0.1",
    "192.168.16.227",
    "192.168.16.228",
    "192.168.16.229"
],
"key": {
    "algo": "rsa",
    "size": 2048
},
"names": [
    {
        "C": "US",
        "ST": "CA",
        "L": "San Francisco"
    }
]

}

生成client certificate

$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client 

将会得到如下文件

client-key.pem
client.csr
client.pem

拷贝节点1生成的证书到全部节点,并将证书全部置于/etc/ssl/etcd/目录, 至此TLS证书全部生成完成。

测试TLS

示例1: 客户端到服务器采用HTTPS客户端证书授权

启动etcd服务:

$ /export/etcd/etcd -name infra0 --data-dir infra0 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem --cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem   
--advertise-client-urls=https://127.0.0.1:2379 --listen-client-urls=https://127.0.0.1:2379

插入数据:

$ curl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem -L https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v

读取数据成功

$ curl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem -L https://127.0.0.1:2379/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":12,"createdIndex":12

示例2:Using self-signed certificates both encrypts traffic and authenticates its connections

各节点的etcd配置分别如下

$ /export/etcd/etcd 
--name infra0 
--initial-advertise-peer-urls https://192.168.16.227:2380 
--listen-peer-urls https://192.168.16.227:2380 
--listen-client-urls https://192.168.16.227:2379,https://127.0.0.1:2379 
--advertise-client-urls https://192.168.16.227:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-state new 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem 
--cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem 
--peer-client-cert-auth --peer-trusted-ca-file=/etc/ssl/etcd/ca.pem 
--peer-cert-file=/etc/ssl/etcd/member1.pem --peer-key-file=/etc/ssl/etcd/member1-key.pem
$ /export/etcd/etcd 
--name infra1 
--initial-advertise-peer-urls https://192.168.16.228:2380 
--listen-peer-urls https://192.168.16.228:2380 
--listen-client-urls https://192.168.16.228:2379,https://127.0.0.1:2379 
--advertise-client-urls https://192.168.16.228:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-state new 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem 
--cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem 
--peer-client-cert-auth --peer-trusted-ca-file=/etc/ssl/etcd/ca.pem 
--peer-cert-file=/etc/ssl/etcd/member2.pem --peer-key-file=/etc/ssl/etcd/member2-key.pem
$ /export/etcd/etcd 
--name infra2 
--initial-advertise-peer-urls https://192.168.16.229:2380 
--listen-peer-urls https://192.168.16.229:2380 
--listen-client-urls https://192.168.16.229:2379,https://127.0.0.1:2379 
--advertise-client-urls https://192.168.16.229:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-state new 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem 
--cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem 
--peer-client-cert-auth --peer-trusted-ca-file=/etc/ssl/etcd/ca.pem 
--peer-cert-file=/etc/ssl/etcd/member3.pem --peer-key-file=/etc/ssl/etcd/member3-key.pem

准备测试数据:

$ curl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem -L https://127.0.0.1:2379/v2/keys/fristname -XPUT -d value=Xia -v

$ ETCDCTL_API=3 /export/etcd/etcdctl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem --endpoints=https://192.168.16.227:2379,https://192.168.16.228:2379,https://192.168.16.229:2379 put lasttname 'Zhang'

验证测试结果:

$ curl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem -L https://127.0.0.1:2379/v2/keys/
{"action":"get","node":{"dir":true,"nodes":[{"key":"/foo","value":"bar","modifiedIndex":19,"createdIndex":19},{"key":"/fristname","value":"Xia","modifiedIndex":20,"createdIndex":20},{"key":"/lasttname","value":"Zhang","modifiedIndex":21,"createdIndex":21}]

etcd Troubleshooting

etcd failure主要分为如下5种情况:

  1. 少数followers failure
  2. Leader failure
  3. 多数failure
  4. Network partition
  5. 启动时失败

接下来主要对上面情况3进行处理,也就是平时常说的Disaster Recovery

灾备恢复(Disaster Recovery)

以etcd v3 provides snapshot 方式为例说明etcd一次灾难恢复过程。
首先,etcd正常工作时利用etcdctl snapshot save命令或拷贝etcd目录中的member/snap/db文件,以前者为例:

$ ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db}}
如果enable TLS,需要如下命令:
{{{$ ETCDCTL_API=3 /export/etcd/etcdctl --endpoints=https://192.168.16.227:2379,https://192.168.16.228:2379,https://192.168.16.228:2379 snapshot save snapshot.db --cacert=/etc/ssl/etcd/ca.pem --cert=/etc/ssl/etcd/client.pem --key=/etc/ssl/etcd/client-key.pem

Snapshot saved at snapshot.db

将生成snapshot拷贝到集群其他2个节点上,所有节点灾备的恢复都用同一个snapshot。

插入部分数据用于测试灾备:

$ curl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem -L https://127.0.0.1:2379/v2/keys/fristname -XPUT -d value=Xia -v

$ ETCDCTL_API=3 /export/etcd/etcdctl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem --endpoints=https://192.168.16.227:2379,https://192.168.16.228:2379,https://192.168.16.229:2379 put lasttname 'Zhang'

测试数据已插入成功:

$ ETCDCTL_API=3 /export/etcd/etcdctl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem --endpoints=https://192.168.16.227:2379,https://192.168.16.228:2379,https://192.168.16.229:2379  get  firstname

$ curl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem -L https://127.0.0.1:2379/v2/keys/
{"action":"get","node":{"dir":true,"nodes":[{"key":"/foo","value":"bar","modifiedIndex":19,"createdIndex":19},{"key":"/fristname","value":"Xia","modifiedIndex":20,"createdIndex":20},{"key":"/lasttname","value":"Zhang","modifiedIndex":21,"createdIndex":21}]

停止3个机器的etcd服务,并删除全部节点上etcd数据目录 。
恢复数据,以TLS enable为例,分别在3个节点执行如下命令进行恢复:

$ ETCDCTL_API=3 /export/etcd/etcdctl snapshot restore snapshot.db 
--name infra0 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-token etcd-cluster-1 
--initial-advertise-peer-urls https://192.168.16.227:2380 
--cacert /etc/ssl/etcd/ca.pem 
--cert /etc/ssl/etcd/client.pem 
--key /etc/ssl/etcd/client-key.pem
$ ETCDCTL_API=3 /export/etcd/etcdctl snapshot restore snapshot.db 
--name infra1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-token etcd-cluster-1 
--initial-advertise-peer-urls https://192.168.16.228:2380 
--cacert /etc/ssl/etcd/ca.pem 
--cert /etc/ssl/etcd/client.pem 
--key /etc/ssl/etcd/client-key.pem
$ ETCDCTL_API=3 /export/etcd/etcdctl snapshot restore snapshot.db 
--name infra2 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-token etcd-cluster-1 
--initial-advertise-peer-urls https://192.168.16.229:2380 
--cacert /etc/ssl/etcd/ca.pem 
--cert /etc/ssl/etcd/client.pem 
--key /etc/ssl/etcd/client-key.pem

恢复数据log示例:

$ ETCDCTL_API=3 /export/etcd/etcdctl snapshot restore snapshot.db   --name infra0   --initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380   --initial-cluster-token etcd-cluster-1   --initial-advertise-peer-urls https://192.168.16.227:2380   --cacert /etc/ssl/etcd/ca.pem   --cert /etc/ssl/etcd/client.pem   --key /etc/ssl/etcd/client-key.pem
2017-08-06 04:09:12.853510 I | etcdserver/membership: added member 3e5097be4ea17ebe [https://192.168.16.229:2380] to cluster cabc8098aa3afc98
2017-08-06 04:09:12.853567 I | etcdserver/membership: added member 67d47e92a1704b1a [https://192.168.16.227:2380] to cluster cabc8098aa3afc98
2017-08-06 04:09:12.853583 I | etcdserver/membership: added member b4725a5341abf1a0 [https://192.168.16.228:2380] to cluster cabc8098aa3afc98

接下来,在3个节点上分别执行:

$ /export/etcd/etcd 
--name infra0 
--initial-advertise-peer-urls https://192.168.16.227:2380 
--listen-peer-urls https://192.168.16.227:2380 
--listen-client-urls https://192.168.16.227:2379,https://127.0.0.1:2379 
--advertise-client-urls https://192.168.16.227:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-state new 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem 
--cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem 
--peer-client-cert-auth --peer-trusted-ca-file=/etc/ssl/etcd/ca.pem 
--peer-cert-file=/etc/ssl/etcd/member1.pem --peer-key-file=/etc/ssl/etcd/member1-key.pem
$ /export/etcd/etcd 
--name infra1 
--initial-advertise-peer-urls https://192.168.16.228:2380 
--listen-peer-urls https://192.168.16.228:2380 
--listen-client-urls https://192.168.16.228:2379,https://127.0.0.1:2379 
--advertise-client-urls https://192.168.16.228:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-state new 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem 
--cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem 
--peer-client-cert-auth --peer-trusted-ca-file=/etc/ssl/etcd/ca.pem 
--peer-cert-file=/etc/ssl/etcd/member2.pem --peer-key-file=/etc/ssl/etcd/member2-key.pem
$ /export/etcd/etcd 
--name infra2 
--initial-advertise-peer-urls https://192.168.16.229:2380 
--listen-peer-urls https://192.168.16.229:2380 
--listen-client-urls https://192.168.16.229:2379,https://127.0.0.1:2379 
--advertise-client-urls https://192.168.16.229:2379 
--initial-cluster-token etcd-cluster-1 
--initial-cluster infra0=https://192.168.16.227:2380,infra1=https://192.168.16.228:2380,infra2=https://192.168.16.229:2380 
--initial-cluster-state new 
--client-cert-auth --trusted-ca-file=/etc/ssl/etcd/ca.pem 
--cert-file=/etc/ssl/etcd/server.pem --key-file=/etc/ssl/etcd/server-key.pem 
--peer-client-cert-auth --peer-trusted-ca-file=/etc/ssl/etcd/ca.pem 
--peer-cert-file=/etc/ssl/etcd/member3.pem --peer-key-file=/etc/ssl/etcd/member3-key.pem

验证灾备恢复效果,原集群数据是否保存:

$ ETCDCTL_API=3 /export/etcd/etcdctl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem --endpoints=https://192.168.16.227:2379,https://192.168.16.228:2379,https://192.168.16.229:2379 get lasttname
lasttname
Zhang

$ ETCDCTL_API=3 /export/etcd/etcdctl --cacert /etc/ssl/etcd/ca.pem --cert /etc/ssl/etcd/client.pem --key /etc/ssl/etcd/client-key.pem --endpoints=https://192.168.16.227:2379,https://192.168.16.228:2379,https://192.168.16.229:2379 get firstname
firstname
Xia

从上面结果可以看出,灾备恢复成功。

etcd系统限制

  1. 请求大小限制:当前支持 RPC requests 1MB 数据,未来会有所增加或可配置
  2. 存储大小限制:默认 2GB存储,可配置 –quota-backend-bytes扩展到8GB

监控

etcd提供基于Prometheus + builtin Grafana的etcd Metrics监控方案和监控项,具体请参见
etcd Metrics: https://coreos.com/etcd/docs/latest/metrics.html
Prometheus + builtin Grafana: https://coreos.com/etcd/docs/latest/op-guide/monitoring.html