ansible

ansible不是以服务的方式运行,用户需要时执行 首先必须设置主机清单  vim /etc/ansible/hosts  ,添加如下内容: [web] 172.16.41.51 172.16.41.61 [beifen] 172.16.41.88 172.16.41.152 ansible 172.16.41.61 -m ping  如果主机清单中未设置172.16.41.61,则此命令执行报错 [root@centos76 11:13 .ssh]# ansible 172.16.41.61 -m ping [WARNING]: Could not match supplied host pattern, ignoring: 172.16.41.61 [WARNING]: No hosts matched, nothing to do 主机清单添加对应的地址后执行命令:第一次执行会出现yes/no的提示 ansible 172.16.41.51 -m ping The authenticity of host '172.16.41.51 (172.16.41.51)' can't be established. ECDSA key fingerprint is SHA256:ipiclPOhfzuGppT1kscx7sIW5oadl2G+VKKgmwi4NX0. ECDSA key fingerprint is MD5:f1:40:3e:af:56:a8:95:df:f6:bc:5a:f3:13:a6:fe:e1. Are you sure you want to continue connecting (yes/no)? yes 取消此项设置:在配置文件中vim /etc/ansible/ansible.cfg  取消下面的注释 #host_key_checking = False修改为host_key_checking = False 测试命令,提示下列错误,即验证失败,未设置是基于口令或基于publickey验证 [root@centos76 11:15 .ssh]# ansible 172.16.41.61 -m ping 172.16.41.61 | UNREACHABLE! => {     "changed": false,     "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.41.61' (RSA) to the list of known hosts.\r\nPermission denied (publickey,password).",     "unreachable": true } 需要添加选项 -k   ansible 172.16.41.61 -m ping -k 然后输入主机对应默认的root密码即可成功,而且只可以输入一次,如果多个主机口令不一致会导致执行失败 ansible <host-pattern> [-m module_name] [-a args] 选项定义: -m module   指定模块,默认为command     -k   提示输入ssh连接密码,默认key验证       -u   指定远程执行的用户      -b   sudo切换     -K   提示输入sudo时的口令 -C   检查,并不执行 --list-hosts   显示主机列表,可简写 --list -v   详细过程 –vv -vvv更详细 基于key验证,需要将在安装ansible的机器上生成ssh公钥并拷贝值主机清单的机器上 ssh-keygen;ssh-copy-id 172.16.41.51;;ssh-copy-id 172.16.41.61;ssh-copy-id 172.16.41.152;ssh-copy-id 172.16.41.88  ssh-copy-id 172.16.41.52 测试分组的连接情况:ansible web/beifen/all -m ping 查看组的主机列表:ansible all --list-host   ansible all --list   ansible web --list-host      ansible beifen--list-host 配置文件修改内容: log_path = /var/log/ansible.log    取消此行的注释,开启日志功能 host_key_checking = False             检查对应服务器的host_key,建议取消注释 #module_name = command          将此行修改为下面对应的内容,将默认的模块名修改为shell  module_name = shell                      host-pattern: [root@centos76 12:40 .ssh]# ansible 'web:!beifen' --list    [root@centos76 12:40 .ssh]# ansible "web:!beifen" --list 注意上述示例中单引号和双引号的标记,如果使用非 !  的话需要使用单引号,使用双引号会报错

ansible常用模块:

1、command模块:执行命令         ansible-doc -s command ansible web -m command -a 'cat /etc/redhat-release' ansible web -m command -a 'chdir=/etc cat redhat-release' ansible web -m command -a 'ls /data' ansible web -m command -a 'rm -rf  /data' ansible web -m command -a 'ls /data' ansible web -m command -a 'hostname' ansible web -m command -a 'echo $HOSTNAME'           不可以显示出预想的结果,结果是 ansible web -m command -a "echo $HOSTNAME"          不可以显示出预想的结果,结果是 ansible web -m command -a "echo 123456|passwd --stdin root"              不可以显示出预想的结果,结果是 2、shell模块 :执行命令  注意单引号双引号                   ansible-doc -s shell ansible web -m  shell -a 'echo $HOSTNAME'     注意使用的是单引号        使用双引号ansible web -m  shell -a "echo $HOSTNAME" 返回的是ansible的主机名 ansible web -m shell -a 'chdir=/data touch a.txt' ansible web -m shell -a 'ls /data' ansible web -m shell -a 'sed -i "s/SELINUX=disabled/SELINUX=enforcing/" /etc/selinux/config' ansible web -m shell -a 'cat  /etc/selinux/config' ansible web -m shell -a 'sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config' ansible web -m shell -a 'yum remove -y httpd' 3、script模块:执行脚本           ansible-doc -s script ansible web -m script -a '/data/test.sh' 4、copy模块 :拷贝文件             ansible-doc -s copy ansible web -m copy -a 'src=/etc/fstab dest=/data/151 mode=777 owner=wang group=wang backup=yes'    指定备份backup 复制目录和文件夹:ansible web -m copy -a 'src=/etc/sysconfig dest=/data/' 指定内容生成文件:ansible web -m copy -a 'content=wangbin\nceshi\n123\n456 dest=/data/copy.txt' ansible web -m copy -a 'content=[test]\nname=test\nurl=test dest=/data/test.txt' 5、fetch模块 :抓取文件,当前不支持抓取文件夹和目录   ansible-doc -s fetch ansible web -m fetch -a 'src=/data/test.txt dest=/data'          ansible web -m shell -a 'tar jcvf /root/data.tar.bz2 /data'   打包命令 ansible web -m fetch -a 'src=/root/data.tar.bz2 dest=/data'   抓取打包文件 6、file模块:设置文件属性   ansible-doc -s file ansible web -m file -a 'path=/data/test.log owner=wang mode=777' ansible web -m file -a 'src=/data/test.log name=/data/test.link state=link'   创建软连接   state=hard  创建硬链接 ansible web -m file -a 'path=/data/dir1  state=directory'          创建目录 ansible web -m file -a 'path=/data/f1.txt  state=touch'             创建文件 ansible web -m file -a 'path=/data/f1.txt  state=absent'            删除文件 ansible web -m file -a 'path=/data/dir1 state=absent'               删除目录             absent 关键字 ansible web -m file -a 'path=/data/* state=absent'                    删除所有文件,此种用法不可用,不会删除所有的文件 ansible web -m shell -a 'rm -rf /data/"'                                        这样删除目录下的所有文件 7、hostname模块:修改主机名 ansible 172.16.41.61 -m hostname -a 'name=6.10-mini'                         centos6  修改了/etc/sysconfig/network文件  未修改/etc/hosts ansible 172.16.41.51 -m hostname -a 'name=7.6-mini-DNS'                  centos7  修改了/etc/hostname  未修改/etc/hosts 8、cron模块:计划任务 ansible web -m cron -a 'name=synctime minute=/5 job="/usr/sbin/ntpdate 172.16.41.151 &> /dev/null"' ansible web -m cron -a 'name=synctime minute=/5 job="/usr/sbin/ntpdate 172.16.41.151 &> /dev/null" disabled=true'          禁用定义的计划任务,实际上就是注释掉计划任务 ansible web -m cron -a 'name=synctime minute=/5 job="/usr/sbin/ntpdate 172.16.41.151 &> /dev/null" disabled=false'         启用禁用的计划任务 ansible web -m cron -a 'name=synctime minute=*/5 job="/usr/sbin/ntpdate 172.16.41.151 &> /dev/null" state=absent'           删除计划任务 ansible web -m shell -a 'crontab -l ' 9、yum模块:管理包 ansible web -m yum -a 'name=ntpdate' ansible 172.16.41.88 -m yum -a 'name=ntpdate state=absent'   卸载包 10、service模块:管理服务 ansible web -m service -a 'name=named state=started enabled=yes'           enabled 设置为true和yes都可以 ansible web -m shell -a 'ss -ntlu|grep 53' ansible web -a 'service named status ' 11、user模块:用户管理 ansible web -m user -a 'name=wangbin system=yes shell=/sbin/nologin'  ansible web -m user -a 'name=mysql state=absent remove=yes' remove=yes  删除用户家目录   state=absent  移除用户 12、group组:管理组

ansible-galaxy   角色 连接 https://galaxy.ansible.com 下载相应的roles 列出所有已安装的galaxy     ansible-galaxy list 安装galaxy     ansible-galaxy install geerlingguy.redis 删除galaxy ansible-galaxy remove geerlingguy.redis 查看相关文件:tree /root/.ansible/roles/

ansible-pull

ansible-vault ansible-vault encrypt hello.yml         加密 功能:管理加密解密yml文件 ansible-vault [create|decrypt|edit|encrypt|rekey|view] ansible-vault encrypt hello.yml 加密 ansible-vault decrypt hello.yml 解密 ansible-vault view hello.yml 查看 ansible-vault edit hello.yml 编辑加密文件 ansible-vault rekey hello.yml 修改口令 ansible-vault create new.yml 创建新文件

ansible-console:交互式

ansible-playbook

    -C:测试但不执行,干跑模式 ansible-playbook -C hello.yml vim hello.yml  注意语法结果,严格要求空格个数和对齐 #hello world yml file

  • hosts: web   remote_user: root   tasks:     - name: hello world       command: /usr/bin/wall hello world yaml语言: 三个连续横线区分多个档案  可以用三个点号 表示档案结尾 缩进必须是统一的,不能空格和tab混用 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的

yaml语法: 列表  其所有元素都使用 -  打头 字典  通常由多个key和value构成   kay: value  注意冒号  :  后面一定要有空格 多个之间使用  ,  分隔

Playbook核心元素 Hosts 执行的远程主机列表 Tasks 任务集 Varniables 内置变量或自定义变量在playbook中调用 Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件 Handlers 和 notity 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行 tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断 ansible-playbook –t tagsname useradd.yml

  • hosts: web   remote_user: root   tasks:     - name: name1       module: arguments   httpd.yml  其中路径可以写相对httpd.yml的相对路径 例如下述的 src=files/httpd.conf

#install httpd

  • hosts: web   remote_user: root

  tasks:     - name: install httpd       yum: name=httpd     - name: copy conf       copy: src=/data/httpd.conf dest=/etc/httpd/conf/ backup=yes     - name: service       service: name=httpd state=started enabled=yes

user.yml

#user add

  • hosts: web   remote_user: root   tasks:     - name: group add       group: name=mysql gid=3306 system=yes     - name: user add       user: name=mysql group=mysql uid=3306 home=/data/mysql shell=/sbin/nologin system=yes create_home=no

handlers和notify结合使用触发条件 Handlers 是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作 Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

#install httpd

  • hosts: web   remote_user: root

  tasks:     - name: install httpd       yum: name=httpd     - name: copy conf       copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes       notify: restart service     - name: service       service: name=httpd state=started enabled=yes          handlers:     - name: restart service       service: name=httpd state=restarted

tags   执行时使用-t 参数,多个参数之间使用逗号分隔  多个不同的动作可以使用相同的标签 ansible-playbook -t config,service httpd.yml

Playbook中变量使用 变量名:仅能由字母、数字和下划线组成,且只能以字母开头 变量来源: 1 ansible setup facts 远程主机的所有变量都可直接调用 setup模块: ansible all -m  setup ansible all -m  setup -a 'filter="*fqdn"' ansible_fqdn   ansible_hostname   ansible_nodename   主机名  ansible_memtotal_mb  内存信息 引用变量  {{ 变量名 }}   双大括号之间的变量前后可以不加空格,但一般建议添加一个空格 2 在/etc/ansible/hosts中定义 普通变量:主机组中主机单独定义,优先级高于公共变量 公共(组)变量:针对主机组中所有主机定义统一变量 主机清单中定义变量:/etc/ansible/hosts [web] 172.16.41.51 port=80                   普通变量 172.16.41.61 port=8080               普通变量 [web:vars] mark="---"                                    公共(组)变量 port=88888 普通变量的优先级高于公共组合变量 3 通过命令行指定变量,优先级最高     命令行定义变量  -e选项   -e  变量=变量值 ansible-playbook –e varname=value                ansible-playbook -e port=8484  file.yml 4 playbook中定义的变量    高于主机清单中的变量 vars:   - var1: value1   - var2: value2 5 在独立的变量YAML文件中定义  引用 port: 2222 mark: ___ 6 在role中定义

file var

  - hosts: web     remote_user: root     vars:       - port: 4848     vars_files:       - vars.yml                          vars.yml是独立的变量YAML文件

    tasks:       - name: file         file: name=/data/{{ansible_nodename}}{{mark}}{{port}}.log state=touch 变量优先级:命令行变量(-e)  >>独立的变量YAML文件>>playbook变量>主机清单普通变量>主机清单公共(组)变量

模版template    根据模块文件动态生成对应的配置文件

文本文件,嵌套有脚本(使用模板编程语言编写) Jinja2语言,使用字面量,有下面形式 字符串:使用单引号或双引号 数字:整数,浮点数 列表:[item1, item2, ...]                                       可以修改 元组:(item1, item2, ...)                                       不可以修改 字典:{key1:value1, key2:value2, ...} 布尔型:true/false 算术运算:+, -, *, /, //, %, **                                                 // 整除 比较操作:==, !=, >, >=, <, <= 逻辑运算:and,or,not 流表达式:For,If,When

template功能:根据模块文件动态生成对应的配置文件 template文件必须存放于templates目录下,且命名为 .j2 结尾 在放置yaml文件的目录下 创建 templates目录 yml 文件需和templates目录平级,目录结构如下: ./ ├── temnginx.yml └── templates               └── nginx.conf.j2

ansible web -m shell -a 'yum -y remove httpd' nginx.yml  内容如下:

#nginx   - hosts: web7     remote_user: root

    tasks:       - name: package         yum: name=nginx       - name: conf         template: src=nginx.j2 dest=/etc/nginx/nginx.conf         notify: restart service       - name: service         service: name=nginx state=started enabled=yes

    handlers:       - name: restart service                                                                                                 service: name=nginx state=restarted nginx配置进程个数: worker_processes {{ansible_processor_vcpus*2+2}}; 引用模版:

  • name: config   template: src=模版文件名称 dest=配置文件存放位置

when: 系统主版本:ansible_distribution_major_version  6或者7

#install httpd

  • hosts: web   remote_user: root

  tasks:     - name: install httpd       yum: name=httpd     - name: copy conf 7       template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf       when: ansible_distribution_major_version == "7"       notify: restart service     - name: copy conf 6                                                                                                     template: src=templates/httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf       when: ansible_distribution_major_version == "6"       notify: restart service     - name: service       service: name=httpd state=started enabled=yes

  handlers:     - name: restart service       service: name=httpd state=restarted

迭代:

  • name: add several users user: name={{ item }} state=present groups=wheel with_items:
  • testuser1
  • testuser2 新建组和用户,组合用户先定义,使用字典
  • name: create user   user:  name={{item.named}} group{{item.group}}   with items:      - {name: "alice",group: "agroup"}     - {name: "bob",group: "bgroup"}     - {name: "centos",group: "cgroup"}

Playbook中template for if vim test.for.j2 {%for i in test_ports%} server {     listen {{i}}     servername www.a.com     root /app/websitea } {%endfor%}

vim test.for.jml 

  • host: web   remote_user: root   vars:     test_ports:       - 81       - 82       - 83   tasks:      - name: template        template: src=test.for.j2 dest=/data/test.conf

vim test.for.jml 

  • host: web   remote_user: root   vars:     test_ports:       - 81       - 82       - 83   tasks:      - name: template        template: src=test.for.j2 dest=/data/test.conf

vim test2.for.jml 

  • host: web   remote_user: root   vars:     vhosts:        - web1:          port: 81         name:www.a.com         dir: /data/websitea       - web2:          port: 82         name:www.b.com         dir: /data/websiteb       - web3          port: 83         name:www.c.com         dir: /data/websiteac   tasks:      - name: template        template: src=test2.for.j2 dest=/data/test2.conf vim test2.for.j2 {%for i in vhosts%} server {     listen {{i.port}}     servername {{i.name}}     root {{i.dir}} } {%endfor%}