首页 > Server > ansible 安装使用详解
2018
04-24

ansible 安装使用详解

ansible———-2012年创建,最近被红帽1.5亿收购(兼有一些pupuet、fabric、agentless功能)

用于yum install ansible (前提yum源仓库为epel源)

1、特性:

模块化:调用特定的模块(插件)来完成特定任务核心组件所以小;

基于Python语言实现:由Paramiko, PyYAML和Jinja2三个关键模块实现;

部署简单:agentless

主从模式:

支持自定义模块:

支持playbook(剧本):

 

支持幂等性:运行一次或N次结果一样,如果有些不幂等性,要人工使其幂等

 

2、组成部分:

ansible core:主体核心(默认每次批量5个,可根据需要改变其值)

host inventory:管理范围的文件 (没在管理范围内的不管理)

connection plugins:连接插件(一般基于ssh来连接的)—用于与每一个被管理主机建立会话并发送管理指令

modules:要做的每一个操作都要靠模块来定义(连接插件等操作不能靠每次输入)

core modules       核心模块(自带)

custom modules  用户自定义模块

Plugins                   扩展插件(如email、logging、other或者自己开发的插件)

Playbooks: 批量命令文件(事先编写好,让ansible完成的操作,ansible复用就靠它了)

 

3、配置文件:

主配置文件:/etc/ansible/ansible.cfg      —————ansible core file

管理范围文件 /etc/ansible/hosts      —————Host Inventory file

 

4ansible命令:

ansible  <host-pattern>  [-f forks]  [-m module_name]  [-a args]

<host-pattern>: 要管理主机的匹配模式

-f forks:表示一次管理几个主机(默认一批是5个主机)

-m module_name:要使用的模块名字(默认模块command)

-a args:模块专用参数(key value   ———-kv键值)

 

管理范围文件:/etc/ansible/hosts(文件名路径可以指定     -i PATH, –inventory=PATH:指明使用的host inventory文件路径;)

定义(INI风格):

中括号中的字符是组名          如:[webservers];

组号要放入[]号:                      如:[webservers]

多主机名:                                  如:www[001:006].example.com———–表示从001到006主机

一个组也可以包括其他组:

同一个主机出现在多个组:

 

自定义:

[webserver]

172.16.38.3:2222       #这里加2222是因为此主机不是通过22号端口远程连接,而是2222。因为ansible是通过ssh连接管理的

172.16.38.4

 

[dbserver]

172.16.38.5

 

 

配置基于密钥认证:在控制端

1、生成密钥对:ssh-keygen -t rsa

.ssh目录下生成两个文件 ,我们要用的是id-rsa.pub

 

2、复制公钥给被控端:ssh-copy-id -i .ssh/id-rsa.pub root@host

[root@nfs .ssh]# ssh-copy-id -p 2222 -i id_rsa.pub root@172.16.38.3

[root@nfs .ssh]# ssh-copy-id -i id_rsa.pub root@172.16.38.4

 

5ansible-doc命令:获取模块列表,及模块使用格式;

 

ansible-doc  -l                                   # 获取列表

ansible-doc  -s  module_name      # 获取某个模块的具体使用参数

 

常用模块:

[-a args]:

args: key=value

 

注意:command模块的参数非为kv格式,而是直接给出要执行的命令即可;

 

command:默认模块

-a  ‘COMMAND’

[root@nfs ~]# ansible all -a ifconfig

[root@nfs ~]# ansible all -a ‘crontab -l’   # 命令带选项时,要把整个命令段用单引号引起来

 

 

user:创建删除用户

-a  ‘name=  state={present|absent}  force=   system=  uid=  shell=  home=’

[root@nfs ~]# ansible webserver -m user -a “name=test state=present”           # 在webserver上面创建test用户

[root@nfs ~]# ansible webserver -m user -a “name=test state=absent remove=yes”    # 删除test用户及其家目录

 

group:创建工作组

-a  ‘name=  state={present|absent}  gid=  system=’

[root@nfs ~]# ansible webserver -m group -a “name=mygrp state=present gid=300 system=true”   #添加系统组mygrp,GID为300,system=true(是系统组)

[root@abc ~]# cat /etc/group

mygrp:x:300:

[root@nfs ~]# ansible webserver -m group -a “name=mygrp state=absent”            # 删除mygrp组

 

cron:计划任务

-a  ‘name=  state=  minute=  hour=  day=  month=  weekday=  job=’

[root@nfs ~]# ansible all -m cron -a “minute=’*/1′ job=’cat /etc/passwd &>test.txt’ name=’showpasswd'”  # 创建计划并输出到test.txt文件中,计划名为showpasswd

[root@nfs ~]# ansible all -m cron -a “name=’showpasswd’ state=absent”    #删除计划

 

ping:查看主机状态—没有参数(下面是测试结果,主机都活着)

[root@nfs ~]# ansible webserver -m ping

172.16.38.3 | success >> {

“changed”: false,

“ping”: “pong”

}

 

172.16.38.4 | success >> {

“changed”: false,

“ping”: “pong”

}

[root@nfs .ssh]# ansible all -m ping      # 不仅是webserver列表的,而是所有的

 

file:文件创建删除等管理

-a  ‘path=  mode=  owner=  group=  state={file|directory|link|hard|touch|absent}  src=’

[root@nfs ~]# ansible webserver -m file -a “path=/tmp/abc.txt owner=ftp mode=600 state=touch”   # 创建文件abc.txt 所有者ftp,权限600

[root@abc tmp]# ll

-rw——- 1 ftp  root  0 Jan 31 21:38 abc.txt

[root@nfs ~]# ansible webserver -m file -a “path=/tmp/abc.txt state=absent”

 

copy:文件复制

-a  ‘dest=  src=  content=  owner=  group=  mode=’

[root@nfs ~]# ansible webserver -m copy  -a ‘src=/etc/fstab dest=/tmp/fstab.xyz mode=600 ‘      # 复制本机的fstab 文件到webserver组的tmp目录下

[root@nfs ~]# ansible webserver -a ‘rm /tmp/fstab.xyz’    #   删除文件

 

template

-a  ‘dest=  src=  content=  owner=  group=  mode=’

 

yum:yum安装

-a  ‘name=  conf_file=  state={present|latest|absent}  enablerepo=  disablerepo=’

[root@nfs ~]# ansible webserver -m yum -a “name=zsh state=present”     #  安装zsh在webserver上

[root@nfs ~]# ansible webserver -m yum -a “name=zsh state=absent”

 

service:管理服务的

-a  ‘name=  state={started|stopped|restarted}  enabled=  runlevel=’

[root@nfs ~]# ansible webserver -m service -a ‘name=httpd state=started’                #  开启webserver组的httpd服务

[root@nfs ~]# ansible webserver -m service -a ‘name=httpd state=stopped’              #  停止webserver组的httpd服务

 

shell:用shell程序打开

-a  ‘COMMAND’

[root@nfs ~]# ansible webserver -a ‘echo “gayj.cn” | passwd –stdin root’                #  用shell改变root密码

172.16.38.3 | success | rc=0 >>

gayj.cn | passwd –stdin root

172.16.38.4 | success | rc=0 >>

gayj.cn | passwd –stdin root

 

script:指定本地主机上的脚本文件,在远程主机上运行一次

-a  ‘/PATH/TO/SCRIPT’

[root@nfs ~]# ansible webserver -m script -a ‘test.sh’      #  让本地主机的test.sh在webserver主机上运行一次

 

setup:收集主机的变量状态

[root@nfs ~]# ansible 172.16.38.3 -m setup

获取指定主机的facts;

 

 

 

十、playbooks

 

1、核心元素:

Tasks     任务

Variables  变量

Templates  模板

Handlers    处理器

Roles    角色

 

2、组织格式:YAML ——–可读性较高的,可以用来表达资料序列的格式

YAML Ain’t  Markup Language;  Yet Another Markup Language;

http://www.yaml.org

 

语法:(键值段用冒号间隔,列表用-隔开)

name: Jerry

age: 21

gender: Male

 

spouse: (嵌套)

name: Lily

age: 19

gender: Female

 

children:(嵌套)

–         name: tom

age: 2

gender: male

–         name: obama

age: 5

gender: male

 

列表:-

字典: k:v(键值)———–上面三种颜色区域即表示三个字典

{name: jerry, age: 21, genden: male}—–字典可以写在{}中

 

3playbook:

– host: 172.16.100.68

vars:

var1: value

var2: value

tasks:(任务)

– name:

 

– name:

 

– name:

 

handlers:(处理器)

– name:

 

remote_user:  (以什么用户身份)

 

– host: 172.16.100.69

vars:

tasks:

handlers:

remote_user:

– host: 172.16.100.6

vars:

tasks:

handlers:

remote_user:

 

如何定义任务:

– name: task description

module_name: module_args

 

4ansible-playbook命令:

ansible-playbook  <filename.yml> …  [options]

 

5playbook的元素:

 

变量:

变量命名:字母、数字和下划线组成,仅能以字母开头;

 

变量种类:

facts:由远程主机发回的主机属性信息,这些信息被保存在ansible变量中;无须定义,可直接调用;

自定义变量:

通过命令行传递: ansible-playbook  test.yml  –extra-vars “host=www user=mageedu”

通过roles传递

主机变量:定义在inventory中的主机之后的变量;

组变量:定义在inventory中的组上的变量

[group_name:vars]

var1=value

var2=value

 

[websrvs]

[websrvs:vars]

 

变量使用示例:

–       hosts: websrvs

remote_user: root

vars:

username: student

password: mageedu

tasks:

– name: add user

user: name={{ username }} state=present

– name: set password

shell: /bin/echo {{ password }} | /usr/bin/passwd –stdin {{ username }}

 

# ansible-playbook  /PATH/TO/SOME_YAML_FILE  { -e VARS|–extra-vars=VARS}    前面{}中方式二选一, 从新定义vars值,命令行传送的优先于hosts中的vars值

 

– hosts: webserver

remote_user: root

vars:

username: student

password: 123456

tasks:

– name: add user

user: name={{ username }} state=present

– name: set password

shell: /bin/echo {{ password }} | /usr/bin/passwd –stdin {{ username }}

 

[root@nfs ~]# ansible-playbook test.yml

 

PLAY [webserver] **************************************************************

 

GATHERING FACTS ***************************************************************

ok: [192.168.1.4]

ok: [192.168.1.3]

 

TASK: [add user] **************************************************************

changed: [192.168.1.3]

changed: [192.168.1.4]

 

TASK: [set password] **********************************************************

changed: [192.168.1.4]

changed: [192.168.1.3]

 

PLAY RECAP ********************************************************************

192.168.1.3                : ok=3    changed=2    unreachable=0    failed=0

192.168.1.4                : ok=3    changed=2    unreachable=0    failed=0

 

删除刚才创建的用户:

– hosts: webserver

remote_user: root

vars:

username: student

tasks:

– name: del user

user: name={{ username }} state=absent remove=true

 

[root@nfs ~]# ansible-playbook test.yml

 

PLAY [webserver] **************************************************************

 

GATHERING FACTS ***************************************************************

ok: [192.168.1.4]

ok: [192.168.1.3]

 

TASK: [del user] **************************************************************

changed: [192.168.1.4]

changed: [192.168.1.3]

 

PLAY RECAP ********************************************************************

192.168.1.3                : ok=2    changed=1    unreachable=0    failed=0

192.168.1.4                : ok=2    changed=1    unreachable=0    failed=0

 

 

 

inventory参数:(hosts文件对应的Ip主机后定义)

ansible基于ssh连接inventory中指定的远程主机时,将以此处的参数指定的属性进行;

ansible_ssh_port

ansible_ssh_user

ansible_ssh_pass

ansible_sudo_pass

 

如下:

[webserver]

172.16.38.3 ansible_ssh_user=root ansible_ssh_pass=12345 ansible_ssh_port=2222

 

条件测试:

在某task后面添加when子句即可实现条件测试功能;when语句支持Jinja2语法;

 

tasks:

– name: install web server package

yum: name=httpd state=present

when: ansible_os_family == “RedHat”

 

– hosts: webserver

remote_user: root

tasks:

– name: install web server package

yum: name=zsh state=present

when: ansible_os_family == “Debian”       # 当为Debint系统时执行安装

– name: say hello

command: /bin/echo “hello”                      #  向所以webserver组的主机说hello

 

[root@nfs ~]#

[root@nfs ~]# ansible-playbook test.yml

 

PLAY [webserver] **************************************************************

 

GATHERING FACTS ***************************************************************

ok: [192.168.1.4]

ok: [192.168.1.3]

 

TASK: [install web server package] ********************************************

skipping: [192.168.1.3]

skipping: [192.168.1.4]

 

TASK: [say hello] *************************************************************

changed: [192.168.1.3]

changed: [192.168.1.4]

 

PLAY RECAP ********************************************************************

192.168.1.3                : ok=2    changed=1    unreachable=0    failed=0

192.168.1.4                : ok=2    changed=1    unreachable=0    failed=0

 

 

 

迭代:

在task中调用内置的item(元素)变量;在某task后面使用with_items语句来定义元素列表;

– name: add four users

user: name={{ item }}  state=present

with_items:

– testuser1

– testuser2

– testuser3

– testuser4

 

注意:迭代中,列表中的每个元素可以为字典格式;

 

– name: add two users

user: name={{ item.name }}  state=present  groups={{ item.groups }}

with_items:

– { name: ‘testuser5’, groups: ‘wheel’ }

– { name: ‘testuser6’, groups: ‘root’ }

 

handlers——–处理(触发)

也是task,但只有其关注的条件满足时,才会被触发执行;—-当复制一个命令到远程主机,主机不知道是否重载命令,这就要靠handlers

 

– hosts: websrvs

remote_user: root

tasks:

– name: install httpd

yum: name=httpd state=present

 

– name: install config file

copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf

notify: restart httpd                  #notify是当然条件满足时,触发handlers。让服务重新启动

 

– name: start httpd service

service: name=httpd state=started

 

handlers:

– name: restart httpd

service: name=httpd state=restarted

 

templates——模板

用于生成文本文件(配置文件);模板文件中可使用jinja2表达式,表达式要定义在{{ }},也可以简单地仅执行变量替换;

 

roles——-角色

roles用于实现“代码复用”;

roles以特定的层次型格式组织起来的playbook元素(variables, tasks, templates, handlers);可被playbook以role的名字直接进行调用;

 

roles/

webserver/

files/:此角色中用到的所有文件均放置于此目录中;

templates/:Jinja2模板文件存放位置;

tasks/:任务列表文件;可以有多个,但至少有一个叫做main.yml的文件;

handlers/:处理器列表文件;可以有多个,但至少有一个叫做main.yml的文件;

vars/:变量字典文件;可以有多个,但至少有一个叫做main.yml的文件;

meta/:此角色的特殊设定及依赖关系;

 

6tags——标签

 

– name: install config file

template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf

notify: restart httpd

tags: conf

 

-t, TAGS, –tags=TAGS

 

http://www.ansible.com.cn

 

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++故障状态:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

进行了密钥认证后,还是不能使用基于密钥认证的ansible登陆

 

[root@lvs ~]# ansible all -m ping

172.16.38.3 | FAILED => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

while connecting to 172.16.38.3:2222

It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

172.16.38.4 | FAILED => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

while connecting to 172.16.38.4:22

It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

172.16.38.5 | FAILED => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

while connecting to 172.16.38.5:22

It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

 

导致原因:

ask-pass 原来是被注释的

 

[defaults]

 

# some basic default values…

 

inventory      = /etc/ansible/hosts

#library        = /usr/share/my_modules/

remote_tmp     = $HOME/.ansible/tmp

pattern        = *

forks          = 5

poll_interval  = 15

sudo_user      = root

#ask_sudo_pass = True

ask_pass      = True

 

解决方法:

将ask_pass 取消注释,在测试命令,差什么程序包按提示安装提示包就行了(注意:yum install sshpass –nogpgcheck,后面是取消gpgcheck检查)

这样有个问题,每次登陆要输入密码:

 

最终于原因 ————-目录权限给太大了,系统为了安全考虑反而没权限了

drwxrwxrwx.   6 root root 4096 Feb 17 20:20 root

 

[root@lvs ~]# ssh 172.16.38.4

root@172.16.38.4’s password:               # 这样认证就不起作用

 

[root@lgq ~]# tail /var/log/secure    # 被控端,显示错误 bad ownership or modes for directory /root   错误的属主权限

Feb 17 20:31:51 lgq sshd[4721]: Authentication refused: bad ownership or modes for directory /root

Feb 17 20:32:36 lgq sshd[4721]: Accepted password for root from 172.16.38.17 port 41620 ssh2

 

在于被控端登陆用户的家目录不能为777,只能为700

改掉被控端权限,不用开启ask_pass选项

 

[root@lgq ~]# chmod 700 /root/

drwx——.   6 root root 4096 Feb 17 20:20 root

 

 

+++++++++++++++++++++++++++++++目录权限给太大了,系统为了安全考虑反而没权限了+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

最后编辑:
作者:李国庆
这个作者貌似有点懒,什么都没有留下。
捐 赠如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!

留下一个回复

你的email不会被公开。