1.ansible简介

特性:

  • 模块化:调用特定的模块,完成特定的任务;
  • 基于python语言实现,由Paramiko,PyYAML和Jinja2三个关键模块;
  • 部署简单:agentless
  • 支持自定义模块;
  • 支持playbook

配置文件:

  • /etc/ansible/hosts #主机清单文件,定义ansible管控哪些主机
  • /etc/ansible/ansible.cfg #ansible主配置文件

    2.ansible相关指令

  1. ansible指令
    ```shell ansible HOST_PATTERN OPTION OPTIONS: -m,—module-name:模块名称 -a,—args:向模块传递参数 -f,—forks:在几个主机上并行(default=5) -C,—check:don’t make any changes; —list-host:列出匹配主机

connection Options: -u,—user:以指定身份登录远程主机 -c,—connection:连接方式(default=smart)

example: ansible HOST_PATTERN -m MODULE_NAME -a MODULE_ARGS -f FORKS -C

  1. 2. ansible-doc指令
  2. ```shell
  3. ansible-doc OPTION MODULE
  4. OPTIONS:
  5. -s:查看模块的简单说明
  6. -l,--list:列出所有模块
  7. -a,--all:查看所有文档
  8. example:
  9. ansible-doc -s ping #查看ping模块的说明

3.ansible常用模块

1.ping模块

  1. #检测ansible连接的主机是否在线
  2. [root@node1 ~]# ansible all -m ping
  3. 192.168.10.13 | SUCCESS => {
  4. "ansible_facts": {
  5. "discovered_interpreter_python": "/usr/bin/python"
  6. },
  7. "changed": false,
  8. "ping": "pong"
  9. }
  10. 192.168.10.12 | SUCCESS => {
  11. "ansible_facts": {
  12. "discovered_interpreter_python": "/usr/bin/python"
  13. },
  14. "changed": false,
  15. "ping": "pong"
  16. }

2.group模块

  1. #该模块用于添加或者删除一个group
  2. ARG
  3. gid #set group id
  4. name= #set group name
  5. state #set group state;the values is "present" or "absent"
  6. system #if "yes",indicates that the group create is system group
  7. example:
  8. 1.ansible all -m group -a "gid=3000 name=mygroup state=present system=no"
  9. #创建一个gid为3000 名称为mygroup的组
  10. 2.ansible all -m group -a "gid=3000 name=mygroup state=absent system=no"
  11. #删除一个gid为3000 名称为mygroup的组
  12. 注意:带等号为必填

3.user模块

  1. #Manage user accounts,管理用户账户
  2. ARG
  3. comment #描述信息
  4. expires #过期时间
  5. group #基本组
  6. groups #附加组
  7. home #家目录路径
  8. password #密码
  9. shell #用户的shell
  10. state #present or absent 创建还是删除
  11. system #系统用户
  12. uid #用户id
  13. move_home #两次创建一个用户,家目录不是同一路径,是否需要直接移动家目录
  14. generate_ssh_key #创建用户时,是否同时生成一对秘钥
  15. create_home #当创建用户或者家目录不存在时,是否为用户创建家目录
  16. example
  17. ansible all -m user -a "name=aa uid=5555 state=present shell=/sbin/nologin create_home=no"

4.copy模块

  1. #copy files to remote locations
  2. ARG:
  3. backup
  4. content #不指定src,由content生成的内容即为复制内容
  5. dest #目标路径
  6. directory_mode #
  7. src #本机路径,如果复制目录,有"/"则表示复制目录下所有文件,否则递归复制整个目录
  8. remote_src #从远程主机复制到另一个远程主机
  9. group
  10. owner #copy之后的属主,属组,权限
  11. mode
  12. example
  13. 1.ansible all -m copy -a "src=/etc/passwd dest=/tmp/passwd.ansible mode=644"
  14. 2.ansible all -m copy -a 'content="hello world\n" dest=/tmp/hello.txt mode=600'
  15. #用content生成的内容复制到目标主机名称为hello.txt
  16. 3.ansible all -m copy -a 'src=/home/linxi dest=/tmp/'
  17. #复制改目录到指定目录下
  18. #copy 可以创建文件

5.fetch模块

  1. #Fetch files from remote nodes 从远程主机获取文件
  2. ARG
  3. dest #目标
  4. src #源
  5. fail_on_missing #由于任何原因无法读取远程文件,则任务将失败
  6. example
  7. ansible all -m fetch -a 'dest=/tmp/backup.ansible? src=/etc/passwd'
  8. #fetch复制文件时,会在本地创建目录,将多个主机上的文件都放在改目录下

6.command模块

  1. #Execute commands on target 在目标主机上执行指令
  2. ARG
  3. chdir #切换目录执行command
  4. example
  5. ansible all -m command -a 'whoami'
  6. #command模块不能解析shell语句

7.shell模块

  1. #Execute shell commands on targets在目标主机上执行shell指令
  2. ARG
  3. chdir #切换目录执行command
  4. executable #使用其他的shell解析
  5. example:
  6. ansible all -m shell -a 'echo "123465"|passwd --stdin root'

8.file模块

  1. #Manage files and file properties管理文件和文件属性
  2. ARG
  3. state #文件属性directory,file,link
  4. src #在目标主机上创建符号链接
  5. path #创建文件或目录路径
  6. mode
  7. owner
  8. group
  9. example:
  10. ansible all -m file -a "path=/root/ansible state=directory mode=644 owner=root"
  11. #在目标主机上创建目录
  12. ansible all -m file -a "src=/etc/fstab path=/root/fatab.link state=link"
  13. #在目标主机创建链接
  14. #不建议创建文件,

9.cron模块

  1. #Manage cron.d and crontab entries管理cron.d和contab条目
  2. ARG
  3. day #天
  4. hour #小时
  5. minute #分钟
  6. job #执行指令
  7. name #任务名
  8. state #present or absent
  9. user #执行任务的用户
  10. weekday #星期
  11. example
  12. ansible all -m cron -a 'name="sync time" minute=*/1 job="/usr/sbin/ntpdate 192.168.10.11 &> /dev/null" state=present'

10.yum模块

  1. #Manages packages with the `yum' package manager 使用yum管理程序包
  2. ARG
  3. name #软件包名称
  4. state #install(present or latest),remove(absten or removed)
  5. disable #禁用某个安装仓库
  6. enable #启用某个安装仓库
  7. disable_gpg_check #是否使用gpgcheck
  8. example:
  9. ansible all -m yum -a "name=nginx state=present"

11.service模块

  1. #Manage services
  2. ARG
  3. enable #开机自启
  4. name #服务名称
  5. pattern #服务不支持status,无法获取服务状态信息时,可以使用pattern过滤关键字
  6. runlevel #启动级别
  7. state #设置服务是启动还是停止,reloaded, restarted, started, stopped
  8. example
  9. ansible all -m service -a "name=nginx state=started "

12.script模块

  1. #Runs a local script on a remote node after transferring it 在远程主机上执行本地脚本
  2. example
  3. ansible all -m script -a "/root/a.sh" #直接指定本地脚本

4.ansible playbook

1.playbook格式:

palybook是由yaml语言构成
yaml是由:键值对,列表,关联数组构成

  1. 键值对:keyvalue
  2. name:jack
  3. age:18
  1. 列表:一组类型相同的元素,由‘—’开头
  2. -apple
  3. -orange
  1. 关联数组:键值对与列表的嵌套
  2. -host
  3. name:node1
  4. age:10
  5. -host
  6. name:node2
  7. age:10

2.palybook的组成

核心元素 作用
Hosts 主机列表
Remoter_user,su sudo 执行远程主机任务的用户
Tasks 任务列表
Variables 变量
Templates 模板文本
Handlers,notify 由特定条件出发的任务
Tag 标记式运行

3.运行palybook方式

  1. 测试
    ```shell 1.ansible-playbook —syntax-host #检测语法错误

2.ansible-playbook —list-host #列出运行任务的主机

3.ansible-playbook —list-task #列出任务

  1. 2. 直接运行
  2. ```shell
  3. 1.ansible-playbook PATH #直接接路径运行
  4. 2.ansible-playbook -t TAG_NAME PATH #运行playbook中指定的TAG

4.palybook实战

1.ansible-playbook
  1. [root@node1 playbooks]# vim httpd.yaml
  2. #hosts指定运行主机,也可以使用ansible的hosts文件中定义的标签
  3. - hosts: 192.168.10.12
  4. #remote_user执行远程任务的主机
  5. remote_user: root
  6. #task任务列表
  7. tasks:
  8. #name任务名称
  9. - name: install httpd
  10. #MODULE:ARG调用的模块和模块使用的参数
  11. yum: name=httpd state=installed
  12. - name: configure httpd file
  13. copy: content="ansible test" dest=/var/www/html/index.html owner=apache group=apache
  14. - name: start httpd
  15. service: name=httpd state=started
  16. #语法检测
  17. [root@node1 playbooks]# ansible-playbook httpd.yaml --syntax-check
  18. playbook: httpd.yaml
  19. #运行
  20. [root@node1 playbooks]# ansible-playbook httpd.yaml
  21. #Gathering Facts 获取远程主机信息
  22. TASK [Gathering Facts] ***************************************************************************************************************
  23. ok: [192.168.10.12]
  24. TASK [install httpd] ******************************************************************************************************************
  25. changed: [192.168.10.12]
  26. TASK [configure httpd file] ***********************************************************************************************************
  27. changed: [192.168.10.12]
  28. TASK [start httpd] ********************************************************************************************************************
  29. changed: [192.168.10.12]
  30. PLAY RECAP ****************************************************************************************************************************
  31. 192.168.10.12 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

2.Handlers触发执行
  1. [root@node1 playbooks]# vim httpd.yaml
  2. - hosts: 192.168.10.12
  3. remote_user: root
  4. tasks:
  5. - name: install httpd
  6. yum: name=httpd state=installed
  7. - name: configure httpd file
  8. copy: content="ansible test" dest=/var/www/html/index.html owner=apache group=apache
  9. #当任务状态为changed才会通知handlers
  10. notify: restart httpd
  11. - name: start httpd
  12. service: name=httpd state=started
  13. handlers:
  14. - name: restart httpd
  15. service: name=httpd state=restarted

3.Tag选择执行
  1. [root@node1 playbooks]# vim httpd.yaml
  2. - hosts: 192.168.10.12
  3. remote_user: root
  4. tasks:
  5. - name: install httpd
  6. yum: name=httpd state=installed
  7. - name: configure httpd file
  8. copy: content="ansible test" dest=/var/www/html/index.html owner=apache group=apache
  9. notify: restart httpd
  10. #定义任务标签名
  11. tags:configure_httpd
  12. - name: start httpd
  13. service: name=httpd state=started
  14. handlers:
  15. - name: restart httpd
  16. service: name=httpd state=restarted
  17. #-t选项只执行标签任务
  18. [root@node1 playbooks]# ansible-playbook httpd.yaml -t configure_httpd
  19. TASK [Gathering Facts] ***************************************************************************************************************
  20. ok: [192.168.10.12]
  21. TASK [configure httpd file] **********************************************************************************************************
  22. ok: [192.168.10.12]
  23. #--skip-tags不执行标签中的内容
  24. [root@node1 playbooks]# ansible-playbook --skip-tags configure_httpd httpd.yaml
  25. TASK [Gathering Facts] ***************************************************************************************************************
  26. ok: [192.168.10.12]
  27. TASK [install httpd] *****************************************************************************************************************
  28. ok: [192.168.10.12]
  29. #没有执行configure httpd file
  30. TASK [start httpd] *******************************************************************************************************************
  31. ok: [192.168.10.12]

5.Variable的使用
  1. 内建变量,fects,直接调用
    ```yaml

    ansible的内建变量是由setup模块提供的,里面记录许多的主机信息;ansible使用{{ }}来引用变量,注意前后有空格;

    ansible 192.168.10.12 -m setup #获取192.168.10.12的内建变量

注意变量只能在ansible-playbook中使用,因为只有使用palybook时,才会获取远程主机信息,也就是Gathering Facts

[root@node1 playbooks]# vim facts.yaml

  • hosts: 192.168.10.12 remote_user: root tasks:
    • name: look up internal variable
      1. #注意括号与变量名中间的空格
      copy: content={{ ansible_default_ipv4 }} dest=/tmp/ansible.variable

[root@node1 playbooks]# ansible-playbook facts.yaml

[root@node1 playbooks]# ansible 192.168.10.12 -m shell -a ‘cat /tmp/ansible.variable’ {“macaddress”: “00:0c:29:d5:c5:7b”, “network”: “192.168.10.0”, “mtu”: 1500, “broadcast”: “192.168.10.255”, “alias”: “ens33”, “netmask”: “255.255.255.0”, “address”: “192.168.10.12”, “interface”: “ens33”, “type”: “ether”, “gateway”: “192.168.10.254”}

  1. 2. 通过命令行传递变量
  2. ```yaml
  3. #ansible命令行中使用-e VARS,--extra-vars=VARS来指定,使用key:value格式指定
  4. [root@node1 playbooks]# vim install_package.yaml
  5. - hosts: 192.168.10.12
  6. remote_user: root
  7. tasks:
  8. - name: install {{ package_name }}
  9. yum: name={{ package_name }} state=installed
  10. #传递nginx到package_name
  11. [root@node1 playbooks]# ansible-playbook -e package_name=nginx install_package.yaml
  12. TASK [Gathering Facts] **************************************************************************************************************
  13. ok: [192.168.10.12]
  14. TASK [install nginx] #将package_name替换为nginx
  15. **************************************************************************************************************
  16. ok: [192.168.10.12]
  1. 在playbook中自定义变量
    ```yaml [root@node1 playbook]# vim pb_var.yaml
  • hosts: 192.168.10.12 remote_user: root vars: #定义变量

    变量是同一类元素,用列表,表示方法,key:value

    • pb: palybook variable tasks:
    • name: palybook variable copy: content={{ pb }} dest=/tmp/pb.var

[root@node1 playbook]# ansible 192.168.10.12 -m shell -a ‘cat /tmp/pb.var’ #查看变量名称是否正确 192.168.10.12 | CHANGED | rc=0 >> palybook variable

  1. 4. Host Inventory,通过主机清单定义变量<br />(a) Inventory参数,用于定义ansible连接远程主机时使用的参数 <br />(b)主机清单自定义变量
  2. | Inventory参数 | 作用 |
  3. | --- | --- |
  4. | ansible_ssh_host | 定义远程连接的主机 |
  5. | ansible_ssh_port | 远程连接的主机的端口 |
  6. | ansible_ssh_user | 远程连接登录的用户 |
  7. | ansible_ssh_pass | 远程连接登录的密码 |
  8. | ansible_sudo_pass | 远程连接提权密码 |
  9. ```shell
  10. [root@node1 playbook]# ansible all -m user -a 'name=test1 state=present'
  11. [root@node1 playbook]# ansible all -m shell -a "echo 123456 | passwd --stdin test1"
  12. [root@node1 playbook]# vim /etc/ansible/hosts
  13. 192.168.10.12 ansible_ssh_user=test1 ansible_ssh_pass=123456
  14. 192.168.10.13 ansible_ssh_user=test1 ansible_ssh_pass=123456
  15. [root@node1 playbook]# ansible all -m shell -a 'whoami'
  16. 192.168.10.13 | CHANGED | rc=0 >>
  17. test1
  18. 192.168.10.12 | CHANGED | rc=0 >>
  19. test1
  1. vim /etc/ansible/hosts
  2. [web_server]
  3. 192.168.10.12 ipaddr=192.168.10.12 #ipaddr为主机清单自定义变量
  4. 192.168.10.13 ipaddr=192.168.10.13
  5. [web_server]
  6. domain=abc.com #自定义组变量
  7. #将变量存在目标主机
  8. [root@node1 playbook]# ansible all -m copy -a 'content={{ ipaddr }} dest=/tmp/host.var'
  9. #查看变量内容
  10. [root@node1 playbook]# ansible all -m shell -a 'cat /tmp/host.var'
  11. 192.168.10.13 | CHANGED | rc=0 >>
  12. 192.168.10.13
  13. 192.168.10.12 | CHANGED | rc=0 >>
  14. 192.168.10.12

6.模板 Template
  1. template模块:基于模板方式生成一个文件复制到远程主机

    1. ARG
    2. src #模板文件
    3. dest #目标主机目录
    4. owner
    5. group #文件属主属组权限
    6. mode
  2. 文本文件,嵌套脚本(使用模板编程语言)

    1. 变量:(与python一直)
    2. 字符串:使用单引号和双引号
    3. 数字:整数,浮点数
    4. 列表:["arg","arg2"]
    5. 元组:("arg1","arg2")
    6. 字典:{"key1":"values2","key2":"values2"}
    7. 算数运算符:+ - * /
  3. 实战,基于模板将redis监听端口为网卡地址,密码为主机名
    ```yaml

    1.复制redis主配置文件

    cp /etc/redis.conf /root/playbook/redis.conf.j2

2.修改监听地址,与密码为对应变量

vim redis.conf.j2 #配置模板文件 bind {{ ansible_default_ipv4.address }} requirepass ansible_fqdn

3.配置playbook

vim redis.yaml

  • hosts: 192.168.10.12 remote_user: root tasks:
  • name: install redis yum: name=redis state=installed
  • name: config redis template: src=/root/playbook/redis.conf.j2 dest=/etc/redis.conf #src为模板文件直接复制到远程主机 notify: restart_redis
  • name: start service service: name=redis state=started handlers:
  • name: restart_redis service: name=redis state=restarted ```
    7.playbook循环和判断
  1. 条件测试,when语句,在tasks中使用
    ```shell

    需求:当系统是Centos7安装mariadb,Centos6安装mysql

    1.使用ansible setup模块获取版本信息

    “ansible_distribution_major_version”: “7”

2.编写playbook

  1. - hosts: all
  2. remote_user: root
  3. tasks:
  4. - name: install mariadb
  5. yum: name=mariadb state=installed
  6. when: ansible_distribution_major_version == "7" #测试当前系统版本信息
  7. - name: install mysql
  8. yum: name=mysql state=installed
  9. when: ansible_distribution_major_version == "6"
  1. 2. 需要重复执行的任务,循环;对循环的引用固定变量名为{{ item }},暂停with_items给定要循环的元素列表
  2. ```yaml
  3. #需求,使用循环,安装lamp环境
  4. vim intsall_LNMP.yaml
  5. - hosts: 192.168.10.12
  6. remote_user: root
  7. tasks:
  8. - name: install package
  9. yum: name={{ item }} state=installed
  10. with_items:
  11. - nginx
  12. - mysql
  13. - php
  14. - php-fpm
  15. - php-mysql

8.roles角色
  1. 执行同一种任务的所有元素的集合,构成角色;
    ```shell

    1. 定义角色存放的路径

    [root@node1 ~]# grep roles /etc/ansible/ansible.cfg roles_path = /etc/ansible/roles

2. 角色的集合

[root@node1 ~]# tree /etc/ansible/roles/ -L 1 /etc/ansible/roles/ ├── httpd #完成httpd任务的集合 ├── mysql ├── nginx └── redis

  1. 2. 每个角色都有特定的目录结构
  2. ```shell
  3. [root@node1 ansible]# tree roles/nginx/ -d
  4. roles/nginx/
  5. ├── default #设定默认变量时使用此目录中的main.yml文件
  6. ├── files #存放由copy或script模块等调用的文件
  7. ├── handlers #此目录的任务由notify调用,文件名为main.yml,其它文件需要通过include包含
  8. ├── meta #定义当前角色的特殊设定及其依赖关系
  9. ├── tasks #至少要有一个tasks目录,执行任务的目录下的文件名都是mian.yml
  10. ├── templates #template模块查找所需要模板文件的目录
  11. └── vars #此目录用来存储playbook变量,文件名为main.yml,其它文件需要通过include包含
  1. 部署一个nginx
    ```yaml

    每一个层级都有自己对应的配置文件,将playbook的功能划分为各个层级

    [root@node1 ansible]# tree roles/nginx/ roles/nginx/ ├── default ├── files │ └── index.html ├── handlers │ └── main.yml ├── meta ├── tasks │ └── main.yml ├── templates │ └── vhost1.conf.j2 └── vars └── main.yml

1. tasks文件

  1. - name: install nginx
  2. yum: name=nginx state=installed
  3. - name: config file
  4. template: src=vhost1.conf.j2 dest=/etc/nginx/conf.d/vhost1.conf
  5. notify: restart nginx
  6. tags: config_nginx
  7. - name: set site web root
  8. file: path={{ nginx_root }} state=directory
  9. - name: set sete index
  10. copy: src=index.html dest={{ nginx_root }}/index.html #copy中的src默认是调用file目录中文件
  11. - name: start nginx
  12. service: name=nginx state=started

2. vars文件

  1. nginx_root: /nginx/date

3. handlers文件

  1. - name: restart nginx
  2. service: name=nginx state=restarted

4.template模板

  1. server{
  2. listen 80;
  3. server_name {{ ansible_fqdn }};
  4. location / {
  5. root {{ nginx_root }}; #vars中定义的变量
  6. index index.html;
  7. }
  8. }

5. file被调用文件

  1. <h1>vhost1</h1>

6. nginx.yml直接调用角色

  1. - hosts: node2.abc.com
  2. remote_user: root
  3. roles:
  4. - nginx

```