初识Ansible

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识Ansible相关的知识,希望对你有一定的参考价值。

Ansible

Ansible 基于 Python 语言实现
默认使用 SSH(Secure Shell)协议对设备进行管理。
也就是说被控制端必须安装SSH和Python,其它设置与操作都在Ansible主机操作

Ansible主要有3种模块:
Command(默认模块,尽量使用这个): does not use shell(Bash/SH), can not use pipes or redirects
Shell: supports pipes and redirects, can get messed up by user settings
Raw: just sends commands over ssh, does not need python

安装 Ansible
[[email protected] ~ ]# yum -y install ansible

[[email protected] ~ ]# vi /etc/hosts
192.168.1.48 linux-node0
192.168.1.201 linux-node1
192.168.1.32 linux-node2

Ansible 管理机与被管理机做秘钥认证
[[email protected] ~ ]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
fc:d6:ae:c2:f0:6b:e3:97:e7:8c:e0:90:dc:cf:d6:55 [email protected]
The key‘s randomart image is:
+--[ RSA 2048]----+
. E
S .
..o . . .
++o oo..
o*=++o
o+*=++

+-----------------+

[[email protected]~]# ls /root/.ssh
id_rsa id_rsa.pub

[[email protected]~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
The authenticity of host ‘linux-node0 (192.168.1.48)‘ can‘t be established.
ECDSA key fingerprint is 3d:c8:02:ba:60:56:ea:a8:8b:0e:7c:88:f0:2d:07:8b.
Are you sure you want to continue connecting (yes/no)?yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]‘s password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh ‘[email protected]0‘"
and check to make sure that only the key(s) you wanted were added.

[[email protected]~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
The authenticity of host ‘linux-node1 (192.168.1.201)‘ can‘t be established.
ECDSA key fingerprint is 4b:40:f1:c3:7e:da:a3:1b:81:ec:68:de:5c:33:c1:9f.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]‘s password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh ‘[email protected]‘"
and check to make sure that only the key(s) you wanted were added.

hosts 文件添加被管理机
[[email protected] ~]# vi /etc/ansible/hosts
linux-node0
linux-node1

测试 Ansible
[[email protected] ~]# ansible -m ping all
linux-node0 | SUCCESS => {
"changed": false,
"ping": "pong"
}
linux-node1 | SUCCESS => {
"changed": false,
"ping": "pong"
}

[[email protected] ~]# ansible -m shell -a ‘python -V‘ all
linux-node0 | SUCCESS | rc=0 >>
Python 2.7.5
linux-node1 | SUCCESS | rc=0 >>
Python 2.7.5

[[email protected] ~]# ansible all -a ‘uptime‘
linux-node0 | SUCCESS | rc=0 >>
13:26:38 up 20:25, 2 users, load average: 0.00, 0.01, 0.05
linux-node1 | SUCCESS | rc=0 >>
13:26:38 up 21:30, 1 user, load average: 0.25, 0.17, 0.15

[[email protected] ~]# ansible all -a ‘whoami‘
linux-node0 | SUCCESS | rc=0 >>
root
linux-node1 | SUCCESS | rc=0 >>
root

[[email protected] ~]# ansible all -b -a ‘whoami‘ (如果上面的whoami不是root,这里可以用-b,使别的用户变成root再运行whoami)
linux-node0 | SUCCESS | rc=0 >>
root
linux-node1 | SUCCESS | rc=0 >>
root

[[email protected] ~]# ansible all -b -m yum -a ‘name=httpd state=latest‘ (在所有主机上安装最新版apache)

[[email protected] ~]# ansible all -b -m command -a ‘echo "hello" >/root/hello.txt‘ (-m command可以省,这个执行后,被控端并没有生成hello.txt,因为command does not use shell)
linux-node0 | SUCCESS | rc=0 >>
hello >/root/hello.txt
linux-node1 | SUCCESS | rc=0 >>
hello >/root/hello.txt

[[email protected] ~]# ansible all -b -m shell -a ‘echo "hello" >/root/hello.txt‘
(被控端生成hello.txt)
linux-node0 | SUCCESS | rc=0 >>
linux-node1 | SUCCESS | rc=0 >>

被控端
[[email protected] ~]# cat /root/hello.txt
Hello

删除文件(用了-m file模块)
[[email protected] ~]# ansible all -b -m file -a ‘path=/root/hello.txt state=absent‘
linux-node0 | SUCCESS => {
"changed": true,
"path": "/root/hello.txt",
"state": "absent"
}
linux-node1 | SUCCESS => {
"changed": true,
"path": "/root/hello.txt",
"state": "absent"
}

被控端
[[email protected] ~]# cat /root/hello.txt
cat: /root/hello.txt: No such file or directory

复制文件(用了-m copy模块)
[[email protected] ~]# ansible all -b -m copy -a ‘src=/etc/hosts dest=/etc/hosts‘
linux-node0 | SUCCESS => {
"changed": true,
"checksum": "f8a18de2bf1528cc840179039ab991e0a94068fe",
"dest": "/etc/hosts",
"gid": 0,
"group": "root",
"md5sum": "3c20904bc44d3669c1a18429aea169b5",
"mode": "0644",
"owner": "root",
"size": 261,
"src": "/root/.ansible/tmp/ansible-tmp-1532501917.65-225783863411073/source",
"state": "file",
"uid": 0
}
linux-node1 | SUCCESS => {
"changed": true,
"checksum": "f8a18de2bf1528cc840179039ab991e0a94068fe",
"dest": "/etc/hosts",
"gid": 0,
"group": "root",
"md5sum": "3c20904bc44d3669c1a18429aea169b5",
"mode": "0644",
"owner": "root",
"size": 261,
"src": "/root/.ansible/tmp/ansible-tmp-1532501917.66-73905370255186/source",
"state": "file",
"uid": 0
}

Playbook 实战
[[email protected] ~]# vi test.yaml

  • hosts: all
    tasks:

    • name: do a uname
      shell: uname -a > /root/results.txt

    • name: whoami
      shell: whoami >> /root/results.txt

[[email protected] ~]# ansible-playbook test.yaml

PLAY [all] *****

TASK [Gathering Facts] *****
ok: [linux-node0]
ok: [linux-node1]

TASK [do a uname] **
changed: [linux-node0]
changed: [linux-node1]

TASK [whoami] **
changed: [linux-node0]
changed: [linux-node1]

PLAY RECAP *****
linux-node0 : ok=3 changed=2 unreachable=0 failed=0
linux-node1 : ok=3 changed=2 unreachable=0 failed=0

被控端
[[email protected] ~]# cat /root/results.txt
Linux linux-node0 3.10.0-693.11.1.el7.x86_64 #1 SMP Mon Dec 4 23:52:40 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
root

[[email protected] ~]# vi test.yaml (指定使用root执行)

  • hosts: all
    become: yes #或者true
    tasks:

    • name: do a uname
      shell: uname -a > /root/results.txt

    • name: whoami
      shell: whoami >> /root/results.txt

Handlers实战
[[email protected] ~]# vi test1.yaml

  • hosts: all
    become: yes
    tasks:

    • name: install vsftpd on Ubuntu (因为我没有装Ubuntu,所以红色部分省)
      apt: name=vsftpd update_cache=yes state=latest
      ignore_errors: yes
      notify:start vsftpd

    • name: install vsftpd on centos
      yum: name=vsftpd state=latest
      ignore_errors: yes
      notify: start vsftpd

    handlers:

    • name: start vsftpd
      service: name=vsftpd enabled=yes state=started

[[email protected] ~]# ansible-playbook test1.yaml

PLAY [all] ****

TASK [Gathering Facts] ****
ok: [linux-node0]
ok: [linux-node1]

TASK [install vsftpd on centos] ***
changed: [linux-node0]
changed: [linux-node1]

RUNNING HANDLER [start vsftpd] ****
changed: [linux-node0]
changed: [linux-node1]

PLAY RECAP ****
linux-node0 : ok=3 changed=2 unreachable=0 failed=0
linux-node1 : ok=3 changed=2 unreachable=0 failed=0

被控端
[[email protected] ~]# service vsftpd status
Redirecting to /bin/systemctl status vsftpd.service
?vsftpd.service - Vsftpd ftp daemon
Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2018-07-25 17:49:03 CST; 20h ago
Process: 8091 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
Main PID: 8092 (vsftpd)
CGroup: /system.slice/vsftpd.service
忖8092 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

Jul 25 17:49:03 linux-node0 systemd[1]: Starting Vsftpd ftp daemon...
Jul 25 17:49:03 linux-node0 systemd[1]: Started Vsftpd ftp daemon.

Variables and Facts实战
[[email protected] ~]# ansible linux-node0 -m setup -a "filter=family"
(ansible linux-node0 -m setup能得到 CPU type, RAM, IP address, CPU cores, etc)
linux-node0 | SUCCESS => {
"ansible_facts": {
"ansible_os_family": "RedHat"
},
"changed": false
}

[[email protected] ~]# vi test2.yaml

  • hosts: linux-node0
    vars:

    • var1: cool stuff here
    • var2: cool stuff there

    tasks:

    • name: echo stuff
      shell: echo " {{var1}} is var1, but var2 is {{var2}}" > /root/{{ansible_os_family}}.txt

[[email protected] ~]# ansible-playbook test2.yaml

PLAY [linux-node0] ****

TASK [Gathering Facts] ****
ok: [linux-node0]

TASK [echo stuff] *****
changed: [linux-node0]

PLAY RECAP ****
linux-node0 : ok=2 changed=1 unreachable=0 failed=0

被控端
[[email protected] ~]# cat /root/RedHat.txt
cool stuff here is var1, but var2 is cool stuff there

Debug Module实战(不会对被控端进行修改)
[[email protected] ~]# vi test3.yaml

  • hosts: linux-node0
    vars:

    • var_thing: "never gonna"

    tasks:

    • name: echo stuff
      command: echo -e "{{var_thing}} give you up, {{var_thing}} let you down, {{var_thing}} run around and dessert you"
      register: results

    • name: show results
      debug: msg={{results.stdout_lines}}

[[email protected] ~]# ansible-playbook test3.yaml

PLAY [linux-node0] ****

TASK [Gathering Facts] ****
ok: [linux-node0]

TASK [echo stuff] *****
changed: [linux-node0]

TASK [show results] ***
ok: [linux-node0] => {
"msg": [
"never gonna give you up,",
" never gonna let you down,",
"never gonna run around and dessert you"
]
}

PLAY RECAP ****
linux-node0 : ok=3 changed=1 unreachable=0 failed=0

Conditionals实战
[[email protected] ~]# vi test4.yaml

  • hosts: linux-node0
    become: yes

    tasks:

    • name: install apache2
      apt: name=apache2 state=latest
      when: ansible_os_family == "Debian"

    • name: install httpd
      yum: name=httpd state=latest
      when: ansible_os_family == "RedHat"

[[email protected] ~]# ansible-playbook test4.yaml

PLAY [linux-node0] *****

TASK [Gathering Facts] *****
ok: [linux-node0]

TASK [install apache2] *****
skipping: [linux-node0]

TASK [install httpd] ***
changed: [linux-node0]

PLAY RECAP *****
linux-node0 : ok=2 changed=1 unreachable=0 failed=0

被控端
[[email protected] ~]# service httpd status
Redirecting to /bin/systemctl status httpd.service
?httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:httpd(8)
man:apachectl(8)

Loops实战
with_items:
[[email protected] ~]# vi test5.yaml (在被控端安装vim, nano, httpd)

  • hosts: linux-node0
    become: yes

    tasks:

    • name: install stuff
      yum: name={{item}} state=latest
      with_items:
      • vim
      • nano
      • httpd

[[email protected] ~]# ansible-playbook test5.yaml

PLAY [linux-node0] ****

TASK [Gathering Facts] ****
ok: [linux-node0]

TASK [install stuff] **
changed: [linux-node0] => (item=[u‘vim‘, u‘nano‘, u‘httpd‘])

PLAY RECAP ****
linux-node0 : ok=2 changed=1 unreachable=0 failed=0

with_file:
[[email protected] ~]# vi test6.yaml

  • hosts: linux-node0
    become: yes

    tasks:

    • name: show file contents
      debug: msg={{item}}
      with_file:
      • file1.txt
      • file2.txt

[[email protected] ~]# vi file1.txt
This is file number 1

[[email protected] ~]# vi file2.txt
This is file
number 2

[[email protected] ~]# ansible-playbook test6.yaml

PLAY [linux-node0] ****

TASK [Gathering Facts] ****
ok: [linux-node0]

TASK [show file contents] *****
ok: [linux-node0] => (item=This is file number 1) => {
"msg": "This is file number 1"
}
ok: [linux-node0] => (item=This is file
number 2) => {
"msg": "This is file number 2"
}

PLAY RECAP ****
linux-node0 : ok=2 changed=0 unreachable=0 failed=0

with_sequence:
[[email protected] ~]# vi test7.yaml

  • hosts: linux-node0
    become: yes

    tasks:

    • name: show file contents
      debug: msg="this is loop {{item}}"
      with_sequence: start=1 end=10

[[email protected] ~]# ansible-playbook test7.yaml

PLAY [linux-node0] ****

TASK [Gathering Facts] ****
ok: [linux-node0]

TASK [show file contents] *****
ok: [linux-node0] => (item=1) => {
"msg": "this is loop 1"
}
ok: [linux-node0] => (item=2) => {
"msg": "this is loop 2"
}
ok: [linux-node0] => (item=3) => {
"msg": "this is loop 3"
}
ok: [linux-node0] => (item=4) => {
"msg": "this is loop 4"
}
ok: [linux-node0] => (item=5) => {
"msg": "this is loop 5"
}
ok: [linux-node0] => (item=6) => {
"msg": "this is loop 6"
}
ok: [linux-node0] => (item=7) => {
"msg": "this is loop 7"
}
ok: [linux-node0] => (item=8) => {
"msg": "this is loop 8"
}
ok: [linux-node0] => (item=9) => {
"msg": "this is loop 9"
}
ok: [linux-node0] => (item=10) => {
"msg": "this is loop 10"
}

PLAY RECAP ****
linux-node0 : ok=2 changed=0 unreachable=0 failed=0

Ansible Templates实战
[[email protected] ~]# vi test8.yaml

  • hosts: all
    become: yes
    vars:
    file_version: 1.0
    tasks:

    • name: install index
      template:
      src: index.html.j2
      dest: /var/www/html/index.html
      mode: 0777

[[email protected] ~]# vi index.html.j2
<html>
<center>
<h1>This computer‘s hostname is {{ansible_hostname}}</hl>
<h3>It is running the{{ansible_os_family}} family of operating system</h3>
<small>This file is version{{file_version}}</small>
{#this will not end up in the final output file on the remote server#}
</center>
</html>

[[email protected] ~]# ansible-playbook test8.yaml

PLAY [all] ****

TASK [Gathering Facts] ****
ok: [linux-node0]
ok: [linux-node1]

TASK [install index] **
changed: [linux-node0]
changed: [linux-node1]

PLAY RECAP ****
linux-node0 : ok=2 changed=1 unreachable=0 failed=0
linux-node1 : ok=2 changed=1 unreachable=0 failed=0

被控端
[[email protected] ~]# cat /var/www/html/index.html
<html>
<center>
<h1>This computer‘s hostname is linux-node0</hl>
<h3>It is running theRedHat family of operating system</h3>
<small>This file is version1.0</small>
</center>
</html>

以上是关于初识Ansible的主要内容,如果未能解决你的问题,请参考以下文章

Ansibleansible安装,用户级执行ansible命令,清单构建,配置文件详解

Ansibleansible安装,用户级执行ansible命令,清单构建,配置文件详解

Ansibleansible安装,用户级执行ansible命令,清单构建,配置文件详解

AnsibleAnsible控制windows插件安装及运行error与解决方法

ansible控制windows 2019

Ansible 自动化常用实例