首页 > 其他分享 >playbook

playbook

时间:2022-10-24 18:37:49浏览次数:30  
标签:httpd name web ansible playbook root

playbook

目录

1. 实施playbook

1.1 Ansible playbook与临时命令

临时命令可以作为一次性命令对一组目标主机运行一项简单的任务。不过,若要真正发挥Ansible的力量,需要了解如何使用playbook以便轻松重复的方式对一组目标主机执行多项复杂的任务。

play是针对清单中选定的主机运行的一组有序任务。playbook是一个文本文件,其中包含由一个或多个按特定顺序运行的play组成的列表。

Play可以将一系列冗长而复杂的手动管理任务转变为可轻松重复的例程,并且具有可预测的成功成果。在playbook中,可以将play内的任务序列保存为人类可读并可立即运行的形式。根据任务的编写方式,任务本身记录了部署应用或基础架构所需的步骤。(可以把部署的一些服务的步骤写到playbook里,按照所能识别的语言有序的表达出来)

1.2 格式化Ansible playbook

这个任务可以将其编写为一个单任务的play并保存在playbook中。生成的playbook如下方所示:

---
- name: Configure important user consistently(名字)
  hosts: 172.16.103.129 (清单所在的主机组)
  tasks:(任务)
    - name: runtime exists with UID 4000(描述动作--状态)
      user:
        name: runtime
        uid: 4000
        state: present
        
(冒号后面必须有一个空格)
(上下级别缩进两个空格)
(同级别的必须对齐)

Playbook是以YAML格式编写的文本文件,通常使用扩展名yml保存。Playbook使用空格字符缩进来表示其数据结构。YAML对用于缩进的空格数量没有严格的要求,但有两个基本的规则:

  • 处于层次结构中同一级别的数据元素(例如同一列表中的项目)必须具有相同的缩进量。
  • 如果项目属于其他项目的子项,其缩进量必须大于父项

只有空格字符可用于缩进,不允许使用tab键。约定俗成的缩进量一般是一级2个空格。

Playbook开头的一行由三个破折号(---)组成
这是文档开始标记。其末尾可能使用三个圆点(...)作为文档结束标记,尽管在实践中这通常会省略。第二行则是顶行写一个(-)一个空格

在这两个标记之间,会以一个play列表的形式来定义playbook。YAML列表中的项目以一个破折号加空格开头。例如,YAML列表可能显示如下:

- apple
- orange
- grape

Play本身是一个键值对集合。同一play中的键应当使用相同的缩进量。以下示例显示了具有三个键的YAML代码片段。前两个键具有简单的值。第三个将含有三个项目的列表作为值。

- name: just an example
  hosts: webservers
  tasks:
    - first
    - second
    - third

作为play中的一部分,tasks属性按顺序实际列出要在受管主机上运行的任务。列表中各项任务本身是一个键值对集合。
还以上面创建用户的play为例,play中唯一任务有两个键:

  • name是记录任务用途的可选标签。最好命名所有的任务,从而帮助记录自动流程中的每一步用途。
  • user是要为这个任务运行的模块。其参数作为一组键值对传递,它们是模块的子项(name、uid和state)。

下面再来看一个含有多项任务的tasks属性案例:


tasks:
  - name: web server is enabled
    service:
      name: httpd
      enabled: true
      
  - name: NTP server is enabled
    service:
      name: chronyd
      enabled: true
      
  - name: Postfix is enabled
    service:
      name: postfix
      enabled: true

任务
模块
参数

playbook中play和任务列出的顺序很重要,因为Ansible会按照相同的顺序运行它们。

1.3 运行playbook

部署环境

主机名 IP
a 192.168.29.129
b 192.168.29.130
c 192.168.29.131
做映射
[root@a ~]# vim /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.29.130 b
192.168.29.131 c
[root@a ~]# ping b
PING b (192.168.29.130) 56(84) bytes of data.
64 bytes from b (192.168.29.130): icmp_seq=1 ttl=64 time=0.281 ms
64 bytes from b (192.168.29.130): icmp_seq=2 ttl=64 time=0.180 ms
^C
--- b ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1012ms
rtt min/avg/max/mdev = 0.180/0.230/0.281/0.052 ms
[root@a ~]# ping c
PING c (192.168.29.131) 56(84) bytes of data.
64 bytes from c (192.168.29.131): icmp_seq=1 ttl=64 time=0.616 ms
64 bytes from c (192.168.29.131): icmp_seq=2 ttl=64 time=1.13 ms
^C
--- c ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1066ms
rtt min/avg/max/mdev = 0.616/0.873/1.131/0.259 ms
免密登录
[root@a ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
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:
SHA256:smr0O5H2yyMaOUQiAYIOc3MNoLORKW1/oZ7Tv5yqNlI root@a
The key's randomart image is:
+---[RSA 3072]----+
|* ...o           |
|=*o . .          |
|@o+o. .          |
|.B + . .         |
|.   + o.S        |
|   oE=+o         |
|   oBooo         |
|  . +=++o.       |
|   +++o=B+       |
+----[SHA256]-----+
[root@a ~]# ssh-copy-id b
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host 'b (192.168.29.130)' can't be established.
ECDSA key fingerprint is SHA256:GKhyLI0ugf8uSsj22Zqei3oSFf76aLw8wpWYai88Fcc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 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
root@b's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'b'"
and check to make sure that only the key(s) you wanted were added.

[root@a ~]# ssh-copy-id c
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host 'c (192.168.29.131)' can't be established.
ECDSA key fingerprint is SHA256:iwjjWZAX8/wtQpwoSyPVUn/9J3MlDrs7X2/W5L0Vpb0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 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
root@c's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'c'"
and check to make sure that only the key(s) you wanted were added.

[root@a ~]# ssh b
Last login: Mon Oct 24 14:20:07 2022 from 192.168.29.1
[root@b ~]# exit
注销
Connection to b closed.
[root@a ~]# ssh c
Last login: Mon Oct 24 14:20:11 2022 from 192.168.29.1
[root@c ~]# exit
注销
Connection to c closed.
[root@a ~]# cd /opt/
[root@a opt]# ls
[root@a opt]# mkdir project
[root@a opt]# ls
project
[root@a opt]# cd project/
[root@a project]# ls
[root@a project]# cp /etc/ansible/ansible.cfg .
[root@a project]# ls
ansible.cfg
[root@a project]# vim ansible.cfg 
[defaults]

# some basic default values...

inventory      = inventory//修改这一栏
[root@a project]# vim inventory
[webservers]
b
c
[root@a project]# ansible all --list-hosts
  hosts (2):
    b
    c
[root@a project]# ansible webservers --list-hosts
  hosts (2):
    b
    c
[root@a project]# ansible all -m ping
b | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
c | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
[root@a project]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@a project]# vim /etc/selinux/config 
SELINUX=disabled
[root@a project]# setenforce 0

[root@b ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enab>
   Active: active (running) since Mon 2022-10-24 14:20:02 CST; 1h >
     Docs: man:firewalld(1)
 Main PID: 939 (firewalld)
    Tasks: 2 (limit: 11201)
   Memory: 35.6M
   CGroup: /system.slice/firewalld.service
           └─939 /usr/libexec/platform-python -s /usr/sbin/firewal>

10月 24 14:19:59 b systemd[1]: Starting firewalld - dynamic firewa>
10月 24 14:20:02 b systemd[1]: Started firewalld - dynamic firewal>
10月 24 14:20:03 b firewalld[939]: WARNING: AllowZoneDrifting is e>
[root@b ~]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@b ~]# vim /etc/selinux/config 
SELINUX=disabled
[root@b ~]# setenforce 0

[root@c ~]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@c ~]# vim /etc/selinux/config
SELINUX=disabled
[root@c ~]#  setenforce 0


absible-playbook命令可用于运行playbook。该命令在控制节点上执行,要运行的playbook的名称则作为参数传递。
ansible-playbook site.yml

在运行playbook时,将生成输出来显示所执行的play和任务。输出中也会报告执行的每一项任务的结果。

以下示例中显示了一个简单的playbook的内容,后面是运行它的结果。

[root@a project]# mkdir playbooks
[root@a project]# ls
ansible.cfg  inventory  playbooks
[root@a project]# cd playbooks/
[root@a playbooks]# ls
[root@a playbooks]# vim web.yml
---
- name: deploy web server
  hosts: b
  tasks:
    - name: ensure web service exists
      yum:
        name: httpd
        state: present
        
    - name: ensure httpd service is started and enabled
      service:
        name: httpd
        state: started
        enabled: yes
[root@a playbooks]# cd ..
[root@a project]# ls
ansible.cfg  inventory  playbooks

[root@b ~]# rpm -qa|grep httpd
[root@b ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*            

[root@a project]# ansible-playbook playbooks/web.yml 

PLAY [deploy web server] *******************************************************

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

TASK [ensure web service exists] ***********************************************
changed: [b]

TASK [ensure httpd service is started and enabled] *****************************
changed: [b]

PLAY RECAP *********************************************************************
b                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@a project]# ansible-playbook playbooks/web.yml 

PLAY [deploy web server] *******************************************************

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

TASK [ensure web service exists] ***********************************************
ok: [b]

TASK [ensure httpd service is started and enabled] *****************************
ok: [b]

PLAY RECAP *********************************************************************
b                          : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@b ~]# rpm -qa|grep httpd
httpd-2.4.37-47.module_el8.6.0+1111+ce6f4ceb.1.x86_64
httpd-tools-2.4.37-47.module_el8.6.0+1111+ce6f4ceb.1.x86_64
httpd-filesystem-2.4.37-47.module_el8.6.0+1111+ce6f4ceb.1.noarch
centos-logos-httpd-85.8-2.el8.noarch
[root@b ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128                *:80               *:*            
LISTEN 0      128             [::]:22            [::]:*    

请注意,在playbook运行时,屏幕中会显示每个play和任务的name键的值。(Gathering Facts任务是一项特别的任务,setup模块通常在play启动时自动运行这项任务。)对于含有多个play和任务的playbook,设置name属性后可以更加轻松地监控playbook执行的进展。

通常而言,Ansible Playbook中的任务是幂等的,而且能够安全地多次运行playbook。如果目标受管主机已处于正确的状态,则不应进行任何更改。如果再次运行这个playbook,所有任务都会以状态OK传递,且不报告任何更改。

1.4 提高输出的详细程度

ansible-playbook命令提供的默认输出不提供详细的任务执行信息。ansible-playbook -v命令提供了额外的信息,总共有四个级别。

配置Playbook执行的输出详细程序

选项 描述
-v 显示任务结果
-vv 任务结果和任务配置都会显示
-vvv 包含关于与受管主机连接的信息
-vvvv 增加了连接插件相关的额外详细程序选项,包括受管主机上用于执行脚本的用户以及所执行的脚本
[root@a project]# ansible-playbook playbooks/web.yml -v
Using /opt/project/ansible.cfg as config file

PLAY [deploy web server] *******************************************************

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

TASK [ensure web service exists] ***********************************************
ok: [b] => {"changed": false, "msg": "Nothing to do", "rc": 0, "results": []}

TASK [ensure httpd service is started and enabled] *****************************
ok: [b] => {"changed": false, "enabled": true, "name": "httpd", "state": "started", "status": {"ActiveState": "active", "AllowedCPUs": "", "AllowedMemoryNodes": "", "BlockIOAccounting": "no", "BlockIOWeight": "[not set]", "CPUAccounting": "no", "CPUAffinity": "", "CPUAffinityFromNUMA": "no", "CPUQuotaPerSecUSec": "infinity", "CPUQuotaPeriodUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "[not set]", "CPUUsageNSec": "[not set]", "CPUWeight": "[not set]", "ControlGroup": "/system.slice/httpd.service", "ControlPID": "0", "DefaultMemoryLow": "0", "DefaultMemoryMin": "0", "Delegate": "no", "DevicePolicy": "auto", "EffectiveCPUs": "", "EffectiveMemoryNodes": "", "Environment": "LANG=C", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "151387", "ExecMainStartTimestamp": "Mon 2022-10-24 15:50:27 CST", "ExecMainStartTimestampMonotonic": "5439315832", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[Mon 2022-10-24 15:50:27 CST] ; stop_time=[n/a] ; pid=151387 ; code=(null) ; status=0/0 }", "FileDescriptorStoreMax": "0", "GID": "[not set]", "GuessMainPID": "yes", "IOAccounting": "no", "IOSchedulingClass": "0", "IOSchedulingPriority": "0", "IOWeight": "[not set]", "IPAccounting": "no", "IPEgressBytes": "18446744073709551615", "IPEgressPackets": "18446744073709551615", "IPIngressBytes": "18446744073709551615", "IPIngressPackets": "18446744073709551615", "LimitAS": "infinity", "LimitASSoft": "infinity", "LimitCORE": "infinity", "LimitCORESoft": "infinity", "LimitCPU": "infinity", "LimitCPUSoft": "infinity", "LimitDATA": "infinity", "LimitDATASoft": "infinity", "LimitFSIZE": "infinity", "LimitFSIZESoft": "infinity", "LimitLOCKS": "infinity", "LimitLOCKSSoft": "infinity", "LimitMEMLOCK": "65536", "LimitMEMLOCKSoft": "65536", "LimitMSGQUEUE": "819200", "LimitMSGQUEUESoft": "819200", "LimitNICE": "0", "LimitNICESoft": "0", "LimitNOFILE": "262144", "LimitNOFILESoft": "1024", "LimitNPROC": "7001", "LimitNPROCSoft": "7001", "LimitRSS": "infinity", "LimitRSSSoft": "infinity", "LimitRTPRIO": "0", "LimitRTPRIOSoft": "0", "LimitRTTIME": "infinity", "LimitRTTIMESoft": "infinity", "LimitSIGPENDING": "7001", "LimitSIGPENDINGSoft": "7001", "LimitSTACK": "infinity", "LimitSTACKSoft": "8388608", "LogLevelMax": "-1", "LogRateLimitBurst": "0", "LogRateLimitIntervalUSec": "0", "MainPID": "151387", "MemoryAccounting": "yes", "MemoryCurrent": "26718208", "MemoryHigh": "infinity", "MemoryLimit": "infinity", "MemoryLow": "0", "MemoryMax": "infinity", "MemoryMin": "0", "MemorySwapMax": "infinity", "NFileDescriptorStore": "0", "NRestarts": "0", "NUMAMask": "", "NUMAPolicy": "n/a", "Nice": "0", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "PermissionsStartOnly": "no", "RemainAfterExit": "no", "Restart": "no", "RestartUSec": "100ms", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeMaxUSec": "infinity", "SecureBits": "0", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardInputData": "", "StandardOutput": "journal", "StartupBlockIOWeight": "[not set]", "StartupCPUShares": "[not set]", "StartupCPUWeight": "[not set]", "StartupIOWeight": "[not set]", "StatusErrno": "0", "StatusText": "Running, listening on: port 80", "SyslogFacility": "3", "SyslogLevel": "6", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "yes", "TasksCurrent": "213", "TasksMax": "11201", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Type": "notify", "UID": "[not set]", "UMask": "0022", "WatchdogTimestamp": "Mon 2022-10-24 15:50:42 CST", "WatchdogTimestampMonotonic": "5454419114", "WatchdogUSec": "0"}}

PLAY RECAP *********************************************************************
b                          : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@a project]# ansible-playbook playbooks/web.yml -vv
ansible-playbook 2.9.27
  config file = /opt/project/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 3.6.8 (default, Sep 10 2021, 09:13:53) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]
Using /opt/project/ansible.cfg as config file
Skipping callback 'actionable', as we already have a stdout callback.
Skipping callback 'counter_enabled', as we already have a stdout callback.
Skipping callback 'debug', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'full_skip', as we already have a stdout callback.
Skipping callback 'json', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'null', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
Skipping callback 'selective', as we already have a stdout callback.
Skipping callback 'skippy', as we already have a stdout callback.
Skipping callback 'stderr', as we already have a stdout callback.
Skipping callback 'unixy', as we already have a stdout callback.
Skipping callback 'yaml', as we already have a stdout callback.

PLAYBOOK: web.yml **************************************************************
1 plays in playbooks/web.yml

PLAY [deploy web server] *******************************************************

TASK [Gathering Facts] *********************************************************
task path: /opt/project/playbooks/web.yml:2
ok: [b]
META: ran handlers

TASK [ensure web service exists] ***********************************************
task path: /opt/project/playbooks/web.yml:5
ok: [b] => {"changed": false, "msg": "Nothing to do", "rc": 0, "results": []}

TASK [ensure httpd service is started and enabled] *****************************
task path: /opt/project/playbooks/web.yml:10
ok: [b] => {"changed": false, "enabled": true, "name": "httpd", "state": "started", "status": {"ActiveState": "active", "AllowedCPUs": "", "AllowedMemoryNodes": "", "BlockIOAccounting": "no", "BlockIOWeight": "[not set]", "CPUAccounting": "no", "CPUAffinity": "", "CPUAffinityFromNUMA": "no", "CPUQuotaPerSecUSec": "infinity", "CPUQuotaPeriodUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "[not set]", "CPUUsageNSec": "[not set]", "CPUWeight": "[not set]", "ControlGroup": "/system.slice/httpd.service", "ControlPID": "0", "DefaultMemoryLow": "0", "DefaultMemoryMin": "0", "Delegate": "no", "DevicePolicy": "auto", "EffectiveCPUs": "", "EffectiveMemoryNodes": "", "Environment": "LANG=C", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "151387", "ExecMainStartTimestamp": "Mon 2022-10-24 15:50:27 CST", "ExecMainStartTimestampMonotonic": "5439315832", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[Mon 2022-10-24 15:50:27 CST] ; stop_time=[n/a] ; pid=151387 ; code=(null) ; status=0/0 }", "FileDescriptorStoreMax": "0", "GID": "[not set]", "GuessMainPID": "yes", "IOAccounting": "no", "IOSchedulingClass": "0", "IOSchedulingPriority": "0", "IOWeight": "[not set]", "IPAccounting": "no", "IPEgressBytes": "18446744073709551615", "IPEgressPackets": "18446744073709551615", "IPIngressBytes": "18446744073709551615", "IPIngressPackets": "18446744073709551615", "LimitAS": "infinity", "LimitASSoft": "infinity", "LimitCORE": "infinity", "LimitCORESoft": "infinity", "LimitCPU": "infinity", "LimitCPUSoft": "infinity", "LimitDATA": "infinity", "LimitDATASoft": "infinity", "LimitFSIZE": "infinity", "LimitFSIZESoft": "infinity", "LimitLOCKS": "infinity", "LimitLOCKSSoft": "infinity", "LimitMEMLOCK": "65536", "LimitMEMLOCKSoft": "65536", "LimitMSGQUEUE": "819200", "LimitMSGQUEUESoft": "819200", "LimitNICE": "0", "LimitNICESoft": "0", "LimitNOFILE": "262144", "LimitNOFILESoft": "1024", "LimitNPROC": "7001", "LimitNPROCSoft": "7001", "LimitRSS": "infinity", "LimitRSSSoft": "infinity", "LimitRTPRIO": "0", "LimitRTPRIOSoft": "0", "LimitRTTIME": "infinity", "LimitRTTIMESoft": "infinity", "LimitSIGPENDING": "7001", "LimitSIGPENDINGSoft": "7001", "LimitSTACK": "infinity", "LimitSTACKSoft": "8388608", "LogLevelMax": "-1", "LogRateLimitBurst": "0", "LogRateLimitIntervalUSec": "0", "MainPID": "151387", "MemoryAccounting": "yes", "MemoryCurrent": "26718208", "MemoryHigh": "infinity", "MemoryLimit": "infinity", "MemoryLow": "0", "MemoryMax": "infinity", "MemoryMin": "0", "MemorySwapMax": "infinity", "NFileDescriptorStore": "0", "NRestarts": "0", "NUMAMask": "", "NUMAPolicy": "n/a", "Nice": "0", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "PermissionsStartOnly": "no", "RemainAfterExit": "no", "Restart": "no", "RestartUSec": "100ms", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeMaxUSec": "infinity", "SecureBits": "0", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardInputData": "", "StandardOutput": "journal", "StartupBlockIOWeight": "[not set]", "StartupCPUShares": "[not set]", "StartupCPUWeight": "[not set]", "StartupIOWeight": "[not set]", "StatusErrno": "0", "StatusText": "Running, listening on: port 80", "SyslogFacility": "3", "SyslogLevel": "6", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "yes", "TasksCurrent": "213", "TasksMax": "11201", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Type": "notify", "UID": "[not set]", "UMask": "0022", "WatchdogTimestamp": "Mon 2022-10-24 15:50:42 CST", "WatchdogTimestampMonotonic": "5454419114", "WatchdogUSec": "0"}}
META: ran handlers
META: ran handlers

PLAY RECAP *********************************************************************
b                          : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@a project]# 

1.5 语法验证

在执行playbook之前,最好要进行验证,确保其内容的语法正确无误。ansible-playbook命令提供了一个--syntax-check选项,可用于验证playbook的语法。

下例演示了一个playbook成功通过语法验证:

[root@a playbooks]# ansible-playbook --syntax-check web.yml [WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: b

playbook: web.yml
[root@a project]# ansible-playbook --syntax-check playbooks/web.yml (在清单文件的目录上执行)

playbook: playbooks/web.yml

语法验证失败时,将报告语法错误。输出中包含语法问题在playbook中的大致位置。
下例演示了一个playbook语法验证失败的情况:

[root@a playbooks]# vim web.yml 
---
- name: deploy web server
  hosts: b
  tasks:
    - name: ensure web service exists
      yum:
        name: httpd
        state: present

    - name: ensure httpd service is started and enabled
      service:
        name: httpd
        state: started
       enabled: yes(此处缩进一个空格)
[root@a project]#  ansible-playbook --syntax-check playbooks/web.yml
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)

Syntax Error while loading YAML.
  did not find expected key

The error appears to be in '/opt/project/playbooks/web.yml': line 14, column 8, but may(告诉语法错误的地方)
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

        state: started
       enabled: yes
       ^ here
[root@a playbooks]# vim web.yml 
---
- name: deploy web server
  hosts: b
  tasks:
    - name: ensure web service exists
      yum:
        name: httpd
        state: present

    - name: ensure httpd service is started and enabled
      service:
        name: httpd
        state: started
        enabled: yes
 [root@a project]#  ansible-playbook --syntax-check playbooks/web.yml

playbook: playbooks/web.yml

1.6 执行空运行

可以使用-C选项对playbook执行空运行。这会使Ansible报告在执行该playbook时将会发生什么更改,但不会对受管主机进行任何实际的更改。

下例演示了一个playbook的空运行,它包含单项任务,可确保在受管主机上安装了最新版本的httpd软件包。注意该空运行报告此任务会对受管主机产生的更改。
ansible-playbook -C webserver.yml

[root@a playbooks]# vim web.yml 
---
- name: deploy web server
  hosts: c
  tasks:
    - name: ensure web service exists
      yum:
        name: httpd
        state: present

    - name: ensure httpd service is started and enabled
      service:
        name: httpd
        state: started
        enabled: yes

[root@c ~]# rpm -qa|grep httpd
[root@c ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*           

[root@a project]#  ansible-playbook --syntax-check playbooks/web.yml

playbook: playbooks/web.yml
[root@a project]#  ansible-playbook -C  playbooks/web.yml(空运行)
PLAY [deploy web server] *******************************************************

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

TASK [ensure web service exists] ***********************************************
changed: [c]

TASK [ensure httpd service is started and enabled] *****************************
changed: [c]

PLAY RECAP *********************************************************************
c                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@a project]# 

[root@c ~]# rpm -qa|grep httpd
[root@c ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*            
[root@a project]#  ansible-playbook playbooks/web.yml

PLAY [deploy web server] *******************************************************

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

TASK [ensure web service exists] ***********************************************
changed: [c]

TASK [ensure httpd service is started and enabled] *****************************
changed: [c]

PLAY RECAP *********************************************************************
c                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@c ~]# rpm -qa|grep httpd
httpd-2.4.37-47.module_el8.6.0+1111+ce6f4ceb.1.x86_64
httpd-tools-2.4.37-47.module_el8.6.0+1111+ce6f4ceb.1.x86_64
httpd-filesystem-2.4.37-47.module_el8.6.0+1111+ce6f4ceb.1.noarch
centos-logos-httpd-85.8-2.el8.noarch
[root@c ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*            
LISTEN 0      128                *:80               *:*            


2. 实施多个play

2.1 缩写多个play

Playbook是一个YAML文件,含有由一个或多个play组成的列表。记住一个play按顺序列出了要对清单中的选定主机执行的任务。因此,如果一个playbook中有多个play,每个play可以将其任务应用到单独的一组主机。

在编排可能涉及对不同主机执行不同任务的复杂部署时,这会大有帮助。我们可以这样进行编写:对一组主机运行一个play,完成后再对另一组主机运行另一个play。

缩写包含多个play的playbook非常简单。Playbook中的各个play编写为playbook中的顶级列表项。各个play是含有常用play关键字的列表项。

相同的主机相同的事
[root@a playbooks]# cp web.yml httpd.yml
[root@a playbooks]# ls
httpd.yml  web.yml
[root@a playbooks]# vim httpd.yml 
---
- hosts: c
  tasks:
    - name: ensure web service exists
      yum:
        name: httpd
        state: present

    - name: ensure httpd service is started and enabled
      service:
        name: httpd
        state: started
        enabled: yes
[root@a project]#  ansible-playbook playbooks/httpd.yml 

PLAY [c] ***********************************************************************

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

TASK [ensure web service exists] ***********************************************
ok: [c]

TASK [ensure httpd service is started and enabled] *****************************
ok: [c]

PLAY RECAP *********************************************************************
c                          : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

不同的主机不同的事
[root@a playbooks]# ls
httpd.yml  web.yml
[root@a playbooks]# vim lnmp.yml
---
- name: deploy web server on b
  hosts: b
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: present

    - name: start service httpd
      service:
        name: httpd
        state: started
        enabled: yes

- name: deploy database server on c
  hosts: c
  tasks: 
    - name: install mariadb
      yum:
        name: mariadb-server
        state: present

    - name: start mariadb
      service: 
        name: mariadb
        state: started
        enabled: yes
[root@a project]# ansible-playbook --syntax-check playbooks/lnmp.yml 

playbook: playbooks/lnmp.yml
[root@a project]# ansible-playbook -C playbooks/lnmp.yml 
PLAY [deploy web server on b] **************************************************

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

TASK [install httpd] ***********************************************************
ok: [b]

TASK [start service httpd] *****************************************************
ok: [b]

PLAY [deploy database server on c] *********************************************

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

TASK [install mariadb] *********************************************************
changed: [c]

TASK [start mariadb] ***********************************************************
changed: [c]

PLAY RECAP *********************************************************************
b                          : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
c                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@a project]# ansible-playbook  playbooks/lnmp.yml 

PLAY [deploy web server on b] **************************************************

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

TASK [install httpd] ***********************************************************
ok: [b]

TASK [start service httpd] *****************************************************
ok: [b]

PLAY [deploy database server on c] *********************************************

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

TASK [install mariadb] *********************************************************
changed: [c]

TASK [start mariadb] ***********************************************************
changed: [c]

PLAY RECAP *********************************************************************
b                          : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
c                          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@a project]# 


[root@b ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128                *:80               *:*            
LISTEN 0      128             [::]:22            [::]:*      
[root@c ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*            
LISTEN 0      80                 *:3306             *:*            
LISTEN 0      128                *:80               *:*           

2.2 play中的远程用户和特权升级

Play可以将不同的远程用户或特权升级设置用于play,取代配置文件中指定的默认设置。这些在play本身中与hosts或tasks关键字相同的级别上设置。

2.2.1 用户属性

playbook中的任务通常通过与受管主机的网络连接来执行。与临时命令相同,用于任务执行的用户帐户取决于Ansible配置文件/etc/ansible/ansible.cfg中的不同关键字。运行任务的用户可以通过remote_user关键字来定义。不过,如果启用了特权升级,become_user等其他关键字也会发生作用。

如果用于任务执行的Ansible配置中定义的远程用户不合适,可以通过在play中使用remote_user关键字覆盖。
remote_user: remoteuser

以下示例演示了如何在play中使用这些关键字:


- name: /etc/hosts is up to date
  hosts: 172.16.103.129
  remote_user: automation
  become: yes
  
  tasks:
    - name: 172.16.103.129 in /etc/hosts
      lineinfile:(模块--确保某一行在某个文件中有)
        path: /etc/hosts
        line: '172.16.103.129 web1.example.com'
        state: present
        (确保/etc/hosts文件中有172.16.103.129 web1.example.com这一行,没有则启动)

2.2.2 特权升级属性

Ansible也提供额外的关键字,从而在playbook内定义特权升级参数。become布尔值关键字可用于启用或禁用特权升级,无论它在Ansible配置文件中的定义为何。它可取yes或true值来启用特权升级,或者取no或false值来禁用它。

become: true

如果启用了特权升级,则可以使用become_method关键字来定义特定play期间要使用的特权升级方法。
以下示例中指定sudo用于特权升级:

become_method: sudo

此外,启用了特权升级时,become_user关键字可定义特定play上下文内要用于特权升级的用户帐户。
become_user: privileged_user

2.3 查找用于任务的模块

2.3.1 模块文档

Ansible随附打包的大量模块为管理员提供了许多用于常见管理任务的工具。前面我们介绍了Ansible官方网站的帮助文档链接https://docs.ansible.com/。通过模块索引,可以很轻松的找到对应的模块。例如,适用于用户和服务管理的模块可以在Systems Modules下找到,而适合数据库管理的模块则可在Database Modules下找到。

对于每一个模块,Ansible官网提供了其功能摘要,以及关于如何通过模块的选项来调用各项具体功能的说明。文档还提供了实用的示例,演示各个模块的用法,以及任务中关键字的设置方法。

前面我们用到过ansible-doc -l命令。这将显示模块名称列表以及其功能的概要。

ansible-doc -l

使用ansible-doc [module name]命令来显示模块的详细文档。与Ansible官网一样,该命令提供模块功能的概要、其不同选项的详细信息,以及示例。

ansible-doc yum # 显示yum模块的帮助文档

ansible-doc命令还提供-s选项,它会生成示例输出,可以充当如何在playbook在使用特定模块的示范。此输出可以作为起步模板,包含在实施该模块以执行任务的playbook中。输出中包含的注释,提醒管理员各个选项的用法。下例演示了yum模块的这种输出:

ansible-doc -s yum

使用ansible-doc命令可以查找和了解如何使用模块。尽管command、shell和raw模块的用法可能看似简单,但在可能时,应尽量避免在playbook中使用它们因为它们可以取胜任意命令,因此使用这些模块时很容易写出非幂等的playbook。

例如,以下使用shell模块的任务为非幂等。每次运行play时,它都会重写/etc/resolv.conf,即使它已经包含了行nameserver 172.16.103.2。

  • name: Non-idepotent approach with shell module
    shell: echo "nameserver 172.16.103.2" > /etc/resolv.conf

可以通过多种方式编写以幂等方式使用shell模块的任务,而且有时候进行这些更改并使用shell是最佳的做法。但更快的方案或许是使用ansible-doc发现copy模块,再使用它获得所需的效果。
在以下示例中,如果/etc/resolv.conf文件已包含正确的内容,则不会重写该文件:

  • name: Idempotent approach with copy module
    copy:
    dest: /etc/resolv.conf
    content: "nameserver 172.16.103.2\n"

copy模块可以测试来了解是否达到了需要的状态,如果已达到,则不进行任何更改。shell模块容许非常大的灵活性,但需要格外小心,从而确保它以幂等方式运行。

幂等的playbook可以重复运行,确保系统处于特定的状态,而不会破坏状态已经正确的系统。

2.3.2 playbook语法变化

2.3.3 过时的“键=值”playbook简写

标签:httpd,name,web,ansible,playbook,root
From: https://www.cnblogs.com/marymary/p/16822357.html

相关文章

  • 关于ansible-通过Ad-hoc和playbook-对linux主机的连接性测试
    环境:被控主机都是linux主机,不过好几种发行版本,但是笔者都还是设计了统一的标准1、主控和被控端都是Linux操作系统,都是有ansible用户的2、主控通过ssh-key的私钥登录到被......
  • 关于ansible-通过playbook-对aws上windows-server的连接性测试
    因笔者这ansible对windows的管理没有使用常规的连接方式而是采用的ansible主控端,通过发送ssm命令管理远端的aws上的windows主机因此一台新的机器接入进来后,及各个相关的......
  • 安装apache之playbook
    ----name:installhttpdhosts:allvars:dir:/usr/local/srcinstall_dir:/apps/httpdhttpd_ver:httpd-2.4.54httpd_url:https://mirrors.tuna.tsi......
  • 安装nfs之ansible-playbook
    ----name:installnfshosts:alltasks:-name:yumnfsyum:name:nfs-utilsstate:presentwhen:ansible_distribution=="CentOS"......
  • 安装Mysql之Playbook
    ----name:installmysqlhosts:allvars:mysql:mysql-8.0.28-linux-glibc2.12-x86_64tasks:-name:installpackageyum:name:-l......
  • 安装zabbix-agent2之ansible-playbook
    ----name:installagenthosts:allvars:server_host:"192.168.100.206"tasks:-shell:"rpm-Uvhhttps://repo.zabbix.com/zabbix/6.0/rhel/8/x86_64/zab......
  • 安装zabbix-agent2之ansible-playbook
    zabbix被监控端安装zabbix-agent2之ansible-playbook----name:installagenthosts:allvars:server_host:"192.168.100.206"tasks:-shell:"rpm......
  • 第十八章 Ansible-playbook-Role基础介绍
    一、AnsibleRoles概述roles不管是Ansible还是saltstack,我在写一键部署的时候,都不可能把所有的步骤全部写入到一个'剧本'文件当中,我们肯定需要把不同的工作模块,拆分开来,解......
  • 第十五章 Ansible-playbook错误处理
    一、playbook忽略错误默认playbook会检测task执行的返回状态,如果遇到错误则会立即终止playbook的后续task执行,然而有些时候playbook即使执行错误了也要让其继续执行。加......
  • 第十一章 Ansible-playbook变量注册和Facts缓存
    一、变量注册概述当absible的模块在运行之后,其实都会返回一些result结果,就像是执行脚本,我们有的时候需要脚本给我们一些return返回值,我们才知道,上一步是否可以执行成功,但......