Ansible配置与基本使用

snow chuai汇总、整理、撰写---2020/2/4

最后更新时间---2022/01/24


1. Ansible安装与基础配置
1) 启动sshd,并完成免密登录
2) 准备好EPEL源
3) 安装Ansible [root@node1 ~]# yum --enablerepo=epel install ansible openssh-clients -y
4) 配置Ansible [root@node1 ~]# vim /etc/ansible/ansible.cfg # 71行,取消注释。开启关闭对未连接的主机SSH秘钥检测 host_key_checking = False
5) 编写Ansible主机管理文件 [root@node1 ~]# mv /etc/ansible/hosts /etc/ansible/hosts.bak [root@node1 ~]# vim /etc/ansible/hosts ...... ...... ...... ...... ...... ......
# 建立目标群组,并写入被管机(目标服务器)的IP/FQDN [qyy_servers] node2.1000cc.net node3.1000cc.net

6) 验证设定 [root@node1 ~]# ansible all --list-hosts hosts (2): node2.1000cc.net node3.1000cc.net
[root@node1 ~]# ansible qyy_servers --list-hosts hosts (2): node2.1000cc.net node3.1000cc.net
2. Ansible的基本使用
1) ansbiel使用语法
[root@node1 ~]# ansible [目标主机] [选项] -m [模块] -a [参数]
2) ansbiel模块查看 [root@node1 ~]# ansible-doc -l ...... ...... ...... ...... ...... ......
[root@node1 ~]# ansible-doc -s 模块名
3) ping目标主机 [root@node1 ~]# ansible qyy_servers -m ping node2.1000cc.net | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
node3.1000cc.net | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
4) 使用ssh密码(-k),查看目标主机的uptime [root@node1 ~]# ansible qyy_servers -k -m command -a 'uptime' SSH password: # 输入远程账户的密码 node2.1000cc.net | CHANGED | rc=0 >> 13:55:06 up 7 min, 2 users, load average: 0.00, 0.03, 0.04
node3.1000cc.net | CHANGED | rc=0 >> 13:55:06 up 7 min, 2 users, load average: 0.08, 0.03, 0.03
5) 使用sudo方式,完成任务(目标端需先创建好账户及赋予相关的sudo权限 [root@node1 ~]# su - snow [snow@node1 ~]$ ansible qyy_servers -k -m command -a "cat /etc/shadow" -b --ask-become-pass SSH password: # 输入SSH连接时所需要的密码 BECOME password[defaults to SSH password]: # 输入Sudo需要的密码 node2.1000cc.net | CHANGED | rc=0 >> root:$6$6eTOe1s0ABbI9l4.$Lfqf3L.87wg4ScIZByRu6gTPDkHqQRzjSMxxOsX7c4Sso.212cZm5DleOSvrSJ4U7/Fw bsTrJEMO7SUMuTYkd1::0:99999:7::: bin:*:17834:0:99999:7::: daemon:*:17834:0:99999:7::: ...... ...... ...... ...... ...... ......
6) 使用su方式,切换至root账户,执行date命令 [snow@node1 ~]$ ansible qyy_servers -k -m shell -a 'date' -b --become-method su --become-user root --ask-become-pass SSH password: BECOME password[defaults to SSH password]: node2.1000cc.net | CHANGED | rc=0 >> Tue Feb 4 14:13:29 CST 2020
node3.1000cc.net | CHANGED | rc=0 >> Tue Feb 4 14:13:29 CST 2020
7) 切换远程主目录到/etc/default/下并显示其目内容 [root@node1 ~]# ansible qyy_servers -a 'chdir=/etc/default/ ls' node3.1000cc.net | CHANGED | rc=0 >> grub nss useradd
node2.1000cc.net | CHANGED | rc=0 >> grub nss useradd
8) 其他举例 # 创建test.txt并写入字串111 [root@node1 ~]# ansible qyy_servers -m shell -a 'echo 111 > /tmp/test.txt'
# 获取eth0的ip地址 [root@node1 ~]# ansible qyy_servers -m shell -a "ifconfig eth0 |sed -n 2p |awk '{print \$2}'"
# 将本地文件复制到目标主机的/tmp目录下 [root@node1 ~]# ansible qyy_servers -m copy -a 'src=/root/test.sh dest=/tmp/test.sh mode=600 owner=root'
# 执行主控端节点test.sh脚本以应用至被控端 # 为被控端主机节点安装wget [root@node1 ~]# vim /root/test.sh #! /bin/bash
yum install wget -y

[root@node1 ~]# ansible qyy_servers -m script -a '/root/test.sh'
# 执行crontab任务 [root@node1 ~]# ansible qyy_servers -m cron -a 'name="test" minute=*/5 hour=* day=* month=* weekday=* job="echo aaa"' [root@node1 ~]# ansible qyy_servers -a 'crontab -l'
9) 安装/删除软件 [root@node1 ~]# ansible qyy_servers -m yum -a 'name=psmisc state=installed' [root@node1 ~]# ansible qyy_servers -a 'yum history list' [root@node1 ~]# ansible qyy_servers -a 'yum history list 6' [root@node1 ~]# ansible qyy_servers -m yum -a 'name=psmisc state=removed'
10) 服务控制 [root@node1 ~]# ansible qyy_servers -m service -a 'name=httpd state=started' [root@node1 ~]# ansible qyy_servers -m service -a 'name=httpd state=restarted' [root@node1 ~]# ansible qyy_servers -m service -a 'name=httpd state=stopped' [root@node1 ~]# ansible qyy_servers -m service -a 'name=httpd enabled=yes' [root@node1 ~]# ansible qyy_servers -m service -a 'name=httpd enabled=no' [root@node1 ~]# ansible qyy_servers -m shell -a 'systemctl is-active httpd'
11) 用户添加 [root@node1 ~]# ansible qyy_servers -m user -a 'name=gzliu state=present'
12) 设定账户密码 [root@node1 ~]# yum --enablerepo=epel install python-pip -y [root@node1 ~]# python -c 'import crypt;print(crypt.crypt("123456","gzliu"))' gzQTBkV1KXGdk [root@node1 ~]# ansible qyy_servers -m user -a 'name=gzliu password=gzQTBkV1KXGdk update_password=always'
3. Ansible-Playbook使用
3.1 使用Ansible-Playbook创建文件
[root@node1 ~]# vim playbook_create_files.yml
# 定义目标主机群组
- hosts: qyy_servers
  # 定义任务
  tasks:
  # 定义任务名称
  - name: Test Task
    # 所需要执行的动作
    file: path=/home/snow/test.conf state=touch owner=snow group=snow mode=0600
[root@node1 ~]# ansible-playbook playbook_create_files.yml PLAY [qyy_servers] *******************************************************************************
TASK [Gathering Facts] ******************************************************************************* ok: [node3.1000cc.net] ok: [node2.1000cc.net]
TASK [Test Task] ******************************************************************************* changed: [node3.1000cc.net] changed: [node2.1000cc.net]
PLAY RECAP ******************************************************************** node2.1000cc.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node1 ~]# ansible qyy_servers -m command -a "ls -l /home/snow" node3.1000cc.net | CHANGED | rc=0 >> total 0 -rw------- 1 snow snow 0 Feb 4 15:33 test.conf
node2.1000cc.net | CHANGED | rc=0 >> total 0 -rw------- 1 snow snow 0 Feb 4 15:33 test.conf
3.2 使用Ansible-Playbook安装httpd服务并启动
[snow@node1 ~]$ vim playbook_httpd_install.yml
- hosts: qyy_servers
  # 切换至roo账户
  become: yes
  # 使用方式为sudo
  become_method: sudo
  # 定义任务
  tasks:
  - name: httpd is installed
    # 安装httpd
    yum: name=httpd state=installed
- name: httpd is running and enabled # 启动httpd并enable service: name=httpd state=started enabled=yes

[snow@node1 ~]$ ansible-playbook playbook_httpd_install.yml --ask-become-pass BECOME password:
PLAY [qyy_servers] ********************************************************************************
TASK [Gathering Facts] ********************************************************************************
ok: [node3.1000cc.net] ok: [node2.1000cc.net]
TASK [httpd is installed] *********************************************************************************
changed: [node2.1000cc.net] changed: [node3.1000cc.net]
TASK [httpd is running and enabled] *********************************************************************************
changed: [node2.1000cc.net] changed: [node3.1000cc.net]
PLAY RECAP **********************************************************************
node2.1000cc.net : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[snow@node1 ~]$ ansible qyy_servers -m shell -a "/bin/systemctl is-active httpd" -b --ask-become-pass BECOME password: node3.1000cc.net | CHANGED | rc=0 >> active
node2.1000cc.net | CHANGED | rc=0 >> active
3.3 使用tag标签用于指定或跳过某个任务
1) 创建tags标签
[snow@node1 ~]$ vim tags-test.yml 
- hosts: servers
  remote_user: snow
  become: yes
  become_method: sudo
  tasks:
  - name: task1
    file:
      path: /tmp/test1
      state: touch
    tags: test1
  - name: task2
    file:
      path: /tmp/test2
      state: touch
    tags: test2
  - name: task3
    file:      
      path: /tmp/test3
      state: touch
    tags: test3
2) 使用tags标签执行指定task [snow@node1 ~]$ ansible-playbook --tags=test2 tags-test.yml -K BECOME password:
PLAY [servers] ***************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [srv3.1000y.cloud] ok: [srv2.1000y.cloud]
TASK [task2] ***************************************************************************************** changed: [srv3.1000y.cloud] changed: [srv2.1000y.cloud]
PLAY RECAP ******************************************************************************************$ srv2.1000y.cloud : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 srv3.1000y.cloud : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[snow@node1 ~]$ ansible qyy_servers -m command -a "ls -l /tmp/test2" node3.1000cc.net | CHANGED | rc=0 >> -rw-r--r-- 1 root root 0 Feb 4 15:33 /tmp/test2 node2.1000cc.net | CHANGED | rc=0 >> -rw-r--r-- 1 root root 0 Feb 4 15:33 /tmp/test2
3) 使用tags标签执行指定task [snow@node1 ~]$ ansible-playbook --tags=test1,test3 tags-test.yml -K
4) 使用tags标签执行跳过指定task [snow@node1 ~]$ ansible-playbook --skip-tags=test2 tags-test.yml -K
3.4 使用变量
1) 文件内定义变量
[snow@node1 ~]$ vim playbook_install_test.yml
- hosts: qyy_servers
  become: yes
  become_method: sudo
  tasks:
  - name: General packages are installed
    # 定义变量item
    yum: name={{ item }} state=installed
    # 定义变量的值
    with_items:
      - vim-enhanced
      - wget
      - unzip
    tags: General_Packages
[snow@node1 ~]$ ansible-playbook playbook_install_test.yml --ask-become-pass BECOME password:
PLAY [qyy_servers] *****************************************************************************
TASK [Gathering Facts] ***************************************************************************** ok: [node3.1000cc.net] ok: [node2.1000cc.net]
TASK [General packages are installed] ***************************************************************************** ok: [node2.1000cc.net] => (item=[u'vim-enhanced', u'wget', u'unzip']) ok: [node3.1000cc.net] => (item=[u'vim-enhanced', u'wget', u'unzip'])
PLAY RECAP ****************************************************************** node2.1000cc.net : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net. : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[snow@node1 ~]$ ansible qyy_servers -m shell -a "rpm -qa | grep -E 'vim-enhanced|wget|unzip'" --ask-become-pass BECOME password:
node3.1000cc.net | CHANGED | rc=0 >> wget-1.14-18.el7_6.1.x86_64 unzip-6.0-20.el7.x86_64 vim-enhanced-7.4.629-6.el7.x86_64
node2.1000cc.net | CHANGED | rc=0 >> wget-1.14-18.el7_6.1.x86_64 unzip-6.0-20.el7.x86_64 vim-enhanced-7.4.629-6.el7.x86_64
2) 显示指定的内容 # 显示目标主机信息 [snow@node1 ~]$ ansible node2.1000cc.net -m setup
[snow@node1 ~]$ vim playbook_out_display.yml
- hosts: qyy_servers tasks: - name: Refer to Gathering Facts # 仅显示ansible_distribution与ansible_distribution_version字段的信息 command: echo "{{ ansible_distribution }} {{ ansible_distribution_version }}" register: dist - debug: msg="{{ dist.stdout }}", - debug: msg="{{ ansible_fqdn }} {{ ansible_default_ipv4.address }}"

[snow@node1 ~]# ansible-playbook playbook_out_display.yml ...... ...... ...... ...... ...... ...... TASK [debug] ******************************************************************************************** ok: [node2.1000cc.net] => { "msg": "CentOS 7.7" } ok: [node3.1000cc.net] => { "msg": "CentOS 7.7" } TASK [debug] ******************************************************************************************** ok: [node2.1000cc.net] => { "msg": "node2.1000cc.net 192.168.1.12" } ok: [node3.1000cc.net] => { "msg": "node3.1000cc.net 192.168.1.13" } ...... ...... ...... ...... ...... ......
3.5 使用when进行判断
1) 如果目标主机不存在/var/www/html/index.html则创建此文件
[snow@node1 ~]$ vim playbook-index-check.yml
- hosts: qyy_servers
  become: yes
  become_method: sudo
  tasks:
  - name: index file exists or not
    # 调用shell模块,使用test命令检测index.html是否存在,存在值为0,不存在则为1
    shell: test -f /var/www/html/index.html
    ignore_errors: true
    register: file_exists
    failed_when: file_exists.rc not in [0, 1]
- name: put index.html shell: echo "httpd index" > /var/www/html/index.html # 使用when判断test的值如果为1,则调用echo命令进行创建文件 when: file_exists.rc == 1

[snow@node1 ~]$ ansible-playbook playbook-index-check.yml -K BECOME password:
PLAY [qyy_servers] *****************************************************************************
TASK [Gathering Facts] ***************************************************************************** ok: [node2.1000cc.net] ok: [node3.1000cc.net]
TASK [index file exists or not] ****************************************************************************** changed: [node2.1000cc.net] changed: [node3.1000cc.net]
TASK [put index.html] ****************************************************************************** changed: [node2.1000cc.net] changed: [node3.1000cc.net]
PLAY RECAP ****************************************************************** node2.1000cc.net : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.6 使用"notify", "handlers"定义任务
[snow@node1 ~]$ vim playbook_ssh_modify.yml 
- hosts: qyy_servers
  become: yes
  become_method: sudo
  handlers:
  - name: restart sshd
    service: name=sshd state=restarted
  tasks:
  - lineinfile:
      path: /etc/ssh/sshd_config
      regexp: '^#PermitRootLogin'
      line: 'PermitRootLogin no'
    notify: restart sshd
    tags: Edit_sshd_config
[snow@node1 ~]$ ansible-playbook playbook_ssh_modify.yml -K BECOME password:
PLAY [qyy_servers] **************************************************************************
TASK [Gathering Facts] ************************************************************************** ok: [node2.1000cc.net] ok: [node3.1000cc.net]
TASK [edit sshd_config] ************************************************************************** changed: [node2.1000cc.net] => (item={u'regexp': u'^#PermitRootLogin', u'line': u'PermitRootLogin no'}) changed: [node3.1000cc.net] => (item={u'regexp': u'^#PermitRootLogin', u'line': u'PermitRootLogin no'})
RUNNING HANDLER [restart sshd] **************************************************************************** changed: [node3.1000cc.net] changed: [node2.1000cc.net]
PLAY RECAP ********************************************************************** node2.1000cc.net : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[snow@ndoe1 ~]$ ansible qyy_servers -m command -a "grep '^PermitRootLogin' /etc/ssh/sshd_config" -b -K SUDO password: node2.1000cc.net | success | rc=0 >> PermitRootLogin no
node3.1000cc.net | success | rc=0 >> PermitRootLogin no
3.7 调用外部tasks脚本
1) 目录及文件结构
[snow@node1 ~]$ tree
.
├── playbook_install_lynx.yml
└── tasks
    └── soft-install.yml
1 directory, 2 files
2) 编写playbook_install_lynx.yml文件 [snow@node1 ~]$ vim playbook_install_lynx.yml - hosts: qyy_servers become: yes become_method: sudo tasks: - include: tasks/soft-install.yml vars: general_packages: htop, iftop
[snow@node1 ~]$ vim tasks/soft-install.yml - name: General packages are installed yum: name="{{ general_packages }}" enablerepo=epel state=installed tags: General_Packages
[snow@node1 ~]$ ansible-playbook playbook_install_lynx.yml -K BECOME password:
PLAY [qyy_servers] ******************************************************************************
TASK [Gathering Facts] ****************************************************************************** ok: [node3.1000cc.net] ok: [node2.1000cc.net]
TASK [General packages are installed] *******************************************************************************
changed: [node2.1000cc.net] => (item=[u'htop, iftop']) changed: [node3.1000cc.net] => (item=[u'htop, iftop'])
PLAY RECAP ******************************************************************** node2.1000cc.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.8 调用其他Playbook剧本
[snow@node1 ~]$ vim playbook_httpd_install.yml
- hosts: qyy_servers
  become: yes
  become_method: sudo
  tasks:
    - include: tasks/soft-install.yml
      vars:
        general_packages: lynx
# 调用httpd.yum剧本
- import_playbook: httpd.yml
[snow@node1 ~]$ vim httpd.yml - hosts: qyy_servers become: yes become_method: sudo tasks: - name: httpd is installed yum: name=httpd state=installed - name: httpd is running and enabled service: name=httpd state=started enabled=yes
[snow@node1 ~]$ vim tasks/soft-install.yml - name: General packages are installed yum: name="{{ general_packages }}" enablerepo=epel state=installed tags: General_Packages
[snow@node1 ~]$ ansible-playbook playbook_httpd_install.yml -K SUDO password:
PLAY [target_servers] *********************************************************
GATHERING FACTS *************************************************************** ok: [node3.1000cc.net] ok: [node2.1000cc.net]
TASK: [General packages are installed] **************************************** changed: [node2.1000cc.net] => (item=vim-enhanced,wget,unzip) changed: [node3.1000cc.net] => (item=vim-enhanced,wget,unzip)
PLAY [target_servers] *********************************************************
GATHERING FACTS *************************************************************** ok: [node3.1000cc.net] ok: [node2.1000cc.net]
TASK: [httpd is installed] **************************************************** ok: [node2.1000cc.net] ok: [node3.1000cc.net]
TASK: [httpd is running and enabled] ****************************************** ok: [node2.1000cc.net] ok: [node3.1000cc.net]
PLAY RECAP ******************************************************************** node2.1000cc.net : ok=5 changed=1 unreachable=0 failed=0 node3.1000cc.net : ok=5 changed=1 unreachable=0 failed=0
3.9 使用Role
1) 目录结构
# 一般建议目录结构为一下样式
+--- playbook.yml
|
+--- roles/
     |                                 
     +--- role01/                     
          |
          +--- files/
          |
          +--- templates/
          |
          +--- tasks/
          |
          +--- handlers/
          |
          +--- vars/
          |
          +--- defaults/
          |
          +--- meta/
2) 本案例目录结构 [snow@node1 ~]$ mkdir -p roles/ins_python_lib/{tasks,vars} [snow@node1 ~]$ mkdir -p roles/ins_httpd/{files,tasks,vars} [snow@node1 ~]$ tree . └── roles ├── ins_httpd │   ├── files │   ├── tasks │   └── vars └── ins_python_lib ├── tasks └── vars
8 directories, 0 files
3) 创建playbook剧本 [snow@node1 ~]$ vim playbook_httpd.yml - hosts: qyy_servers become: yes become_method: sudo roles: - ins_python_lib - ins_httpd
[snow@node1 ~]$ vim roles/ins_python_lib/vars/main.yml setuptools: - python-setuptools - python2-pip
py_pip: - pip
py_libs: - httplib2

[snow@node1 ~]$ vim roles/ins_python_lib/tasks/main.yml - name: setuptools is installed yum: name="{{ item }}" enablerepo=epel state=installed with_items: - "{{ setuptools }}" tags: install_setuptools
- name: pip is installed easy_install: name="{{ item }}" with_items: - "{{ py_pip }}" tags: install_pip
- name: httplib2 are installed pip: name="{{ item }}" with_items: - "{{ py_libs }}" tags: install_httplib2

[snow@node1 ~]$ vim roles/ins_httpd/vars/main.yml packages: - httpd
[snow@node1 ~]$ vim roles/ins_httpd/tasks/main.yml - name: httpd is installed yum: name="{{ item }}" state=installed with_items: - "{{ packages }}" tags: install_httpd
- name: edit httpd.conf lineinfile: > dest=/etc/httpd/conf/httpd.conf regexp="{{ item.regexp }}" line="{{ item.line }}" with_items: - { regexp: "^#ServerName", line: "ServerName {{ ansible_fqdn }}:80" } tags: edit_httpd.conf
- name: httpd is running and enabled service: name=httpd state=started enabled=yes
- name: put index.html copy: src=index.html dest=/var/www/html owner=root group=root mode=0644

[snow@node1 ~]$ echo "www.1000cc.net.cn" > roles/ins_httpd/files/index.html
4) 最终的目录及文件结构 [snow@node1 ~]$ tree . ├── playbook_httpd.yml └── roles ├── ins_httpd │   ├── files │   │   └── index.html │   ├── tasks │   │   └── main.yml │   └── vars │   └── main.yml └── ins_python_lib ├── tasks │   └── main.yml └── vars └── main.yml
8 directories, 6 files
5) 执行并验证结果 [snow@node1 ~]$ ansible-playbook playbook_httpd.yml -K BECOME password:
...... ...... ...... ...... ...... ...... PLAY RECAP **************************************************************************************** node2.1000cc.net : ok=8 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3.1000cc.net : ok=8 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

 

 

如对您有帮助,请随缘打个赏。^-^

gold