ansiable学习笔记

介绍

Ansible 简单的说是一个配置管理系统(configuration management system)。你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它使用推送的方式,而不是像 puppet 等那样使用拉取安装agent的方式。你可以将代码部署到任意数量的服务器上。ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。

模块化:调用特定的模块,完成特定任务有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块

  1. 支持自定义模块
  2. 基于Python语言实现
  3. 部署简单,基于python和SSH(默认已安装),agentless
  4. 安全,基于OpenSSH
  5. 支持playbook编排任务
  6. 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
  7. 无需代理不依赖PKI(无需ssl)
  8. 可使用任何编程语言写模块
  9. YAML格式,编排任务,支持丰富的数据结构
  10. 较强大的多层解决方案

安装

yum安装

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo yum -y install ansible 
配置文件:/etc/ansible/ansible.cfg 
主机清单:/etc/ansible/hosts

源码安装

下载
git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
复制ansible根目录中的examples目录下的ansible.cfg配置文件到/etc/ansible/目录下
cp examples/ansible.cfg /etc/ansible/
创建hosts文件
vim /etc/ansible/hosts
需要的python模块
sudo pip install paramiko PyYAML Jinja2 httplib2 six
启动
source ./hacking/env-setup
一旦运行env-setup脚本,就意味着Ansible从源码中运行起来了.默认的inventory文件是 /etc/ansible/hosts.inventory
$ echo "127.0.0.1" > ~/ansible_hosts
$ export ANSIBLE_HOSTS=~/ansible_hosts

SSH认证

在~/.ssh目录下生成钥id_rsa.pub(公钥)和id_rsa
ssh-keygen
 将公钥发到被管节点的root用户下的.shh目录,生成authorized_keys
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.2.100

验证是否成功
ssh root@192.168.2.100
提示Failed to connect to the host via ssh
chown username: /home/username/.ssh
chown username: /home/username/.ssh/*
chmod 700 /home/username/.ssh
chmod 600 /home/username.ssh/*

目录结构

*配置文件或指令* *描述*
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles/ 存放角色的目录
/usr/bin/ansible 主程序,临时命令执行工具
/usr/bin/ansible-doc 查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
/usr/bin/ansible-pull 远程执行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基于Console界面与用户交互的执行工具

配置文件

Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认)

[defaults]
inventory = /etc/ansible/hosts # 主机列表配置文件
library = /usr/share/my_modules/ # 库文件存放目录
remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
forks = 5 # 默认并发数
sudo_user = root # 默认sudo 用户
ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
ask_pass = True      #连接时提示输入ssh密码
remote_port = 22     #远程主机的默认端口,生产中这个端口应该会不同
log_path = /var/log/ansible.log #日志
host_key_checking = False # 检查对应服务器的host_key,建议取消注释。也就是不会弹出

Ansible必须通过Inventory 来管理主机(即/etc/anAnsible/hosts文件。)可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置。

ansible_ssh_host
将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
ansible_ssh_port
ssh端口号.如果不是默认的端口号,通过此变量设置.这种可以使用 ip:端口 192.168.1.100:2222
ansible_ssh_user
默认的 ssh 用户名
ansible_ssh_pass
ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)
ansible_sudo_pass
sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)
ansible_sudo_exe (new in version 1.8)
sudo 命令路径(适用于1.8及以上版本)
ansible_connection
与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.
ansible_ssh_private_key_file
ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
ansible_shell_type
目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.
ansible_python_interpreter
目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如  \*BSD, 或者 /usr/bin/python 不是 2.X 版本的 Python.
我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).
与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....

快速定义主机组

单台主机
green.example.com    >   FQDN192.168.100.10       >   IP地址192.168.100.11:2222  >   非标准SSH端口

[webservers]         >   定义了一个组名     
alpha.example.org    >   组内的单台主机192.168.100.10 

[dbservers]
192.168.100.10       >   一台主机可以是不同的组,这台主机同时属于[webservers] 

[group:children]     >  组嵌套组,group为自定义的组名,children是关键字,固定语法,必须填写。
dns                  >  group组内包含的其他组名
db                   >  group组内包含的其他组名

[webservers] 
www[001:006].hunk.tech > 有规律的名称列表,
这里表示相当于:
www001.hunk.tech
www002.hunk.tech
www003.hunk.tech
www004.hunk.tech
www005.hunk.tech
www006.hunk.tech

[databases]
db-[a:e].example.com   >   定义字母范围的简写模式,
这里表示相当于:
db-a.example.com
db-b.example.com
db-c.example.com
db-d.example.com
db-e.example.com

以下这2条定义了一台主机的连接方式,而不是读取默认的配置设定
localhost       ansible_connection=local
www.163.com     ansible_connection=ssh        ansible_ssh_user=hunk

最后还有一个隐藏的分组,那就是all,代表全部主机,这个是隐式的,不需要写出来的。

验证

ansible 10.128.50.53 -u root -m ping
返回
10.128.50.53 | success >> {
    "changed": false, 
    "ping": "pong"
}

使用

测试命令

Anisble安装完成后(一般情况我们连ssh的免密登录一起做完,详见附录)我们会测试anisble是否可用。测试命令没有固定的格式,我们使用linux下hello world ,命令ping来测试是否可用。
指令成功和失败都会有不同的颜色反映出来且配合changed :false,changed :SUCCESS,可以让我们非常清晰的知道执行的结果。
绿色:执行成功并且不需要做改变的操作
×××:执行成功并且对目标主机做变更
红色:执行失败
可以在配置文件中定义

  • highlight = white
  • verbose = blue
  • warn = bright purple
  • error = red
  • debug = dark gray
  • deprecate = purple
  • skip = cyan
  • unreachable = red
  • ok = green
  • changed = yellow
  • diff_add = green
  • diff_remove = red
  • diff_lines = cyan

命令执行过程

ansible db -m command -a 'ls -l /' -vvv 这条命令为例

1.加载自己的配置文件,默认/etc/ansible/ansible.cfg
Using /etc/ansible/ansible.cfg as config file
2.匹配主机清单
Parsed /etc/ansible/hosts inventory source with ini plugin
3.加载指令对应的模块文件,如command,生成.py的文件到本机的临时目录,这个目录就是在/etc/ansible/ansible.cfg定义的
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
PUT /tmp/tmp4JvsLH TO /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py
4. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件,
这个目录就是在/etc/ansible/ansible.cfg定义的
( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861 `" ....)
sftp> put /tmp/tmp4JvsLH /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py\n'
5. 给文件+x 权限
'chmod u+x /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/ /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py && sleep 0'
6. 执行并返回结果
'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py;
7. 删除临时py文件,sleep 0退出
rm -rf "/root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/" > /dev/null 2>&1 && sleep 0
8.断开远程主机连接
'Shared connection to 7-db-3.hunk.tech closed.\r\n')

高级话题Playbooks

playbook是ansible用于配置,部署,和管理被控节点的剧本。是由一个或多个play组成的列表,主要功能是将task定义好的角色归并为一组进行统一管理,也就是通过Ansible的模板将多个play组织在一个Playbook中运行。
Playbook可以理解为批处理任务,不过palybook有自己的语法格式,使用playbook你可以方便的重用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。你也会发现,你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook,之后管理服务器会变得十分简单。比如安装nginx、mysql等服务。

yaml格式

playbook由YMAL语言编写。YAML( /ˈjæməl/ )参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822,Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。
YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。

文件的第一行应该以 ”—” (三个连字符)开始,表明YMAL文件的开始。在同一行中,#之后的内容表示注释,类似于shell,python和ruby。YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。

- apple - banana - orange等价于JSON的这种格式
[ “apple”, “banana”, “orange” ]
同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。

play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以”:”分隔表示,”:”后面还要增加一个空格。

house:
family: { name: Doe, parents: [John, Jane], children: [Paul, Mark, Simone] }
address: { number: 34, street: Main Street, city: Nowheretown, zipcode: 12345 }

剧本以.yml后缀

如图所示:在mysql.yml中,主要由三个部分组成。
hosts部分:
使用hosts指示使用哪个主机或主机组来运行下面的tasks,每个playbook都必须指定hosts,hosts也可以使用通配符格式。主机或主机组在inventory清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行task的过程中。
remote_user:
指定远端主机中的哪个用户来登录远端系统,在远端系统执行task的用户,可以任意指定,也可以使用sudo,但是用户必须要有执行相应task的权限。
tasks:
指定远端主机将要执行的一系列动作。tasks的核心为ansible的模块,前面已经提到模块的用法。tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

使用ansible-playbook运行playbook文件,得到如下输出信息,输出内容为JSON格式。并且由不同颜色组成,便于识别。一般而言
绿色代表执行成功,系统保持原样
×××代表系统代表系统状态发生改变
红色代表执行失败,显示错误输出

Playbook的核心元素

· Playbook本身由以下各部分组成:
(1)Hosts:运行指定任务的目标主机;
(2)Tasks:任务,即调用模块完成的操作;
(3)Variables:变量;
(4)Templates:模板;
(5)Handles:处理器,当某条件满足时,触发执行的操作;
(6)Roles:角色

Play的主体是任务列表。任务列表中的任务依照次序逐个在hosts中指定的所有主机上执行,如果发生错误会将所有已执行任务回滚。

模块、模块参数格式
task的任务是按照指定的参数去执行模块。
(1)action:moudle options
(2)moudle:options,其中后者可以实现向后兼容。
注意:在Ansible自带模块中,command模块和shell模块只需要一个列表定义即可,无需使用key=value格式。
Handles和tags的使用
Handlers用于当关注的资源发生变化时所采取的操作。使用tags让用户选择跳过没有变化的代码,只运行Playbook中发生变化的部分代码。
(1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;
(2) 任务可以通过“tags“打标签,通过 ansible-playbook命令 使用 --tags选项能实现仅运行指定的tasks。

- hosts: nginx
  remote_user: root
  tasks:
    - name:yum install epel-release -y    #安装epel源
      yum: name=epel-release state=latest
    - name: yum install nginx -y  #安装nginx
      yum: name=nginx state=latest
    - name: copy nginx.conf   #拷贝配置文件
      copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
      notify:
        - reload     #会触发handlers中名字为reload的任务
      tags: 
        - reloadnginx
    - name: start nginx   #启动nginx服务
      service: name=nginx state=started
      tags: 
        - startnginx
  handlers:
    - name: reload  #重载配置
      service: name=nginx state=reloaded

执行:ansible-playbook nginx.yml 



修改配置文件内容之后执行时调用标签ansible-playbook nginx.yml --tags= "reloadnginx",就会跳过安装步骤直接重载配置文件并启动服务。

variables:变量
(1) facts:可直接调用
注意:可使用setup模块直接获取目标主机的facters
ansible xxx -m setup
(2) 用户自定义变量:
通过命令行传递变量
ansible-playbook xxx.yml -extra-vars "host-www user-mageedu"
在playbook中定义变量的方法
vars:

  • var1: value1
  • var2: value2
    (3)通过roles传递变量
    (4)Host Inventory(主机清单)

Templates:模板文件以.j2后缀
Jinja是基于 Python的模板引擎。 Template类是 Jinja的另一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递 Python的变量给模板去替换模板中的标记。

循环:迭代,即需要重复执行的任务。
(1)when 语句:只需要在task之后添加when语句即可。

vim /etc/ansible/when.yml

- hosts: nginx
  remote_user: root
  vars:
    - username: user10
  tasks:
    - name: create {{username}} user
      user: name={{username}}
      when: ansible_fqdn=="promote.cache-dns.local"
执行:ansible-playbook when.yml 就会创建在nginx组的主机上

(2)迭代:直接将需要迭代的内容定义为item变量并进行引用,然后通过with_items语句来指明迭代的元素。

vim /etc/ansible/items.yml

- hosts: nginx
  remote_user: root
  tasks:
    - name: install packages  #安装with_items中列出的包
      yum: name={{ item }} state=latest
      with_items:
        - php
        - php-mysql

执行:ansible-playbook items.yml 就会安装列表中的包

角色列表: Roles
Ansible为了层次化、结构化地组织 Playbook,使用了角色( roles),可以根据层次结构自动装载变量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include指令即可使用 roles。简单来讲, roles就是通过分别将变量、文件、任务、模块及处理器设置于单独的目录中,便捷地使用他们。
创建roles时的注意事项:
(1)目录名同角色名的定义
(2)目录结构有固定的格式:

files 用来存放由copy模块或script模块调用的文件
templates 用来存放jinjia2模板
tasks 至少有一个main.yml文件,定义各tasks
handlers 有一个main.yml文件,定义各handlers
vars 有一个main.yml文件,定义变量
default 有一个main.yml文件,定义默认变量
meta 有一个main.yml文件,定义此角色的特殊设定及其依赖关系

注意:在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、default和vars目录,用不到的目录可以创建为空目录,但不可以不创建。

示例

·、在roles目录下生成对应的目录结构
mkdir -pv /etc/ansible/roles/{httpd,mysql,php}/{files,templates,vars,tasks,handlers,meta,default}


2、在每个角色的handlers、tasks、meta、default、vars目录下创建main.yml文件,千万不能自定义
touch /etc/ansible/roles/{httpd,mysql,php}/{default,vars,tasks,meta,handlers}/main.yml

3、定义每个角色中tasks/main.yml的配置文件。
------编写httpd模块------
vim /etc/ansible/roles/httpd/tasks/main.yml

- name: ensure apache is at the latest version 
  yum: name={{item}} state=latest
  with_items:
    - httpd
    - httpd-devel
- name: conf
  template: src=/etc/ansible/roles/httpd/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  tags: 
    - httpdconf
  notify: 
    - new conf to reload
  tags:
    - reload
- name: start service
  service: name=httpd enabled=true state=started

-------编写mysql模块-------
vim /etc/ansible/roles/mysql/tasks/main.yml

- name: ensure mysql is at the latest version 
  yum: name={{item}} state=latest
  with_items:
    - mariadb
    - mariadb-server
    - mariadb-libs
    - mariadb-devel
- name: start service
  service: name=mariadb enabled=true state=started

-------编写php模块-----
vim /etc/ansible/roles/php/tasks/main.yml

- name: ensure php is at the latest version
  yum: name={{item}} state=latest
  with_items:
    - php
    - php-mysql
    - php-gd
    - php-ldap
    - php-odbc
    - php-pear
    - php-xml
    - php-xmlrpc
    - php-mbstring
    - php-snmp
    - php-soap
    - curl
    - curl-devel 
    - php-bcmath

4、修改变量文件vars/main.yml
vim /etc/ansible/roles/httpd/vars/main.yml

http_port : 80    #添加变量
server_name : www.yun.com:80

5、定义handlers文件handlers/main.yml
vim /etc/ansible/roles/httpd/handlers/main.yml

- name: new conf to reload
  service: name=httpd state=reloaded

6、定义/etc/ansible/lamp.yml的playbook文件
-----编写roles示例-----
vi /etc/ansible/lamp.yml

- hosts: lamp
  remote_user: root
  roles:
    - httpd
    - mysql
    - php

7、执行lamp.yml的playbook文件
ansible-playbook lamp.yml

8、前往部署lamp的主机上编写php测试页,打开浏览器看网页是否正常。
vim /var/www/html/index.php

<?php
   phpinfo();
?>

访问http://ip/index.php验证

常用命令

语法

ansible <host-pattern> [-m module_name] [options]
指令 匹配规则的主机清单 -m 模块名 选项
--version 显示版本
-a 模块参数(如果有)
-m module 指定模块,默认为command
-v 详细过程 –vv -vvv更详细
--list-hosts 显示主机列表,可简写--list
-k, --ask-pass 提示连接密码,默认Key验证
-K,--ask-become-pass 提示使用sudo密码
-C, --check 检查,并不执行
-T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
-u, --user=REMOTE_USER 执行远程执行的用户
-U, SUDO_USER, --sudo-user 指定sudu用户
-b, --become 代替旧版的sudo 切换
ansible-doc: 显示模块帮助
ansible-doc [options] [module...]
-a 显示所有模块的文档-l, --list 列出可用模块-s, --snippet 显示指定模块的简要说明

命令

/usr/bin/ansible:Ansibe AD-Hoc 临时命令执行工具,常用于临时命的执行
/usr/bin/ansible-doc:Ansible 模块功能查看工具
/usr/bin/ansible-galaxy:下载/上传优秀代码或Roles模块 的官网平台,基于网络的
/usr/bin/ansible-playbook:Ansible 定制自动化的任务集编排工具
/usr/bin/ansible-pull:Ansible远程执行命令的工具,拉取配置而非推送配置(使用较少,海量机器时使用,对运维的架构能力要求较高)
/usr/bin/ansible-vault:Ansible 文件加密工具
/usr/bin/ansible-console:Ansible基于Linux Consoble界面可与用户交互的命令执行工具
Ansible-doc命令
查看 ansible-doc 的使用说明:
一般用法:
ansible-doc -l 获取所有模块信息
ansible-doc -s MOD_NAME 获取指定模块的使用帮助
ansible-doc
-h Usage: ansible-doc [options] [module...]
Options:
-h, --help show this help message and exit # 显示命令参数API文档
-l, --list List available modules #列出可用的模块
-M MODULE_PATH, --module-path=MODULE_PATH #指定模块的路径specify path(s) to module library (default=None)
-s, --snippet Show playbook snippet for specified module(s) #显示playbook制定模块的用法
--version show program's version number and exit # 显示ansible-doc的版本号查看模块列表:ion
ansible-doc -l

常用模块

官方文档

模块 功能
ping 测试连通性
command 命令行不能接收shell表达式
shell 可以解析shell表达式、通配符等如管道
copy 复制文件到远程主机,可以改权限等
file file 设置文件属性
Fetch fetch从远程某主机获取文件到本地
cron cron 管理cron计划任务
group 添加或删除组
user 管理用户、获取用户信息
yum 远程安装包
service 管理服务
setup 获取主机信息
script 执行脚本
get_url 下载指定文件存放到dest指定的目录
posted @ 2020-07-19 01:14  名字很长容易被惦记  阅读(328)  评论(0编辑  收藏  举报