一篇文章搞懂——ansible-playbook高级用法

ansible-playbook高级用法

  • ansible-playbook介绍

img

  • playbook 剧本是由一个或多个"play"组成的列表
  • play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
  • Playbook 文件是采用YAML语言编写的

YAML的格式

  • 在单一文件第一行,用连续三个连字号"-" 开始,还有选择性的连续三个点号( … )用来表示文件的结尾
  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  • 使用#号注释代码
  • 缩进必须是统一的,不能空格和tab混用
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
  • YAML文件内容是区别大小写的,key/value的值均需大小写敏感
  • 多个key/value可同行写也可换行写,同行使用,分隔
  • key后面冒号要加一个空格 比如: key: value
  • value可是个字符串,也可是另一个列表
  • YAML文件扩展名通常为yml或yaml
scalar 标量
#key对应value
name: wang
age: 18

#使用缩进的方式
name: 
 wang
age:
 18
Dictionary 字典
  • 字典由多个key与value构成,key和value之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一行,或者每个 k/v 分别放在不同行
#汇总模式
account: { name: wang, age: 30 }

#缩进模式
account: 
 name: wang
 age: 18
List 列表
  • 列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所有元素用 [ ] 括起来放在同一行
course: [ linux , golang , python ]

#缩进模式
course:
 - linux
 - golang
 - python
#数据里面也可以包含字典
course:
 - linux: manjaro
 - golang: gin
 - python: django
三种常见的数据格式
  • XML:Extensible Markup Language,可扩展标记语言,可用于数据交换和配置
  • JSON:JavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注释
  • YAML:YAML Ain’t Markup Language YAML 不是一种标记语言, 主要用来配置,大小写敏感,不支持tab

img

  • 可以用工具互相转换,参考网站:
    • https://www.json2yaml.com/
    • http://www.bejson.com/json/json2yaml/

Playbook 核心组件

  • 一个playbook 中由多个组件组成,其中所用到的常见组件类型如下:
    • Hosts 执行的远程主机列表
    • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最少元素需包括 name 和 task,一个name只能包括一个task
    • Variables 内置变量或自定义变量在playbook中调用
    • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
    • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
    • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
hosts 组件
  • Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
Websrvs:dbsrvs     #或者,两个组的并集
Websrvs:&dbsrvs   #与,两个组的交集
webservers:!dbsrvs  #在websrvs组,但不在dbsrvs组
remote_user 组件
  • remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
- hosts: websrvs
 remote_user: root
  
 tasks:
   - name: test connection
     ping:
     remote_user: nameke
     sudo: yes #默认sudo为root
     sudo_user:chengzi  #sudo为chengzi
task列表和action组件
  • play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task
  • task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
  • 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。
  • 如果未提供name,则action的结果将用于输出
  • task两种格式:
action: module arguments  #示例: action: shell wall hello 
module: arguments   #建议使用 #示例: shell: wall hello
#注意:shell和command模块后面跟命令,而非key=value
---
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
   - name: install httpd
     yum: name=httpd 
   - name: start httpd
     service: name=httpd state=started enabled=yes
其它组件说明
  • 某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务
  • 还可以通过"tags"给task 打标签,可在ansible-playbook命令上使用-t指定进行调
ShellScripts VS Playbook 案例
#1、SHELL脚本实现
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd 
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
systemctl enable --now httpd

#2、Playbook实现
---
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
   - name: "安装Apache"
     yum: name=httpd
   - name: "复制配置文件"
     copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
   - name: "复制配置文件"
     copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
   - name: "启动Apache,并设置开机启动"
     service: name=httpd state=started enabled=yes
playbook 命令
  • 格式:ansible-playbook <filename.yml> … [options]
#常用选项
--syntax-check      #语法检查,可缩写成--syntax, 相当于bash -n 
-C --check #模拟执行,只检测可能会发生的改变,但不真正执行操作,dry run 
--list-hosts    #列出运行任务的主机
--list-tags #列出tag
--list-tasks #列出task
--limit 主机列表 #只针对主机列表中的特定主机执行
-i INVENTORY        #指定主机清单文件,通常一个项对应一个主机清单文件
--start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的
name
-v -vv  -vvv #显示过程

playbook应用案例

  • 利用 playbook 创建 mysql 用户
---
- hosts: dbsrvs
 remote_user: root
 gather_facts: no
 tasks:
   - {name: create group, group: name=mysql system=yes gid=306}
   - name: create user
     user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_home=no
  • 利用 playbook 安装 nginx
---
# install nginx 
- hosts: websrvs
 remote_user: root 
 gather_facts: no
 tasks:
    - name: add group nginx
     group: name=nginx state=present
    - name: add user nginx
     user: name=nginx state=present group=nginx
    - name: Install Nginx
     yum: name=nginx state=present
    - name: web page
     copy: src=files/index.html dest=/usr/share/nginx/html/index.html
    - name: Start Nginx
      service: name=nginx state=started enabled=yes
  • 利用 playbook 安装和卸载 httpd
[root@centos8 ansible]#cat install_httpd.yml 
---
#install httpd
- hosts: websrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: Instal1 httpd
     yum: name=httpd
    - name: Modify config list port
     lineinfile: 
       path: /etc/httpd/conf/httpd.conf 
       regexp: '^Listen'
       line: 'Listen 8080'
    - name: Modify config data1
     lineinfile: 
       path: /etc/httpd/conf/httpd.conf 
       regexp: '^DocumentRoot "/var/www/html"'
       line: 'DocumentRoot "/data/html"'
    - name: Modify config data2
     lineinfile: 
       path: /etc/httpd/conf/httpd.conf 
       regexp: '^<Directory "/var/www/html">'
       line: '<Directory "/data/html">'
    - name: Mkdir website dir
     file: path=/data/html state=directory
    - name: Web html
     copy: src=files/index.html dest=/data/html/
    - name: Start service
      service: name=httpd state=started enabled=yes


ansible-playbook   instal_httpd.yml --limit 192.168.56.15
#remove_httpd.yml
---
- hosts: websrvs
 remote_user: root
 gather_facts: no 
 tasks:
   - name: remove httpd package
     yum: name=httpd state=absent
   - name: remove apache user 
     user: name=apache state=absent
   - name: remove config file
     file: name=/etc/httpd state=absent
   - name: remove web html
     file: name=/data/html/ state=absent
  • 安装mysql-5.6.46-linux-glibc2.12
[root@ansible ~]#cat /data/ansible/files/my.cnf 
[mysqld]
socket=/tmp/mysql.sock
user=mysql
symbolic-links=0
datadir=/data/mysql
innodb_file_per_table=1
log-bin
pid-file=/data/mysql/mysqld.pid
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld_safe]
log-error=/var/log/mysqld.log
[root@ansible ~]#cat /data/ansible/files/secure_mysql.sh 
#!/bin/bash
/usr/local/mysql/bin/mysql_secure_installation <<EOF
y
magedu
magedu
yyyy
EOF
[root@ansible ~]#tree /data/ansible/files/
/data/ansible/files/
├── my.cnf
├── mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
└── secure_mysql.sh


[root@ansible ~]#cat /data/ansible/install_mysql.yml
---
# install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
- hosts: dbsrvs
 remote_user: root
 gather_facts: no
 tasks:
 - name: install packages
     yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
    - name: create mysql group
     group: name=mysql gid=306
    - name: create mysql user
     user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes
create_home=no home=/data/mysql
    - name: copy tar to remote host and file mode 
     unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-
x86_64.tar.gz dest=/usr/local/ owner=root group=root 
    - name: create linkfile /usr/local/mysql 
     file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 
dest=/usr/local/mysql state=link
    - name: data dir
     shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --
datadir=/data/mysql --user=mysql
     tags: data
    - name: config my.cnf
     copy: src=/data/ansible/files/my.cnf  dest=/etc/my.cnf 
    - name: service script
     shell: /bin/cp /usr/local/mysql/support-files/mysql.server 
/etc/init.d/mysqld
    - name: enable service
     shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on 
     tags: service
    - name: PATH variable
     copy: content='PATH=/usr/local/mysql/bin:$PATH'
dest=/etc/profile.d/mysql.sh
    - name: secure script
     script: /data/ansible/files/secure_mysql.sh
     tags: script
  • 安装mariadb
---
#Installing MariaDB Binary Tarballs
- hosts: dbsrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: create group
     group: name=mysql gid=27 system=yes
    - name: create user
     user: name=mysql uid=27 system=yes group=mysql shell=/sbin/nologin home=/data/mysql create_home=no
    - name: mkdir datadir
     file: path=/data/mysql owner=mysql group=mysql state=directory
    - name: unarchive package
     unarchive: src=/data/ansible/files/mariadb-10.2.27-linux-x86_64.tar.gz dest=/usr/local/ owner=root group=root
    - name: link
     file: src=/usr/local/mariadb-10.2.27-linux-x86_64 path=/usr/local/mysql state=link 
    - name: install database
      shell: chdir=/usr/local/mysql   ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
    - name: config file
     copy: src=/data/ansible/files/my.cnf  dest=/etc/ backup=yes
    - name: service script
     shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
    - name: start service
      service: name=mysqld state=started enabled=yes
    - name: PATH variable
     copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh

忽略错误 ignore_errors

  • 如果一个task出错,默认将不会继续执行后续的其它task,利用 ignore_errors: yes 可以忽略此task的错误,继续向下执行playbook其它task
[root@ansible ansible]#cat test_ignore.yml
---
- hosts: websrvs
  
 tasks:
   - name: error
     command: /bin/false
     ignore_errors: yes
   - name: continue
     command: wall continue

handlers和notify

  • Handlers本质是task list ,类似于MySQL中的触发器触发的行为,其中的task与前述的task并没有本质上的不同,主要用于当关注的资源发生变化时,才会采取一定的操作。
  • 而Notify对应的action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作
  • 注意:
    • 如果多个task通知了相同的handlers, 此handlers仅会在所有tasks结束后运行一 次。
    • 只有notify对应的task发生改变了才会通知handlers, 没有改变则不会触发handlers
    • handlers 是在所有前面的tasks都成功执行才会执行,如果前面任何一个task失败,会导致handler跳过执行,可以使用force_handlers: yes 强制执行handler
---
- hosts: websrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: Install httpd
     yum: name=httpd state=present
    - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/conf/
     notify: 
        - restart httpd 
        - wall
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
   
 handlers:
    - name: restart httpd
      service: name=httpd state=restarted
    - name: wall
     command: wall "The config file is changed"
---
- hosts: websrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: add group nginx
     user: name=nginx state=present
    - name: add user nginx
     user: name=nginx state=present group=nginx
    - name: Install Nginx
     yum: name=nginx state=present
    - name: config 
     copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
     notify: ["Restart Nginx","Check Nginx Process"] #或者下面格式
        - Restart Nginx
        - Check Nginx Process
   
   handlers:
     - name: Restart Nginx
       service: name=nginx state=restarted enabled=yes
     - name: Check Nginx process
       shell: killall -0 nginx &> /tmp/nginx.log
tags组件
  • 在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件
  • 可以一个task对应多个tag,也可以多个task对应一个tag
  • 还有另外3个特殊关键字用于标签, tagged, untagged 和 all,它们分别是仅运行已标记,只有未标记和所有任务。
cat >httpd.yml<<EOF
---
# tags example
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
    - name: Install httpd
     yum: name=httpd state=present
    - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/conf/
     tags: [ conf,file ] #写在一行
        - conf    #写成多行
        - file
    - name: start httpd service
     tags: service
      service: name=httpd state=started enabled=yes
EOF

ansible-playbook --list-tags httpd.yml
ansible-playbook -t conf,service httpd.yml
ansible-playbook --skip-tags conf httpd.yml
ansible-playbook   httpd.yml --skip-tags untagged
Playbook中使用变量
  • 变量名:仅能由字母、数字和下划线组成,且只能以字母开头
#定义
variable=value
variable: value
#范例
http_port=80
http_port: 80
  • 变量调用方式:通过 {{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效
  • 变量来源
    • \1. ansible 的 setup facts 远程主机的所有变量都可直接调用
    • \2. 通过命令行指定变量,优先级最高
ansible-playbook -e varname=value test.yml
    • \3. 在playbook文件中定义
vars:
 var1: value1
 var2: value2
    • \4. 在独立的变量YAML文件中定义
- hosts: all
 vars_files:
   - vars.yml
    • \5. 在主机清单文件中定义
      • 主机(普通)变量:主机组中主机单独定义,优先级高于公共变量
      • 组(公共)变量:针对主机组中所有主机定义统一变量
    • \6. 在项目中针对主机和主机组定义
      • 在项目目录中创建 host_vars和group_vars目录
    • \7. 在role中定义
  • 变量的优先级从高到低如下

-e选项定义变量-->playbook中vars_files -->playbook中vars变量定义-->host_vars/主机名文件-->主机清单中主机变量-->group_vars/主机组名文件-->group_vars/all文件-->主机清单组变量
#普通用户下[03:16:58 nameke@admin-dns ~/ansible]$ ansible --version
ansible 2.9.27
  config file = /home/nameke/ansible/ansible.cfg
  configured module search path = [u'/home/nameke/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
........#root用户家目录下
[03:17:19 root@admin-dns ~]# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
........#root用户指定目录下
[03:17:27 root@admin-dns ~]# cd ansible/
[03:17:36 root@admin-dns ~/ansible]# ansible --version
ansible 2.9.27
  config file = /root/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
........
setup 模块中变量
  • facts 变量的实际使用场景案例

    • 通过facts变量获取被控端CPU的个数信息,从而生成不同的Nginx配置文件
    • 通过facts变量获取被控端内存大小信息,从而生成不同的memcached的配置文件
    • 通过facts变量获取被控端主机名称信息,从而生成不同的Zabbix配置文件
  • 显示 eth0 网卡的 IP 地址

[root@ansible ansible]#cat show_ip.yml 
- hosts: websrvs
  
 tasks:
    - name: show eth0 ip address {{ ansible_facts["eth0"]["ipv4"]["address"] }} 
      debug:  
        msg: IP address {{ ansible_eth0.ipv4.address }}
        #msg: IP address {{ ansible_facts["eth0"]["ipv4"]["address"] }}
        #msg: IP address {{ ansible_facts.eth0.ipv4.address }}
        #msg: IP address {{ ansible_eth0.ipv4.address }}
        #msg: IP address {{ ansible_eth0.ipv4.address.split('.')[-1] }} #取IP中的最后一个数字
[root@ansible ansible]#ansible-playbook -v show_ip.yml
  • 在playbook 命令行中定义变量
vim var2.yml
---
- hosts: websrvs
 remote_user: root
 tasks:
   - name: install package
     yum: name={{ pkname }} state=present
[root@ansible ~]#ansible-playbook -e pkname=httpd var2.yml

#也可以将多个变量放在一个文件中
[root@ansible ~]#cat vars
pkname1: memcached
pkname2: vsftpd 
[root@ansible ~]#vim var2.yml
---
- hosts: websrvs
 remote_user: root
 tasks:
    - name: install package {{ pkname1 }
     yum: name={{ pkname1 }} state=present
    - name: install package {{ pkname2 }
     yum: name={{ pkname2 }} state=present
[root@ansible ~]#ansible-playbook -e pkname1=memcached -e pkname2=httpd var5.yml
[root@ansible ~]#ansible-playbook -e '@vars' var2.yml
  • 在playbook文件中定义变量
[root@ansible ~]#vim var3.yml
---
- hosts: websrvs
 remote_user: root
 vars:
   username: user1
   groupname: group1
  
 tasks:
    - name: create group {{ groupname }}
     group: name={{ groupname }} state=present
    - name: create user {{ username }}
     user: name={{ username }} group={{ groupname }} state=present
[root@ansible ~]#ansible-playbook -e "username=user2 groupname=group2" var3.yml
  • 变量的相互调用
[root@ansible ~]#cat var4.yaml
---
  - hosts: websrvs
   remote_user: root
   vars:
     collect_info: "/data/test/{{ansible_default_ipv4['address']}}/"
   tasks:
      - name: create IP directory
       file: name="{{collect_info}}" state=directory 
#执行结果
tree /data/test/
/data/test/
└── 10.0.0.102
1 directory, 0 files
[root@ansible ansible]#cat var2.yml
---
- hosts: websrvs
 vars: 
   suffix: "txt"
   file: "{{ ansible_nodename }}.{{suffix}}"
  
 tasks:
    - name: test var
     file: path="/data/{{file}}" state=touch
#安装httpd
[root@ansible ~]#cat install.yml 
- hosts: websrvs
 vars:
   web: httpd
   db: mariadb-server
    
 tasks:
    - name: install {{ web }} {{ db }}
     yum:
       name:
          - "{{ web }}"
          - "{{ db }}"
       state: latest    
#安装httpd       
[root@ansible ~]#cat install2.yml 
- hosts: websrvs
 tasks:
    - name: install packages
     yum: name={{ pack }}
     vars:
       pack:
          - httpd
          - memcached
  • 范例:安装指定版本的MySQL
[root@ansible ansible]#cat install_mysql.yml 
---
# install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
- hosts: dbsrvs
 remote_user: root
 gather_facts: no
 vars:
   version: "mysql-5.6.46-linux-glibc2.12-x86_64"
   suffix: "tar.gz"
   file: "{{version}}.{{suffix}}"
 tasks:
    - name: install packages
     yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
    - name: create mysql group
     group: name=mysql gid=306
    - name: create mysql user
     user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql
    - name: copy tar to remote host and file mode 
     unarchive: src=/data/ansible/files/{{file}} dest=/usr/local/ owner=root group=root 
    - name: create linkfile /usr/local/mysql 
     file: src=/usr/local/{{version}} dest=/usr/local/mysql state=link
    - name: data dir
     shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
     tags: data
    - name: config my.cnf
     copy: src=/data/ansible/files/my.cnf  dest=/etc/my.cnf 
    - name: service script
     shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
    - name: enable service
     shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on 
     tags: service
    - name: PATH variable
     copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
    - name: secure script
     script: /data/ansible/files/secure_mysql.sh
     tags: script
  • 使用变量文件
    • 可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高
vim vars.yml
---
# variables file
package_name: mariadb-server
service_name: mariadb
vim var5.yml
---
#install package and start service
- hosts: dbsrvs
 remote_user: root
 vars_files:
    - vars.yml
 tasks:
    - name: install package
     yum: name={{ package_name }}
     tags: install
    - name: start service
      service: name={{ service_name }} state=started enabled=yes
主机和主机组的变量
  • 所有项目的主机变量
#在inventory 主机清单文件中为指定的主机定义变量以便于在playbook中使用
[websrvs]
www1.magedu.com http_port=80 maxRequestsPerChild=808
www2.magedu.com http_port=8080 maxRequestsPerChild=909
  • 所有项目的组(公共)变量
#在inventory 主机清单文件中赋予给指定组内所有主机上的在playbook中可用的变量,如果和主机变是同名,优先级低于主机变量
[websrvs:vars]
http_port=80
ntp_server=ntp.magedu.com
nfs_server=nfs.magedu.com
[all:vars]
# --------- Main Variables ---------------
# Cluster container-runtime supported: docker, containerd
CONTAINER_RUNTIME="docker"
# Network plugins supported: calico, flannel, kube-router, cilium, kube-ovn
CLUSTER_NETWORK="calico"
# Service proxy mode of kube-proxy: 'iptables' or 'ipvs
PROXY_MODE="ipvs"
# K8S Service CIDR, not overlap with node(host) networking
SERVICE_CIDR="192.168.0.0/16"
# Cluster CIDR (Pod CIDR), not overlap with node(host) networking
CLUSTER_CIDR="172.16.0.0/16"
# NodePort Range
NODE_PORT_RANGE="20000-60000"
# Cluster DNS Domain
CLUSTER_DNS_DOMAIN="magedu.local."
  • 范例
[root@ansible ~]#vim /etc/ansible/hosts
[websrvs]
192.168.56.14 hname=www1 domain=chengzi.io
192.168.56.15 hname=www2 
[websrvs:vars]
mark="-"
[all:vars]
domain=chengzi.org
[root@ansible ~]#ansible websrvs -m hostname -a 'name={{ hname }}{{ mark }}{{ domain }}'
#命令行指定变量:
[root@ansible ~]#ansible websrvs -e domain=chengzi.cn -m hostname -a 'name={{ hname }}{{ mark }}{{ domain }}'
  • 范例: k8s 的ansible 变量文件
[etcd]
192.168.56.104 NODE_NAME=etcd1
192.168.56.105 NODE_NAME=etcd2
192.168.56.106 NODE_NAME=etcd3
[kube-master]
192.168.56.103 NEW_MASTER=yes
192.168.56.101
192.168.56.102
[kube-node]
192.168.56.109 NEW_NODE=yes
192.168.56.107
192.168.56.108
[harbor]
[ex-lb]
192.168.56.111 LB_ROLE=master EX_APISERVER_VIP=192.168.56.100 EX_APISERVER_PORT=8443
192.168.56.112 LB_ROLE=backup EX_APISERVER_VIP=192.168.56.100 EX_APISERVER_PORT=8443
[chrony]
[all:vars]
CONTAINER_RUNTIME="docker"
CLUSTER_NETWORK="calico"
PROXY_MODE="ipvs"
SERVICE_CIDR="192.168.0.0/16"
CLUSTER_CIDR="172.16.0.0/16"
NODE_PORT_RANGE="20000-60000"
CLUSTER_DNS_DOMAIN="chengzi.local."
bin_dir="/usr/bin"
ca_dir="/etc/kubernetes/ssl"
base_dir="/etc/ansible"
针对当前项目的主机和主机组的变量
  • 上面的方式是针对所有项目都有效,而官方更建议的方式是使用ansible特定项目的主机变量和组变量
  • 生产建议在项目目录中创建额外的两个变量目录,分别是host_vars和group_vars
  • host_vars下面的文件名和主机清单主机名一致,针对单个主机进行变量定义,格式:host_vars/hostname
  • group_vars下面的文件名和主机清单中组名一致, 针对单个组进行变量定义,格式:gorup_vars/groupname
  • group_vars/all文件内定义的变量对所有组都有效
[root@ansible ansible]#pwd
/data/ansible
[root@ansible ansible]#mkdir host_vars 
[root@ansible ansible]#mkdir group_vars
[root@ansible ansible]#cat host_vars/192.168.56.08
id: 2
[root@ansible ansible]#cat host_vars/192.168.56.07
id: 1
[root@ansible ansible]#cat group_vars/websrvs 
name: web 
[root@ansible ansible]#cat group_vars/all
domain: chengzi.org
[root@ansible ansible]#tree host_vars/ group_vars/
host_vars/
├── 192.168.56.08
└── 192.168.56.07
group_vars/
├── all
└── websrvs
0 directories, 4 files
[root@ansible ansible]#cat test.yml
- hosts: websrvs
  
 tasks:
    - name: get variable
     command: echo "{{name}}{{id}}.{{domain}}"
     register: result
    - name: print variable
     debug:
       msg: "{{result.stdout}}"
[root@ansible ansible]#ansible-playbook test.yml
register 注册变量
  • 在playbook中可以使用register将捕获命令的输出保存在临时变量中,然后使用debug模块进行显示输出
  • 范例: 利用debug 模块输出变量
[root@centos8 ~]#cat register1.yml 
- hosts: dbsrvs
  tasks:
    - name: get variable
     shell: hostname
     register: name
    - name: "print variable"
     debug:
       msg: "{{ name }}"     #输出register注册的name变量的全部信息,注意变量要加" "引起来
       #msg: "{{ name.cmd }}"             #显示命令
       #msg: "{{ name.rc }}"             #显示命令成功与否
       #msg: "{{ name.stdout }}"         #显示命令的输出结果为字符串形式
       #msg: "{{ name.stdout_lines }}"   #显示命令的输出结果为列表形式
       #msg: "{{ name.stdout_lines[0] }}" #显示命令的输出结果的列表中的第一个元素
       #msg: "{{ name['stdout_lines'] }}" #显示命令的执行结果为列表形式
#说明
第一个 task 中,使用了register 注册变量名为name;当 shell 模块执行完毕后,会将数据放到该变量中。
第二给 task 中,使用了 debug 模块,并从变量name中获取数据。
[root@centos8 ~]#ansible-playbook register1.yml
  • 范例:使用 register 注册变量创建文件
[root@centos8 ~]#cat register2.yml 
- hosts: dbsrvs
 tasks:
    - name: get variable
     shell: hostname
     register: name
    - name: create file
     file: dest=/tmp/{{ name.stdout }}.log state=touch
[root@centos8 ~]#ansible-playbook register2.yml
  • 范例: register和debug模块
[root@centos8 ~]#cat debug_test.yml
---
- hosts: dbsrvs
 tasks:
    - shell: echo hello world
     register: say_hi
    - shell: "awk -F: 'NR==1{print $1}' /etc/passwd"
     register: user
    - debug: var=say_hi.stdout   #自定义输出变量代替msg
    - debug: var=user.stdout     #自定义输出变量代替msg
[root@centos8 ~]#ansible-playbook debug_test.yml
  • 范例: 安装启动服务并检查
[root@ansible ansible]#cat service.yml
---
- hosts: websrvs
 vars:
   package_name: nginx
   service_name: nginx
 tasks:
    - name: install {{ package_name }}
     yum: name={{ package_name }}
    - name: start {{ service_name }}
      service: name={{ service_name }} state=started enabled=yes
    - name: check
     shell: ps axu|grep {{ service_name }}
     register: check_service
    - name: debug
     debug:
       msg: "{{ check_service.stdout_lines }}"
[root@ansible ansible]#ansible-playbook service.yml
  • 范例: 批量修改主机名
[root@ansible ansible]#cat hostname.yml
- hosts: websrvs
 vars:
   host: web
   domain: chengzi.org
  
 tasks:
    - name: get variable
     shell: echo $RANDOM | md5sum | cut -c 1-8
     register: get_random
    - name: print variable
     debug:
       msg: "{{ get_random.stdout }}"
    - name: set hostname
     hostname: name={{ host }}-{{ get_random.stdout }}.{{ domain }}
[root@ansible ansible]#ansible-playbook hostname.yml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值