Ansible介绍, 安装, 远程执行命令, 拷贝文件或目录, 远程执行脚本, 管理任务计划, 安装rpm包/管理服务

Ansible介绍

  • 不需要安装客户端,通过sshd去通信
  • 基于模块工作,模块可以由任何语言开发
  • 不仅支持命令行使用模块,也支持编写yaml格式的playbook,易于编写和阅读 安装十分简单,centos上可直接yum安装
  • 有提供UI(浏览器图形化)www.ansible.com/tower,收费的
  • 官方文档 http://docs.ansible.com/ansible/latest/index.html
  • ansible已经被redhat公司收购,它在github上是一个非常受欢迎的开源软件,github地址https://github.com/ansible/ansible
  • 一本不错的入门电子书 https://ansible-book.gitbooks.io/ansible-first-book/

Ansible安装

  • 准备两台机器,前面我们做实验的两台机器aming-01,aming-02
  • 只需要在aming-01上安装ansible
  • yum list |grep ansible 可以看到自带源里就有2.4版本的ansible
  • yum install -y ansible
  • aming-01上生成密钥对 ssh-keygen -t rsa
  • 把公钥放到aming-02上,设置密钥认证
  • vi /etc/ansible/hosts //增加
    [testhost]
    127.0.0.1
    192.168.133.132 说明: testhost为主机组名字,自定义的。 下面两个ip为组内的机器ip。
<root@linux0 /srv/salt>$ yum list |grep ansible
ansible.noarch                              2.4.2.0-2.el7              @extras  
ansible-doc.noarch                          2.4.2.0-2.el7              @extras  
centos-release-ansible26.noarch             1-3.el7.centos             extras
 <root@linux0 /srv/salt>$ yum install ansible ansible-doc
 <root@linux0 /srv/salt>$ ssh 192.168.87.150
[email protected]'s password:    #需要密码;

<root@linux0 /srv/salt>$ ssh-copy-id 192.168.87.150  #把公钥复制过去,实现无密码登陆机器,ssh只认IP和帐号,不判断hostname(旧的hostname生成的密钥也可以用);149机器即本机需要做同样的工序,linux可本机ssh登陆本机;
<root@linux0 /srv/salt>$ vim /etc/ansible/hosts #添加如下内容;
[thosts]   #设置一个主机组;可使用组名操作组内机器;
192.168.87.149  #组内机器IP;
192.168.87.150  #组内机器IP;

Ansible远程执行命令

  • ansible testhost -m command -a ‘w’ 这样就可以批量执行命令了。
  • 这里的testhost 为主机组名,-m后边是模块名字,-a后面是命令。当然我们也可以直接写一个ip,针对某一台机器来执行命令。
  • ansible 127.0.0.1 -m command -a ‘hostname’
  • 错误: “msg”: “Aborting, target uses selinux but python bindings (libselinux-python) aren’t installed!”
  • 解决: yum install -y libselinux-python
  • 还有一个模块就是shell同样也可以实现 ansible testhost -m shell -a ‘w’
<root@linux0 /srv/salt>$ ansible thosts -m command -a 'hostname'
192.168.87.150 | SUCCESS | rc=0 >>
linux1

192.168.87.149 | SUCCESS | rc=0 >>
linux0
<root@linux0 /srv/salt>$ ansible thosts -m shell -a "ps aux |grep http"   #shell才可以用管道符;
192.168.87.150 | SUCCESS | rc=0 >>
#不展示具体内容;
192.168.87.149 | SUCCESS | rc=0 >>
<root@linux0 /srv/salt>$ ansible thosts -m command -a "ps aux |grep http"   #command使用出错;
192.168.87.150 | FAILED | rc=1 >>
error: garbage option


192.168.87.149 | FAILED | rc=1 >>
error: garbage option

Ansible拷贝文件或者目录

  • ansible aming-02 -m copy -a “src=/etc/ansible dest=/tmp/ansibletest owner=root group=root mode=0755”
  • 注意:源目录会放到目标目录下面去,如果目标指定的目录不存在,它会自动创建。如果拷贝的是文件,dest指定的名字和源如果不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。但相反,如果desc是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面。
  • ansible testhost -m copy -a “src=/etc/passwd dest=/tmp/123”
    这里的/tmp/123和源机器上的/etc/passwd是一致的,但如果目标机器上已经有/tmp/123目录,则会再/tmp/123目录下面建立passwd文件
<root@linux0 ~>$ vi /etc/ansible/hosts #修改hosts name;
[thosts]
192.168.87.149  #ansible命令控制一台机器时,一定要用这个名字;
#192.168.87.150
linux1   #改成字符形式;
<root@linux0 ~>$ ansible 192.168.87.150  -m command -a "w"  #修改之后不能用IP登陆;
 [WARNING]: Could not match supplied host pattern, ignoring: 192.168.87.150

 [WARNING]: No hosts matched, nothing to do
<root@linux0 ~>$ cat !$
cat /etc/hosts
#127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
#::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
#192.168.87.149 linux0
192.168.87.150 linux1  #设置hosts; 对应ansible hosts设置;
<root@linux0 ~>$ ansible linux1  -m command -a "w"
linux1 | SUCCESS | rc=0 >>
 12:32:38 up 21 days, 22:45,  2 users,  load average: 0.10, 0.18, 0.13
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/1    192.168.87.1     五17    3:18   0.13s  0.13s -bash
root     pts/2    linux0           12:32    0.00s  0.10s  0.00s w
<root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible  dest=/tmp/bucunzai owner=root group=root mode=0755"  #目标路径是源目录的上级目录,不存在会创建,并把整个目录放在新建目录下;
linux1 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/bucunzai/", 
    "src": "/etc/ansible"
}
<root@linux0 ~>$ ansible linux1  -m command -a "ls -ld /tmp/bucunzai"
linux1 | SUCCESS | rc=0 >>
drwxr-xr-x 3 root root 21 12月 30 12:37 /tmp/bucunzai

<root@linux0 ~>$ date
2019年 12月 30日 星期一 12:37:55 CST
<root@linux0 ~>$ ansible linux1  -m command -a "ls -l /tmp/bucunzai"
linux1 | SUCCESS | rc=0 >>
总用量 0
drwxr-xr-x 3 root root 51 12月 30 12:37 ansible

<root@linux0 ~>$ ls /etc/ansible
ansible.cfg  hosts  roles
<root@linux0 ~>$ ll !$
ll /etc/ansible
总用量 24
-rw-r--r-- 1 root root 19179 1月  30 2018 ansible.cfg
-rw-r--r-- 1 root root  1062 12月 30 12:28 hosts
drwxr-xr-x 2 root root     6 1月  30 2018 roles
<root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible/hosts  dest=/tmp/bucunzaifile"   #copy文件,修改了文件名字;
linux1 | SUCCESS => {
    "changed": true, 
    "checksum": "d2498e8c027056bce4504550d372d02a144ad2a5", 
    "dest": "/tmp/bucunzaifile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "9e8b0416c70cd4cbc058d85475545ee4", 
    "mode": "0644", 
    "owner": "root", 
    "size": 1062, 
    "src": "/root/.ansible/tmp/ansible-tmp-1577681221.99-76751054633404/source", 
    "state": "file", 
    "uid": 0
}
<root@linux0 ~>$ ansible linux1  -m command -a "ll  /tmp/bucunzaifile"  #不能用别名,cp这些别名与名字一样的命令可用;
linux1 | FAILED | rc=2 >>  
[Errno 2] 没有那个文件或目录

<root@linux0 ~>$ ansible linux1  -m command -a "ls -l  /tmp/bucunzaifile"
linux1 | SUCCESS | rc=0 >>
-rw-r--r-- 1 root root 1062 12月 30 12:47 /tmp/bucunzaifile

<root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible/hosts  dest=/tmp/bucunzai2/bucunzaifile"  #复制文件时,文件名之前的目录必须要存在的,不存在的目录不会自动创建;
linux1 | FAILED! => {
    "changed": false, 
    "checksum": "d2498e8c027056bce4504550d372d02a144ad2a5", 
    "msg": "Destination directory /tmp/bucunzai2 does not exist"
}
<root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible/hosts  dest=/tmp/bucunzai/bucunzaifile"  #存在目录时,会修改名字,dest最后一段就是文件名;
linux1 | SUCCESS => {
    "changed": true, 
    "checksum": "d2498e8c027056bce4504550d372d02a144ad2a5", 
    "dest": "/tmp/bucunzai/bucunzaifile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "9e8b0416c70cd4cbc058d85475545ee4", 
    "mode": "0644", 
    "owner": "root", 
    "size": 1062, 
    "src": "/root/.ansible/tmp/ansible-tmp-1577681488.34-51934515577145/source", 
    "state": "file", 
    "uid": 0
}

Ansible远程执行脚本

  • 首先创建一个shell脚本
    vim /tmp/test.sh //加入内容
    #!/bin/bash echo
    date > /tmp/ansible_test.txt
  • 然后把该脚本分发到各个机器上
    ansible testhost -m copy -a “src=/tmp/test.sh dest=/tmp/test.sh mode=0755”
  • 最后是批量执行该shell脚本
    ansible testhost -m shell -a “/tmp/test.sh”
  • shell模块,还支持远程执行命令并且带管道
    ansible testhost -m shell -a "cat /etc/passwd|wc -l "
root@linux0 ~>$ vim /tmp/test.sh
[root@linux0 ~]# cat /tmp/test.sh 
#! /bin/bash
echo `date` > /tmp/ansible_test.txt
[root@linux0 ~]# ansible thosts -m copy -a "src=/tmp/test.sh dest=/tmp/test.sh mode=0755"
linux1 | SUCCESS => {
    "changed": true,    #复制成功;黄色显示;莹光粉警告,如找不到文件;红色运行失败,如脚本语法错误;
    "checksum": "432f5691b624e4f391ca4f564e99845d58c0eeab", 
    "dest": "/tmp/test.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "bb8fe20b104f03555ca8374f0bf68caa", 
    "mode": "0755", 
    "owner": "root", 
    "size": 49, 
    "src": "/root/.ansible/tmp/ansible-tmp-1577685322.11-198777298584552/source", 
    "state": "file", 
    "uid": 0
}
192.168.87.149 | SUCCESS => {
    "changed": false,   #本机复制不成功,不用操作,绿色显示;
    "checksum": "432f5691b624e4f391ca4f564e99845d58c0eeab", 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/tmp/test.sh", 
    "size": 49, 
    "state": "file", 
    "uid": 0
}
[root@linux0 ~]# ansible thosts -m shell -a "/tmp/test.sh"
linux1 | SUCCESS | rc=0 >>


192.168.87.149 | SUCCESS | rc=0 >>


[root@linux0 ~]# ansible thosts -m shell -a "cat /tmp/ansible_test.txt"   #生成的文件内容;
linux1 | SUCCESS | rc=0 >>
2019年 12月 30日 星期一 13:56:07 CST

192.168.87.149 | SUCCESS | rc=0 >>
2019年 12月 30日 星期一 13:56:08 CST


Ansible管理任务计划

  • ansible testhost -m cron -a “name=‘test cron’ job=’/bin/touch /tmp/1212.txt’ weekday=6”
  • 若要删除该cron 只需要加一个字段 state=absent
  • ansible testhost -m cron -a “name=‘test cron’ state=absent”
  • 其他的时间表示:分钟 minute 小时 hour 日期 day 月份 month
[root@linux0 ~]# ansible thosts -m cron -a "name='test cron' job='/bin/touch /tmp/1212.txt' minute=1 hour=3 day=10"
linux1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]
}
192.168.87.149 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]
}
[root@linux0 ~]# crontab -l
#Ansible: test cron
1 3 10 * * /bin/touch /tmp/1212.txt
[root@linux0 ~]# ansible thosts -m cron -a "name='test cron' state=absent"
linux1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
192.168.87.149 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
[root@linux0 ~]# crontab -l

Ansible安装rpm包/管理服务

  • ansible testhost -m yum -a “name=httpd”
  • 在name后面还可以加上state=installed/removed
  • ansible testhost -m service -a “name=httpd state=started enabled=yes”
  • 这里的name是centos系统里的服务名,可以通过chkconfig --list查到。
  • Ansible文档的使用
    ansible-doc -l 列出所有的模块
    ansible-doc cron 查看指定模块的文档
[root@linux0 ~]# ansible linux1 -m yum -a "name=httpd state=removed"   #删除;
linux1 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加载插件:fastestmirror\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-90.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package       架构           版本                          源             大小\n================================================================================\n正在删除:\n httpd         x86_64         2.4.6-90.el7.centos           @base         9.4 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : httpd-2.4.6-90.el7.centos.x86_64                            1/1 \n  验证中      : httpd-2.4.6-90.el7.centos.x86_64                            1/1 \n\n删除:\n  httpd.x86_64 0:2.4.6-90.el7.centos                                            \n\n完毕!\n"
    ]
}
[root@linux0 ~]# ansible linux1 -m yum -a "name=httpd"   #安装;
linux1 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-90.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch           Version                        Repository    Size\n================================================================================\nInstalling:\n httpd         x86_64         2.4.6-90.el7.centos            base         2.7 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-2.4.6-90.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-90.el7.centos.x86_64                             1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-90.el7.centos                                            \n\nComplete!\n"
    ]
}
[root@linux0 ~]# ansible linux1 -m service -a "name=httpd state=started enabled=yes"   #启动;
linux1 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started",
[root@linux0 ~]# ansible linux1 -m command -a "systemctl status httpd"   #可使用service/systemctl查询状态,只有开启状态会绿色显示,关闭状态会显示成红色,其实并没有错误,只是因为返回码是3;
linux1 | SUCCESS | rc=0 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since 一 2019-12-30 16:04:04 CST; 1min 30s ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 68555 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─68555 /usr/sbin/httpd -DFOREGROUND
           ├─68598 /usr/sbin/httpd -DFOREGROUND
           ├─68599 /usr/sbin/httpd -DFOREGROUND
           ├─68600 /usr/sbin/httpd -DFOREGROUND
           ├─68601 /usr/sbin/httpd -DFOREGROUND
           └─68602 /usr/sbin/httpd -DFOREGROUND

12月 30 16:03:44 linux1 systemd[1]: Starting The Apache HTTP Server...
12月 30 16:03:54 linux1 httpd[68555]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::50a5:f454:5189:9942. Set the 'ServerName' directive globally to suppress this message
12月 30 16:04:04 linux1 systemd[1]: Started The Apache HTTP Server. 
[root@linux0 ~]# ansible linux1 -m service -a "name=httpd state=stauts"  #service模块并没有status;
linux1 | FAILED! => {
    "changed": false, 
    "msg": "value of state must be one of: started,stopped,restarted,reloaded, got: stauts"
}
发布了125 篇原创文章 · 获赞 5 · 访问量 4606

猜你喜欢

转载自blog.csdn.net/tanyyinyu/article/details/103763812