使用saltstack部署zabbix-agent

使用saltstack批量部署服务是工作中一种常见的内容,对于一个服务的部署可以分为:前期准备(系统资源的设定、参数调整、软件包的下载)、安装、配置、启动这几个步骤。
本文以zabbix客户端的设定为例,向大家展示如何用saltstack部署服务。

部署步骤

1.首先利用pillar定义配置文件中一些关键的数据,例如zabbix server的IP(如果有需求还可以设置开放端口、客户端名称)。在整个部署开始之前,我们需要了解pillar和file的相关目录信息,在master的配置文件中:

file_roots:
  base:
    - /srv/salt/prod
  dev:
    - /srv/salt/dev/services
    - /srv/salt/dev/states
  prod:
    - /srv/salt/prod/services
    - /srv/salt/prod/states
以及:
pillar_roots:
  base:
    - /srv/pillar

file_roots以及pillar_roots里的base、dev和prod会在后续的配置中经常使用,默认情况下我们在每个base地址下创建一个top.sls文件。

2.pillar文件的配置

pillar的根文件top.sls:

[root@server2 pillar]# cat top.sls 
base:
  '*':
    - zabbix

指定了任何minion都包含zabbix.sls的静态数据,在zabbix.sls文件中我们指定了zabbix_server的ip地址:

[root@server2 pillar]# cat zabbix.sls 
zabbix-agent:
  Zabbix_Server: 192.168.42.129
  port: 10050

查看下pillar中定义的Zabbix_Server和port的值:

[root@server2 pillar]#  salt '*' pillar.items
minion-192.168.42.130:
    ----------
    zabbix_agent:
        ----------
        Zabbix_Server:
            192.168.42.129
        port:
            10050
minion-192.168.42.128:
    ----------
    zabbix_agent:
        ----------
        Zabbix_Server:
            192.168.42.129
        port:
            10050

3.zabbix服务配置

此示例中使用源码进行安装,请提前准备好zabbix 源码包以及配置文件的模板。

[root@server2 files]# pwd
/srv/salt/prod/zabbix/files
[root@server2 files]# ls
zabbix-3.2.1.tar.gz  zabbix_agentd.conf

查看file_roots目录(/srv/salt/prod)中的内容:

[root@server2 prod]# ls
top.sls  zabbix

首先编写top.sls文件:

[root@server2 prod]# cat top.sls 

base:
  '*':
    - zabbix.zabbix_agent

这里的base指的是file_roots定义目录中的base:

file_roots:
  base:
    - /srv/salt/prod

在这个目录中有一个zabbix目录,该目录中有一个zabbix_agent.sls文件,主要的配置都在该文件中:

[root@server2 zabbix]# cat zabbix_agent.sls 
include:
  - zabbix.common_install

create_zabbix_user:
  user.present:
    - name: zabbix
    - shell: /sbin/nologin
  group.present:
    - name: zabbix

zabbix_tar:
  file.managed:
    - name: /tmp/zabbix-3.2.1.tar.gz
    - source: salt://zabbix/files/zabbix-3.2.1.tar.gz
    - user: zabbix
    - group: zabbix
    - mode: 0644

/opt/app:
  file.directory:
    - user: zabbix
    - group: zabbix

zabbix_decompression:
  cmd.run:
    - name: tar xvf /tmp/zabbix-3.2.1.tar.gz -C /opt/app 
    - unless: test -d /opt/app/zabbix-3.2.1
    - require:
      - file: /tmp/zabbix-3.2.1.tar.gz

zabbix_install:
  cmd.run:
    - name: cd /opt/app/zabbix-3.2.1 && ./configure --enable-agent && make && make install
    - require:
      - cmd: zabbix_decompression

/usr/local/etc/zabbix_agented.conf:
  file.managed:
    - name: /usr/local/etc/zabbix_agentd.conf
    - source: salt://zabbix/files/zabbix_agentd.conf
    - user: zabbix
    - group: zabbix
    - mode: 0644
    - template: jinja
    - defaults:
      Server: {{pillar['zabbix_agent']['Zabbix_Server']}}
    - require:
      - cmd: zabbix_install
run_zabbix:
  cmd.run:
    - name: /usr/local/sbin/zabbix_agentd -c /usr/local/etc/zabbix_agentd.conf
    - require:
      - cmd: zabbix_install
    - watch:
      - file: /usr/local/etc/zabbix_agentd.conf

在该文件的开始有一个include操作,安装zabbix之前系统可能需要先安装相关软件包和编译工具,所以把这个操作放在单独的zabbix.common_install文件中,该文件也在/srv/salt/prod/zabbix目录。内容如下:

[root@server2 zabbix]# cat common_install.sls 
pkg-init:
  pkg.installed:
    - names:
      - gcc
      - gcc-c++
      - glibc
      - make
      - autoconf
      - openssl
      - openssl-devel

接下来的过程包括:
(1)zabbix用户和组的创建;
(2)zabbix源码包的拷贝;
(3)源码包的解压缩和配置安装;
(4)zabbix客户端配置文件(zabbix_agentd.conf)的部署;
(5)zabbix服务的开启;

4.执行过程:

-------------

[root@server2 zabbix]# salt '*' state.highstate

Succeeded: 15 (changed=3)
Failed:     0
-------------
Total states run:     15
Total run time:   26.597 s

python的加、减、乘、除、取整、取余计算

注意:所用版本是Python3.5.2。(因为Python2系列和Python3系列差距很大,特别提醒)

加法:

输入以下代码:

>>>1+1
>>>1.0+1

减法:

输入以下代码:

>>>1-2
>>>1.0-2

乘法:

输入以下代码:

>>>2*4
>>>2.0*4

除法:

输入以下代码:

>>>2/4
>>>2.0/4
>>>2//4
>>>2.0//4

取整:

输入以下代码:

>>>2//4
>>>2.0//4
>>>2.01//4

取余:

输入以下代码:

>>>10%2
>>>10%2.0

现象:

未分类

NGINX 如何实现读写限流的方法

这篇文章主要介绍了nginx 如何实现读写限流的方法的相关资料,这里提供实例代码及如何配置,需要的朋友可以参考下.

nginx 读写限流,万能的nginx,几行配置搞定。

先定义好规则,需要写在server外面

limit_req_zone $binary_remote_addr $uri zone=api_write:20m rate=10r/s; # 写
limit_req_zone $binary_remote_addr $uri zone=api_read:20m rate=50r/s; # 读

把需要限速的接口应用上上面的规则

写10/秒

location = /api/v1/trade {
limit_req zone=api_write burst=10;
proxy_pass http://api_server;
}

查询50/秒

location /api/v1/query {
limit_req zone=api_read burst=50;
proxy_pass http://api_server;
}

Nginx请求限制

连接频率限制:limit_conn_module
请求频率限制:limit_req_module

HTTP协议的连接与请求:

未分类

HTTP请求建立在一次TCP连接基础上

一次TCP请求至少产生一次HTTP请求,也可以产生多次。

1. 连接限制

Syntax: limit_conn_zone key zone=name:size;
Default: ——
Context: http
  • limit_conn_zone :开辟一块空间
  • key:以什么作为key存储,比如可以用ip作为限制,则ip为key
  • zone=name:size:name为申请空间的名字,方便后面其他调用,size表示大小
Syntax: limit_conn zone number;
Default: ——
Context: http,server,location
  • zone:表示空间名字
  • number:表示同一时间运行的并发个数

2. 请求限制

Syntax: limit_req_zone key zone=name:size rate=rate;
Default: ——
Context:http

前面部分的语法和前面类似,rate表示的是请求的速率。

Syntax: limit_req zone=name [burst=number][nodelay];
Default:——
Context:http,server,location

3. 测试

测试一:

# 设置空间名为req_zone 大小为1m,速率为每秒1个,地址的二进制的客户端地址用于节省空间
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
    location / {
        root /opt/app/code;
        limit_req zone=req_zone; 
        index  index.html index.htm;
    }

未分类

测试二:

# 设置空间名为req_zone 大小为1m,速率为每秒1个,地址的二进制的客户端地址用于节省空间
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
    location / {
        root /opt/app/code;
        limit_req zone=req_zone burst=3 nodelay; 
        index  index.html index.htm;
    }

burst为3表示有三个延迟响应,起到缓冲作用,其他直接返回。

未分类

测试三:

    limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
    location / {
        root /opt/app/code;
        limit_conn conn_zone 1;
        index  index.html index.htm;
    }

未分类

nginx配置https的部署实践

http以明文的形式在浏览器和服务器之间交换数据,没有任何数据加密,攻击者可以在截取之间的信息并读懂,这明显不安全,所以现在浏览器浏览器都要求网站域名配置SSL域名证书,以https协议传输内容。

那问题来了:

未分类

HTTP与HTTPS

  • HTTP:超文本传输协议
  • HTTPS:超文本传输安全协议

简单来说,可以用这个公式:HTTPS = HTTP + SSL

  • SSL:安全套接层,一种安全协议

也就是说:

为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

未分类


未分类

申请ssl域名证书

登录腾讯云之后,找到SSL证书管理栏目,购买或者申请域名证书。

注意:

  • 免费证书有效期是一年,一年后手动重新申请即可
  • 域名需要备案

未分类

申请完了之后,就可以下载证书啦~

未分类

如图下载的域名证书,可以配置到Apache、Nginx、Tomcat等服务器上面。

未分类

nginx配置https步骤

好,接下来我们进入正题,给nginx配置域名证书嘿~

解压下载下来的域名证书,获取Nginx里面的两个文件。

未分类

  • crt文件是以PEM格式存在的证书,可以用于不同的程序和设备
  • key文件是授权文件

第一步

把crt和key文件上传到nginx的conf目录下。

未分类

第二步

nginx.conf或自定义配置文件上配置SSL证书。

未分类

HTTPS的默认端口是443,就像HTTP的默认端口80一样,从图中可以看到,这个服务最后代理的是8080端口的tomcat。

第三步

配置完了第二步已经完成一大半了,只要用户输入https://www.java-mindmap.com就可以访问我的社区网站,但是一般用户都懒得输入https://,而不输入的话默认就是发起http链接,所以,需要还需要配置http强制转换成https的链接。

未分类

这样,当用户访问http链接时候,强制转成了https的服务了。

未分类

至此,HTTPS配置成功~

未分类

部署 Django 项目背后的原理:为什么需要 Nginx 和 Gunicron这些东西?

相信用过 Django 的同学一定会被 “Very easy to setup” 惊艳到。只要一行命令,就可以在 admin 界面看到一个完整的登陆注册。但是到了部署的时候,你一定会被网上复杂的部署教程搞的头晕,为啥本地开发这么简单,到了服务器却需要又是 Nginx,又是 uWSGI 这种东西呢?

未分类
摘自The Full Stack Python Guide to Deployments 一书

本文试图解释这些程序在一个 Web 服务中扮演的角色,为什么部署 Python web程序需要它们。本文不介绍如何部署 Django 应用等,这一类教程网上有很多,读者可自行搜索。其中 Nginx 和 Apache 算是一类的,可以替换。Gunicorn 和 uWSGI 的角色是类似的。同理最后端的 Web 框架是一类的,比如 Django 和 Flask。本文的内容替换以上任意一个应该也适用。

如果你读了网上任意一篇教程,你应该知道一个完整的部署应该类似这样:

HTTP Server <-----> WSGI <-----> App

最后后面的 App 我们知道,只要 runserver 就可以访问了,但是 Django 的文档明确说明:

DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that’s how it’s gonna stay. We’re in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.)

即 Django 做的事情只是一个框架,不会去关心一些安全问题、HTTP 的性能问题等。所以我们需要一个专业的 HTTP 服务器。这就出现了 Nginx 或 Apache。那么如何将 HTTP 服务器和我们的应用连接起来呢?动态网站问世的时候,就出现了 CGI 协议。注意这是一个协议,定义了HTTP 服务器如何通过后端的应用获取动态内容。可以简单的理解成 HTTP 服务器通过CGI 协议调用后端应用吧!WSGI 可以理解成 Python 的 CGI。uWSGI 和 Gunicorn 是这种 WSGI 的一些实现。这样,就出现了上面提到的三层的部署。

但是,为什么我们还需要 Nginx 呢?这些 WSGI 程序本身不是也提供访问吗?

uWSGI 和 Gunicorn 本身就是一个便携的 web 服务器了,Nginx 作为一个经过更长时间验证的 HTTP 服务器来说,它有很多 uWSGI 没有支持的 feature。比如:

  1. 处理静态资源更加优秀,E-Tag 的设置,Gzip 压缩等
  2. 处理网络连接,降低网络负载。例如 reuqest_buffering ,加入部署一个 uWSGI 程序,如果有慢的请求存在,uWSGI 必须等待整个 HTTP 请求发过来之后才开始处理请求。但是如果前置 Nginx,那么 Nginx 会帮你收到整个 HTTP 请求之后才交给 uWSGI 处理,也就是说,uWSGI获得的永远会是完整的 HTTP 请求,不会占用一个线程在等待。
  3. 甚至缓存动态的内容,例如将博客的首页缓存 5 分钟
  4. 作为一个负载均衡的前置,这样每一层的实例数量可以横向扩展
  5. Nginx 本身是作为一个服务存在的,几乎在任何 Linux 版本上安装之后都可以用 initd 启动,就像 MySQL 那样。uWSGI 一般是需要自己将其配置成服务的。(虽然前置了 Nginx 依然是需要配置 uWSGI)
  6. ……

此外,这样分开的好处还是得,到达 uWSGI 和 Gunicorn 的请求的情况变得简单了很多,Nginx 处理了一层,将过滤和处理之后的请求交给 uWSGI 或 Gunicorn。这使得这些 WSGI 程序的实现简单了一些,简化了开发的工作。专业的事情交给专业的人去做。

当然,并不是所有的项目都需要这么复杂的部署,有一个可选的是将 WSGI 程序嫁接到 HTTP 服务器上,比如 Apache httpd + mod_wsgi, Nginx + mod_uwsgi 等。

Nginx状态统计模块

前面简单介绍了Nginx的手动编译安装过程,详细过程请参见Nginx服务搭建;
而Nginx内置了状态统计模块,用来反馈当前的web访问情况,那么该如何开启Nginx内置状态统计模块呢?且我们该如何通过客户端进入状态统计页面?

编译安装Nginx

cd /opt/nginx-1.6.0/       //这里我将Nginx源码包解压在/opt目录下

 ./configure 
--prefix=/usr/local/nginx 
--user=nginx 
--group=nginx 
--with-http_stub_status_module    //开启stub_status状态统计模块,切记要将状态统计模块编译
make && make install 
/usr/local/nginx/sbin/nginx -V //查看Nginx是否安装状态统计模块成功

修改配置文件

要使用Nginx的状态统计功能,除了编译模块以外,还需要修改Nginx的主配置文件制定访问位置并添加stub_status配置代码。

vim /usr/local/nginx/conf/nginx.conf
server {
        listen       80;
        server_name  localhost;
        charset utf-8;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location ~ /status {     //访问位置/status
        stub_status   on;        //开启状态统计功能
        access_log off;          //关闭此模块的日志
        }                       //在"server"这里插入的这4行

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

       }
    }

重启Nginx服务即可,详细服务启动配置脚本请参见:
Nginx服务搭建。

查看状态统计页面

由于本机采用内网IP形式提供服务,且IP地址为192.168.100.111,故在客户端访问:192.168.100.111/status即可进入状态统计页面。为了试验效果,每次刷新页面即可看到状态统计页面的情况:

未分类

未分类

未分类

Debian Linux安装NFS

要在两台Linux电脑上共享一个目录,最简单的方式是使用NFS,将一台电脑的目录映射到另一台。

在Debian上实现NFS非常容易,首先,在作为服务端的电脑192.168.1.99上安装:

# apt-get install nfs-common nfs-kernel-server

创建需要共享的目录:

# mkdir /srv/upload
# chmod a+w /srv/upload

然后修改/etc/exports文件,将需要共享的目录和客户端添加进来:

/srv/upload  192.168.1.100(rw,sync)

表示允许IP为192.168.1.100的客户端以rw的模式访问。如果以只读模式访问则设置为ro。

然后启动服务:

# /etc/init.d/nfs-kernel-server start

在客户端安装NFS:

# apt-get install nfs-common

创建目录并挂载NFS:

# mkdir /mnt/upload
# mount 192.168.1.99:/srv/upload /mnt/upload

此时已经可以写入/mnt/upload,对应的服务器端可以看到创建的文件。

要在客户端每次启动时自动挂载NFS,可以编辑/etc/fstab,添加一行:

192.168.1.99:/srv/upload /mnt/upload nfs rsize=8192,wsize=8192,timeo=14,intr

均为缺省参数。

MySQL 字符串 转 int/double CAST与CONVERT 函数的用法

MySQL 的CAST()和CONVERT()函数可用来获取一个类型的值,并产生另一个类型的值。两者具体的语法如下:

CAST(value as type);  
CONVERT(value, type);  

就是CAST(xxx AS 类型), CONVERT(xxx,类型)。

mysql> SELECT CAST('3.35' AS signed);  
+------------------------+  
| CAST('3.35' AS signed) |  
+------------------------+  
|                      3 |  
+------------------------+  
1 row in set  

可以转换的类型是有限制的。这个类型可以是以下值其中的一个:

  • 二进制,同带binary前缀的效果 : BINARY
  • 字符型,可带参数 : CHAR()
  • 日期 : DATE
  • 时间: TIME
  • 日期时间型 : DATETIME
  • 浮点数 : DECIMAL
  • 整数 : SIGNED
  • 无符号整数 : UNSIGNED

下面举几个例子:

例一

mysql> SELECT CONVERT('23',SIGNED);  
+----------------------+  
| CONVERT('23',SIGNED) |  
+----------------------+  
|                   23 |  
+----------------------+  
1 row in set  

例二

mysql> SELECT CAST('125e342.83' AS signed);  
+------------------------------+  
| CAST('125e342.83' AS signed) |  
+------------------------------+  
|                          125 |  
+------------------------------+  
1 row in set  

例三

mysql> SELECT CAST('3.35' AS signed);  
+------------------------+  
| CAST('3.35' AS signed) |  
+------------------------+  
|                      3 |  
+------------------------+  
1 row in set  

像上面例子一样,将varchar 转为int 用 cast(a as signed),其中a为varchar类型的字符串。

mariadb数据库冷备份实验

数据的重要性不言而喻,做好数据备份方能在数据损坏丢失时及时恢复

  • 冷备份
  • 热备份
  • 完全备份
  • 增量备份

冷备份即暂停Mariadb服务,用户不能读写访问数据库,直接拷贝整个数据文件

实验拓扑

未分类

实验准备

  • 两台CentOS 7.4 server
  • mariadb软件版本 mariadb-server-5.5.56-2.el7.x86_64
  • sql数据库脚本,一个用于生成测试数据库hellodb,一个是存储过程,批量增加10W条数据记录
    https://github.com/zhongchengling/linuxshell

实验步骤

172.16.8.71–DB1

yum install -y mariadb-server

修改/etc/my.cnf文件拆分innodb引擎的数据库文件

innodb_file_per_table = ON
systemctl start mariadb.service
git clone [email protected]:zhongchengling/linuxshell.git
cd linuxshell
mysql < hellodb_innodb.sql
mysql --database=hellodb < testlog.sql
  • 安装MariaDB软件,修改/etc/my.cnf配置文件,并启动服务
  • 从同性交友网站GitHub上克隆sql脚本,导入数据库hellodb和存储引擎
  • 调用call pro_testlog();导入十万条记录
MariaDB [hellodb]> show databases;
MariaDB [hellodb]> show tables;
MariaDB [hellodb]> call pro_testlog();
MariaDB [hellodb]> select count(*) from testlog;

未分类

systemctl stop mariadb.service

暂停数据服务,打包备份/var/lib/mysql下的所有数据文件到172.16.8.7

cd /var/lib/
tar -Jcvf data.tar.xz mysql
scp /etc/my.cnf [email protected]:/etc
scp data.tar.xz [email protected]:/root

数据备份完成,在172.16.8.71机器上进行数据的验证恢复

172.16.8.71–DB1

  • 同样地yum安装Mariadb,确保版本相同,以避免潜在问题
  • 解压数据文件到/var/lib/mysql
tar -xvf data.tar.xz -C /var/lib/mysql
  • 启动mairadb服务,验证数据

未分类