zoukankan      html  css  js  c++  java
  • ansible简介及基本操作

    ansible 自动化运维工具

    ansible的软件可以去登录ansible官网去下载;也可以去epel源去下载。

    命令 ansible saltstack
    文件 ansible puppet func

    运维工具的分类: 是否具有客户端代理

    agent: puppet, func 带有客户端代理
    agentless: ansible, fabric, saltstack 无客户端代理
    ssh

    运维工作:系统安装(物理机、虚拟机)--> 程序包安装、配置、服务启动 --> 批量操作 --> 程序发布(svn,git) --> 监控

    ansible:
    模块化,调用特定的模块,完成特定的任务;
    基于Python语言实现,由Paramiko、PyYAML和Jinja2三个关键模块;
    部署简单,agentless;只需要布置服务器端;客户端必须预装ssh和python
    主从模式
    支持自定义模块
    支持Playbook: 以文件形式自动化管理
    幂等性:多次执行同一个操作,结果都是一致的

    特点: 高度模块化、无客户端代理、支持playbook、幂等性

    工作原理: 管理端靠paramiko模块连接,发送功能模块,在被管理端运行功能模块;运行后模块会自动删除

    playbook的核心元素:
    tasks: 任务,即调用模块完成的某操作
    variables: 变量 -------yaml语言中变量需要事先定义
    templates: 模板
    handlers: 触发器,由某时间触发执行的操作
    roles: 角色

    一、ansible如何以命令形式管理:

    1)、准备工作

    时间同步、实验环境->双机互信(真实只需将管理端公钥拷贝给被管理端)----->>可以靠expect编写脚本--->实现秘钥自动分发
    ----->>pxe装机可以实现安装后脚本-->wget 下载公钥

    客户端还需:Python环境

    2)、使用格式:

    #man ansible
    ansible <host-pattern> [options]

    -m: 指定调用哪些模块
    -a: 向模块传递的参数

    3)、配置文件解读:

    #vim /etc/ansible/ansible.cfg
    [defaults]
    inventory = /etc/ansible/hosts 指定主机清单文件
    roles_path = /etc/ansible/roles 指定角色的根目录
    timeout = 10 连接超时
    remote_user = root 默认连接远程的用户

    [inventory] 设定动态清单文件

    [privilege_escalation] 定义切换用户身份(执行模块的身份)
    #become=True
    #become_method=sudo
    #become_user=root
    #become_ask_pass=False

    [paramiko_connection] 定义远程连接

    [colors] 定义显示的颜色

    4)、定义主机清单文件:

    #vim /etc/ansible/hosts
    192.168.0.248 单独定义一个主机

    [node1] 定义第一个主机组,名称为node1,成员为247
    192.168.0.247

    [node2]
    192.168.0.248

    [allnodes]
    192.168.0.247
    192.168.0.248

    查看主机组:

    #ansible 主机组名(host-pattern) --list-hosts

    查看ansible都安装哪些模块:

    #ansible-doc -l

    获取模块参数帮助文档:

    #ansible-doc 模块名

    ansible命令管理:

    #ansible 主机组名 -m 模块名 -a '向模块传递的参数'

    常用模块:

    ping(验证连通性) cron (时间同步) command shell(执行命令) user、group(用户与组管理)

    copy (拷贝) lineinfile(主文件内容管理) file(文件权限管理) archive unarchive (归档与展开归档)

    yum(rpm包管理) yum_repository(配置yum源文件) mount(挂载)

    service(服务管理) iptables firewalld (防火墙管理)


    二、ansible中Playbook编写和使用: 了解列表和字典

    playbook: YAML语言(借助了python两种数据结构:列表、字典)

    YAML语言的格式:

    python中:

    列表: 多个有序元素的集合

    (1).定义列表
    列表名(变量名)=['元素1', '元素2','元素3', ...]

    name=['tom', 'jerry','lisi']

    (2).引用列表元素:有序的 *****
    靠列表索引去引用元素: 索引类似数组的下标
    print name[0]
    print name[1]
    ...
    注释:索引从0开始

    (3). 列表的嵌套: *****
    list1=['tom','jerry','lisi']

    list2=['a1','b2',list1,'c3','d4','e5']

    list2第3个元素,其值又是一个列表

    print list2[2]
    ['tom','jerry','lisi']

    print list2[2][1]
    jerry


    字典: 多个键值对的集合
    python中:
    (1).定义字典:
    dict1={'name':'loring', 'age': 40 , 'uid': 99}

    (2).引用字典元素: 是无序的集合 *****
    print dict1['name']
    loring

    (3).字典嵌套:

    dict2={'class': 1 , 'alltype': dict1 , 'score': 80}

    print dict2['alltype']
    {'age': 40, 'name': 'loring', 'uid': 99}

    print dict2['alltype']['uid']
    99

    列表中嵌套字典:
    dict1={'name':'loring', 'age': 40 , 'uid': 99}

    list3=['hello','welcome',dict1,'haha']

    字典嵌套列表:
    dict3={'passwd': 'redhat', 'username': 'root', 'test1': list1 , 'shell': 'bash'}


    YAML语言中:
    列表:
    [tom , jerry , lisi]

    yaml:
    - tom
    - jerry
    - lisi

    [a1, b2, [tom, jerry ,lisi] , c3, d4]

    - a1
    - b2
    - tom
    - jerry
    - lisi
    - c3
    - d4

    字典:
    {name: loring , age:40 , uid:99}


    name: loring
    age: 40
    uid: 99

    {'class': 1 , 'alltype': dict1 , 'score': 80}

    class: 1
    alltype:
    name: loring
    age: 40
    uid: 99
    score: 80

    列表嵌套字典:
    dict1={name: loring , age:40 , uid:99}
    list3=['hello','welcome',dict1,'haha']


    - hello
    - welcome
    - name: loring
    age: 40
    uid: 99
    - haha

    字典嵌套列表:
    list1=['tom', 'jerry', 'lisi']
    dict3={'passwd': 'redhat', 'username': 'root', 'test1': list1 , 'shell': 'bash'}

    passwd: redhat
    username: root
    test1:
    - tom
    - jerry
    - lisi
    shell: bash

    格式:
    playbook编写:

    #vim a.yml (或者使用a.yaml)
    ---
    - hosts: 主机组名 #指定管理的主机组
    remote_user: 用户名 #连接远程主机的用户
    tasks: #任务、指定调用的模块
    - 模块1: 参数名1=值1 参数名2=值2 ...
    - 模块2:
    参数名1:值1
    参数名2:值2
    ...
    ...

    注释:在playbook文件中,最外层列表,每一个元素值,代表了一个play(主机、用户和任务)

    检测:
    运行playbook: ansible-playbook命令

    格式:
    ansible-playbook [options] playbook.yml

    --syntax-check: 语法检测
    -C, --check: dry-run 测试运行,但不会真正执行

    编写多play剧本:对不同主机组操作

    #vim multipaly.yml
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - user:
    name: jerry66
    state: present

    - hosts: allnodes
    remote_user: root
    tasks:
    - user:
    name: jerry77
    state: present
    三、ansible中变量使用:playbook中

    1、变量命名规则:naming variables:the same to the variables in shell
    只能包含字母、数值、下划线、;不能以字母开头;不能使用关键字

    2、定义变量:
    全局:Global scope: Variables set from the command line or Ansible configuration

    在play中:Play scope: Variables set in the play and related structures

    主机:Host scope: Variables set on host groups and individual hosts by the inventory, fact gathering,or registered tasks

    变量优先级判断:1·引用变量先后顺序,后大于前;2·作用范围大小,小的优先级高

    变量优先级:
    主机组变量 < 主机变量 < fact变量 < in-play变量 < register变量 < globle变量

    变量类别:

    1、主机组变量:

    定义: 在主机清单中定义
    #vim /etc/ansible/hosts
    [主机组:vars]
    变量名=变量值

    引用主机组变量: 引用变量用 {{ 变量名 }} ;括号和名之间必须有空格

    ---
    - hosts: allnodes
    remote_user: root
    tasks:
    - debug: #可以打印信息
    msg: "{{ testvar }}"

    注意1:变量引用前面,如果没有其它字符串,变量要加引号

    注意2:如果多个主机组中都去定义变量,变量名尽量不要一样

    2、主机变量: host 在清单文件中定义

    定义:
    #vim /etc/ansible/hosts
    [allnodes]
    192.168.0.247 testvar="from 247"
    192.168.0.248 testvar="from 248"

    3、fact变量: 靠setup模块实现 *****

    setup 模块获取:在连接之后;默认是执行的第一个模块

    只对本次剧本运行有效
    ---
    - hosts: allnodes
    remote_user: root
    gather_facts: false #关闭模拟的fact变量获取
    tasks:
    - debug:
    msg: "{{ ansible_fqdn }}"

    利用setup模块,打印所有fact变量(关于node2主机组的常用变量)
    #ansible node2 -m setup | more

    { "ansible_facts": {键值对(变量)} }

    靠嵌套字典中的键,去引用变量值


    迭代引用变量
    ---
    - hosts: allnodes
    remote_user: root
    gather_facts: false
    tasks:
    - setup:
    - debug:
    msg: "{{ ansible_date_time['date'] }}"

    注意: ansible_date_time['date'] 等同于 ansible_date_time.date
    其中最后的date都代表前ansible_date_time值中的一个叫data的键


    4、 register变量: 变量名自定义;其值来自上某个模块运行的结果

    位置与对应模块对齐

    对register变量运行之后的模块有效
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - yum:
    name: vsftpd
    state: installed
    register: haha

    - debug:
    msg: "{{ haha }}"
    5、in play 变量:

    在playbook的play中用

    vars: vars_files:
    变量: “值” - 文件名
    例1:
    ---
    - hosts: node2
    remote_user: root
    vars:
    testvar1: "hello loring"
    testvar2: "welcmoe tom"
    tasks:
    - debug:
    msg: "{{ testvar1 }} and {{ testvar2 }}"
    例2:
    ---
    - hosts: node2
    remote_user: root
    vars_files:
    - /etc/ansible/playbooks/varfiles.yml
    tasks:
    - debug:
    msg: "{{ testvar1 }} and {{ testvar2 }}"

    6、全局变量: 命令行传递

    playbook中引用变量

    #ansible-playbook var10.yml -e "变量名='变量值'"

    #ansible-playbook var10.yml -e "@/etc/ansible/playbooks/varfiles.yml"
    #ansible-playbook var10.yml -e "@变量所在文件"

    vim /etc/ansible/playbooks/varfiles.yml
    testvar1: "test from file1"
    testvar2: "haha to file2"

    7、交互式输入变量: vars_prompt

    ---
    - hosts: node2
    remote_user: root
    vars_prompt:
    - name: "testvar1"
    prompt: "input a num"
    - name: "testvar2"
    prompt: "input your name"
    tasks:
    - debug:
    msg: "{{ testvar1 }} and {{ testvar2 }}"

    四、ansible中实现控制:

    一)、循环
    1·with_items: 类似for循环
    值为列表循环
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - yum:
    name: "{{ item }}"
    state: installed
    with_items:
    - vsftpd
    - dhcp
    - httpd
    ------------------------
    值为列表嵌套字典循环
    - debug:
    msg: "{{ item.name }} and {{ item['pass'] }}"
    with_items:
    - {name: 'tom' , pass: 'redhat'}
    - {name: 'jerry' , pass: 'fedora'}

    2·with_nested: 类似双重for循环

    ---
    - hosts: node2
    remote_user: root
    tasks:
    - debug:
    msg: "{{ item[0] }} and {{ item[1] }}"
    with_nested:
    - ['tom','jerry']
    - ['redhat','fedora','suse']

    二)、判断: when

    例1:
    #vim when1.yml
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - debug:
    msg: "{{ loringvar }}"
    when: loringvar is defined

    注释:当when给定的条件为真,则会运行所在的模块;如果为假,则不运行; loringvar is difined代表判断loringvar变量是否被定义

    when: 变量1 in 变量2

    注释:当变量1的值被包含在变量2的值中时为真;否则为假

    with_items: "{{ ansible_mounts }}"
    when: item.mount == "/" and item.size_available > 20199577600

    注释:在when中,支持比较运算和逻辑运算

    三)、忽略错误: ignore_errors: (建议忽略与之后程序无关的error)

    可忽略错误继续运行playbook
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - yum:
    name: httpdfs
    state: installed
    ignore_errors: yes
    - debug:
    msg: "the test for ignore_errors"
    四)、标签:tags:

    可将打标签的模块动作 一个或几个标签 单独运行;但不能改变模块在playbook中的运行顺序

    注意: 多个模块,可以共用一个名称的标签;将整个任务分组(过滤)

    #vim tag1.yml
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - name: 安装dhcp服务
    yum:
    name: dhcp
    state: installed
    tags: dhcptag

    - name: 安装httpd服务
    yum:
    name: httpd
    state: installed
    tags: httpdtag

    - name: 安装vsftpd服务
    yum:
    name: vsftpd
    state: installed
    tags: vsftpdtag

    tags应用:
    #ansible-playbook tag1.yml --tags='dhcptag,vsftpdtag'

    五)、handlers: 触发器

    触发器:当满足某个特定条件时自动触发执行哪些操作

    触发器属于某个play;在play中定义触发器(每个play中只能有一个handlers)

    注意:触发器要在所有tasks任务运行结束之后,去运行

    handlers定义:

    一般在playbook中末尾定义handlers ;且handlers与hosts平级

    handlers:
    - name: loringhand #触发器名
    service:
    name: httpd
    state: restarted

    handlers应用 : notify--> 通知

    - name: 下载页面文件
    get_url:
    url: http://192.168.0.247/loringdir/test.html
    dest: /var/www/virtual/index.html
    mode: 0777
    force: yes
    notify: loringhand #通知loringhand触发器
    注释:当该模块运行状态为changed时,回调用触发器

    六)、block: 类似if多分支语句

    - block:
    rescue:
    always:

    一般都tasks的最后编写

    运行顺序:张氏定义([block || rescue] 为真 ;运行-->之后的模块 else 不运行---> 之后的模块 {always常运行} )

    注释:
    先运行block下的模块,一旦运行成功,则不会运行rescue下的模块,但是always下模块会运行,而且整个状态为真

    如果block下模块运行失败,则运行rescue下的模块,always下会运行,整个状态为真

    如果block下模块运行失败,去运行rescue下的模块也失败,也会运行always下模块,但是整个状态为假;在下面所有模块不再运行

    #vim block1.yml
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - block:
    - name: 安装httpd
    yum:
    name: httpd
    state: installed
    rescue:
    - name: 安装dhcp服务
    yum:
    name: dhcp
    state: installed
    always:
    - debug:
    msg: "message from always"
    - debug:
    msg: "the end for testing..."

    七)、ansible中使用jinja2模板: ---->(一般为拷贝大文件“配置文件”修改某个变量值实现不同功能)

    在拷贝文件中,文件中支持变量引用
    jinja2模版文件,必须与.j2结尾

    注释:调用template模块,去拷贝j2文件;在拷贝时支持变量引用

    例1:基本使用

    #vim /tmp/haha.j2
    hello from ansible
    welcome to {{ ansible_fqdn }}

    #vim jinja.yml
    ---
    - hosts: node2
    remote_user: root
    tasks:
    - template:
    src: /tmp/haha.j2
    dest: /var/www/virtual/c.txt

    例2:jianji2中使用控制语句:

    格式;for语句:

    {% for 变量名 in 列表 %}
    内容(可引用变量)
    {% endif %}
    {# 注释信息 #} ---->> (对模版的注释;不输出显示)

    格式: if语句:

    {% if 条件判断 %}
    内容(可引用变量)
    {% elseif %}
    内容
    {% else %}
    内容
    {% endif %}

    #vim if.j2

    {% if ansible_fqdn=="c1.loring.com" %}
    TYPE master
    proity 100
    {% else %}
    TYPE backup
    proity 90
    {% endif %}
    device eth0
    address 192.168.0.100

    注释: 以上jianja2模版文件定义好后,需在playbook中被调用才有意义


    vim jinja4.yml
    ---
    - hosts: allnodes
    remote_user: root
    tasks:
    - file:
    path: /loringdir
    state: directory
    - template:
    src: /etc/ansible/playbooks/if.j2
    dest: /loringdir/if.conf

    八)、ansible中使用角色(role): *****

    #vim /etc/ansible/ansible.cfg
    roles_path = /etc/ansible/roles 指定角色根目录

    在根目录中,建立的所有子目录,都是角色目录(角色名)

    角色目录中的关键文件:角色目录是自定义

    defaults(目录): 在该目录中建立的main.yml中,包含了角色的默认值(变量默认值)

    files(目录): 该目录中,包含了角色需要使用的静态文件,可以被copy模块所调用,调用只需使用相对路径;不包括jinja2模板

    handlers(目录): 该目录中,main.yml文件,是角色需要用到的触发器

    meta(目录): 该目录中的main.yml包含了源数据,无需自己给定源数据

    tasks(目录***): 该目录中的main.yml文件,就是角色的任务;必须要有

    templates(目录): 该目录中,保存jinja2模板

    tests(目录): 测试剧本的目录,一般不用给定

    vars(目录): 该目录中main.yml是定义角色的变量,可以覆盖defaults中设定的变量


    九)、ansible中使用vault(文件加密):

    ansible-vault


    创建:
    #ansible-vault create a.yml

    查看:
    #ansible-vault view a.yml

    修改:
    #ansible-vault edit a.yml

    加密文件: 前提b.yml文件必须存在
    #ansible-vault encrypt b.yml

    解密:
    #ansible-vault decrypt b.yml

    修改秘钥(密码):
    #ansible-vault rekey a.yml

    使用文件保存密码:
    #vim pass.txt 存放vault密码的文件
    redhat

    #ansible-vault view a.yml --vault-password-file=pass.txt


    #ansible-vault encrypt vault.yml 将整个剧本加密

    #ansible-playbook vault.yml --ask-vault-pass 加密剧本运行


    #ansible-vault encrypt varfile.yml 对变量文件加密

    #ansible-playbook vault.yml --ask-vault-pass

    注释:只有剧本使用到的文件被加密,那么在运行剧本时,必须加--ask-vault-pass选项

    或者:
    #vim pass.txt
    redhat 存放vault密码的文件

    #ansible-playbook vault.yml --vault-password-file=pass.txt

    为了保证数据的安全(来剧本所需的文件;如账号密码等);也可以防止其它人随意修改


    十)、配置文件、普通用户管理:

    一、设定主机清单文件

    1)、默认清单文件修改主配置文件
    #vim /etc/ansible/ansible.cfg
    [defaults]
    inventory = /etc/ansible/hosts ----默认清单文件(可为目录;目录下所有文件皆为清单文件)指定(文件名随意)
    #vim /etc/ansible/hosts ------- 清单文件内容编辑
    [node1]
    192.168.0.247
    [node2]
    192.168.0.248
    [allnodes]
    192.168.0.247
    192.168.0.248

    手动指定主机清单文件
    -i: 指定主机清单文件
    #vim a.txt
    [node1]
    192.168.2.10

    [node2]
    192.168.2.20

    #ansible node2 --list-hosts -i a.txt

    2)、设定配置文件:

    默认主配置文件: /etc/ansible/ansible.cfg

    自定义:

    在家目录中定义: ~/.ansible.cfg 或: $HOME/.ansible.cfg
    在运行剧本的当前目录: ./ansible.cfg


    优先级: 当前位置配置文件 > 家目录中配置文件 > 默认配置文件


    二、普通用户

    普通用户管理需sudo提权

    所有主机节点: 设定sudo条目
    #vim /etc/sudoers
    loring ALL=(root) NOPASSWD: ALL ----- (不一定为ALL)

    1)、命令方式管理:

    $ ansible node2 -m user -a 'name=tom666 state=present' --become --become-method "sudo" --become-user "root"

    --become: 在执行模块时,要切换身份
    --become-user: 切换到哪个用户身份,一般是root
    --become-method: 以哪种方式切换,一般为sudo
    --ask-sudo-pass: 是否需要sudo密码

    2)、剧本方式管理:

    执行剧本模块运行sudo: 在剧本中
    $vim user2.yml
    ---
    - hosts: node2
    remote_user: loring
    become: yes #切换用户
    become_method: sudo
    become_user: root
    tasks:
    - name: 创建tom999
    user:
    name: tom999
    state: present

    3)、全局sudo:

    $vim ~/.ansible.cfg
    [defaults]
    inventory = /etc/ansible/hosts

    [privilege_escalation]
    become=True
    become_method=sudo
    become_user=root
    become_ask_pass=False

  • 相关阅读:
    去除Html标签
    asp.net弹出多个模态窗口
    window.returnValue的用法
    eTerm-用于报价的指令(GK状态码的使用)
    使用ffmpeg 操作音频文件前后部分静音移除.
    使用Visual Studio 2017开发python,并在iis上部署Python Django
    解决wampserver 服务无法启动
    网站优化记录-通过命令预编译Asp.net 网站,成功优化到毫秒级别。
    Scut游戏引擎改造兼容Codis。
    windows修改Host后未生效。
  • 原文地址:https://www.cnblogs.com/zhangshan-log/p/13745312.html
Copyright © 2011-2022 走看看