三. 运维自动化之Ansible

1. 安装

源安装:

    yum -y install ansible # EPEL源(CentOS)
    apt -y install ansible # Ubuntu

编译安装:

    yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
    tar -xvf ansible-1.5.4.tar.gz
    cd ansible-1.5.4
    python setup.py build
    python setup.py install
    mkdir /etc/ansible
    cp -r examples/* /etc/ansible

Git:

    git clone git://github.com/ansible/ansible.git --recursive
    cd ./ansible
    source ./hacking/env-setup

pip:

    yum install python-pip python-devel
    yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
    pip install --upgrade pip
    pip install ansible --upgrade

确认安装:

root@ubuntu:~/playbook# ansible --version
ansible 2.5.1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.17 (default, Feb 27 2021, 15:10:58) [GCC 7.5.0]

2. 常用模块

模块文档:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

Command:#在远程主机执行命令,默认模块,可忽略-m选项
    ansible srvs -m command -a 'service vsftpd start'
    ansible srvs -m command -a 'echo adong |passwd --stdin 123456'
    此命令不支持 $VARNAME < > | ; & 等,用shell模块实现
    chdir:  进入到被管理主机目录
    creates: 如果有一个目录是存在的,步骤将不会运行Command命令
    ansible websrvs -a 'chdir=/data/ ls'
Shell:#和command相似,用shell执行命令
    ansible all -m shell -a 'getenforce'  #查看SELINUX状态
    ansible all -m shell -a "sed -i 's/SELINUX=.*/SELINUX=disabled'/ /etc/selinux/config"
    ansible srv -m shell -a 'echo magedu | passwd –stdin wang'
    #调用bash执行命令 类似 
    cat /tmp/stanley.md | awk -F'|' '{print $1,$2}' &> /tmp/example.txt   
    #这些复杂命令,即使使用shell也可能会失败
    #解决办法:写到脚本时,copy到远程执行,再把需要的结果拉回执行命令的机器
    #修改配置文件,使shell作为默认模块   
        vim /etc/ansible/ansible.cfg
        module_name = shell
Script:#在远程主机上运行ansible服务器上的脚本
    -a "/PATH/TO/SCRIPT_FILE"
    ansible websrvs -m script -a /data/test.sh
Copy:#主控端复制文件到远程主机
    src : 源文件  指定拷贝文件的本地路径  (如果有/ 则拷贝目录内容,比拷贝目录本身)
    dest: 指定目标路径
    mode: 设置权限
    backup: 备份源文件
    content: 代替src  指定本机文件内容,生成目标主机文件
    ansible websrvs -m copy -a "src=/root/test1.sh dest=/tmp/test2.showner=wang mode=600 backup=yes"
    #如果目标存在,默认覆盖,此处指定先备份
    ansible websrvs -m copy -a "content='test content\nxxx' dest=/tmp/test.txt"
    #指定内容,直接生成目标文件
Fetch:#从远程主机提取文件至主控端,copy相反,目前不支持目录,可以先打包,再提取文件
    ansible websrvs -m fetch -a 'src=/root/test.sh dest=/data/scripts'
    #会生成每个被管理主机不同编号的目录,不会发生文件名冲突
    ansible all -m shell -a 'tar jxvf test.tar.gz /root/test.sh'
    ansible all -m fetch -a 'src=/root/test.tar.gz dest=/data/'
File:# 设置文件属性
    path: 要管理的文件路径 (强制添加)
    recurse: 递归,文件夹要用递归
    src:  创建硬链接,软链接时,指定源目标,配合'state=link' 'state=hard' 设置软链接,硬链接
    state: 状态
          absent 缺席,删除
     ansible websrvs -m file -a "path=/app/test.txt state=touch" #创建文件
     ansible websrvs -m file -a "path=/data/testdir state=directory" #创建目录   
     ansible websrvs -m file -a "path=/root/test.sh owner=wang mode=755" #设置权限755
     ansible websrvs -m file -a 'src=/data/testfile dest=/data/testfile-link state=link' #创建软链接
unarchive:# 解包解压缩,有两种用法:
    1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes.
    2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
    常见参数:
        copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
        src: 源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no
        dest:远程主机上的目标路径
        mode:设置解压缩后的文件权限

        ansible websrvs -m unarchive -a 'src=foo.tgz dest=/var/lib/foo' 
        # 默认copy为yes ,将本机目录文件解压到目标主机对应目录下
        ansible websrvs -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777'
        # 解压被管理主机的foo.zip到data目录下, 并设置权限777
        ansible websrvs -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'
Archive:# 打包压缩
    ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=wang mode=0777'
    # 将远程主机目录打包
        path:  指定路径
        dest:  指定目标文件
        format: 指定打包格式
        owner:  指定所属者
        mode:  设置权限
Hostname:# 管理主机名
    ansible appsrvs -m hostname -a "name=app.adong.com"  #更改一组的主机名
    ansible 192.168.38.103 -m hostname -a "name=app2.adong.com" #更改单个主机名
Cron:# 计划任务
    支持时间:minute,hour,day,month,weekday
    ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime"
    # 创建任务
    ansible websrvs -m cron -a 'state=absent name=Synctime'
    # 删除任务
    ansible websrvs -m cron -a 'minute=*/10 job='/usr/sbin/ntpdate 172.30.0.100" name=synctime disabled=yes'
    注释任务,不在生效
Yum:# 管理包
    ansible websrvs -m yum -a 'list=httpd'  #查看程序列表
    ansible websrvs -m yum -a 'name=httpd state=present' #安装
    ansible websrvs -m yum -a 'name=httpd state=absent'  #删除
    # 可以同时安装多个程序包
Service:# 管理服务
    ansible srv -m service -a 'name=httpd state=stopped' #停止服务
    ansible srv -m service -a 'name=httpd state=started enabled=yes' #启动服务,并设为开机自启
    ansible srv -m service -a 'name=httpd state=reloaded' #重新加载
    ansible srv -m service -a 'name=httpd state=restarted' #重启服务
User:# 管理用户
    home  指定家目录路径
    system 指定系统账号
    group  指定组
    remove 清除账户
    shell  指定shell类型
    ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
    ansible websrvs -m user -a 'name=sysuser1 system=yes home=/app/sysuser1'
    # remove=yes,删除用户及家目录等数据,默认remove=no
    ansible websrvs -m user -a 'name=user1 state=absent remove=yes' #清空用户所有数据
    ansible websrvs -m user -a 'name=app uid=88 system=yes home=/app groups=root shell=/sbin/nologin password="password"' #创建用户
    ansible websrvs -m user -a 'name=app state=absent' #不会删除家目录
Group:# 管理组
    ansible srv -m group -a "name=testgroup system=yes" #创建组
    ansible srv -m group -a "name=testgroup state=absent" #删除组

3. Playbook

playbook是由一个或多个"play"组成的列表

play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。

Task实际是调用ansible的一个module,将多个play组织在一个playbook中,

即可以让它们联合起来,按事先编排的机制执行预定义的动作

Playbook采用YAML语言编写

image

Playbook核心组件

Hosts:
    playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。
    hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
    可以是如下形式:
        one.example.com
        one.example.com:two.example.com
        192.168.1.50
        192.168.1.*
     Websrvs:dbsrvs      #或者,两个组的并集
     Websrvs:&dbsrvs      #与,两个组的交集
     webservers:!phoenix  #在websrvs组,但不在dbsrvs组
    #示例: 
    - hosts: websrvs:dbsrvs
remote_user:
    可用于Host和task中。
    也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;
    此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
    - hosts: websrvs
      remote_user: root  (可省略,默认为root)  以root身份连接
      tasks:    指定任务
    - name: test connection
        ping:
        remote_user: magedu
        sudo: yes          默认sudo为root
        sudo_user:wang      sudo为wang
task列表和action
    任务列表task:由多个动作,多个任务组合起来的,每个任务都调用的模块,一个模块一个模块执行
    1> play的主体部分是task list,task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务

    2> task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致

    3> 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。

    如果未提供name,则action的结果将用于输出

tasks:任务列表
    两种格式:
    (1) action: module arguments
    (2) module: arguments 建议使用  模块: 参数
    注意:shell和command模块后面跟命令,而非key=value
    某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers
    任务可以通过"tags"打标签,可在ansible-playbook命令上使用-t指定进行调用

示例:

tasks:
  - name: disable selinux  描述
    command: /sbin/setenforce 0  模块名: 模块对应的参数
    # 如果命令或脚本的退出码不为零,可以使用如下方式替代

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true 
    # 转错为正  如果命令失败则执行 true,或者使用ignore_errors来忽略错误信息

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True  #忽略错误

示例: 安装apache,修改配置文件重启

---
- hosts: webtest
  remote_user: root
  tasks:
    - name: "安装Apache-httpd"
      yum: name=httpd

    - name: "修改配置文件"
      shell: sed -i "s/Listen 80/Listen 10080/" /etc/httpd/conf/httpd.conf

    - name: "重启Apache-httpd,设置开机启动"
      service: name=httpd state=started enabled=yes

    - name: "测试运行状态"
      shell: echo "test" > /var/www/html/index.html && ss -nutlp | grep 10080 ; curl -I -m 10 -o /dev/null -s -w %{http_code} localhost:10080
      register: check

    - name: "显示测试结果"
      debug: var=check.stdout verbosity=0

执行结果

root@ubuntu:~/playbook# ansible-playbook webtest.yml --syntax-check

playbook: webtest.yml
root@ubuntu:~/playbook# ansible-playbook webtest.yml

PLAY [webtest] ******************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************
ok: [172.17.0.7]

TASK [安装Apache-httpd] ***********************************************************************************************************************************************************
changed: [172.17.0.7]

TASK [修改配置文件] *******************************************************************************************************************************************************************
 [WARNING]: Consider using the replace, lineinfile or template module rather than running sed.  If you need to use command because replace, lineinfile or template is
insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.

changed: [172.17.0.7]

TASK [重启Apache-httpd,设置开机启动] ****************************************************************************************************************************************************
changed: [172.17.0.7]

TASK [测试运行状态] *******************************************************************************************************************************************************************
changed: [172.17.0.7]

TASK [显示测试结果] *******************************************************************************************************************************************************************
ok: [172.17.0.7] => {
    "check.stdout": "tcp    LISTEN     0      511       *:10080                 *:*                   users:((\"httpd\",pid=524,fd=3),(\"httpd\",pid=523,fd=3),(\"httpd\",pid=522,fd=3),(\"httpd\",pid=521,fd=3),(\"httpd\",pid=520,fd=3),(\"httpd\",pid=519,fd=3))\n200"
}

PLAY RECAP **********************************************************************************************************************************************************************
172.17.0.7                 : ok=6    changed=4    unreachable=0    failed=0   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值