赞
踩
1、简介 Ansible是一个自动化统一配置管理工具,自动化主要体现在Ansible集成了丰富模块以及功能组件,可以通过一个命令完成一系列的操作,进而能减少重复性的工作和维护成本,可以提高工作效率。 2、组成 1.连接插件connection plugins用于连接主机 用来连接被管理端 2.核心模块core modules连接主机实现操作, 它依赖于具体的模块来做具体的事情 3.自定义模块custom modules根据自己的需求编写具体的模块 4.插件plugins完成模块功能的补充 5.剧本playbookansible的配置文件,将多个任务定义在剧本中,由ansible自动执行 6.主机清单inventor定义ansible需要操作主机的范围 最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块 3、执行流程 1.Ansible读取playbook剧本,剧本中会记录对哪些主机执行哪些任务。 #web 安装nginx 2.首先Ansible通过主机清单找到要执行的主机,然后调用具体的模块。 #web 是谁 3.其次Ansible会通过连接插件连接对应的主机并推送对应的任务列表。 #使用yum模块安装nginx 4.最后被管理的主机会将Ansible发送过来的任务解析为本地Shell命令执行。 #受控端执行yum install -y nginx
#1.安装epel源
[root@m01 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#2.安装Ansible
[root@m01 ~]# yum install -y ansible
# ansible <host-pattern> [options] #不常用参数 --version #ansible版本信息 -v #显示详细信息 -i #主机清单文件路径,默认是在/etc/ansible/hosts -k #提示输入ssh密码,而不使用基于ssh的密钥认证 -C #模拟执行测试,但不会真的执行 -T #执行命令的超时 #常用参数 -m #使用的模块名称,默认使用command模块 -a #使用的模块参数,模块的具体动作 --syntax-check #验证语法 [root@m01 ~]# ansible --version ansible 2.9.15 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/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
[root@m01 ~]# rpm -qc ansible /etc/ansible/ansible.cfg /etc/ansible/hosts [root@m01 ~]# cat /etc/ansible/ansible.cfg #inventory = /etc/ansible/hosts #主机列表配置文件 #library = /usr/share/my_modules/ #库文件存放目录 #remote_tmp = ~/.ansible/tmp #临时py文件存放在远程主机目录 #local_tmp = ~/.ansible/tmp #本机的临时执行目录 #forks = 5 #默认并发数 #sudo_user = root #默认sudo用户 #ask_sudo_pass = True #每次执行是否询问sudo的ssh密码 #ask_pass = True #每次执行是否询问ssh密码 #remote_port = 22 #远程主机端口 host_key_checking = False #跳过检查主机指纹 log_path = /var/log/ansible.log #ansible日志 #普通用户提权操作 [privilege_escalation] #become=True #become_method=sudo #become_user=root #become_ask_pass=False
1、单主机配置 #方式一: ip + 端口 + 用户名 + 用户密码 [root@m01 ~]# vim /etc/ansible/hosts [web01] 10.0.0.7 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' [web02] 10.0.0.8 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' #测试 [root@m01 ~]# ansible web01 -m ping 10.0.0.7 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } #方式二: ip + 用户密码 [root@m01 ~]# vim /etc/ansible/hosts [web01] 10.0.0.7 ansible_ssh_pass='1' [web02] 10.0.0.8 ansible_ssh_pass='1' [root@m01 ~]# ansible web02 -m ping 10.0.0.8 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } #方式三: ip + 变量密码 [root@m01 ~]# vim /etc/ansible/hosts [web01] 10.0.0.7 [web02] 10.0.0.8 [web01:vars] ansible_ssh_pass='1' 2、多主机配置 [root@m01 ~]# vim /etc/ansible/hosts [web_group] 10.0.0.7 ansible_ssh_pass='1' 10.0.0.8 ansible_ssh_pass='1' [root@m01 ~]# ansible 'web_group' -m ping 10.0.0.8 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 10.0.0.7 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
1.生成密钥对 [root@m01 ~]# ssh-keygen 2.推送公钥 [root@m01 ~]# ssh-copy-id 10.0.0.7 [root@m01 ~]# ssh-copy-id 10.0.0.8 3、配置主机清单 [root@m01 ~]# vim /etc/ansible/hosts [web_group] 10.0.0.7 10.0.0.8 4、修改host配置主机清单 #配置主机清单 [root@m01 ~]# vim /etc/ansible/hosts [web_group] web01 web02 #配置hosts [root@m01 ~]# vim /etc/hosts 10.0.0.7 web01 10.0.0.8 web02 #测试 [root@m01 ~]# ansible 'web_group' -m ping web02 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } web01 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
[root@m01 ~]# vim /etc/ansible/hosts [web_group] web01 web02 [nfs_server] nfs ansible_ssh_pass='1' [rsync_server] backup ansible_ssh_pass='1' [db_server] db01 ansible_ssh_pass='1' #定义整合组,下面包含多个组 [www:children] web_group nfs_server rsync_server #配置hosts [root@m01 ~]# vim /etc/hosts 10.0.0.7 web01 10.0.0.8 web02 10.0.0.31 nfs 10.0.0.41 backup 10.0.0.51 db01
[root@m01 ~]# ansible www --list-host
hosts (4):
web01
web02
nfs
backup
#单主机
[root@m01 ~]# ansible 'web01' -m ping
#所有主机
[root@m01 ~]# ansible '*' -m ping
#所有主机
[root@m01 ~]# ansible 'all' -m ping
#主机组
[root@m01 ~]# ansible 'web_group' -m ping
#整合组
[root@m01 ~]# ansible 'www' -m ping
ad-hoc简而言之就是"临时命令",执行完即结束,并不会保存 [root@m01 ~]# ansible web01 -m command -a 'df -h' web01 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on /dev/sda3 18G 1.6G 17G 9% / devtmpfs 476M 0 476M 0% /dev tmpfs 487M 0 487M 0% /dev/shm tmpfs 487M 7.7M 479M 2% /run tmpfs 487M 0 487M 0% /sys/fs/cgroup /dev/sda1 1014M 127M 888M 13% /boot tmpfs 98M 0 98M 0% /run/user/0 [root@m01 ~]# ansible web_group -m command -a 'free -m' web01 | CHANGED | rc=0 >> total used free shared buff/cache available Mem: 972 128 481 7 362 658 Swap: 1023 0 1023 web02 | CHANGED | rc=0 >> total used free shared buff/cache available Mem: 972 111 551 7 309 691 Swap: 1023 0 1023 绿色: 代表被管理端主机没有被修改 黄色: 代表被管理端主机发现变更 红色: 代表出现了故障,注意查看提示
command # 执行shell命令(不支持管道等特殊字符) shell # 执行shell命令 scripts # 执行shell脚本 yum_repository # 配置yum仓库 yum # 安装软件 copy # 变更配置文件 file # 建立目录或文件 service # 启动与停止服务 systemd # 启动与停止服务 mount # 挂载设备 cron # 定时任务 get_url #下载软件 firewalld #防火墙 selinux #selinux setup #获取主机信息 注意:查看帮助 #1.查看所有模块 [root@m01 ~]# ansible-doc -l #2.查看指定模块的用法 [root@m01 ~]# ansible-doc yum #3.查看模块参数 [root@m01 ~]# ansible-doc -s yum
1、command #默认模块,远程执行命令 [root@m01 ~]# ansible web01 -m command -a 'free -m' web01 | CHANGED | rc=0 >> total used free shared buff/cache available Mem: 972 128 479 7 364 658 Swap: 1023 0 1023 #不支持特殊字符 [root@m01 ~]# ansible web01 -m command -a "ifconfig eth0 | awk 'NR==2 {print \$2}'" web01 | FAILED | rc=1 >> |: Unknown host ifconfig: `--help' gives usage information.non-zero return code 2、shell [root@m01 ~]# ansible web01 -m shell -a 'free -m' web01 | CHANGED | rc=0 >> total used free shared buff/cache available Mem: 972 128 479 7 364 658 Swap: 1023 0 1023 #支持特殊字符 [root@m01 ~]# ansible web01 -m shell -a "ifconfig eth0 | awk 'NR==2 {print \$2}'" web01 | CHANGED | rc=0 >> 10.0.0.7
1、copy [root@m01 ~]# ansible-doc copy EXAMPLES: - name: Copy file with owner and permissions copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: '0644' backup: yes content: '# This file was moved to /etc/other.conf' follow: yes src #文件的源地址 dest #目标地址或文件 owner #文da件属主 group #文件属组 mode #文件的权限 backup #替换的文件是否备份 content #直接将内容写入文件 follow #处理软连接 例子: #推送文件并备份 [root@m01 ~]# ansible web_group -m copy -a 'src=/root/index.html dest=/root/ owner=adm group=adm backup=yes' 注意:buckup参数不是用来回滚的,需要回滚的话要备份原来m01上推送的文件 #直接将内容写入文件 [root@m01 ~]# ansible web_group -m copy -a 'content="rsync_backup:123456" dest=/tmp/rsync.password mode=600' 2、file模块 [root@m01 ~]# ansible-doc file EXAMPLES: - name: Change file ownership, group and permissions file: src: /file/to/link/to path: /etc/foo.conf owner: foo group: foo mode: '0644' state: link recurse: yes path #创建的文件或目录的地址 owner #文件或目录的属主 group #文件或目录的属组 mode #文件或目录的权限 state link #创建软链接 src #源文件 dest #软链接的名字 touch #创建文件 directory #创建目录 absent #删除,目录,文件,软链接 recurse #递归授权 例子:#单纯的创建目录 [root@m01 ~]# ansible web01 -m file -a 'path=/code state=directory' 相当于在远程机器上执行:mkdir /code #创建目录并授权 [root@m01 ~]# ansible web01 -m file -a 'path=/code state=directory owner=nginx group=nginx' 相当于在远程机器上执行:mkdir /code && chown nginx.nginx /code #递归创建目录,不需要加任何参数 [root@m01 ~]# ansible web01 -m file -a 'path=/code/wordpress/wp-content/pic state=directory' #递归授权目录 [root@m01 ~]# ansible web01 -m file -a 'path=/code/ state=directory owner=nginx group=nginx recurse=yes' #注意: 1.当创建的目录不存在时,递归创建会递归授权 2.当创建的目录已经存在,递归授权只授权最后一层目录下的内容 #创建文件 [root@m01 ~]# ansible web01 -m file -a 'path=/tmp/1.txt state=touch' #创建文件并授权 [root@m01 ~]# ansible web01 -m file -a 'path=/tmp/1.txt state=touch owner=nginx group=nginx' #创建软链接 [root@m01 ~]# ansible web01 -m file -a 'src=/tmp/1.txt dest=/tmp/1.ln state=link' 3、get_url 模块 [root@m01 ~]# ansible-doc get_url EXAMPLES: - name: Download foo.conf get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf mode: '0440' checksum: sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c url #文件下载地址 dest #文件存放路径 mode #文件下载后授权 checksum #验证文件 sha256 #加密方式 例子:#下载网站上的文件 [root@m01 ~]# ansible web01 -m get_url -a 'url=http://10.0.0.7/1.txt dest=/tmp' #下载时验证文件 [root@m01 ~]# ansible web01 -m get_url -a 'url=http://10.0.0.7/1.txt dest=/tmp checksum=md5:d8e8fca2dc0f896fd7cb4cb0031ba249'
5、服务管理模块
1、server [root@m01 ~]# ansible-doc service EXAMPLES: - name: Start service httpd, if not started service: name: httpd state: started name: nginx #服务名字 state: started #启动服务 stopped #停止服务 restarted #重启服务 reloaded #重载服务 enabled: yes #开机自启 2、systemd [root@m01 ~]# ansible-doc systemd EXAMPLES: - name: Make sure a service is running systemd: state: started name: httpd name: nginx #服务名字 state: started #启动服务 stopped #停止服务 restarted #重启服务 reloaded #重载服务 enabled: yes #开机自启
1、group [root@m01 ~]# ansible-doc group EXAMPLES: - name: Ensure group "somegroup" exists group: name: somegroup #组名字 state: present #创建组 absent #删除组 gid: 666 #指定组id 例子: #创建用户组 [root@m01 ~]# ansible web01 -m group -a 'name=www gid=666 state=present' #修改用户组 [root@m01 ~]# ansible web01 -m group -a 'name=www gid=666 state=absent' 2、user [root@m01 ~]# ansible-doc user EXAMPLES: - name: Add the user 'johnd' with a specific uid and a primary group of 'admin' user: name: johnd comment: John Doe uid: 1040 group: admin shell: /bin/bash state: absent remove: yes create_home: false name #用户名字 comment #用户备注 uid #用户id group #用户所在的组名字 shell /bin/bash #用户可以登录 /sbin/nologin #用户不需要登录 state absent #删除用户 present #创建用户 remove #移除家目录 create_home #是否创建家目录 true #创建家目录 false #不创建家目录 例子: #创建用户,不需要登录,有家目录 [root@m01 ~]# ansible web01 -m user -a 'name=www uid=666 group=www shell=/sbin/nologin create_home=true' #删除用户并移除家目录 [root@m01 ~]# ansible web01 -m user -a 'name=www state=absent remove=yes' #注意: 1.当组的名字与用户名字相同时,删除用户,组也会被删除 2.当组的名字与用户名字相同时,而组下面还有其他用户,则删除用户时不会删除同名组
1、cron定时任务模块 [root@m01 ~]# ansible-doc cron EXAMPLES: - name: Ensure a job that runs at 2 and 5 exists. Creates an entry like "0 5,2 * * ls -alh > /dev/null" cron: name: "check dirs" minute: "0" hour: "5,2" day: "*" month: "*" weekday: "*" job: "ls -alh > /dev/null" state: absent disabled: yes name #定时任务的备注 minute #分钟 hour #小时 day #日 month #月 weekday #周 job #指定的定时任务内容 state present #新建定时任务 absent #删除定时任务 disabled yes #注释定时任务 no #取消注释 例子: #添加定时任务,每五分钟执行一次时间同步(只配置分钟,其他不配置默认是 * ) [root@m01 ~]# ansible web01 -m cron -a 'name="测试ansible配置定时任务" minute=*/5 job="ntpdate time1.aliyun.com"' #查看配置 [root@web01 html]# crontab -l #Ansible: 测试ansible配置定时任务 */5 * * * * ntpdate time1.aliyun.com #注释定时任务 [root@m01 ~]# ansible web01 -m cron -a 'name="测试ansible配置定时任务" minute=*/5 job="ntpdate time1.aliyun.com" disabled=yes' #删除定时任务 [root@m01 ~]# ansible web01 -m cron -a 'name="测试ansible配置定时任务" minute=*/5 job="ntpdate time1.aliyun.com" state=absent' #注意: 1.定时任务添加,是通过名字来区分是否一样的,如果不加name参数,则会添加重复的定时任务 2.定时任务注释是通过 name 参数来注释的,所以一定要加 name 参数 3.定时任务删除是通过 name 参数来删除的,所以一定要加 name 参数 2、mount模块 # 安装NFS 1.安装nfs [root@m01 ~]# ansible nfs_server -m yum -a 'name=nfs-utils state=present' 2.配置nfs [root@m01 ~]# ansible nfs_server -m copy -a 'content="/data 172.16.1.0/24(rw,sync,all_squash)" dest=/etc/exports' 3.创建目录 [root@m01 ~]# ansible nfs_server -m file -a 'path=/data state=directory owner=nfsnobody group=nfsnobody' 4.启动服务 [root@m01 ~]# ansible nfs_server -m systemd -a 'name=nfs state=started' # 挂在模块的语法 [root@m01 ~]# ansible-doc mount EXAMPLES: - name: Mount DVD read-only mount: path: /mnt/dvd src: /dev/sr0 fstype: iso9660 opts: ro,noauto state: present path #本机准备挂载的目录 src #远端挂载点 fstype #指定挂载类型 opts #挂载参数(/etc/fstab中的内容) state present #配置开机挂载,将配置写入自动挂载文件,并没有直接挂载 unmounted #取消挂载,但是没有删除自动挂载配置 #常用配置 mounted #配置开机挂载,并且直接挂载上 absent #取消挂载,并且删除自动挂载配置 例子: #配置开机挂载,将配置写入自动挂载文件,并没有直接挂载 [root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=present' #配置开机挂载,并且直接挂载上 [root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=mounted' #取消挂载,但是没有删除自动挂载配置 [root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=unmounted' #取消挂载,并且删除自动挂载配置 [root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=absent 3、selinux模块 - name: Disable SELinux selinux: state: disabled #关闭selinux [root@m01 ~]# ansible web02 -m selinux -a 'state=disabled' web02 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "configfile": "/etc/selinux/config", "msg": "", "policy": "targeted", "reboot_required": false, "state": "disabled" } 4、firewalld模块 [root@m01 ~]# ansible-doc firewalld EXAMPLES: - firewalld: service: https #指定服务 permanent: #是否永久生效 yes #永久生效 no #临时生效 state: enabled #允许通过 port: 8081/tcp #指定端口 zone: dmz #指定区域 rich_rule: rule service name="ftp" audit limit value="1/m" accept #配置富规则 source: 192.0.2.0/24 #指定网段 interface: eth2 #帮定网卡 masquerade: yes #开启IP伪装 例子: #允许访问http服务,永久生效 [root@m01 ~]# ansible web01 -m firewalld -a 'service=http permanent=yes state=enabled' [root@m01 ~]# ansible web01 -m firewalld -a 'service=http state=enabled' #允许访问80端口,临时生效 [root@m01 ~]# ansible web01 -m firewalld -a 'port=80/tcp state=enabled' #配置允许10.0.0.0网段访问22端口 [root@m01 ~]# ansible web01 -m firewalld -a 'rich_rule="rule family=ipv4 source address=10.0.0.0/24 port port=22 protocol=tcp accept" state=enabled' #配置网段白名单 [root@m01 ~]# ansible web01 -m firewalld -a 'source=10.0.0.0/24 zone=trusted state=enabled permanent=yes' [root@m01 ~]# ansible web01 -m firewalld -a 'source=10.0.0.0/24 zone=trusted state=enabled permanent=no' 4、unachive模块 [root@m01 ~]# ansible-doc unarchive EXAMPLES: - name: Extract foo.tgz into /var/lib/foo unarchive: src: foo.tgz dest: /var/lib/foo remote_src: no #默认是no src #包的路径 dest #解压后的目标路径 remote_src yes #包在受控端服务器上 no #包在控制端服务器上 例子: #解压包到受控端,包在控制端上 [root@m01 ~]# ansible web01 -m unarchive -a 'src=/root/php.tar.gz dest=/tmp' : #在受控端解压包,包在受控端 [root@m01 ~]# ansible web01 -m unarchive -a 'src=/tmp/php.tar.gz dest=/tmp remote_src=yes' 5、archive压缩模块 [root@m01 ~]# ansible-doc archive EXAMPLES: - name: Compress directory /path/to/foo/ into /path/to/foo.tgz archive: path: /path/to/foo #要打包的内容 dest: /path/to/foo.tgz #打好的包与存放位置 format:gz #打包的类型 bz2, gz, tar, xz, zip #打包实例 [root@m01 ~]# ansible web01 -m archive -a 'path=/tmp dest=/opt/php.tar.gz'
#1.获取web01主机所有信息 [root@m01 ~]# ansible web01 -m setup #2.获取主机IP [root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4' #3.获取主机名 [root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_fqdn' web01 | SUCCESS => { "ansible_facts": { "ansible_fqdn": "www.baidu.com", "discovered_interpreter_python": "/usr/bin/python" }, "changed": false } #4.获取内存信息 [root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_memory_mb' web01 | SUCCESS => { "ansible_facts": { "ansible_memory_mb": { "nocache": { "free": 720, "used": 252 }, "real": { "free": 276, "total": 972, "used": 696 }, "swap": { "cached": 0, "free": 1023, "total": 1023, "used": 0 } }, "discovered_interpreter_python": "/usr/bin/python" }, "changed": false } #5.常用参数 ansible_all_ipv4_addresses:仅显示ipv4的信息。 ansible_devices:仅显示磁盘设备信息。 ansible_distribution:显示是什么系统,例:centos,suse等。 ansible_distribution_major_version:显示是系统主版本。 ansible_distribution_version:仅显示系统版本。 ansible_machine:显示系统类型,例:32位,还是64位。 ansible_eth0:仅显示eth0的信息。 ansible_hostname:仅显示主机名(不准确) ansible_fqdn:仅显示主机名。 ansible_kernel:仅显示内核版本。 ansible_lvm:显示lvm相关信息。 ansible_memtotal_mb:显示系统总内存。 ansible_memfree_mb:显示可用系统内存。 ansible_memory_mb:详细显示内存情况。 ansible_swaptotal_mb:显示总的swap内存。 ansible_swapfree_mb:显示swap内存的可用内存。 ansible_mounts:显示系统磁盘挂载情况。 ansible_processor:显示cpu个数(具体显示每个cpu的型号)。 ansible_processor_vcpus:显示cpu个数(只显示总的个数)。
[root@m01 ~]# vim touch.yml #定义要执行动作的主机或主机组 - hosts: web_group #定义操作的用户 remote_user: root #定义变量 vars: #变量:变量的值 file_name: lhd #指定主机的动作 tasks: #动作的注释 - name: Touch New File #使用shell模块执行动作 shell: touch /tmp/{{ file_name }} #模拟执行 [root@m01 ~]# ansible-playbook -C touch.yml #验证语法 [root@m01 ~]# ansible-playbook --syntax-check touch.yml #注意:只能验证语法,验证不了逻辑
1.通过命令行进行变量定义 2.在play文件中进行变量定义 3.通过Inventory主机清单中进行变量定义 4.通过vars_file定义变量 5.通过hosts_vars和group_vars定义变量 #变量的优先级 如果在定义变量时,变量冲突了 在上述的三个地方分别设置了: 1.命令行中:age=11 2.play文件中:age=12 3.Inventory中:age=13 那么,最终的age结果一定是 11 变量的读取优先级:命令行 > playbook文件 > Inventory文件 #变量设置:命名时,应该由字母,数字,下划线组成,必须由字母开头 方式一:在模块下方定义 [root@m01 project]# vim yum.yml - hosts: db01 tasks: - name: Installed http Server yum: name: "{{ packages }}" vars: packages: - httpd - httpd-tools #问题: 1.如果将变量设置到模块下,那么其他的name是不识别的 方式二:在hosts下定义 [root@m01 project]# vim yum.yml - hosts: db01 vars: packages: - httpd - httpd-tools tasks: - name: Installed http Server yum: name: "{{ packages }}" - name: Mkdir Dir file: path: /tmp/{{ packages }} state: directory #问题: 1.创建目录时可能会出现格式转换问题 2.如果将变量设置到hosts下,那么其他的hosts是不识别的 # 刚才我们学到在playbook中使用vars定义变量,有一个缺陷,就是其他的playbook无法使用该变量。所以我们可以采取第二种定义变量的方式,在vars_file中定义变量。 [root@m01 project]# mkdir vars [root@m01 project]# cd vars/ [root@m01 vars]# vim vars.yml packages: httpd dbs: mariadb-server # 调用变量 [root@m01 project]# vim yum.yml - hosts: db01 vars_files: /project/vars/vars.yml tasks: - name: Installed http Server yum: name: "{{ packages }}" - hosts: db01 vars_files: /project/vars/vars.yml tasks: - name: Installed http Server yum: name: "{{ dbs }}" #通过inventory主机清单中进行变量定义 [root@m01 project]# vim /etc/ansible/hosts ... ... [db_server] db01 ansible_ssh_pass='1' [db_server:vars] web=suibianshezhideneirong 调用变量: [root@m01 project]# vim yum.yml - hosts: db_server tasks: - name: Touch File file: path: /tmp/{{ web }} state: touch #注意: 1.主机清单中定义变量,只要hosts配置的是主机清单中设置变量的组,可以直接使用变量 2.如果hosts配置的不是主机清单中设置变量的组,变量不可识别 3.主机组定义的变量优先级高于整合组定义的变量 4.主机定义的变量优先级高于主机组定义的变量 # 命令行定义变量 [root@m01 project]# ansible-playbook test.yml -e "file=command" -e "file2=command2" # 直接使用内置变量 #使用内置变量创建目录,目录格式为 主机名_IP_时间 [root@m01 project]# vim test.yml - hosts: web_group tasks: - name: Touch File file: path: /backup/{{ ansible_fqdn }}_{{ ansible_eth1.ipv4.address }}_{{ ansible_date_time.date }} state: directory
[root@m01 project]# vim startserver.yml - hosts: web_group tasks: - name: Start CentOS 6 Server shell: "/etc/init.d/httpd start" when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "6" - name: Start CentOS 7 Server shell: "systemctl start httpd" when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "7" [root@m01 project]# vim startserver.yml - hosts: web_group tasks: - name: Start CentOS 6 Server shell: "/etc/init.d/httpd start" when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "6") - name: Start CentOS 7 Server shell: "systemctl start httpd" when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "7") - hosts: web_group tasks: - name: Check Httpd Server command: systemctl is-active httpd ignore_errors: yes register: check_httpd - name: debug outprint debug: var=check_httpd - name: Httpd Restart service: name: httpd state: restarted when: check_httpd.rc == 0
#错误写法 [root@m01 project]# vim start.yml - hosts: web_group tasks: - name: Start Server systemd: name: "{{ package }}" state: started vars: package: - redis - httpd #正确写法 [root@m01 project]# vim start.yml - hosts: web_group tasks: - name: Start Server systemd: name: "{{ item }}" state: started with_items: - redis - httpd [root@m01 project]# cat user.yml - hosts: lb01 tasks: - name: Create Some Group group: name: "{{ item.name }}" gid: "{{ item.gid }}" state: present with_items: - { name: "lhd", gid: "777" } - { name: "test", gid: "888" } - { name: "egon", gid: "999" } - name: Create Some User user: name: "{{ item.name }}" uid: "{{ item.uid }}" group: "{{ item.group }}" shell: "{{ item.shell }}" create_home: "{{ item.create_home }}" with_items: - { name: "lhd", uid: "777", group: "lhd", shell: "/sbin/nologin", create_home: "false" } - { name: "test", uid: "888", group: "test", shell: "/bin/bash", create_home: "false" } - { name: "egon", uid: "999", group: "egon", shell: "/bin/bash", create_home: "true" }
handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。 在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。 [root@m01 project]# cat nginx.yml - hosts: nginx tasks: - name: Config Nginx Server copy: src: /etc/nginx/nginx.conf dest: /etc/nginx/ notify: restart_nginx - name: Start Nginx Server systemd: name: nginx state: started handlers: - name: restart_nginx systemd: name: nginx state: restarted 1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。 2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。 3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。 4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。 5.不能使用handlers替代tasks
- hosts: nginx
- name: Config Nginx Server
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/
notify: restart_nginx
tags: reconf_nginx
- hosts: nginx
- name: Config Nginx Server
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/
notify: restart_nginx
tags:
- reconf_nginx
- reconfig_nginx
- hosts: nginx
- name: Config Nginx Server
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/
notify: restart_nginx
tags: reconf_nginx
- name: Config Nginx wordpress
copy:
src: /project/conf/linux.wp.com.conf
dest: /etc/nginx/conf.d/
notify: reload_nginx
when: (ansible_fqdn == "web01") or (ansible_fqdn == "web02")
tags: reconf_nginx
1、查看标签
[root@m01 project]# ansible-playbook wp.yml --list-tags
playbook: wp.yml
play #1 (nginx): nginx TAGS: []
TASK TAGS: [reconf_nginx, reconfig_nginx]
2、执行制定标签的内容
[root@m01 project]# ansible-playbook wp.yml -t reconfig_nginx
[root@m01 project]# ansible-playbook wp.yml -t reconf_nginx,reconfig_nginx
[root@m01 project]# ansible-playbook wp.yml --skip-tags reconfig_nginx # 跳过标签内容
[root@m01 project]# cat play1.yml - name: Install Nginx Server yum: name: nginx state: present [root@m01 project]# cat play2.yml - name: Config Nginx Server copy: src: /etc/nginx/nginx.conf dest: /etc/nginx/ [root@m01 project]# vim main.yml - hosts: web_group tasks: - include_tasks: /project/play1.yml - include_tasks: /project/play2.yml [root@m01 project]# cat main.yml - import_playbook: ./base.yml - import_playbook: ./nginx.yml - import_playbook: ./php.yml - import_playbook: ./wordpress.yml - import_playbook: ./mariadb.yml
- hosts: web_group tasks: - name: Check Httpd Server #使用命令检查服务启动状态时,如果服务没有启动则会得到错误结果,剧本会停止运行 command: systemctl is-active httpd #配置忽略错误可以继续执行剧本 ignore_errors: yes register: check_httpd - name: debug outprint debug: msg: "{{ check_httpd }}" - name: Httpd Restart service: name: httpd state: restarted when: check_httpd.rc == 0 # 强制执行handle的内容 [root@m01 ~]# cat handler.yml - hosts: web_group vars: - http_port: 8080 force_handlers: yes tasks: - name: config httpd server template: src: ./httpd.j2 dest: /etc/httpd/conf notify: - Restart Httpd Server - Restart PHP Server - name: Install Http Server yum: name: htttpd state: present - name: start httpd server service: name:httpd state: started enabled: yes handlers: - name: Restart Httpd Server systemd: name: httpd state: restarted - name: Restart PHP Server systemd: name: php-fpm state: restarted
roles不管是Ansible还是saltstack,我在写一键部署的时候,都不可能把所有的步骤全部写入到一个'剧本'文件当中,我们肯定需要把不同的工作模块,拆分开来,解耦,那么说到解耦,我们就需要用到roles官方推荐,因为roles的目录结构层次更加清晰。
例如:我们之前推荐大家写一个base.yml里面写所有基础优化的项目,其实把所有东西摞进去也是很鸡肋的,不如我们把这些功能全部拆分开,谁需要使用,就调用即可。
建议:每个roles最好只使用一个tasks这样方便我们去调用,能够很好的做到解耦。(SOA)
production # inventory file for production servers staging # inventory file for staging environment group_vars/ group1.yml # here we assign variables to particular groups group2.yml host_vars/ hostname1.yml # here we assign variables to particular systems hostname2.yml library/ # if any custom modules, put them here (optional) module_utils/ # if any custom module_utils to support modules, put them here (optional) filter_plugins/ # if any custom filter plugins, put them here (optional) site.yml # master playbook webservers.yml # playbook for webserver tier dbservers.yml # playbook for dbserver tier roles/ common/ # this hierarchy represents a "role" tasks/ # main.yml # <-- tasks file can include smaller files if warranted handlers/ # main.yml # <-- handlers file templates/ # <-- files for use with the template resource ntp.conf.j2 # <------- templates end in .j2 files/ # bar.txt # <-- files for use with the copy resource foo.sh # <-- script files for use with the script resource vars/ # main.yml # <-- variables associated with this role defaults/ # main.yml # <-- default lower priority variables for this role meta/ # main.yml # <-- role dependencies library/ # roles can also include custom modules module_utils/ # roles can also include custom module_utils lookup_plugins/ # or other types of plugins, like lookup in this case webtier/ # same kind of structure as "common" was above, done for the webtier role monitoring/ # "" fooapp/ # ""
[root@m01 roles]# ansible-galaxy init nginx - Role nginx was created successfully [root@m01 roles]# tree nginx nginx #项目目录名称 ├── defaults #默认的变量(优先级很低) │ └── main.yml ├── files #存放文件,使用copy模块时自动获取 ├── handlers #存放触发器的配置 │ └── main.yml ├── meta #依赖的服务,执行该项目时先执行其他的项目 │ └── main.yml ├── README.md ├── tasks #默认执行的playbook │ └── main.yml ├── templates #存放jinja2模板,使用template模块时自动获取 ├── tests │ ├── inventory │ └── test.yml └── vars #存放变量 └── main.yml
`roles`允许你再使用roles时自动引入其他的roles。role依赖关系存储在roles目录中meta/main.yml文件中。
例如:推送wordpress并解压,前提条件,必须要安装nginx和php,把服务跑起来,才能运行wordpress的页面,此时我们就可以在wordpress的roles中定义依赖nginx和php的roles
[root@m01 roles]# vim /etc/ansible/roles/wordpress/meta/main.yml
dependencies:
- { role: nginx }
- { role: php }
如果编写了meta目录下的main.yml文件,那么Ansible会自动先执行meta目录中main.yml文件中的dependencies文件,如上所示,就会先执行nginx和php的安装。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。