# # 前戏: ansible openpyxl puppet ansible saltstack # ansible 批量在远程主机上执行命令 python2.7编写 ## 安装 第一步:下载epel源 ```shell wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo ``` 第二步:安装 ```shell yum install -y ansible ``` ## ansible 命令格式 ```shell Usage: ansible <host-pattern> [options] -a MODULE_ARGS 模块参数 -C, --check 检查语法 -f FORKS 并发 --list-hosts 列出主机列表 -m MODULE_NAME 模块名字 ``` ssh 认证方式 - 密码 - 秘钥 - ssh-keygen 生成密钥对 - ssh-copy-id 复制公钥到远程主机 - 私钥加密,公钥解密 查看ansible生成的文件 ```shell rpm -ql ansible /etc/ansible /etc/ansible/ansible.cfg # ansible 配置文件 /etc/ansible/hosts /etc/ansible/roles ``` ## ping 走的是ICMP协议 ## ansible第一条命令 ```shell ansible 192.168.12.26 -m ping ping 一台机器 ansible 192.168.12.26,192.168.12.28 -m ping ping多台机器 ansible all -m ping ping所有机器 ansible web -m ping ping 一个组 ansible 'web:!db' -m ping ping web中有但是db中没有 ansible "web:&db" -m ping ping web和db的并集 ansible "web:db" -m ping ping web和db的交集 ``` hosts文件内容 ```shell # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character #是注释 # - Blank lines are ignored 空行被忽略 # - Groups of hosts are delimited by [header] elements []表示主机组 # - You can enter hostnames or ip addresses 可以输入主机名或者ip地址 # - A hostname/ip can be a member of multiple groups 一台主机可以被分配多个组 www[001:006].example.com www001到www006.example.com ``` ### host-pattern格式 - 单个的机器 - 多个的机器,逗号隔开 - 全部机器,all - 可以写一个分组 - 可以写多个分组 - 并集 - 逗号隔开 - 冒号隔开 - 交集,:&隔开 - 差集: :!隔开 ## ansible-doc 查看模块帮助信息 ```shell ansible-doc [-l|-F|-s] [options] [-t <plugin type> ] [plugin] -j 以json格式显示所有模块信息 -l 列出所有的模块 -s 显示模块的摘要信息 # 直接显示模块的所有帮助信息 ``` ansible 特性: 幂等性 不管执行几次,结果都是一样的 # 命令相关 ## command ```shell ansible web -a 'ls' ansible web -a 'chdir=/tmp pwd' # 先切换目录,在执行相应的命令,一般情况下在编译时候使用 ansible web -a 'creates=/tmp pwd' # 如果creates的文件存在,则不执行后面的操作 ansible web -a 'removes=/tmp pwd' # 如果removes的文件存在,则执行后面的操作 ansible web -a 'removes=/tmp mkdir /data' # 会执行后面的mkdir命令 ansible web -a 'creates=/data2 mkdir /data2' #会执行后面的mkdir命令 ``` 补充 ```shell 查看用户是否被创建成功 tail -1 /etc/passwd -1最后一条显示 tail -1 /etc/shadow id xxxx 非交互式设置密码 ``` ## shell ```shell <>|;& $ 这些特殊字符command不支持 ansible web -m shell -a 'echo "1" | passwd --stdin alex' 设置alex的密码 ansible 192.168.12.25 -m shell -a '/root/a.sh' 执行shell脚本,前提是脚本有可执行权限 ansible 192.168.12.25 -m shell -a '/root/a.py' 执行python脚本,前提是脚本有可执行权限 ``` ## script ```shell ansible db -m script -a '/root/m.sh' 执行管控机上的文件 ansible web -m script -a 'creates=/root/a.sh /root/m.sh' # 查看的是被管控机上的文件是否存在 ``` # 文件相关的模块 ## copy ```shell ansible db -m copy -a "dest=/tmp/a.sh src=/root/m.sh" 复制文件到远程主机 ansible db -m copy -a "dest=/tmp/a.sh src=/root/m.sh backup=yes" 复制文件并备份远程文件 ansible web -m copy -a "dest=/tmp/a.sh src=/root/m.sh owner=alex mode=700" 修改复制后的文件的属主和权限 ansible web -m copy -a "src=/etc/init.d dest=/tmp" 复制目录到远程主机 ansible web -m copy -a "src=/etc/init.d/ dest=/tmp" 复制目录里面的文件到远程主机 ansible web -m copy -a "src=/etc/ansible dest=/tmp owner=alex" 复制目录到远程主机,并修改目录的属主,并且里面文件的属主也被修改了 ansible web -m copy -a "content='大弦嘈嘈如急雨,小弦切切如私语' dest=/tmp/b.txt" 直接将content里面的内容添加到dest的文件里面 ``` ## file ### 补充 ```shell\ ln -s 原文件地址 目标文件地址 创建软连接 ln 创建硬链接 ``` ```shell ansible cache -m file -a "path=/tmp/wupeiqi state=directory" 创建一个目录 ansible cache -m file -a "path=/tmp/wupeiqi.txt state=touch" 创建一个文件 ansible cache -m file -a "path=/tmp/t state=link src=/etc/init.d" 创建软连接 path是目标文件 src是源文件 ansible cache -m file -a "path=/tmp/t state=absent " 删除文件 ``` ## 今日内容总结 ```shell ansible 安装 epel源 ``` host-pattern格式 - 单个主机 - 多个主机 - all - 一个组 - 多个组 - 交集 'web:&db' - 并集 'web:db' - 差集 'web:!db' 命令相关的模块 - command 不支持特殊字符 <>;!$|& - shell - script 执行管控机上的脚本 文件相关的模块 - copy - content - dest - src - onwer - group - mode - backup - file - path - state - directory - touch - file - absent - link - hard - src - link - hard
2
# 今日内容回顾 ansible 安装 epel源 host-pattern的格式 - 单台机器 - 多台机器 - 全部机器 - 单个分组 - 多个分组 - 交集 'web:&db' - 并集 - 'web:db' - web,db - 差集 'web:!db' - 命令相关 - command 不支持特殊字符<>|!;$ - shell - script - 文件相关 - copy - dest - src - group - owner - mode - backup - content - file - path - src - link - hard - state - directory - file - touch - link - hard - group - mode - owner # 今日内容详解 ### fetch 用来拉取 被控机上的文件,每个被控机都会创建一个文件夹,并且保留原来的目录格式 ```shell ansible web -m fetch -a 'dest=/tmp src=/var/log/cron' ``` ## 软件包相关 ### yum - rpm 与yum的 区别 - redhat package manage - yum源配置方式 ```shell [epel] # 组名 name=Extra Packages for Enterprise Linux 7 - $basearch #名称 baseurl=http://mirrors.aliyun.com/epel/7/$basearch #url,可以写http,https,ftp,file: failovermethod=priority enabled=1 #是否启用 1表示启用,0表示不启用 gpgcheck=0 #是否校验gpgcheck,0表示不校验,1表示校验 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 ``` - yum 安装包组 ```shell yum grouplist 查询包组 yum groupinstall -y 'Development Tools' 安装包组 rpm -qa |grep python2-pip 查看软件包是否安装成功 ``` ```shell ansible web -m yum -a 'name=python2-pip' 安装python2-pip包 ansible web -m yum -a 'name=@Development Tools' 安装python2-pip包 ``` ## pip ```shell pip freeze > a.txt 给当前python环境的包打快照 pip install -r a.txt 安装文件里面所有的包 pip list 查看所有安装的包 ``` ```shell ansible web -m pip -a 'name=flask' 安装pip包 ``` ### service ```shell service nginx start|stop|restart # centos6 chkconfig add nginx chkconfig nginx on 设置开机自启动 chkconfig --list systemctl start nginx # centos7 systemctl enable nginx # 设置开机自启动 ss -tnlp ``` ```shell ansible web -m service -a 'name=nginx state=started' #启动服务 ansible web -m service -a 'name=nginx state=stopped' #停止服务 ``` ## 计划任务 ### cron ```shell 分 时 日 月 周 job 1 0 * * * * * * * * tar zcvf /tmp/etc.tar.gz /etc/ 这是一个错误的示范 2 */3 * * * 每个3小时 0 15-17 * * 2,3 每周2,周三,15-17点的0分做某件事 ``` ```shell day:天 hour:小时 job:执行的任务 minute:分钟 month:月 name:名字 weekday:周 ansible web -m cron -a 'minute=10 job="touch /tmp/alex.txt" name=touchfile' #新建计划任务 ansible web -m cron -a 'minute=10 job="touch /tmp/alex.txt" name=touchfile disabled=yes' #关闭计划任务 ansible web -m cron -a 'name=touchfile state=absent' #删除计划任务 ``` ## 用户相关 ```shell 用户: 超级用户 root 0 系统用户 不能登录 201-999 centos7 1-499 centos6 普通用户 可以登录系统 1000-60000 centos7 500-65535 centos6 组: 超级组 root 0 系统组 201-999 centos7 1-499 centos6 普通组 1000-60000 centos7 500-65535 centos6 useradd -d /opt/alex alex 指定用户的家目录 useradd -M -d /opt/alex3 alex3 不创建用户的家目录 userdel -r alex3 删除用户并删除用户的家目录 ``` 用户和组的关系 - 一对一 主组 - 一对多 附加组 - 多对多 ```shell ansible db -m user -a 'name=mysql home=/opt/mysql groups=root uid=2000' #创建用户,并指定用户的家目录 ,指定用户的附加组,指定用户的uid ansible db -m user -a 'name=mysql state=absent' #删除用户但是不删除用户的家目录 ansible db -m user -a 'name=mysql state=absent remove=yes' #删除用户并删除用户的家目录 ``` ### group ```shell ansible db -m group -a 'name=wusir' 创建一个普通组 ansible db -m group -a 'name=wusir state=absent' 删除组 ``` ### setup ```shell ansible_all_ipv4_addresses 所有的ipv4地址 ansible_all_ipv6_addresses 所有的ipv6地址 ansible_architecture 系统的架构 ansible_date_time 系统时间 ansible_default_ipv4 系统的默认ipv4地址 ansible_distribution 系统名称 ansible_distribution_file_variety 系统的家族 ansible_distribution_major_version 系统的版本 ansible_domain 系统所在的域 ansible_fqdn 系统的主机名 ansible_hostname 系统的主机名,简写 ansible_os_family 系统的家族 ansible_processor_cores cpu的核数 ansible_processor_count cpu的颗数 ansible_processor_vcpus cpu的个数 ``` web - 创建一个用户alex ansible web -m user -a 'name=alex' - 创建一个用户组wusir ansible web -m group -a 'name=wusir' - 复制/etc/fstab文件到/tmp目录下面 ansible web -m copy -a 'dest=/tmp/fstab src=/etc/fstab' - 安装nginx ansible web -m yum -a 'name=nginx' - 安装redis ansible web -m yum -a 'name=redis' - 并新建crontab每天的晚上12点重启nginx ansible web -m cron -a 'minute=0 hour=0 job=重启' ## playbook ### yaml ```shell 列表: - 字典: key:value 后缀名:yaml yml ``` ### ansible-playbook的命令格式 ```shell ansible-playbook [options] playbook.yml [playbook2 ...] -C --check 干跑 白跑 -f FORKS 用来做并发的 --list-hosts 列出主机列表 --syntax-check 语法检查 -e 传递参数 -t 指定tags ``` 单台机器 ```shell - hosts: cache remote_user: root tasks: - name: createuser user: name=alex - name: creategroup group: name=wusir - name: installredis yum: name=redis ``` 多台机器 ```shell - hosts: web remote_user: root tasks: - name: createuser user: name=wengang - name: creategroup group: name=gebixiaoguniang 执行过程,所有机器都执行完第一个任务,在去执行第二个任务 ``` ### playbook的参数 ```shell - hosts: web remote_user: root tasks: - name: create{{ user }} user: name={{ user }} ``` 第一种传参方式: -e 第二种传参方式:hosts文件里面主机后面写 第三种传参方式:hosts文件里面写[groupname:vars] 第四种传参方式:playbook文件中vars来指定 ```shell - hosts: web remote_user: root vars: - user: alexsb5 tasks: - name: create{{ user }} user: name={{ user }} ``` 第五种传参方式:通过register注册,使用的时候要使用参数的.stdout值 ```shell - hosts: web remote_user: root tasks: - name: sum shell: echo 2+4|bc register: user - name: create{{ user }} user: name=alexsb{{ user.stdout }} ``` ```shell -e > playbooks的vars > hosts文件 ``` ### 条件判断 ```shell - hosts: cache remote_user: 文刚 tasks: - name: 偷看姑娘 dong: 偷看姑娘 when: 站着 - name: 偷看姑娘 dong: 偷看姑娘 when: 趴着 ``` ```shell - hosts: web tasks: - name: file copy: content="凿壁偷光" dest=/tmp/wg.txt when: num=="2" - name: file copy: content="刷流氓" dest=/tmp/wg.txt when: num=="4" ``` ```shell - hosts: cache tasks: - name: createfile copy: content="小弦切切如私语" dest=/tmp/ppx.txt when: ansible_processor_vcpus==1 ``` ```shell - hosts: cache tasks: - name: createfile copy: content="小弦切切如私语" dest=/tmp/ppx.txt when: ansible_python.version.major==1 #取字典内的值 ``` ### 标签 ```shell - hosts: cache remote_user: root tasks: - name: install yum: name=redis - name: copyfile copy: dest=/etc/redis.conf src=/root/redis.conf - name: startredis service: name=redis state=started ``` ```shell - hosts: cache remote_user: root tasks: - name: install yum: name=redis tags: install - name: copyfile copy: dest=/etc/redis.conf src=/root/yaml/redis.conf tags: copyfile - name: startredis service: name=redis state=started tags: start ``` ### 模板 ```shell - hosts: cache remote_user: root tasks: - name: install yum: name=redis tags: install - name: copyfile template: dest=/etc/redis.conf src=redis.conf.j2 # 可以使用相对路径,在当前目录的templates目录里面 tags: copyfile - name: startredis service: name=redis state=started tags: start ``` ### 循环 with_item ```shell - hosts: web remote_user: 文刚 tasks: - name: 偷看姑娘A dong: 偷看姑娘A - name: 偷看姑娘B dong: 偷看姑娘B - name: 偷看姑娘C dong: 偷看姑娘C ``` 进阶版 ```shell - hosts: web remote_user: 文刚 tasks: - name: 偷看姑娘A dong: 偷看{{item}} with_items: - 姑娘A - 姑娘B - 姑娘C ``` ```shell - hosts: db tasks: - name: creatuser user: name={{ item }} with_items: - alex10 - wusir10 - taibai10 ``` ### 循环嵌套 ```shell - hosts: db tasks: - name: group group: name={{item}} with_items: - alex20 - wusir20 - taibai20 - name: creatuser user: name={{ item.name }} group={{item.group}} with_items: - {name: alex30,group: alex20} - {name: wusir30,group: wusir20} - {name: taibai30,group: taibai20} ``` ### handlers ```shell - hosts: cache remote_user: root tasks: - name: install yum: name=redis tags: install - name: copyfile template: dest=/etc/redis.conf src=redis.conf.j2 tags: copyfile notify: restart redis - name: startredis service: name=redis state=started tags: start handlers: - name: restart redis service: name=redis state=restarted ``` # 今日内容总结: - fetch - 每台机器都有一个文件夹,并且保持原来的目录的结构 - yum - name=@development tools 安装包组 - pip - service - cron - disabled=yes - 分钟最好不要是* - user - remove=yes - group - playbook - 基本 - 传参 - -e - hosts文件ip地址后面 - hosts文件[gorup:vars] - playbook里面vars - register - -e > playbook > hosts - when - with_items - handlers - notify - template - 标签 -t
3
4
5