Ansible的使用

一、安装与入门

1、安装

#官方文档
https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.ht
ml

#使用epel源 (Centos7)

yum install -y epel-release

yum install -y ansible

yum info ansible   

ansible --version

---版本

2、Ansible 相关文件 

 /etc/ansible/ansible.cfg 

---主配置文件

/etc/ansible/hosts
--- 主机清单
/etc/ansible/roles/
--- 存放角色的目录
/var/log/ansible.log
---日志

 3、inventory 主机清单文件

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

---官方文档

 

#ansible 相关工具大多数是通过ssh协议,最好先配置密钥实现主机之间免密互通

ssh-keygen

4、Ansible相关工具 

/usr/bin/ansible
--- 主程序,临时命令执行工具
/usr/bin/ansible-doc
--- 查看配置文档,模块功能查看工具 , 相当于 man
/usr/bin/ansible-playbook
--- 定制自动化任务,编排剧本工具 , 相当于脚本
/usr/bin/ansible-pull
--- 远程执行命令的工具
/usr/bin/ansible-vault
--- 文件加密工具
/usr/bin/ansible-console
--- 基于 Console 界面与用户交互的执行工具
/usr/bin/ansible-galaxy
--- 下载 / 上传优秀代码或 Roles 模块的官网平台

1、ansible-doc 帮助文档

ansible-doc 

-l, --list               
---列出可用模块

-s, --snippet       
---显示指定模块的playbook片段
ansible-doc --help
#例子:
#列出所有模块
ansible-doc -l  

#查看指定模块帮助用法
ansible-doc ping  

#查看指定模块帮助用法
ansible-doc -s  ping
#大多时候看不到就是了。。。

5、入门

1、命令格式 ansible-

--version                                    #显示版本


-m module                                 #指定模块,默认为command


-v                                               #详细过程 -vv -vvv更详细


--list-hosts                                  #显示主机列表,可简写 --list


-C, --check                                 #检查,并不执行


-T, --timeout=TIMEOUT             #执行命令的超时时间,默认10s


-k, --ask-pass                             #提示输入ssh连接密码,默认Key验证 


-u, --user=REMOTE_USER       #执行远程执行的用户,默认root


-b, --become                               #代替旧版的sudo 切换


--become-user=USERNAME     #指定sudo的runas用户,默认为root


-K, --ask-become-pass               #提示输入sudo时的口令


-f FORKS, --forks FORKS          #指定并发同时执行ansible任务的主机数

绿色:执行成功并且不需要做改变的操作

黄色:执行成功并且对目标主机做变更
红色:执行失败

2、范例 

#以peng用户执行ping存活检测
ansible all -m ping -u peng  -k


#以peng sudo至root执行ping存活检测
ansible all -m ping -u peng -k -b


#以peng sudo至xiao用户执行ping存活检测
ansible all -m ping -u peng -k -b --become-user=xaio


#以peng sudo至root用户执行ls 
ansible all -m command  -u peng -a 'ls /root' -b --become-user=root -k -K 

二、ansible-playbook (剧本)

#范例:

ansible-playbook hello.yml

cat hello.yml
---
#hello world yml file
- hosts: websrvs
  remote_user: root
  gather_facts: no
  
  tasks:
    - name: hello world
      command: /usr/bin/wall hello world

 1、常用模块

模块简介 — Ansible 社区文档 

Command 模块
功能:在远程主机执行命令,此为默认模块,可忽略 -m 选项
Shell 模块
功能:和 command 相似,用 shell 执行命令 , 支持各种符号 , 比如 :*,$, >
Script 模块
功能:在远程主机上运行 ansible 服务器上的脚本 ( 无需执行权限 )
Copy 模块
功能:从 ansible 服务器主控端复制文件到远程主机
Get_url 模块
功能 : 用于将文件从 http https ftp 下载到被管理机节点上
File 模块
功能:设置文件属性 , 创建软链接等
stat 模块
功能:检查文件或文件系统的状态
Hostname 模块
功能:管理主机名
Cron 模块
功能:计划任务
支持时间: minute hour day month weekday
Yum Apt 模块
功能:
yum 管理软件包,只支持 RHEL CentOS fedora ,不支持 Ubuntu 其它版本
apt 模块管理 Debian 相关版本的软件包
Service 模块
功能:管理服务
User 模块
功能:管理用户
。。。。。。。。。。。。。。。。。。。

2、YAML 语言

YAML 支持以下常用几种数据类型:
标量:单个的、不可再分的值
对象:键值对的集合,又称为映射( mapping / 哈希( hashes / 字典( dictionary
数组:一组按次序排列的值,又称为序列( sequence / 列表( list

3、Playbook 核心组件

 Hosts   :执行的远程主机列表

Tasks     : 任务集 , 由多个 task 的元素组成的列表实现 , 每个 task 是一个字典 , 一个完整的代码块功能需最 少元素需包括 name 和 task, 一个 name 只能包括一个 task
Variables    : 内置变量或自定义变量在 playbook 中调用
Templates      : 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers notify         : 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags         :  标签 指定某条任务执行,用于选择运行 playbook 中的部分代码。

1、remote_user 组件

remote_user: 可用于 Host task 中。也可以通过指定其通过 sudo 的方式在远程主机上执行任务,其可 用于play 全局或某任务;此外,甚至可以在 sudo 时使用 sudo_user 指定 sudo 时切换的用户
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: test connection
      ping:
      remote_user: magedu
      sudo: yes                   #默认sudo为root
      sudo_user:peng              #sudo为peng

 

4、playbook 命令

ansible-playbook --
--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 #显示过程

5、入门

1、利用 playbook 创建 mysql 用户

例子:   
vim  mysql_user.yml
---
- 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 #创建用户
  • 创建一个名为 mysql 的系统用户;

  • shell: /sbin/nologin 表示禁止该用户登录系统;

  • system: yes 表示这是一个系统用户(UID 小于 1000);

  • group: mysql:该用户属于之前创建的 mysql 用户组;

  • uid: 306:指定用户 ID 为 306;

  • home: /data/mysql:设置用户的 home 目录为 /data/mysql

  • create_home: no:不自动创建 /data/mysql 这个目录(只设定 home 目录路径而不创建它)。

2、playbook 安装 nginx 

vim install_nginx.yml

---
# 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
  • 创建一个名为 nginx 的用户组;

  • state=present 表示如果没有就创建,有就跳过(幂等性)。

  • 创建一个用户名为 nginx 的用户;

  • 加入上面创建的 nginx 用户组;

  • 同样 state=present 保证重复执行时不报错。

  • 使用 yum 包管理器安装 Nginx;

  • state=present 表示只要没安装就装,有了就跳过。

  • 将你控制端的 files/index.html 文件复制到远程主机的 /usr/share/nginx/html/index.html(即默认的网站根目录);

  • 注意:你必须在 playbook 同目录下准备好 files/index.html 文件,否则会报错。

  • 启动 nginx 服务;

  • enabled=yes 表示设置为开机自启动。

3、使用handlersnotify

handlers 是在所有前面的 tasks 都成功执行才会执行 , 如果前面任何一个 task 失败 , 会导致 handler 跳 过执行, 可以使用 force_handlers: yes 强制执行 handler
notify 对应的 task 发生改变了才会通知 handlers , 没有改变则不会触发 handlers

例子: 

---
- 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"

#      - name: Install configure file

  • 把你本地 files/httpd.conf 文件复制到远程的 /etc/httpd/conf/ 目录;

  • 如果该文件发生变更(内容不同),则触发下面定义的两个 handlers:

    • restart httpd:重启 Apache 服务;

    • wall:用 wall 命令给所有登录用户发一条消息。

 4、使用tags组件

利用 tags 组件,为特定 task 指定标签,当在执行 playbook 时,可以只执行特 定tags task, 而非整个 playbook 文件
###说白了就是打标签,运行时通过标签指定执行的任务
vim httpd.yml
---
# 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 ] 

    - name: start httpd service
      tags: service
      service: name=httpd state=started enabled=yes
  
[root@ansible ~]#ansible-playbook --list-tags httpd.yml
[root@ansible ~]#ansible-playbook -t conf,service httpd.yml
[root@ansible ~]#ansible-playbook --skip-tags conf httpd.yml
[root@ansible ~]#ansible-playbook   httpd.yml --skip-tags untagged

6、使用变量

变量名:仅能由字母、数字和下划线组成,且只能以字母开头
variable=value
variable: value
变量调用方式:
通过 {{ variable_name }} 调用变量,且变量名前后建议加空格,有时用 "{{ variable_name }}" 才生效

 1、命令行中定义变量
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.yml
pkname1: memcached
pkname2: vsftpd 

[root@ansible ~]#vim var2.yml
---
- hosts: websrvs
  remote_user: root
  gather_facts: no

  vars_files:
    - vars.yml

  tasks:
    - name: install package {{ pkname1 }}
      yum:
        name: "{{ pkname1 }}"
        state: present

    - name: install package {{ pkname2 }}
      yum:
        name: "{{ pkname2 }}"
        state: present

2、文件中定义变量
[root@ansible ~]#vim var3.yml
---
- hosts: websrvs
  remote_user: root
  gather_facts: no

  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

三、template 模板

1、jinja2语言

官方文档欢迎来到 Jinja2 — Jinja2 2.7 documentation

2、template

template 功能:可以根据和参考模块文件,动态生成相类似的配置文件
template 文件必须存放于 templates 目录下,且命名为 .j2 结尾
yaml/yml 文件需和 templates 目录平级,目录结构如下示例:
./
├── temnginx.yml
└── templates
        └── nginx.conf.j2

例子:利用template 同步nginx配置文件

####必须有一个名为 nginx.conf.j2 的模板文件,和 temnginx.yml 在同一个目录(或 templates/ 目录)

[root@ansible ~]#vim nginx.conf.j2

user  nginx;
worker_processes {{ worker_processes }};

events {
    worker_connections 1024;
}

http {
    server {
        listen {{ http_port }};
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
        }
    }
}


[root@ansible ~]#vim temnginx.yml
---
- hosts: websrvs
  remote_user: root
  gather_facts: no
  vars:
    http_port: 80
    worker_processes: 1

  tasks:
    - name: template config to remote hosts
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf


 [root@ansible ~]#ansible-playbook temnginx.yml

3、使用流程控制 for if

1、for 循环

templnginx2.yml

---
- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
      - 81
      - 82
      - 83
  tasks:
    - name: template config
      template:
        src: nginx.conf2.j2
        dest: /data/nginx.conf

templates/nginx.conf2.j2

{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost }}
}
{% endfor %}

ansible-playbook -C templnginx2.yml --limit 10.0.0.8

解释:

  • -C:表示 “check mode” 检查模式(Dry run),不真正执行任务,仅模拟。

  • --limit 10.0.0.8:只在主机为 10.0.0.8 的目标主机上执行 Playbook。

2、if 条件判断

templnginx.yml

- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
      - listen: 8080
        root: "/var/www/nginx/web1/"
      - listen: 8080
        server_name: "web2.magedu.com"
        root: "/var/www/nginx/web2/"
      - listen: 8080
        server_name: "web3.magedu.com"
        root: "/var/www/nginx/web3/"
  tasks:
    - name: template config to 
      template: src=nginx.conf.j2 dest=/data/nginx5.conf

templates/nginx.conf.j2

{% for vhost in nginx_vhosts %}
server {
    listen {{ vhost.listen }};
    {% if vhost.server_name is defined %}
    server_name {{ vhost.server_name }};
    {% endif %}
    root {{ vhost.root }};
}
{% endfor %}

ansible-playbook templnginx.yml
 

server {
    listen 8080;
    root /var/www/nginx/web1/;
}
server {
    listen 8080;
    server_name web2.magedu.com;
    root /var/www/nginx/web2/;
}
server {
    listen 8080;
    server_name web3.magedu.com;
    root /var/www/nginx/web3/;
}

4、使用 when

when 语句可以实现条件测试。如果需要根据变量、 facts 或此前任务的执行结果来做为某 task 执行与否 的前提时要用到条件测试, 通过在 task 后添加 when 子句即可使用条件测试, jinja2 的语法格式

例子:

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: "shutdown RedHat flavored systems"
      command: /sbin/shutdown -h now
      when: ansible_os_family == "RedHat"
  • websrvs 主机组的服务器上;

  • 判断操作系统是否属于 RedHat 系列(如 RHEL、CentOS、Rocky Linux、AlmaLinux 等);

  • 如果是,就执行关机命令 /sbin/shutdown -h now

5、分组 block

执行多个任务时,就需要分组了。而不再每个任务都是用when

---
- hosts: localhost

  tasks:
    - block:
        - debug: msg="first"
        - debug: msg="second"
      when:
        - ansible_facts['distribution'] == "CentOS"
        - ansible_facts['distribution_major_version'] == "8"

####相当于下面写法
---
- hosts: localhost

  tasks:
    - debug: msg="first"
      when:
        - ansible_facts['distribution'] == "CentOS"
        - ansible_facts['distribution_major_version'] == "8"
    - debug: msg="second"
      when:
        - ansible_facts['distribution'] == "CentOS"
        - ansible_facts['distribution_major_version'] == "8"
  • 这里用 block 把多个任务组合成一个块;

  • 这个 block 统一加了 when 条件,表示只有在条件满足时,才执行块内所有任务

  • 也就是说,这个条件对 firstsecond 两个 debug 任务是共用的。

四、roles 角色

roles 就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地
include 它们的一种机制。角色一般用于基于主机构建服务的场景中

1、Role 目录结构

myrole/
├── tasks/
│   └── main.yml       # 主要任务入口
├── handlers/
│   └── main.yml       # 事件触发处理器(如服务重启)
├── templates/         # Jinja2 模板文件
├── files/             # 静态文件
├── vars/
│   └── main.yml       # 变量定义
├── defaults/
│   └── main.yml       # 默认变量(优先级最低)
├── meta/
│   └── main.yml       # 角色元数据(依赖信息)

files/ :存放由 copy script 模块等调用的文件
templates/ template 模块查找所需要模板文件的目录
tasks/ :定义 task,role 的基本元素,至少应该包含一个名为 main.yml 的文件;其它的文件需要在此
文件中通过 include 进行包含
handlers/ :至少应该包含一个名为 main.yml 的文件;此目录下的其它的文件需要在此文件中通过
include 进行包含
vars/ :定义变量,至少应该包含一个名为 main.yml 的文件;此目录下的其它的变量文件需要在此
文件中通过 include 进行包含
meta/ :定义当前角色的特殊设定及其依赖关系 , 至少应该包含一个名为 main.yml 的文件,其它文
件需在此文件中通过 include 进行包含
default/ :设定默认变量时使用此目录中的 main.yml 文件,比 vars 的优先级低

2、Role 的使用流程

roles/ 目录中创建一个角色,比如 nginx

ansible-galaxy init nginx

编辑角色内各目录下的文件,比如 tasks/main.yml 写安装 nginx 的任务。

在 Playbook 里调用角色

---
- hosts: webservers
  roles:
    - nginx

3、常见 Role 示例

nginx 角色示例

目录结构示意

roles/nginx/
├── defaults/
│   └── main.yml
├── handlers/
│   └── main.yml
├── tasks/
│   └── main.yml
├── templates/
│   └── nginx.conf.j2
 

defaults/main.yml

---
nginx_port: 80
nginx_user: nginx
nginx_worker_processes: auto
nginx_error_log: /var/log/nginx/error.log
nginx_access_log: /var/log/nginx/access.log

handlers/main.yml

---
- name: restart nginx
  service:
    name: nginx
    state: restarted

tasks/main.yml   核心任务      

---
- name: 安装 EPEL 源(提供 nginx 包)
  yum:
    name: epel-release
    state: present

- name: 安装 nginx
  yum:
    name: nginx
    state: present

- name: 上传 nginx 配置文件
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: restart nginx

- name: 启动并设置 nginx 开机启动
  service:
    name: nginx
    state: started
    enabled: yes

templates/nginx.conf.j2(Nginx 配置模板)

user {{ nginx_user }};
worker_processes {{ nginx_worker_processes }};

error_log {{ nginx_error_log }};
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  {{ nginx_access_log }}  main;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       {{ nginx_port }};
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

创建一个 site.yml 来调用此角色:

---
- hosts: webservers
  become: yes
  roles:
    - nginx

执行ansible-playbook -i inventory site.yml

最终目录

.
├── site.yml
└── roles/
    └── nginx/
        ├── defaults/
        ├── handlers/
        ├── tasks/
        └── templates/
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值