CentOS 7 中 hostnamectl 的使用

hostnamectl 是在 centos7 中新增加的命令,它是用来修改主机名称的,centos7 修改主机名称会比以往容易许多。

用法

# hostnamectl -h

  -h --help              显示帮助
     --version           显示安装包的版本
     --transient         修改临时主机名
     --static            修改瞬态主机名
     --pretty            修改灵活主机名
  -P --privileged        在执行之前获得的特权
     --no-ask-password   输入密码不提示
  -H --host=[USER@]HOST  操作远程主机

Commands:
  status                 显示当前主机名设置
  set-hostname NAME      设置系统主机名
  set-icon-name NAME     为主机设置icon名
  set-chassis NAME       设置主机平台类型名

在CentOS7中有三种定义的主机名:
静态的(static)、瞬态的(transient)、和灵活的(pretty)。
静态主机名也称为内核主机名,是系统在启动时从/etc/hostname内自动初始化的主机名。
瞬态主机名是在系统运行时临时分配的主机名。
灵活主机名则允许使用特殊字符的主机名。

常用命令

查看状态

# hostnamectl 或者 # hostnamectl status   (显示的结果都一样)

   Static hostname: localhost.localdomain
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 049717292ec9452890e50401d432e43c
           Boot ID: 2e69a66a7c724db6a44a8536f1670f7f
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-229.el7.x86_64
      Architecture: x86_64

修改主机名称

# hostnamectl set-hostname Linuxprobe
# hostnamectl status

   Static hostname: linuxprobe
   Pretty hostname: Linuxprobe
         Icon name: computer-vm
           Chassis: vm
        Machine ID: dc99c115d7414d159fa4c5c0c0541c55
           Boot ID: 6236b67c13af4d98b5fa3780e66dfdeb
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-229.el7.x86_64
      Architecture: x86_64

CentOS 7 Nginx配置Let’s Encrypt SSL证书

去年购买的阿里云到期了,由于阿里云续费比新买贵很多,所以重现买了一台虚拟机,迁移过程中需要重新配置Let’s Encrypt证书,在执行过程中发现了一些问题,经过几个小时的摸索,终于搞定。

安装Let’s Encrypt证书一般的流程

yum install epel-release -y
yum install certbot -y

然后执行:

certbot certonly --webroot -w /home/www/www.biaodianfu.com -d www.biaodianfu.com -m [email protected] --agree-tos

相关参数含义:

  • –webroot是运行模式
    1.standalone模式:需要停止当前的 web server 服务,让出 80 端口,由客户端内置的 web server 启动与Let’ s Encrypt通信。
    2.webroot模式:不需要停止当前 web server,但需要在域名根目录下创建一个临时目录,并要保证外网通过域名可以访问这个目录。
  • -w 指定网站所在目录
  • -d 指定网站域名
  • -m 指定联系邮箱,填写真实有效的,letsencrypt会在证书在过期以前发送预告的通知邮件
  • –agree-tos 表示接受相关协议
    使用webroot模式,Certbot在验证服务器域名的时候,会生成一个随机文件,然后Certbot的服务器会通过HTTP访问你的这个文件,因此要确保你的 Nginx 配置好,以便可以访问到这个文件。
    因为默认LNMP的虚拟主机里是禁止 . 开头的隐藏文件及目录的,所以访问http://www.biaodianfu.com/.well-known/acme-challenge/**** 这个链接的话返回403错误,所以必须在nginx配置的server节点下添加
location ~ /.well-known {
    allow all;
}

最终的配置文件如下:

server {
    listen       80;
    server_name  biaodainfu.com www.biaodianfu.com;
    index index.html index.htm index.php;
    charset utf-8;

    root   /home/www/www.biaodianfu.com;

    location / {
        try_files $uri $uri/ =404;
    }
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ .php$ {
        try_files $uri =404;
        fastcgi_pass php-fpm;
        #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp3|wma)$
    {
        expires      30d;
    }

    location ~ .*.(js|css)$
    {
        expires      12h;
    }

    location ~ /.well-known {
        allow all;
    }
}

重新nginx后执行申请证书的操作,正常情况下可以看到如下的显示内容:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem. Your cert will
   expire on 2018-02-25. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to [email protected].
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

完成后,再配置nginx服务器,将服务器配置成支持https的访问。

server {
  listen 80;
  server_name biaodianfu.com www.biaodianfu.com;
  return 301 https://www.biaodianfu.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name  biaodainfu.com www.biaodianfu.com;
    index index.html index.htm index.php;
    charset utf-8;

    root   /home/www/www.biaodianfu.com;

    ssl_certificate /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.biaodianfu.com/privkey.pem;

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

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

    location ~ .php$ {
        try_files $uri =404;
        fastcgi_pass php-fpm;
        #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp3|wma)$
    {
        expires      30d;
    }

    location ~ .*.(js|css)$
    {
        expires      12h;
    }

    location = /favicon.ico {
    log_not_found off;
    access_log off;
    }

    location ~ /.well-known {
        allow all;
    }
}

以上为一般的步骤与过程,现在在执行centos 7.2时并没有遇到什么问题,这次使用的是centos 7.4却发生了问题。

解决证书安装中的问题

问题一:ImportError: No module named ‘requests.packages.urllib3’
原因是系统自带的requests的版本太低,参照这个地址上的临时解决方案:

pip install requests urllib3 pyOpenSSL --force --upgrade

执行完引发第二个问题:ImportError: ‘pyOpenSSL’ module missing required functionality. Try upgrading to v0.14 or newer.
主要原因是RHEL/CentOS的官方源和epel源的pyOpenSSL版本太旧了,新版的certbot依赖于高版本的pyOpenSSL库,从而失败。
解决方案,卸载epel中的certbot和PyOpenSSL,使用pip进行安装certbot。

pip search certbot
yum remove certbot pyOpenSSL
pip install certbot

pip install certbot。 如果碰到了Python.h或者pyconfig.h找不到的错误,可以安装Python的devel包: yum install -y python-devel;再次运行命令,提示找不到opensslv.h头文件,再安装OpenSSL的devel包: yum install -y openssl-devel;再次运行pip install certbot命令,成功安装certbot。
完成后执行 certbot certificates 进行验证。输出正常,说明pip安装了最新版的certbot,并且能正确运行。

证书的自动更新

由于这个证书的时效只有 90 天,我们需要设置自动更新的功能,帮我们自动更新证书的时效。首先先在命令行模拟证书更新:

certbot renew --dry-run

模拟更新成功的效果如下:

[root@iZuf64dhkm7u57qfwrrhw6Z ~]# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.biaodianfu.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.biaodianfu.com
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
[root@iZuf64dhkm7u57qfwrrhw6Z ~]#

在无法确认你的 nginx 配置是否正确时,一定要运行模拟更新命令,确保certbot和服务器通讯正常。使用 crontab -e 的命令来启用自动任务,命令行:

crontab -e

添加配置:(每隔两个月凌晨2:30自动执行证书更新操作)后保存退出。

30 2 * */2 * /usr/bin/certbot renew --quiet && /bin/systemctl restart nginx

查看证书有效期的命令:

openssl x509 -noout -dates -in /etc/letsencrypt/live/www.biaodianfu.com/cert.pem

测试服务器 SSL 安全性

Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。理想情况下得分是A+,如果你和我一样获得的是A-那么还有很多的改善空间。另外又扑云也有一个测试https的工具:https://www.upyun.com/https
相关改进:

1、生成Perfect Forward Security(PFS)键值

mkdir /etc/ssl/private/ -p
cd /etc/ssl/private/
openssl dhparam 2048 -out dhparam.pem

Perfect Forward Security(PFS),中文翻译成完美前向保密,2014年时候,由于心血漏洞(存在服务器私钥泄漏的可能),没有使用前向保密的站点,加密通信的数据可以通过私钥来解密,导致信息泄漏,这使得前向保密被重视起来。总的来说会更加安全,不能获得A+的评分主要原因也是因为它。(生成的时间有点长)

2、更新配置文件

# https://mozilla.github.io/server-side-tls/ssl-config-generator/
server {
    listen 80;
    server_name biaodianfu.com www.biaodianfu.com;
    return 301 https://www.biaodianfu.com$request_uri;
}
server {
    listen 443 ssl http2;
    server_name  biaodainfu.com www.biaodianfu.com;
    index index.html index.htm index.php;
    charset utf-8;

    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

    root   /home/www/www.biaodianfu.com;

    ssl_certificate /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.biaodianfu.com/privkey.pem;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/ssl/private/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # 一般推荐使用的ssl_ciphers值: https://wiki.mozilla.org/Security/Server_Side_TLS
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

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

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

    location ~ .php$ {
        try_files $uri =404;
        fastcgi_pass php-fpm;
        #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp3|wma)$
    {
        expires      30d;
    }

    location ~ .*.(js|css)$
    {
        expires      12h;
    }

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location ~ /.well-known {
        allow all;
    }
}

其他参考:

  • https://certbot.eff.org/#centosrhel7-nginx
  • https://ruby-china.org/topics/31942
  • https://security.stackexchange.com/questions/54639/recommended-ssl-ciphers-for-security-compatibility-perfect-forward-secrecy

Linux(centos)禁止root用户直接登录sshd并修改默认端口

新建一个帐号

#创建用户 
adduser yourusername 
#设置密码 
passwd yourusernamepassword 

给用户添加sudo权限

#切换到root用户下,执行 
visudo 
#找到root ALL=(ALL) ALL这一行,在下面加上 
yourusername ALL=(ALL) ALL 
# :wq保存并退出 

测试是否成功

su yourusername 
cd ~ 
sudo mkdir test 
#输入密码后成功创建代表设置成功 

修改SSHD配置,禁止root直接登录

vi /etc/ssh/sshd_config 
#找到#PermitRootLogin yes”将yes该外no 
PermitRootLogin no 
#找到#Port 22字段删掉#,将22改为其他不被使用的端口 
Port XXXX 

重启sshd服务

service sshd restart 

重要提醒:这时切莫退出服务器。你要测试能不能使用刚创建的用户成功地通过ssh进入到服务器。打开终端的另一个实例,以之前创建的用户通过ssh进入到服务器。要是一切都正常,你可以以根用户身份安全地注销退出服务器。

Linux CentOS升级Python 3.6版本方法

由于软件环境的需要较高版本的python,默认CentOS6是2.6版本,CentOS7是2.7版本。这里要顺带提一下,有网友提到在CentOS6中无法安装Seafile云盘一键包的原因,因为需要默认最低是Python2.7版本才可以。而且在这篇文章中,老左调试的一个软件需要Python3以上版本,所以我准备安装Python 3.6。
备注:建议我们不熟悉的网友不要直接在生产环境中直接安装,可以先在测试环境安装看看是否可行。

第一、安装必备环境包

yum -y groupinstall development zlib zlib-devel

未分类

第二、下载和安装python3.6

wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
tar xJf Python-3.6.0.tar.xz
cd Python-3.6.0
./configure
make
make install

未分类

第三、检查是否成功

which python3
python3 -V

未分类

第四、创建软链接

cd /usr/bin
mv python python.backup
ln -s /usr/local/bin/python3 /usr/bin/python

然后我们重启下机器,再看看当前的python是不是3.6
未分类
这样python可以升级安装到3.6版本。

CentOS 7编译安装Zabbix server

Zabbix是一个基于WEB界面提供分布式系统监视以及网络监视功能的企业级开源解决方案,如果您手里要需要管理多台服务器,使用Zabbix来监控非常合适。Zabbix由2部分构成,Zabbix server与可选组件zabbix agent。

Zabbix server需要用到PHP + Mysql支持,(SQLite、PostgreSQL等数据库也可以),由于服务器已经安装了OneinStack(Linux + Nginx+ MySQL+ PHP)环境,为了当前环境不受到影响,所以选择源码编译方式安装Zabbix server

1. 编译Zabbix server & agent

#安装各种依赖
yum -y install gcc gcc-c++ curl-devel  mysql-devel curl-devel net-snmp net-snmp-devel
#创建用户 & 用户组
groupadd zabbix
useradd -g zabbix zabbix
#下载源码,可从官方下载最新版
wget http://soft.xiaoz.org/linux/zabbix-3.4.4.tar.gz
#解压
tar -zxvf zabbix-3.4.4.tar.gz && cd zabbix-3.4.4
#编译安装
./configure --enable-server --enable-agent --with-mysql --with-net-snmp --with-libcurl --with-libxml2
make install

注意事项:

xiaoz在写这篇文章的时候Zabbix 最新稳定版为3.4,可以在官方https://www.zabbix.com/download找到最新的源码包

如果编译的时候提示“checking for mysql_config… configure: error: MySQL library not found”这样的报错,这种情况可以指定mysql_config位置,比如:

#查找mysql_config位置
find / -name 'mysql_config'
#指定位置
--with-mysql=/usr/local/mysql/bin/mysql_config

如果编译的时候依然有报错,请根据实际报错情况搜索处理。CentOS 7编译安装Zabbix server后,配置文件路径如下:

/usr/local/etc/zabbix_server.conf
/usr/local/etc/zabbix_agentd.conf

2. 导入数据库

需要自己创建一个数据库(略过),并将源码包里面有3个数据库文件(位于zabbix-3.4.4/database/mysql),一定要按照下面的顺序依次导入:

├─ zabbix-3.4.4/database/mysql
 ├─ schema.sql
 ├─ images.sql
 └─ data.sql

修改配置文件/usr/local/etc/zabbix_server.conf填写正确的数据库账号、密码等信息,然后输入zabbix_server && zabbix_agentd启动Zabbix server和Zabbix agent

3. 安装WEB界面

WEB界面使用PHP开发,所以您需要新建一个站点,PHP源码位于zabbix-3.4.4/frontends/php将里面的所有源码拷贝到您站点目录下,访问您的域名:http://domain.com/输入Zabbix Server的一些基本信息即可完成,安装成功后会看到如下界面。用户名是Admin,密码是zabbix,请登录后务必修改。
未分类
设置中文
Zabbix默认界面是英文语言,可以在个人中心设置为中文语言,方便管理,如下图。
未分类
中文乱码?
打开自己的电脑C:WindowsFonts随便拖一个中文语言字体出来,比如simkai.ttf上传至站点fonts目录下,替换原来的默认字体。

#对原来的字体备份
mv DejaVuSans.ttf DejaVuSans.ttf.bak
#对新上传的字体命名
mv simkai.ttf DejaVuSans.ttf

未分类

4. 开机自动启动

先将Zabbix注册为服务,并赋予权限,再设置开机启动,执行下面的命令即可:

cd zabbix-3.4.4
cp misc/init.d/tru64/zabbix_server  /etc/init.d/zabbix_server
cp misc/init.d/tru64/zabbix_agentd  /etc/init.d/zabbix_agentd
#赋予权限
chmod 755 /etc/init.d/zabbix_*

编辑zabbix_server、zabbix_agentd这两个文件,在头部加入:

#chkconfig: 35 95 95
#description:zabbix Agent server

注册为服务,并开机启动:

chkconfig --add zabbix_server
chkconfig --add zabbix_agentd
chkconfig zabbix_server on
chkconfig zabbix_agentd on

至此安装已基本完成,如果需要监控其它服务器数据,可通过官方RPM包方式仅安装客户端即可。客户端不需要PHP/数据库支持,推荐官方RPM包方式安装客户端,较为便捷。

5. 扩展阅读

  • Zabbix配置文件详解之服务端zabbix_server
  • zabbix_agentd.conf配置文件详解

6. 总结

主机商一般默认带有服务器数据监控功能,但如果您手里有多台服务器且不在一个服务商,管理起来很不方便,而且出现故障无法及时知晓,Zabbix正好可以完美解决这个问题,Zabbix不仅数据详细,且支持多种不同动作及通知等,以及开放的API,可以在现有基础上不断定制和强化。Zabbix功能实在是太强大了,xiaoz连皮毛都还未掌握。
未分类

Ansible常见模块与使用方法

安装
使用extras仓库里面的最新的ansible包

ansible-2.4.1.0-1.el7.noarch
/etc/ansible                #配置文件目录
/etc/ansible/ansible.cfg    #主配置文件
/etc/ansible/hosts          #定义被管理的客户端
/etc/ansible/roles          #

主程序:

                    ansible
                    ansible-playbook
                    ansible-doc
vim /etc/ansible/hosts

## [webservers]             #定义组名
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
## www[001:006].example.com #如果组类拥有同样的命名规范,我们还可以展开

例子

[webserver]
172.18.25.51
172.18.25.52
[dbserver]
172.18.25.52
172.18.25.53

我们这里可以是所有被管控的机器都使用一样的密钥

[ root@node1 ~ ]# ssh-kengen -t rsa -P ''
[ root@node1 ~ ]# for i in 51 52 53 ;do ssh-copy-id -i ~/.ssh/id_rsa.pub
 [email protected].$i; done

然后手动尝试连接验证一下

ansible的简单使用格式:
    ansible  HOST-PATTERN   -m MOD_NAME  -a  MOD_ARGS -f FORKS -C -u USERNAME -c CONNECTION

ansible的常用模块:
获取模块列表:

            ansible-doc  -l
command模块:在远程主机运行命令;
    chdir=:执行命令前切换工作目录至指定的位置;
    creates=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录存在,则不执行命令;
    removes=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录不存在,则不执行命令;
        意为:令此处给定的文件或目录存在时方执行命令;

例子:

[ root@node1 ~ ]# ansible webserver -m command -a "useradd ygl"
        172.18.25.51 | SUCCESS | rc=0 >>


        172.18.25.52 | SUCCESS | rc=0 >>




    shell模块:在远程主机在shell进程下运行命令,支持shell特性,如管道等;
        chdir=:执行命令前切换工作目录至指定的位置;
        creates=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录存在,则不执行命令;
        removes=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录不存在,则不执行命令;
            意为:令此处给定的文件或目录存在时方执行命令;
        executable=/PATH/TO/SHELL:指定运行命令使用的shell解释器;

例子:
[ root@node1 ~ ]# ansible webserver -m shell -a “echo 123 | passwd –stdin ygl”
172.18.25.51 | SUCCESS | rc=0 >>
更改用户 ygl 的密码 。
passwd:所有的身份验证令牌已经成功更新。

172.18.25.52 | SUCCESS | rc=0 >>
更改用户 ygl 的密码 。
passwd:所有的身份验证令牌已经成功更新。  

group模块:管理组账号

    *name=
    state=          #present 创建 #absent 删除
    system=         #是否是系统账号
    gid=            

例子:

        [ root@node1 ~ ]# ansible webserver -m group -a "name=haproxy system=yes state=present"
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "gid": 993, 
            "name": "haproxy", 
            "state": "present", 
            "system": true
        }
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "gid": 993, 
            "name": "haproxy", 
            "state": "present", 
            "system": true
        }


        [ root@node1 ~ ]# ansible webserver -m group -a "name=haproxy system=yes state=absent"
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "name": "haproxy", 
            "state": "absent"
        }
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "name": "haproxy", 
            "state": "absent"
        }     
user模块:管理用户账号
[ root@node1 ~ ]# ansible-doc -s user
 如果后面接受里面有(required)表示必须要写的,不可省略。

            *name=
            system=
            uid=
            shell=
            group=
            groups=         #附加主
            comment=        #注释
            home=
            generate_ssh_key=   ture/false#是否生成一个ssh_key密钥 
            local=

例子:

        #创建tom用户,同名所属组,附加组为haproxy,uid为3000
        shell是tcsh,并且生成ss_key.
        [ root@node1 ~ ]# ansible webserver -m user -a "name=tom groups=haproxy state=present uid=3000 shell=/bin/tcsh generate_ssh_key=true"
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "comment": "", 
            "createhome": true, 
            "failed": false, 
            "group": 3000, 
            "groups": "haproxy", 
            "home": "/home/tom", 
            "name": "tom", 
            "shell": "/bin/tcsh", 
            "ssh_fingerprint": "2048 58:f3:82:5f:c6:cb:c4:e0:96:0e:61:9c:63:5f:5f:2d  ansible-generated on node1 (RSA)", 
            "ssh_key_file": "/home/tom/.ssh/id_rsa", 
            "ssh_public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCo9QnI4Q2S5WNjJ7Spj5jwYeLtH8v3JNiG+y1Oj+Qsnbc/AR6hs3tAMEDUW8MkUXqJT8QUwhAxugB5jdl2y4Yc4Y/s2tQ5PS+N2h6/N56xMQyrVqh26RF+yTEHc3LJhUM/cdHEJrnBFvV9h+S6IaxEOHL/mCzXJ46tPTvorIpkPWyvkfjqdGwyac4GGbcFmPa2GXiO0WuIADdK/GTFHTAyq+r3SisYTNDuGFWMl0HCXKujbQhsEwrPvlHfPH9nnuKp5C+4c7mZ8BMyk3MQgbu/0eI3y51YOC3yi/4eVdEYc6AxE8ifcHkjjTSGudifF7vhlBIoYvzbvey8wf4Tct5D ansible-generated on node1", 
            "state": "present", 
            "system": false, 
            "uid": 3000
        }
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "comment": "", 
            "createhome": true, 
            "failed": false, 
            "group": 3000, 
            "groups": "haproxy", 
            "home": "/home/tom", 
            "name": "tom", 
            "shell": "/bin/tcsh", 
            "ssh_fingerprint": "2048 97:0f:72:fd:fc:13:38:4a:fc:28:63:02:c4:f6:29:53  ansible-generated on node2 (RSA)", 
            "ssh_key_file": "/home/tom/.ssh/id_rsa", 
            "ssh_public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOXS6KtT6zPnFceO1TNLd1jVssT2419VdbL/2OC3LnALoqS0Dyb7ZSJEIocSgoGAVGmSg0JJTKgBf7aBM6agH44ZrZfTEn24C/4t83uRusVA9N8rnGhqOrTLn0U/Hrjdew7wXfnZaJmuoAyh2lQOESKrYflxWmA3z+RJwq5yQELTGGFpJq5cUYhXW13ItI2cxeDq5l9NJx/lOceNkjGXMtMLjtU0vKhaRudKaeXpLoxdHerVYdVVOvyjfHdRMycQRyfgLl+OivbmyfCx8far7JTWf4W+sSVTx/gh6nK2E/5jIGvrInDZWsvq/cePBGvU6S0Fv/MuW979b6VLaS8Te3 ansible-generated on node2", 
            "state": "present", 
            "system": false, 
            "uid": 3000
        }

修改的话,比如把uid改成4000,
但是像ssh_key这种已经生成了的,把true改成false的话,是不能删除掉之前的密钥的。

copy模块: Copies files to remote locations.
    用法:
        (1) src=  dest=
        (2) content=  dest=
        owner, group, mode 

例子:使用用法(1)

        [ root@node1 ~ ]# ansible all -m copy -a "src=test.txt dest=/tmp/ owner=daemon group=nobody mode=644"
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "checksum": "909b3eb9cf443e1fe007b9940910c1b5370157b6", 
            "dest": "/tmp/test.txt", 
            "failed": false, 
            "gid": 99, 
            "group": "nobody", 
            "md5sum": "b5ab68405ea7f38841f44964cac71a3a", 
            "mode": "0644", 
            "owner": "daemon", 
            "size": 31, 
            "src": "/root/.ansible/tmp/ansible-tmp-1511897155.3-203125776259926/source", 
            "state": "file", 
            "uid": 2
        }
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "checksum": "909b3eb9cf443e1fe007b9940910c1b5370157b6", 
            "dest": "/tmp/test.txt", 
            "failed": false, 
            "gid": 99, 
            "group": "nobody", 
            "md5sum": "b5ab68405ea7f38841f44964cac71a3a", 
            "mode": "0644", 
            "owner": "daemon", 
            "size": 31, 
            "src": "/root/.ansible/tmp/ansible-tmp-1511897155.29-136104449376316/source", 
            "state": "file", 
            "uid": 2
        }
        172.18.25.53 | SUCCESS => {
            "changed": true, 
            "checksum": "909b3eb9cf443e1fe007b9940910c1b5370157b6", 
            "dest": "/tmp/test.txt", 
            "failed": false, 
            "gid": 99, 
            "group": "nobody", 
            "md5sum": "b5ab68405ea7f38841f44964cac71a3a", 
            "mode": "0644", 
            "owner": "daemon", 
            "size": 31, 
            "src": "/root/.ansible/tmp/ansible-tmp-1511897155.38-10083863563401/source", 
            "state": "file", 
            "uid": 2
        }

使用用法(2)直接生成一些内容

        [ root@node1 ~ ]# ansible all -m copy -a "content='hello there nhow are you' dest=/tmp/test2.txt owner=daemon group=nobody mode=644"
        172.18.25.53 | SUCCESS => {
            "changed": true, 
            "checksum": "48ac9867d3152d279d7409b994356818ce61b54e", 
            "dest": "/tmp/test2.txt", 
            "failed": false, 
            "gid": 99, 
            "group": "nobody", 
            "md5sum": "65b97a6f52bed5bf307dd96ba01dfae0", 
            "mode": "0644", 
            "owner": "daemon", 
            "size": 24, 
            "src": "/root/.ansible/tmp/ansible-tmp-1511897535.05-274804325591646/source", 
            "state": "file", 
            "uid": 2
        }
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "checksum": "48ac9867d3152d279d7409b994356818ce61b54e", 
            "dest": "/tmp/test2.txt", 
            "failed": false, 
            "gid": 99, 
            "group": "nobody", 
            "md5sum": "65b97a6f52bed5bf307dd96ba01dfae0", 
            "mode": "0644", 
            "owner": "daemon", 
            "size": 24, 
            "src": "/root/.ansible/tmp/ansible-tmp-1511897535.05-210909367052491/source", 
            "state": "file", 
            "uid": 2
        }
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "checksum": "48ac9867d3152d279d7409b994356818ce61b54e", 
            "dest": "/tmp/test2.txt", 
            "failed": false, 
            "gid": 99, 
            "group": "nobody", 
            "md5sum": "65b97a6f52bed5bf307dd96ba01dfae0", 
            "mode": "0644", 
            "owner": "daemon", 
            "size": 24, 
            "src": "/root/.ansible/tmp/ansible-tmp-1511897535.04-149048632090006/source", 
            "state": "file", 
            "uid": 2
        }

fetch模块:Fetches a file from remote nodes

file模块: Sets attributes of files
    用法:
        (1) 创建链接文件:*path=  src=  state=link
        (2) 修改属性:path=  owner= mode= group= 
        (3) 创建目录:path=  state=directory
        注意:state属性的可用值
            file,           #表示必须是一个文件
            directory,      #表示不过不存在就创建一个目录
            link,           #表示是一个链接
            hard,           #表示是一个硬链接
            touch,          #表示不存在就创建一个空文件
            absent          #表示删除



        例子:创建目录
            [ root@node1 ~ ]# ansible all -m file -a "path=/tmp/hidir state=directory owner=nobody mode=777"
            172.18.25.52 | SUCCESS => {
                "changed": true, 
                "failed": false, 
                "gid": 0, 
                "group": "root", 
                "mode": "0777", 
                "owner": "nobody", 
                "path": "/tmp/hidir", 
                "size": 6, 
                "state": "directory", 
                "uid": 99
            }
            172.18.25.53 | SUCCESS => {
                "changed": true, 
                "failed": false, 
                "gid": 0, 
                "group": "root", 
                "mode": "0777", 
                "owner": "nobody", 
                "path": "/tmp/hidir", 
                "size": 6, 
                "state": "directory", 
                "uid": 99
            }
            172.18.25.51 | SUCCESS => {
                "changed": true, 
                "failed": false, 
                "gid": 0, 
                "group": "root", 
                "mode": "0777", 
                "owner": "nobody", 
                "path": "/tmp/hidir", 
                "size": 6, 
                "state": "directory", 
                "uid": 99
            }


        例子:创建空文件
        [ root@node1 ~ ]# ansible all -m file -a "path=/tmp/hifile state=touch owner=nobody mode=777"
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "dest": "/tmp/hifile", 
            "failed": false, 
            "gid": 0, 
            "group": "root", 
            "mode": "0777", 
            "owner": "nobody", 
            "size": 0, 
            "state": "file", 
            "uid": 99
        }
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "dest": "/tmp/hifile", 
            "failed": false, 
            "gid": 0, 
            "group": "root", 
            "mode": "0777", 
            "owner": "nobody", 
            "size": 0, 
            "state": "file", 
            "uid": 99
        }
        172.18.25.53 | SUCCESS => {
            "changed": true, 
            "dest": "/tmp/hifile", 
            "failed": false, 
            "gid": 0, 
            "group": "root", 
            "mode": "0777", 
            "owner": "nobody", 
            "size": 0, 
            "state": "file", 
            "uid": 99
        }

例子:创建一个链接,注意这个源文件是指的目标服务器上的源文件。

   [ root@node1 ~ ]# ansible all -m file -a "path=/tmp/mytest.txt src=/tmp/test2.txt state=link"
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "dest": "/tmp/mytest.txt", 
            "failed": false, 
            "gid": 0, 
            "group": "root", 
            "mode": "0777", 
            "owner": "root", 
            "size": 14, 
            "src": "/tmp/test2.txt", 
            "state": "link", 
            "uid": 0
        }
        172.18.25.53 | SUCCESS => {
            "changed": true, 
            "dest": "/tmp/mytest.txt", 
            "failed": false, 
            "gid": 0, 
            "group": "root", 
            "mode": "0777", 
            "owner": "root", 
            "size": 14, 
            "src": "/tmp/test2.txt", 
            "state": "link", 
            "uid": 0
        }
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "dest": "/tmp/mytest.txt", 
            "failed": false, 
            "gid": 0, 
            "group": "root", 
            "mode": "0777", 
            "owner": "root", 
            "size": 14, 
            "src": "/tmp/test2.txt", 
            "state": "link", 
            "uid": 0
        }

删除符号链接

  [ root@node1 ~ ]# ansible all -m file -a "path=/tmp/mytest.txt  state=absent"
        172.18.25.52 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "path": "/tmp/mytest.txt", 
            "state": "absent"
        }
        172.18.25.53 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "path": "/tmp/mytest.txt", 
            "state": "absent"
        }
        172.18.25.51 | SUCCESS => {
            "changed": true, 
            "failed": false, 
            "path": "/tmp/mytest.txt", 
            "state": "absent"
        }

get_url模块: Downloads files from HTTP, HTTPS, or FTP to node
*url=
*dest=
sha256sum=
owner, group, mode

例子: 然三个主机都下载redis并放在/tmp/目录下    
[ root@node1 ~ ]# ansible all -m get_url -a 
"url=http://download.redis.io/releases/redis-4.0.2.tar.gz dest=/tmp/"
172.18.25.51 | SUCCESS => {
    "changed": true, 
    "checksum_dest": null, 
    "checksum_src": "d2588569a35531fcdf03ff05cf0e16e381bc278f", 
    "dest": "/tmp/redis-4.0.2.tar.gz", 
    "failed": false, 
    "gid": 0, 
    "group": "root", 
    "md5sum": "f0497cc1311cd10dfdf215e9e6fd7416", 
    "mode": "0644", 
    "msg": "OK (1713990 bytes)", 
    "owner": "root", 
    "size": 1713990, 
    "src": "/tmp/tmpSYXHve", 
    "state": "file", 
    "status_code": 200, 
    "uid": 0, 
    "url": "http://download.redis.io/releases/redis-4.0.2.tar.gz"
}
172.18.25.53 | SUCCESS => {
    "changed": true, 
    "checksum_dest": null, 
    "checksum_src": "d2588569a35531fcdf03ff05cf0e16e381bc278f", 
    "dest": "/tmp/redis-4.0.2.tar.gz", 
    "failed": false, 
    "gid": 0, 
    "group": "root", 
    "md5sum": "f0497cc1311cd10dfdf215e9e6fd7416", 
    "mode": "0644", 
    "msg": "OK (1713990 bytes)", 
    "owner": "root", 
    "size": 1713990, 
    "src": "/tmp/tmp4EF_zu", 
    "state": "file", 
    "status_code": 200, 
    "uid": 0, 
    "url": "http://download.redis.io/releases/redis-4.0.2.tar.gz"
}
172.18.25.52 | SUCCESS => {
    "changed": true, 
    "checksum_dest": null, 
    "checksum_src": "d2588569a35531fcdf03ff05cf0e16e381bc278f", 
    "dest": "/tmp/redis-4.0.2.tar.gz", 
    "failed": false, 
    "gid": 0, 
    "group": "root", 
    "md5sum": "f0497cc1311cd10dfdf215e9e6fd7416", 
    "mode": "0644", 
    "msg": "OK (1713990 bytes)", 
    "owner": "root", 
    "size": 1713990, 
    "src": "/tmp/tmpKb1mA2", 
    "state": "file", 
    "status_code": 200, 
    "uid": 0, 
    "url": "http://download.redis.io/releases/redis-4.0.2.tar.gz"
}

git模块:Deploy software (or files) from git checkouts
repo= #仓库路径
dest= #克隆后目标存放路径
version= #获取是选取哪个版本,默认是最新的

例子:首先在webserver上面安装git,然后在github上面下载fastdfs并放在/tmp/下
[ root@node1 ~ ]# ansible webserver -m yum -a "name=git state=latest"

[ root@node1 ~ ]# ansible webserver -m git -a"repo=https://github.com/happyfish100/fastdfs.git dest=/tmp/fastdfs"



deploy_helper模块:Manages some of the steps common in deploying projects.

haproxy模块:Enable, disable, and set weights for HAProxy backend servers using socket commands.
    backend=
    host=
    state=
    weight=

cron 模块:Manage cron.d and crontab entries.
    minute=
    day=
    month=
    weekday=
    hour=
    job=
    *name=
    state=
        present:创建
        absent:删除
例子:每隔五分钟所有机器都去172..18.0.1上面同步一次时间。
[ root@node1 ~ ]# ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dev/null' minute='*/5'"
172.18.25.53 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "failed": false, 
    "jobs": [
        "timesync"
    ]
}
172.18.25.52 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "failed": false, 
    "jobs": [
        "timesync"
    ]
}
172.18.25.51 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "failed": false, 
    "jobs": [
        "timesync"
    ]
}
[ root@node1 ~ ]# crontab -l
#Ansible: timesync
*/5 * * * * /usr/sbin/ntpdate 172.18.0.1 &> /dev/null
删除定义的计划任务
[ root@node1 ~ ]# ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dev/null' minute='*/5' state=absent"
172.18.25.52 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "failed": false, 
    "jobs": []
}
172.18.25.53 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "failed": false, 
    "jobs": []
}
172.18.25.51 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "failed": false, 
    "jobs": []
}
创建计划任务,但是不启用,也就是被注释的
    [ root@node1 ~ ]# ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dev/null' minute='*/5' state=present disabled=true"
    172.18.25.52 | SUCCESS => {
        "changed": true, 
        "envs": [], 
        "failed": false, 
        "jobs": [
            "timesync"
        ]
    }
    172.18.25.53 | SUCCESS => {
        "changed": true, 
        "envs": [], 
        "failed": false, 
        "jobs": [
            "timesync"
        ]
    }
    172.18.25.51 | SUCCESS => {
        "changed": true, 
        "envs": [], 
        "failed": false, 
        "jobs": [
            "timesync"
        ]
    }
    [ root@node1 ~ ]# crontab -l
    #Ansible: timesync
    #*/5 * * * * /usr/sbin/ntpdate 172.18.0.1 &> /dev/null
hostname模块:Manage hostname
    name=

pip模块:Manages Python library dependencies.  #管理python库依赖关系
    name=
    state=
    version=

npm模块:Manage node.js packages with npm          #用npm管理node.js包
    name=
    state=
    version=
yum模块:Manages packages with the `yum' package manager
        name=:程序包名称,可以带版本号;
        state=
            present, 
            latest,         #最新的
            installed
            absent, 
            removed
        其它的包管理工具:apt(debian), zypper(suse), dnf(fedora), rpm, dpkg, ...

例子:都yum安装 nginx

[ root@node1 ~ ]# ansible webserver -m yum -a "name=nginx state=latest"

[ root@node1 ~ ]# ansible webserver -m yum -a "list=nginx"
172.18.25.51 | SUCCESS => {
    "changed": false, 
    "failed": false, 
    "results": [
        {
            "arch": "x86_64", 
            "envra": "1:nginx-1.10.2-1.el7.x86_64", 
            "epoch": "1", 
            "name": "nginx", 
            "release": "1.el7", 
            "repo": "epel", 
            "version": "1.10.2", 
            "yumstate": "available"
        }, 
        {
            "arch": "x86_64", 
            "envra": "1:nginx-1.10.2-1.el7.x86_64", 
            "epoch": "1", 
            "name": "nginx", 
            "release": "1.el7", 
            "repo": "installed", 
            "version": "1.10.2", 
            "yumstate": "installed"
        }
    ]
}
172.18.25.52 | SUCCESS => {
    "changed": false, 
    "failed": false, 
    "results": [
        {
            "arch": "x86_64", 
            "envra": "1:nginx-1.10.2-1.el7.x86_64", 
            "epoch": "1", 
            "name": "nginx", 
            "release": "1.el7", 
            "repo": "epel", 
            "version": "1.10.2", 
            "yumstate": "available"
        }, 
        {
            "arch": "x86_64", 
            "envra": "1:nginx-1.10.2-1.el7.x86_64", 
            "epoch": "1", 
            "name": "nginx", 
            "release": "1.el7", 
            "repo": "installed", 
            "version": "1.10.2", 
            "yumstate": "installed"
        }
    ]
}
service模块:管理服务
                    *name=
                    state=
                        started
                        stopped
                        restarted
                    enabled=
                    runlevel=       #运行级别
例子:启动之前使用ansible批量安装的ngixn
        [ root@node1 ~ ]# ansible webserver -m service -a "name=nginx enabled=true state=started"
172.18.25.51 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "failed": false, 
    "name": "nginx", 
    "state": "started", 
    "status": {
...
    }
}
172.18.25.52 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "failed": false, 
    "name": "nginx", 
    "state": "started", 
    "status": {
 ...
    }
}

使用ansible结合keepalived高可用,nginx反向代理部署小型企业环境

前言:

ansible作为一款灵活、高效、功能丰富的自动化部署工具在企业运维管理中备受推崇。本文演示使用ansible部署小型企业服务框架,实现高可用、负载均衡的目标。如有错误敬请赐教。
目标环境拓扑:
未分类

环境介绍:

前端代理层由两台nginx实现,并安装keepalived实现地址滑动达成高可用。
web层由两套Apache+PHP+WordPress 构建应用环境。数据层由一台mariadb组成,篇幅限制这里并没有做数据库主从复制、读写分离(实际环境数据库一定要实现这两项功能)。

IP一览:

未分类

环境准备:

1.管理端安装ansible,配置ssh秘钥使主机间实现基于秘钥的认证

ssh-keygen  -t rsa  #三次回车,中途的问题是问秘钥存放位置(默认/root/.ssh),是否加密秘钥。实验方便这里不加密
ssh-copy-id -i .ssh/id_rsa.pub [email protected] #将公钥发送给目标主机
ssh-copy-id -i .ssh/id_rsa.pub [email protected]
ssh-copy-id -i .ssh/id_rsa.pub [email protected]
ssh-copy-id -i .ssh/id_rsa.pub [email protected]
ssh-copy-id -i .ssh/id_rsa.pub [email protected]

2.编辑ansible的hosts文件,定义所有的主机
vim /etc/ansible/hosts
未分类
3.为所有主机同步时间

 ansible all -a 'ntpdate 172.18.0.1' #我这里是同步自己局域网的ntp服务器,实验的话选取同一台主机保证时间相同即可

4.创建ansible相关角色的目录

mkdir -pv /etc/ansible/roles/{mysql,web,nginx}/{files,tasks,templates,vars,handlers,meta}

配置web的playbook:

1.创建tasks文件

vim /etc/ansible/roles/web/task/main.yml
- name: install web pakgs
  yum: name={{ item }}
  with_items:
  - httpd
  - php
  - php-mysql
- name: config  web
  copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
  notify: restart the service # 注意这里要与handlers里定义的name相同
- name: copy wordpress
  synchronize: src=wordpress dest=/var/www/html/wordpress/
- name: restart the service
  service: name=httpd state=started

2.创建handles

vim /etc/ansible/roles/web/handlers/main.yml
- name: restart the service  #就这
  service: name=httpd state=restarted

3.添加要复制过去的配置文件
放在/etc/ansible/roles/web/files/下 ① WordPress目录 ② httpd.conf #从别的地方考过来
4.修改WordPress连接数据库的配置文件

 cd wordpress
 cp wp-sample-config.php  wp-config.php
 vim wp-config.php

未分类
5.添加web主剧本

vim /etc/ansible/web.yml
- hosts: web
  remote_user: root
  roles:
  - web

6.测试,没问题的话就下一步

ansible-playbook -C /etc/ansible/web.yml

配置代理层:

1.添加task任务

vim /etc/ansible/roles/nginx/tasks/main.yml
- name: install package
  yum: name={{ item }}
  with_items:
  - nginx
  - keepalived
- name: config keepalived
  template: src=keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf
  notify: restart keepalived
- name: config nginx
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  notify: restart nginx
- name: start service
  service: name={{ item }} state=started enabled=true
  with_items:
  - keepalived
  - nginx

2.添加handlers

vim /etc/ansible/roles/nginx/handlers
- name: restart keepalived
  service: name=keepalived state=restarted
- name: restart nginx
  service: name=nginx state=restarted

3.准备template文件 ①keepalived.conf.j2 ②nginx.conf.j2
4.修改keepalived模板文件

global_defs {
   notification_email {
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id {{ansible_hostname}} #自带变量,通过ansible 主机IP -m setup 查询
   vrrp_mcast_group4 224.0.0.43
}

vrrp_instance VI_1 {
    state {{ state }} #已通过hosts文件定义变量
    interface ens33 #网卡名
    virtual_router_id 51
    priority {{ priority }}
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass lovelinux #设置密码
    }
    virtual_ipaddress {
        172.18.43.88 #虚拟IP
    }
}

5.修改nginx模板文件(定义在http段)

upstream web {                        #新增段
        server 172.18.43.61;
        server 172.18.43.62;
    }
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

    location / {                     #新增段
        proxy_pass    
        }
    }

6.添加nginx主剧本

vim /etc/ansible/nginx.yml
- hosts: nginx
  remote_user: root
  roles:
  - nginx

7.测试,没问题的话就下一步

ansible-playbook -C /etc/ansible/nginx.yml

配置mariadb:

1.配置mariadb的任务清单

roles/mysql/tasks/main.yml
- name: install mariadb
  yum: name=mariadb-server
- name: copy sql file
  copy: src=mysql.sql dest=/tmp/mysql.sql
- name: start mysql service
  service: name=mariadb state=started
- name: config mysql
  shell: "mysql < /tmp/mysql.sql"

2.设置files文件

vim roles/mysql/files/mysql.sql 
CREATE DATABASE wp;
GRANT ALL ON wp.* TO 'wpuser'@'%' IDENTIFIED BY 'lovelinux';

3.添加mysql主剧本

vim /etc/ansible/mysql.yml
- hosts: mysql
  remote_user: root
  roles:
  - mysql

4.测试,没问题的话就下一步

ansible-playbook -C /etc/ansible/mysql.yml

开始表演(执行剧本):

1.目录结构
未分类
2.分别执行

ansible-playbook  web.yml
ansible-playbook  nginx.yml
ansible-playbook  mysql.yml

3.访问页面http://172.18.43.88/wordpress
未分类

项目总结:

1.在定义web的playbook时复制wordpress时开始用的是copy模块执行总是不成功,报错ERROR! A worker was found in a dead state。在确认自己没有语法错误后,百度查找原因无果最后在Google上找到了答案(英文不好不要心虚,技术问题语法都很简单很容易看懂,个别单词查查有道词典就好了),所以有在IT技术的问题问Google准没错。用synchronize模块要比copy模块高效安全的多,synchronize采用rsync复制文件,所以系统必须安装rsync 包否则无法使用这个模块。使用该模块的优点有①增量复制(只复制与目标主机有差异的文件) ② 复制时采用压缩,对复制大文件支持优秀(用copy复制大文件会出错),以下整理了一些synchronize参数:
archive # 是否采用归档模式同步,即以源文件相同属性同步到目标地址
copy_links # 同步的时候是否复制连接
links # Copy symlinks as symlinks
delete # 删除源中没有而目标存在的文件(即以推送方为主)
dest= # 目标地址
dest_port # 目标接受的端口,ansible配置文件中的 ansible_ssh_port 变量优先级高于该 dest_port 变量
dirs # 以非递归的方式传输目录
2.如mysql主机曾经安装过mariadb可能会出现导入SQL命令失败的情况,这时要将mysql的数据库删掉,默认位置在/var/lib/mysql/下
3.编辑nginx代理时注意语句的位置不要写错
4.出现错误仔细看看错误日志,耐心点问题肯没想的那么难。

centos 7.x设置守护进程的文件数量限制

在Bash中有个ulimit命令,提供了对Shell及该Shell启动的进程的可用资源控制。主要包括打开文件描述符数量、用户的最大进程数量、coredump文件的大小等。

在CentOS 5/6等版本中,资源限制的配置可以在/etc/security/limits.conf设置,针对root/user等各个用户或者*代表所有用户来设置。
当然,/etc/security/limits.d/
中可以配置,系统是先加载limits.conf然后按照英文字母顺序加载limits.d目录下的配置文件,后加载配置覆盖之前的配置。 一个配置示例如下:

*     soft   nofile    100000
*     hard   nofile    100000
*     soft   nproc     100000
*     hard   nproc     100000
*     soft   core      100000
*     hard   core      100000

不过,在CentOS 7/RHEL 7的系统中,使用Systemd替代了之前的SysV,因此/etc/security/limits.conf
文件的配置作用域缩小了一些。limits.conf这里的配置,只适用于通过PAM认证登录用户的资源限制,它对systemd的service的资源限制不生效。登录用户的限制,与上面讲的一样,通过/etc/security/limits.conf和
limits.d来配置即可。

对于systemd service的资源限制,如何配置呢?

全局的配置,放在文件/etc/systemd/system.conf和/etc/systemd/user.conf。
同时,也会加载两个对应的目录中的所有.conf文件/etc/systemd/system.conf.d/.conf和/etc/systemd/user.conf.d/.conf

其中,system.conf是系统实例使用的,user.conf用户实例使用的。一般的sevice,使用system.conf中的配置即可。systemd.conf.d/*.conf中配置会覆盖system.conf。

DefaultLimitCORE=infinity
DefaultLimitNOFILE=100000
DefaultLimitNPROC=100000

注意:修改了system.conf后,需要重启系统才会生效。

针对单个Service,也可以设置,以nginx为例。

编辑/usr/lib/systemd/system/nginx.service文件,或者/usr/lib/systemd/system/nginx.service.d/my-limit.conf文件,做如下配置:

[Service]
LimitCORE=infinity
LimitNOFILE=100000
LimitNPROC=100000

然后运行如下命令,才能生效。

sudo systemctl daemon-reload
sudo systemctl restart nginx.service

查看一个进程的limit设置:cat /proc/YOUR-PID/limits

例如我的一个nginx service的配置效果:

$ cat /proc/$(cat /var/run/nginx.pid)/limits

Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        unlimited            unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             100000               100000               processes
Max open files            100000               100000               files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       1030606              1030606              signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

顺便提一下,CentOS7自带的/etc/security/limits.d/20-nproc.conf,里面默认设置了非root用户的最大进程数为4096,被limit.d目录中的配置覆盖了。

CentOS 7 下安装 Nginx

安装所需环境

Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Windows 版本。

一. gcc 安装

安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装:

yum install gcc-c++

二. PCRE pcre-devel 安装

PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:

yum install -y pcre pcre-devel

三. zlib 安装

zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。

yum install -y zlib zlib-devel

四. OpenSSL 安装

OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。
nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库。

yum install -y openssl openssl-devel

官网下载

下载.tar.gz安装包,地址:https://nginx.org/en/download.html

解压

依然是直接命令:

tar -zxvf nginx-1.10.1.tar.gz
cd nginx-1.10.1

配置

其实在 nginx-1.10.1 版本中你就不需要去配置相关东西,默认就可以了。当然,如果你要自己配置目录也是可以的。
1.使用默认配置

./configure

2.自定义配置(不推荐)

./configure 
--prefix=/usr/local/nginx 
--conf-path=/usr/local/nginx/conf/nginx.conf 
--pid-path=/usr/local/nginx/conf/nginx.pid 
--lock-path=/var/lock/nginx.lock 
--error-log-path=/var/log/nginx/error.log 
--http-log-path=/var/log/nginx/access.log 
--with-http_gzip_static_module 
--http-client-body-temp-path=/var/temp/nginx/client 
--http-proxy-temp-path=/var/temp/nginx/proxy 
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi 
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi 
--http-scgi-temp-path=/var/temp/nginx/scgi

注:将临时文件目录指定为/var/temp/nginx,需要在/var下创建temp及nginx目录

编译安装

make
make install

查找安装路径:

whereis nginx

未分类

启动、停止nginx

cd /usr/local/nginx/sbin/
./nginx 
./nginx -s stop
./nginx -s quit
./nginx -s reload

./nginx -s quit:此方式停止步骤是待nginx进程处理任务完毕进行停止。
./nginx -s stop:此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。

查询nginx进程:

ps aux|grep nginx

重启 nginx

1.先停止再启动(推荐):
对 nginx 进行重启相当于先停止再启动,即先执行停止命令再执行启动命令。如下:

./nginx -s quit
./nginx

2.重新加载配置文件:
当 ngin x的配置文件 nginx.conf 修改后,要想让配置生效需要重启 nginx,使用-s reload不用先停止 ngin x再启动 nginx 即可将配置信息在 nginx 中生效,如下:

./nginx -s reload

启动成功后,在浏览器可以看到这样的页面:
未分类

开机自启动

即在rc.local增加启动代码就可以了。

vi /etc/rc.local

增加一行 /usr/local/nginx/sbin/nginx
设置执行权限:

chmod 755 rc.local

未分类
到这里,nginx就安装完毕了,启动、停止、重启操作也都完成了,当然,你也可以添加为系统服务,我这里就不在演示了。

ansible playbook支持的atrributes

ansible这个工具的官方文档其实做得特别不好。不仅没有搜索功能,而且对于playbook的各种属性居然没有介绍,特别是gather_facts:这种属性,在特定的场景下关掉是可以减少很多等待时间的。

因为文档上没有,所以基本只能看代码。

# =================================================================================
# Connection-Related Attributes

# TODO: generalize connection
_accelerate          = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_ipv6     = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_port     = FieldAttribute(isa='int', default=5099, always_post_validate=True)

# Connection
_gather_facts        = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_gather_subset       = FieldAttribute(isa='barelist', default=None, always_post_validate=True)
_gather_timeout      = FieldAttribute(isa='int', default=None, always_post_validate=True)
_hosts               = FieldAttribute(isa='list', required=True, listof=string_types, always_post_validate=True)
_name                = FieldAttribute(isa='string', default='', always_post_validate=True)

# Variable Attributes
_vars_files          = FieldAttribute(isa='list', default=[], priority=99)
_vars_prompt         = FieldAttribute(isa='list', default=[], always_post_validate=True)
_vault_password      = FieldAttribute(isa='string', always_post_validate=True)

# Role Attributes
_roles               = FieldAttribute(isa='list', default=[], priority=90)

# Block (Task) Lists Attributes
_handlers            = FieldAttribute(isa='list', default=[])
_pre_tasks           = FieldAttribute(isa='list', default=[])
_post_tasks          = FieldAttribute(isa='list', default=[])
_tasks               = FieldAttribute(isa='list', default=[])

# Flag/Setting Attributes
_any_errors_fatal    = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_force_handlers      = FieldAttribute(isa='bool', always_post_validate=True)
_max_fail_percentage = FieldAttribute(isa='percent', always_post_validate=True)
_serial              = FieldAttribute(isa='list', default=[], always_post_validate=True)
_strategy            = FieldAttribute(isa='string', default=C.DEFAULT_STRATEGY, always_post_validate=True)

# =================================================================================

还可以通过命令的方式:

python -c 'import ansible.playbook.play as P; print P.Play()._valid_attrs.keys();'

['tasks', 'vars', 'become_user', 'vault_password', 'gather_subset', 'accelerate', 'diff', 'serial', 'port', 'post_tasks', 'environment', 'remote_user', 'become_method', 'gather_timeout', 'strategy', 'no_log', 'pre_tasks', 'vars_files', 'accelerate_port', 'force_handlers', 'tags', 'gather_facts', 'check_mode', 'always_run', 'run_once', 'max_fail_percentage', 'ignore_errors', 'fact_path', 'name', 'roles', 'handlers', 'any_errors_fatal', 'connection', 'hosts', 'become_flags', 'vars_prompt', 'become', 'accelerate_ipv6', 'order']