ansible,playbook知识点复习

ansible

基础知识:

批量管理服务器工具;

使用python编写;

基于ssh进行管理,所以不需要在被控端安装任何软件;

ansible在远程管理主机时,主要通过各种模块进行操作的

对主控端的要求:

配置域名解析,能够通过名字访问所有节点

配置可以通过ssh到所有节点免密登录

安装ansible_soft.tar.gz

ansible配置环境管理

# 创建ansible工作目录,目录名自己定义,不是固定的。

[root@control ~]# mkdir ansible

[root@control ~]# cd ansible

# 创建配置文件。默认的配置文件是/etc/ansible/ansible.cfg,但是一般不使用它,而是在工作目录下创建自己的配置文件

[root@control ansible]# vim ansible.cfg    # 文件名必须是ansible.cfg

[defaults]

inventory = hosts    # 管理的主机,配置在当前目录的hosts文件中,hosts名是自定义的。=号两边空格可有可无。

# 创建主机清单文件。写在[]里的是组名,[]下面的是组内的主机名

[root@control ansible]# vim hosts

[test]

node1

[proxy]

node2

[webserver]

node[3:4]     # node3和node4的简化写法,表示从3到4

[database]

node5

# cluster是组名,自定义的;:children是固定写法,表示下面的组名是cluster的子组。

[cluster:children]

webserver

database

# 查看被管理的所有的主机。注意,一定在工作目录下执行命令。

[root@control ansible]# ansible all --list-hosts

  hosts (5):

    node1

    node2

    node3

    node4

    node5

# 查看webserver组中所有的主机

[root@control ansible]# ansible webserver --list-hosts

  hosts (2):

    node3

node4

ansible的两个管理办法:

adhoc临时命令(在命令行上执行管理命令)

playbook剧本 (把管理任务用特定格式写到文件里)

共同点:都是通过模块加参数进行管理

adhoc临时命令:

语法:ansible 主机或组列表 -m 模块 -a “参数” 【-a  是可选的】

如何测试远程主机的连通性: ansible all -m ping

ansible模块

模块基本信息查看:

ansible-doc -l | wc -l

列出ansible所有模块:

ansible-doc -l

查看和yum有关的模块:

ansible-doc -l | grep yum

查看yum模块的使用说明(专注于EXAMPLE):

ansible-doc yum

模块详细信息:

command模块:

ansible默认模块,用于在远程主机上执行任意命令;

command不支持shell特性,如管道,重定向

例:在被管主机上创建目录:ansible all -a “mkdir /tmp/demo”

shell模块

和command模块类似,但是支持shell特性,如管道,重定向。

例:查看node1的IP地址:ansible node1 -m shell -a “ip a s | head”

script模块

用于在远程主机上执行脚本

例:

在控制端创建脚本即可:vim test.sh

在test组主机上执行脚本:ansible test -m script -a “test.sh”

file模块

可以创建文件,目录,链接等,还可以修改权限、属性等

常用选项:

  path:指定文件路径

  owner:设置文件所有者

  group:设置文件所属组

  state:状态:touch表示创建文件;directory表示创建目录;link表示创建软连接;absent表示删除。

  mode:设置权限

  src:源

  dest:目标

例:

在test主机上创建/tmp/file.txt:ansible test -m file -a “path=/tmp/file state=touch”【touch表示 文件若不存在则创建】

将test主机上将/tmp/file.txt的属主改为sshd,属主改为adm,权限改为0777:admin test -m file -a “path=/tmp/file.txt owner=sshd group=adm mode=’0777’”

在test主机上创建/etc/host 的软连接,目标是/tmp/host.txt:ansible test -m file -a “src=/etc/hosts dest=/tmp/hosts.txt state=link”

copy模块(从上往下)

将文件从控制端拷贝到被控端

常用选项:

  src:源

  dest:目标;被控制端的文件路径

  content:内容;需要写到文件里的内容

例:

将a.txt拷贝到test主机上的/root/:ansible test -m copy -a “src=a3.txt dest=/root/”

在目标主机test上 创建/tmp/mytest.txt,内容是helloword: ansible test -m copy -a “content=’helloword’ dest=/tmp/mytest.txt”

fetch模块:(从下往上)

和copy模块相反,copy是上传,fetch是下载

常用选项:

  src:源;被控制端的文件路径

  desc:目标;控制端的文件路径

例:

将test主机上的/etc/hostname 下载到本地目录的家目录下

ansible test -m fetch -a “src=/etc/hostname desc=~/”

lineinfile模块

用于确保目标文件中有某一行neir

常用选项:

  path:待修改文件的路径

  line:写入文件的一行内容

  regrxp:正正则表达式,用于查找文件内容

例:

test组的主机中,/etc/issue中一定有一行helloword,若不存在则默认添加到行尾:

ansible test -m lineinfile -a “path=/etc/issue line=’helloword’”

test组的主机中,把/etc/issue中有hello的行,替换成chilema:

ansible test -m linefinfile -a “path=/etc/issue line=’chilema’ regrxp=hello”

replace模块

lineinfile会替换一行,replace可以替换关键词

常用选项:

  path:待修改的文件路径

  replace:将正则表达式查到的内容,替换成replace的内容

  regexp:正则表达式,用于查找文件的内容

例:

将test组中主机上的/etc/issue文件中的chi,替换成he

ansible test -m replace -a “path=/etc/issue regexp=’chji’ replace=’he’”

group模块

创建、删除组

常用选项:

  name:待创建组名

  gid:组的id号

  state:present表示创建(默认);absent表示删除

user模块

实现linux用户管理

常用选项:

  name:待创建的用户名

  uid:用户id

  group:设置主组

  groups:设置附加组

  home:设置家目录

  password:设置用户密码

  state:状态;present表示创建(默认选项);absent表示删除;

  remove:删除家目录、邮箱等。值为yes或者true都可以

例:

在test组的主机上创建tom用户:ansible test -m user -a “name=tom”

在test组的主机上,创建jeerry用户。设置其uid为1010,主组啊是adm,附加组是daemon和root,家目录是/home/jerry:

ansible test -m user -a “uid=101 name=jerry group=adm groups=deamon,root home=/home/jerry”

设置tom的密码是123456:

【{{}}是一种固定格式,表示执行命令。password_hash是函数,sha512是一种加密算法,则password_hash函数将会把123456听过sha512加密变成tom的密码】

ansible test -m user -a “name=tom password={{‘123456|password_hash(‘sha512’)’}}”

删除tom用户,但不删除家目录:ansible test -m user -a “name=tom state=absent”

删除Jerry用户,删除家目录:ansible test -m user -a”name=jerry state=absent remove=yes”

yum_repository模块

用于配置yum

常用选项:

  file:指定文件名

  其他选项:需对照文件

例:

在test组主机上配置yum:

ansible test -m yum_repository -a “file=myrepo name=myapp description=’My App’ baseurl=ftp://192.168.4.254/rhel8/AppStream gpgcheck=no enabled=yes”

yum模块:

用于rpm包的管理,如安装、升级、卸载

常用选项:

  name:包名

  state:状态;present表示安装,如果已安装则忽略;latest表示安装或升级到最新版本;absent表示卸载

例:

在test组主机上安装tar: ansible test -m yum -a “name=tar state=present”

在test组主机上卸载tar:ansible test -m yum -a “name=tar state=absent”

service模块:

用于控制服务的启动,关闭,重启,开机自启。

常用选项:

  name:控制的服务名

  state:start表示启动;stopped表示关闭;restart表示重启

  enabled:yes表示设置开机自启;no表示开机不要自启

例:

将test主机上的httpd启动,并设置他开机自启:ansible test -m service -a “name=httpd state=started enabled=yes”

常用于复杂的任务管理,以及管理经常要完成的任务

playbook也是通过模块和他的参数,在特定主机上执行任务

playbook是一个文件,该文件中需要通过yaml格式进行书写

yaml语法规范:

yaml文件的命名,一般以yml或者yaml作为扩展名

文件一般以---作为第一行,不是必须,但是常用

键值对使用冒号表示,冒号后面必须有空格

数组使用-表示,-后面必须有空格

相同层级必须有相同的缩进。如果缩进不对,则会有语法错误。每一级缩进,为两个空格。

全文不可以使用tab,必须使用空格(可以使用特殊设置来适应,方法如下)

让vim适应yaml语法:(首先进入到ansible文件内)

输入vim ~/.vimrc

在文件内输入:

set ai

set ts=2

set et

【完成后即可在vim内使用tab键】

编写playbook:

一个playbook可以包含多个play

每个play用于在指定主机上,通过模块和参数执行相应的任务

每个play可以包含多个任务

任务由模块和参数构成

编写用于测试连通性的playbook,相当于执行ansible all -m ping

---

hosts: all

tasks:

  - ping:

执行playbook:ansible-playbook “yaml文件的名子 ”

更规范的写法如下:

---

- name: test network   【play的名字,可选项】

  hosts: all            【作用于所有的主机】

  tasks:               【任务】

    - name: task 1     【第一个任务的名字,可选选项】

      ping:           【第一个任务使用的模块】

执行playbook:ansible-playbook “yaml文件的名子 ”

例:在test主机和node2上创建/tmp/demo目录,权限是0755。将控制端的/etc/hosts拷贝到目标主机的/tmp/demo中。

---

- name: carete dir and copy file

  host: test,node2

  tasks:

- name: create dir

file:

   path: /tmp/demo

   state: direction

   mode: ‘0755’

- name: copy file

  copy:

    src: /etc/hosts

    dest: /tmp/demo/hosts

执行: ansible-playbook fileop.yaml

通过copy模块创建/tmp/1.txt,文件内容有两行,分别是helloworld和nihao

---

- name: play

  hosts: test

  tasks:

    - name: mkfile 1.txt

      copy:

        dest: /tmp/1.txt

        cintent: |

          helloword

          nihao

在test主机上创建见john用户,他的uid是1040,主组是daemon,密码为123

---

- name: create user

  hosts: test

  tasks:

- name: create user john

  user:

    name: john

    uid: 1040

    group: daemon

    password: “{{‘123’|password_hash(‘sha512’)}}”

在test主机上,安装httpd,php,php-mysqlnd

---

- name: install pkgs

  host: test

  tasks:

    - name: install web pkgs

      yum:

        name: httpd,php,php-mysqlnd    【也可以加个“[ ]”】

        stste: present

或者:

---

- name: install pkgs

  host: test

  tasks:

    - name: install web pkgs

      yum:

        name:

          - httpd

          - php

          - php-mysqlnd

        stste: present

安装软件包组:

列出所有的软件包组:yum grouplist

yum groupinstall "Development Tools"批量安装软件

【如果列出的组名为中文,可以:LANG=C yum grouplist】

在test组中的主机上安装Development Tools组

---

- name: install pkgs

  host: test

  tasks:

    - name: install dev group

      yum:

        name: “@ Development Tools”

        name: present

         

在test组的主机上升级所有的包到最新版本

---

- name: install web pkgs

  hosts: test

  tasks:

    - name: updata system

      yum:

        name: ”*”

        state: latest

ansible变量

facts变量

facts是ansible自带的预定义变量,用于描述被控端软件和硬件的信息

facts变量通过setup模块获得

通过setup查看所有的facts变量:ansible test -m setup

facts变量是一个大的由{}构成的键值对字典,在{}中,有很多层级的嵌套。可以通过参数过滤出第一个层级的内容。

查看所有ipv4的地址,filter是过滤的意思:ansible test -m setup -a “filter=ansible_all_ipv4_address”

查看可用内存:ansible test -m setup -a “filter=ansible_memfree_mb”

常用的facts变量

  1. ansible_all_ipv4_address:所有的ipv4地址
  2. ansible_bios_version:BIOS版本信息
  3. ansible_memotal_mb:总内存大小
  4. ansible_hostname:主机名

在playbook中使用变量:

显示远程主机的主机名和内存大小。在ansible中,变量使用{{}}表示

debug模块用于输出信息,常用的参数是msg,用于指定输出内容

---

- name: display host info

  host: test

  tasks:

- name: display hostname and memory

  debug:

    msg: “hostname: {{ansible_hostname}}; mem: {{ansible_memotal_mb}} MB”

自定义变量:

引入变量,可以方便playbook重复使用。比如装包的playbook,包名可以使用变量。多次执行playbook,只要改变变量名即可,无需重新编写新的playbook。

ansible支持10种以上的变量定义方式。常用的变量来源如下:

  inventory变量。变量主要来自主机清单文件中.

  facts变量。

  playbook变量。变量主要在playbook定义。

  变量文件。专门创建用于保存变量的文件。推荐变量写入单独的文件。

# 使用inventory变量。

[root@control ansible]# vim hosts

[test]

node1 iname="nb"     # 主机变量定义的方法。iname是自定义名称

[proxy]

node2

[webserver]

node[3:4]

[database]

node5

[cluster:children]

webserver

database

[webserver:vars]       # 组变量定义方法。:vars是固定格式

iname="dachui"

# 通过变量创建用户

[root@control ansible]# vim var1.yml

---

- name: test create user

  hosts: test

  tasks:

    - name: create user

      user:

        name: "{{iname}}"

        state: present

       

- name: create user in webserver

  hosts: webserver

  tasks:

    - name: create some users

      user:

        name: "{{iname}}"

        state: present

[root@control ansible]# ansible-playbook var1.yml

# 上述两个play也可以合并为一个,如下:

[root@control ansible]# vim var1.yml

---

- name: test create user

  hosts: test,webserver    # 指定执行的目标是test组和webserver

  tasks:

    - name: create user

      user:

        name: "{{iname}}"

        state: present

       

# playbook中定义变量

# test组中的主机上创建用户jack,他的密码是123456

[root@control ansible]# vim user_jack.yml

---

- name: create user

  hosts: test

  vars:    # 固定格式,用于声明变量

    username: "jack"    # 此处引号可有可无

    mima: "123456"      # 此处引号是需要的,表示数字字符

  tasks:

    - name: create some users

      user:

        name: "{{username}}"   # {}出现在开头,必须有引号

        state: present

        password: "{{mima|password_hash('sha512')}}"

[root@control ansible]# ansible-playbook user_jack.yml

# 将变量定义在文件中

[root@control ansible]# vim vars.yml   # 文件名自定义

---

yonghu: rose

mima: abcd

[root@control ansible]# vim user_rose.yml

---

- name: create user

  hosts: test

  vars_files: vars.yml   # vars_files用于声明变量文件

  tasks:

    - name: create some users

      user:

        name: "{{yonghu}}"   # 这里的变量来自于vars.yml

        state: present

        password: "{{mima|password_hash('sha512')}}"

[root@control ansible]# ansible-playbook user_rose.yml

补充模块

firewalld模块

  • 用于配置防火墙的模块
  • 常用选项:
    • port:声明端口
    • permanent:永久生效,但不会立即生效
    • immediate:立即生效,临时生效
    • state:enabled,放行;disabled拒绝
  • 防火墙一般默认拒绝,明确写入允许的服务。
  • 有一些服务有名字,有些服务没有名字。但是最终都是基于TCP或UDP的某些端口。比如http服务基于TCP80端口。服务名和端口号对应关系的说明文件是:/etc/services
  • 配置服务器的防火墙,一般来说只要配置开放哪些服务或端口即可。没有明确开放的,都默认拒绝。
  • 应用
    • 在test组中的主机上安装并启动httpd
    • 客户端访问服务器的http服务
    • 在test组中的主机上安装并启动firewalld
    • 客户端访问服务器的http服务
    • 在test组中的主机上开放http服务

# 配置httpd服务

[root@control ansible]# vim firewall.yml

---

- name: configure test

  hosts: test

  tasks:

    - name: install httpd pkg   # 这里通过yum模块装httpd

      yum:

        name: httpd

        state: present

    - name: start httpd service   # 这里通过service模块启httpd服务

      service:

        name: httpd

        state: started

        enabled: yes

       

[root@control ansible]# ansible-playbook firewall.yml

[root@control ansible]# curl http://192.168.4.11/  # 可访问

# 安装并启动firewalld

[root@control ansible]# vim firewall.yml

---

- name: configure test

  hosts: test

  tasks:

    - name: install httpd pkg   # 这里通过yum模块装httpd

      yum:

        name: httpd

        state: present

    - name: start httpd service   # 这里通过service模块启httpd服务

      service:

        name: httpd

        state: started

        enabled: yes

 

    - name: install firewalld pkg   # 这里通过yum模块装firewalld

      yum:

        name: firewalld

        state: present

    - name: start firewalld service   # 这里通过service模块启firewalld服务

      service:

        name: firewalld

        state: started

        enabled: yes

 

[root@control ansible]# ansible-playbook firewall.yml

[root@control ansible]# curl http://192.168.4.11/  # 被拒绝

curl: (7) Failed to connect to 192.168.4.11 port 80: 没有到主机的路由

# 配置防火墙规则,放行http协议

[root@control ansible]# vim firewall.yml

---

- name: configure test

  hosts: test

  tasks:

    - name: install httpd pkg   # 这里通过yum模块装httpd

      yum:

        name: httpd

        state: present

    - name: start httpd service   # 这里通过service模块启httpd服务

      service:

        name: httpd

        state: started

        enabled: yes

 

    - name: install firewalld pkg   # 这里通过yum模块安装firewalld

      yum:

        name: firewalld

        state: present

    - name: start firewalld service   # 这里通过service模块启service服务

      service:

        name: firewalld

        state: started

        enabled: yes

 

    - name: set firewalld rules   # 通过firewalld模块开放80端口

      firewalld:

        port: 80/tcp

        permanent: yes

        immediate: yes

        state: enabled

[root@control ansible]# ansible-playbook firewall.yml

[root@control ansible]# curl http://192.168.4.11/  # 可访问

template模块

  • copy模块可以上传文件,但是文件内容固定
  • template模块可以上传具有特定格式的文件(如文件中包含变量)
  • 当远程主机接收到文件之后,文件中的变量将会变成具体的值
  • template模块上传的文件,使用的语法叫Jinja2。
  • 常用选项:
    • src:要上传的文件
    • dest:目标文件路径

# 使用template模块将含有变量的文件上传到test组中的主机

[root@control ansible]# vim index.j2

Welcome to {{ansible_hostname}} on {{ansible_eth0.ipv4.address}}

[root@control ansible]# vim templ.yml

---

- name: upload index

  hosts: test

  tasks:

    - name: create web index

      template:

        src: index.j2

        dest: /var/www/html/index.html

[root@control ansible]# ansible-playbook templ.yml

[root@control ansible]# curl http://192.168.4.11/

Welcome to node1 on 192.168.4.11

[root@node1 ~]# cat /var/www/html/index.html

Welcome to node1 on 192.168.4.11

进阶语法

错误处理

  • 当Playbook中包含很多任务时,当某一个任务遇到错误,它将崩溃,终止执行

# test组中的主机上启动mysqld服务,然后创建/tmp/service.txt

# 因为目标主机上没有mysqld服务,所以它将崩溃,终止执行。即,不会创建/tmp/service.txt文件

[root@control ansible]# vim myerr.yml

---

- name: my errors

  hosts: test

  tasks:

    - name: start mysqld service  # 通过service模块启动mysqld服务

      service:

        name: mysqld

        state: started

        enabled: yes

       

    - name: touch a file   # 通过file模块创建文件

      file:

        path: /tmp/service.txt

        state: touch

# 执行playbook,第1个任务就会失败

[root@control ansible]# ansible-playbook myerr.yml

# node1上查看,因为第2个任务没有执行,所以文件不会创建

[root@node1 ~]# ls /tmp/service.txt

ls: cannot access '/tmp/service.txt': No such file or directory

  • 可以指定某一个任务如果出现错误,则忽略它

# 编辑myerr.yml,如果myslqd服务无法启动,则忽略它

[root@control ansible]# vim myerr.yml

---

- name: my errors

  hosts: test

  tasks:

    - name: start mysqld service

      service:

        name: mysqld

        state: started

        enabled: yes

      ignore_errors: yes    # 即使这个任务失败了,也要继续执行下去

    - name: touch a file

      file:

        path: /tmp/service.txt

        state: touch

[root@control ansible]# ansible-playbook myerr.yml

[root@node1 ~]# ls /tmp/service.txt   # 2个任务已执行

/tmp/service.txt

  • 通过全局设置,无论哪个任务出现问题,都要忽略

[root@control ansible]# vim myerr.yml

---

- name: my errors

  hosts: test

  ignore_errors: yes

  tasks:

    - name: start mysqld service

      service:

        name: mysqld

        state: started

        enabled: yes

    - name: touch a file

      file:

        path: /tmp/mysql.txt

        state: touch

[root@control ansible]# ansible-playbook myerr.yml

[root@node1 ~]# ls /tmp/mysql.txt

/tmp/mysql.txt

触发执行任务

  • 通过handlers定义触发执行的任务
  • handlers中定义的任务,不是一定会执行的
  • 在tasks中定义的任务,通过notify关键通知handlers中的哪个任务要执行
  • 只有tasks中的任务状态是changed才会进行通知。

# 下载node1上的/etc/httpd/conf/httpd.conf

[root@control ansible]# vim get_conf.yml

---

- name: download httpd.conf

  hosts: test

  tasks:

    - name: get httpd.conf

      fetch:

        src: /etc/httpd/conf/httpd.conf

        dest: ./

        flat: yes    # 直接下载文件,不要目录

[root@control ansible]# ansible-playbook get_conf.yml

# 修改httpd.conf的端口为变量

[root@control ansible]# vim +45 httpd.conf

... ...

Listen {{http_port}}

... ...

# 修改httpd服务的端口为8000,重启httpd

[root@control ansible]# vim trigger.yml

---

- name: configure httpd

  hosts: test

  vars:

    http_port: "8000"   # 定义httpd.conf中的变量和值

  tasks:

    - name: upload httpd.conf   # 上传httpd.conf

      template:

        src: ./httpd.conf

        dest: /etc/httpd/conf/httpd.conf

    - name: restart httpd    # 重启服务

      service:

        name: httpd

        state: restarted

# 第一次执行trigger.yml,上传文件和重启服务两个任务的状态都是黄色changed

[root@control ansible]# ansible-playbook trigger.yml

# 第二次执行trigger.yml,上传文件的任务状态是绿色的ok,重启服务任务的状态是黄色changed

[root@control ansible]# ansible-playbook trigger.yml

# 既然配置文件没有改变,那么服务就不应该重启

# 修改Playbook,只有配置文件变化了,才重启服务

[root@control ansible]# vim trigger.yml

---

- name: configure httpd

  hosts: test

  vars:

    http_port: "80"

  tasks:

    - name: upload httpd.conf

      template:

        src: ./httpd.conf

        dest: /etc/httpd/conf/httpd.conf

      notify: restart httpd   # 通知restart httpd需要执行

  handlers:

    - name: restart httpd

      service:

        name: httpd

        state: restarted

# 第一次运行Playbook,因为第1个任务是黄色的changed,所以handlers中的任务也被触发执行

[root@control ansible]# ansible-playbook trigger.yml

# 第二次运行Playbook,因为第1个任务是绿色的OK,也就不会再触发执行其他任务了

[root@control ansible]# ansible-playbook trigger.yml

when条件

  • 只有满足某一条件时,才执行任务
  • 常用的操作符:
    • ==:相等
    • !=:不等
    • >:大于
    • <:小于
    • <=:小于等于
    • >=:大于等于
  • 多个条件或以使用and或or进行连接
  • when表达式中的变量,可以不使用{{}}

# test组中的主机内存大于2G的时候,才安装mariadb-server

[root@control ansible]# vim when1.yml

---

- name: install mariadb

  hosts: test

  tasks:

    - name: install mariadb pkg

      yum:

        name: mariadb-server

        state: present

      when: ansible_memtotal_mb>2048

# 如果目标主机没有2GB内存,则不会安装mariadb-server

[root@control ansible]# ansible-playbook when1.yml

# 多条件。系统发行版是RedHat8才执行任务

# /etc/motd中的内容,将会在用户登陆时显示在屏幕上

[root@control ansible]# vim motd

 _____________

< hello world >

 -------------

        \   ^__^

         \  (oo)\_______

            (__)\       )\/\

                ||----w |

                ||     ||

[root@control ansible]# vim when2.yml

---

- name: when condition

  hosts: test

  tasks:

    - name: modify /etc/motd

      copy:

        dest: /etc/motd

        src: motd

      when: >     # 以下三行合并成一行

        ansible_distribution == "RedHat"

        and

        ansible_distribution_major_version == "8"

[root@control ansible]# ansible-playbook when2.yml

cowsay:

[root@node1 ~]# yum install -y cowsay-3.04-4.el7.noarch.rpm

[root@node1 ~]# cowsay hello world    # 默认是奶牛形象

[root@node1 ~]# cowsay -l   # 查看可用形象

[root@node1 ~]# cowsay -f sheep hello world

[root@node1 ~]# cowsay -l > ss.txt

[root@node1 ~]# vim ss.txt    # 删除第1行的说明

[root@node1 ~]# for i in $(cat ss.txt)

> do

> echo "--------------$i----------------"

> cowsay -f $i hello

> sleep 3

> echo "--------------------------------"

> done

任务块

可以通过block关键字,将多个任务组合到一起

可以将整个block任务组,一起控制是否要执行‘

例:如果test组中的主机系统发行版是RedHat,则安装并启动httpd

---

- name: block tasks

  hosts: test

  tasks:

    - name: define a group of tasks

      block:

        - name: install httpd   # 通过yum安装httpd

          yum:

            name: httpd

            state: present

        - name: start httpd     # 通过service启动httpd服务

          service:

            name: httpd

            state: started

            enabled: yes

      when: ansible_distribution=="RedHat"   # 条件为真才会执行上面的任务

rescue和always

block和rescue,always联合使用

  block中的任务出现失败(failed),rescue中的任务执行

  block中的任务都成功,rescue中的任务不执行

  block中的任务不管怎样,always中的任务忠实执行

---

- name: block test

  hosts: test

  tasks:

    - name: block / rescue / always test1

      block:

        - name: touch a file

          file:

            path: /tmp/test1.txt

            state: touch

      rescue:

        - name: touch file test2.txt

          file:

            path: /tmp/test2.txt

            state: touch

      always:

        - name: touch file test3.txt

          file:

            path: /tmp/test3.txt

            state: touch

执行后将会出现/tmp/test1.txt和/tmp/test3.txt

loop循环

相当于shell里的for循环

ansible中循环用到的变量名是固定的,叫item

例:在test组中的主机上创建5个目录/tmp/{aaa,bbb,ccc,ddd,eee}

---

- name: use loop

  hosts: test

  tasks:

    - name: create directory

      file:

        path: /tmp/{{item}}

        state: directory

      loop: [aaa,bbb,ccc,ddd,eee]

也可以改进为:

---

- name: use loop

  hosts: test

  tasks:

    - name: create directory

      file:

        path: /tmp/{{item}}

        state: directory

      loop:

        - aaa

        - bbb

        - ccc

        - ddd

        - eee

例:使用复杂变量。创建zhangsan用户,密码是123;创建lisi用户,密码是456

 item是固定的,用于表示循环中的变量

循环时,loop中每个-后面的内容作为一个整体赋值给item。

loop中{}中的内容是自己定义的,写法为key:val

取值时使用句点表示。如下例中取出用户名就是{{item.uname}}

---

- name: create users

  hosts: test

  tasks:

    - name: create multiple users

      user:

        name: "{{item.uname}}"

        password: "{{item.upass|password_hash('sha512')}}"

      loop:

        - {"uname": "zhangsan", "upass": "123"}

        - {"uname": "lisi", "upass": "456"}

role角色

  • 为了实现playbook重用,可以使用role角色
  • 角色role相当于把任务打散,放到不同的目录中
  • 再把一些固定的值,如用户名、软件包、服务等,用变量来表示
  • role角色定义好之后,可以在其他playbook中直接调用
# 使用常规playbook,修改/etc/motd的内容
# 1. 修改默认配置
[root@control ansible]# vim ansible.cfg 
[defaults]
inventory = hosts
 
# 2. 创建motd模板文件
[root@control ansible]# vim motd.j2
Hostname: {{ansible_hostname}}     # facts变量,主机名
Date: {{ansible_date_time.date}}   #  facts变量,日期
Contact to: {{admin}}              # 自定义变量
 
# 3. 编写playbook
[root@control ansible]# vim motd.yml
---
- name: modifty /etc/motd
  hosts: test
  vars:
    admin: root@tedu.cn            # 自定义名为admin的变量
  tasks:
    - name: modify motd
      template:
        src: motd.j2
        dest: /etc/motd
 
[root@control ansible]# ansible-playbook motd.yml
[root@node1 ~]# cat /etc/motd 
Hostname: node1
Date: 2021-11-01
Contact to: root@tedu.cn
 
 
# 创建角色
# 1. 声明角色存放的位置
[root@control ansible]# vim ansible.cfg 
[defaults]
inventory = hosts
roles_path = roles    # 定义角色存在当前目录的roles子目录中
 
# 2. 创建角色目录
[root@control ansible]# mkdir roles
 
# 3. 创建名为motd的角色
[root@control ansible]# ansible-galaxy init roles/motd
[root@control ansible]# ls roles/
motd     # 生成了motd角色目录
[root@control ansible]# yum install -y tree
[root@control ansible]# tree roles/motd/
roles/motd/
├── defaults         # 定义变量的目录,一般不用,因为优先级太低
│    └── main.yml
├── files            # 保存上传的文件(如copy模块用到的文件)
├── handlers         # handlers任务写到这个目录的main.yml
│    └── main.yml
├── meta             # 保存说明数据,如角色作者、版本等
│    └── main.yml
├── README.md        # 保存角色如何使用之类的说明
├── tasks            # 保存任务
│    └── main.yml
├── templates        # 保存template模块上传的模板文件
├── tests            # 保存测试用的playbook。可选
│    ├── inventory
│    └── test.yml
└── vars             # 定义变量的位置,推荐使用的位置
     └── main.yml
 
# 4. 将不同的内容分别写到对应目录的main.yml
# 4.1 创建motd.j2模板文件
[root@control ansible]# vim roles/motd/templates/motd.j2
Hostname: {{ansible_hostname}}
Date: {{ansible_date_time.date}}
Contact to: {{admin}}
 
# 4.2 创建变量
[root@control ansible]# vim roles/motd/vars/main.yml  # 追加一行
admin: zzg@tedu.cn
 
# 4.3 创建任务
[root@control ansible]# vim roles/motd/tasks/main.yml  # 追加
- name: modify motd
  template:
    src: motd.j2      # 这里的文件,自动到templates目录下查找
    dest: /etc/motd
 
# 5. 创建playbook,调用motd角色
[root@control ansible]# vim role_motd.yml
---
- name: modify motd with role
  hosts: test
  roles:
    - motd
 
# 6. 执行playbook
[root@control ansible]# ansible-playbook role_motd.yml 
# 在公共仓库中搜索与httpd相关的角色
[root@zzgrhel8 ~]# ansible-galaxy search httpd
# 如果找到相应的角色,如名字为myhttpd,可以下载它到roles目录
[root@zzgrhel8 ~]# ansible-galaxy install myhttpd -p roles/

role练习

  1. 创建名为pkgs的角色。用于装包。包名使用变量pkg代表
  2. 创建inst_http.yml,调用pkgs角色,安装httpd
  3. 创建inst_php.yml,调用pkgs角色,安装php
# 1. 创建名为pkgs的角色。
# 1.1 创建角色目录
[root@control ansible]# ansible-galaxy init roles/pkgs
# 1.2 创建装包的任务,包名使用变量pkg代表
[root@control ansible]# vim roles/pkgs/tasks/main.yml 
---
# tasks file for roles/pkgs
- name: install rpm pkg
  yum:
    name: "{{pkg}}"
    state: present
# 1.3 定义变量
[root@control ansible]# vim roles/pkgs/defaults/main.yml 
---
# defaults file for roles/pkgs
pkg: httpd
 
# 2. 创建inst_http.yml,调用pkgs角色,安装httpd
[root@control ansible]# vim inst_httpd.yml
---
- name: install httpd pkg
  hosts: test
  roles:
    - pkgs
[root@control ansible]# ansible-playbook inst_httpd.yml
 
# 3. 创建inst_php.yml,调用pkgs角色,安装php
[root@control ansible]# vim inst_php.yml 
---
- name: install php pkg
  hosts: node2
  vars:
    pkg: php
  roles:
    - pkgs
[root@control ansible]# ansible-playbook inst_php.yml

ansible加解密文件

  • ansible加解密文件使用ansible-vault命令
[root@control ansible]# echo "Hi ni hao" > hello.txt 
[root@control ansible]# cat hello.txt
Hi ni hao
 
# 加密文件
[root@control ansible]# ansible-vault encrypt hello.txt
New Vault password: 123456
Confirm New Vault password: 123456
Encryption successful
[root@control ansible]# cat hello.txt
$ANSIBLE_VAULT;1.1;AES256
37373366353566346235613731396566646533393361386131313632306563633336333963373465
6164323461356130303863633964393339363738653036310a666564313832316263393061616330
32373133323162353864316435366439386266616661373936363563373634356365326637336165
6336636230366564650a383239636230623633356565623461326431393634656666306330663533
6235
 
# 解密
[root@control ansible]# ansible-vault decrypt hello.txt
Vault password: 123456
Decryption successful
[root@control ansible]# cat hello.txt 
Hi ni hao
 
 
# 加密后更改密码
[root@control ansible]# ansible-vault encrypt hello.txt 
New Vault password: 123456
Confirm New Vault password: 123456
Encryption successful
 
[root@control ansible]# ansible-vault rekey hello.txt   # 改密码
Vault password: 123456    # 旧密码
New Vault password: abcd  # 新密码
Confirm New Vault password: abcd
Rekey successful
 
# 不解密文件,查看内容
[root@control ansible]# ansible-vault view hello.txt 
Vault password: abcd
Hi ni hao
 
 
# 使用密码文件进行加解密
# 1. 将密码写入文件
[root@control ansible]# echo 'tedu.cn' > pass.txt
# 2. 创建明文文件
[root@control ansible]# echo 'hello world' > data.txt
# 3. 使用pass.txt中的内容作为密码加密文件
[root@control ansible]# ansible-vault encrypt --vault-id=pass.txt data.txt
Encryption successful
[root@control ansible]# cat data.txt    # 文件已加密
# 4. 使用pass.txt中的内容作为密码解密文件
[root@control ansible]# ansible-vault decrypt --vault-id=pass.txt data.txt
Decryption successful
[root@control ansible]# cat data.txt 
hello world

sudo命令

  • 一般用于普通用户执行需要root权限的命令
  • 在node1上配置zhangsan拥有sudo权限
# 如果没有zhangsan,手工创建
[root@node1 ~]# visudo   # 将会打开vi,在尾部追加以下一行
zhangsan        ALL=(ALL)       ALL
# 中间的ALL=(ALL)在集中认证的域环境中才有效,单机忽略即可
# zhangsan是用户名,最后的ALL表示zhangsan可以以管理员的身份执行所有命令
 
# 切换成zhangsan用户,执行命令
[root@node1 ~]# su - zhangsan
[zhangsan@node1 ~]$ useradd wangwu   # 失败,因为还是张三身份
[zhangsan@node1 ~]$ sudo useradd wangwu  # 以管理员身份执行
... ...
[sudo] password for zhangsan: # 输入zhangsan的密码,不是root
 
 
# 配置lisi不输入密码可以直接运行sudo
[root@node1 ~]# visudo    # 在最后追加一行
lisi    ALL=(ALL)       NOPASSWD: ALL
 
# 切换成lisi运行
[root@node1 ~]# su - lisi
[lisi@node1 ~]$ ls /root/   # 没权限
ls: cannot open directory '/root/': Permission denied
[lisi@node1 ~]$ sudo ls /root/    # 成功运行,无需输入密码
a3.txt       anaconda-ks.cfg

特殊的主机清单变量

  • 如果远程主机没有使用免密登陆,如果远程主机ssh不是标准的22端口,可以设置特殊的主机清单变量
  • ansible_ssh_user:指定登陆远程主机的用户名
  • ansible_ssh_pass:指定登陆远程主机的密码
  • ansible_ssh_port:指定登陆远程主机的端口号
# 删除远程主机的/root/.ssh/authorized_keys,以便恢复通过密码登陆
[root@control ansible]# ansible all -m file -a "path=/root/.ssh/authorized_keys state=absent"
 
# 创建新的工作目录
[root@control ~]# mkdir myansible
[root@control ~]# cd myansible
[root@control myansible]# vim ansible.cfg
[defaults]
inventory = hosts
[root@control myansible]# vim hosts
[group1]
node1
node2
node3
[root@control myansible]# ansible all -m ping  # 报错,因为无法免密执行
 
# 修改node1 ssh服务的端口为220
[root@node1 ~]# systemctl stop firewalld
[root@node1 ~]# vim +17 /etc/ssh/sshd_config 
Port 220
[root@node1 ~]# systemctl restart sshd
# 退出再登陆时,需要指定端口号
[root@zzgrhel8 ~]# ssh -p220 192.168.4.11 
 
 
 
# 配置ssh通过用户名、密码管理远程主机,通过220端口连接node1
[root@control myansible]# vim hosts 
[group1]
node1 ansible_ssh_user=root ansible_ssh_pass=a ansible_ssh_port=220
node2 ansible_ssh_user=root ansible_ssh_pass=a
node3 ansible_ssh_user=root ansible_ssh_pass=a
 
[root@control myansible]# ansible all -m ping

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值