1、特点

  • 基于ssh架构
  • 模块丰富
  • 支持自定义模块
  • 支持异构IT架构(支持Linux和Windows、Mac)
  • Paramiko(python对ssh的实现),PyYaml和Jinja2三个
  • 安全 基于openssh
  • 幂等性 一次执行和n次执行效果一致 不会因为重复执行带来意外
  • 支持playbook编排任务,yaml格式

2、配置ssh密钥

vim /etc/hosts

ip1 hostname1
ip2 hostname2

ssh-keygen -f /root/.ssh/id_rsa -N ''

for i in node1 node2 node3
do
	ssh-copy-id $i
done

输入:y
输入密码

3、ansible配置文件

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

ansible配置文件查找顺序

  • 系统变量ANSIBLE_CONFIG定义的配置文件
  • 当前目录下的ansible.cfg
  • 家目录下的ansible.cfg vim ~/ansible/ansible.cfg
  • /etc/ansible/ansible.cfg文件

ansible配置文件

[defaults]
inventory = ~/ansible/hosts # 主机清单文件
forks = 5	# ssh并发数量
ask_pass = True	# 使用密钥还是密码远程
host_key_checking = False	# 是否校验密钥

4、主机清单inventory

[test1]
node1

[proxy]
node2
node1

[webserver]
node[3:4]
node[a:z]

[test2:children] # 嵌套组
test1
webserver

检查配置是否正常

cd ~/ansible
ansible all --list-hosts

ansible node1 -m ping
ansible node1,node2 -m ping
ansible webserver -m ping

5、ansible ad-hoc命令

ansible 主机集合(主机名) -m 模块名 -a “参数”

  • -k:使用密码远程 默认使用密钥远程主机
  • -i:指定主机列表文件

模块
模块就是脚本。

默认模块command

ansible node1 -m command -a "uptime"
ansible node1 -m command -a "uname -r"
ansible node1 -a "ip a s eth0"
ansible all -a "date"

ansible –help
ansible-doc -l # 列出所有模块
ansible-doc yum # 查看模块帮助

6、ansible常用模块

6.1、shell和command

command和shell模块区别

  • command模块命令不启动shell,直接通过ssh执行命令
  • command不支持bash特性,如管道和重定向等
  • 所有需要调用shell的功能都无法使用
ansible node1 -a "ps |wc -l" # 失败
ansible node2 -a "ls &" # 失败

使用shell模块会调用shell解释器,但是无法使用vim或者top等。

ansible node1 -m shell -a "ps aux|wc -l"
ansible node1 -m shell -a "who"
ansible node1 -m shell -a "touch /tmp/tmp.txt"

指定命令目录chdir
ansible node1 -m shell -a “chdir=/tmp touch 1.txt”

判断creates、removes

  • creates文件名:文件存在,不执行shell
  • remove文件名:文件不存在,不执行shell
ansible node1 -m shell -a "ssh-keygen -f ~/.ssh/id_rsa -N '' creates=~/.ssh/id_rsa" # 有~/.ssh/id_rsa,则不创建密钥
ansible node1 -m shell -a "unzip xx.zip removes=/bin/unzip" # 没有/bin/unzip则不执行命令

6.2、script模块

执行复杂命令?

  • script允许在本地写脚本,拷贝到被管理端执行脚本
  • 脚本不仅仅是shell脚本(python、perl等)
#!/bin/bash
ansible node1 -m script -a "./test.sh"

6.3、file模块

file模块可以创建文件、目录、链接、修改权限和属性等.

幂等性。

state常用值:absent,directory,file,hard,link,touch

# 创建文件
ansible node1 -m file -a "path=/tmp/file.txt state=touch"

# 创建目录
ansible node1 -m file -a "path=/tmp/mydir state=directory"

# 修改权限
ansible node1 -m file -a "path=/tmp/file.txt owner=sshd group=adm mode=0777"

# 删除
ansible node1 -m file -a "path=/tmp/mydir state=absent"
ansible node1 -m file -a "path=/tmp/1.txt state=absent"

# 链接 src源文件  path链接
ansible node1 -m file -a "src=/etc/hosts path=/tmp/host.txt state=link"

6.4、copy模块

文件拷贝到远程主机 backup=yes 目标主机已存在,先备份

ansible node1 -m copy -a "src=~/a3.txt dest=/root/"
ansible node1 -m copy -a "src=~/a3.txt dest=/root/3a.txt"

# content文件内容
ansible node1 -m copy -a "content='hello world\n' dest=/root/new.txt"

6.5、fetch模块

与copy左右相似,但是作用相反:将其他主机文件拷本到本地

ansible node1 -m fetch -a “src=/etc/hostname dest=~/”

6.6、lineinfile和replace模块

修改单个文件单行内容使用lineinfile

# 添加一行内容,默认在最后
ansible node1 -m lineinfile -a "path=/etc/issue line='hello world'"

# 插入到Kernel行后面
ansible node1 -m lineinfile -a "path=/etc/issue line='insert' insertafter='Kernel'" 

# 匹配hello行,替换整行。没有匹配到,最后行添加;匹配多行,替换最后一行。
ansible node1 -m lineinfile -a "path=/etc/issue regexp='hello' line='ni hao'"

replace会替换关键字

# 全文替换
ansible node1 -m replace -a "path=/etc/issue.net regexp=Kernel replace=Ocean"

6.7、user模块

实现Linux账户管理。

# 创建用户
ansible node1 -m user -a "name=tuser"
ansible node1 -m user -a "name=tuser2 uid=1010 group=adm groups=daemon,root home=/home/tuser2"

# 修改账户密码
ansible node1 -m user -a "name=tuser2 password={{'abc'|password_hash('sha512')}}"

# 修改附加组
ansible node1 -m user -a "name=tuser2 groups=root,daemon"

# 删除账户
ansible node1 -m user -a "name=tuser2 state=absent"

# 删除账户所有信息
ansible node1 -m user -a "name=tuser2 state=absent remove=true"

6.8、yum_repository模块

使用yum_repository可以创建或修改yum源配置文件

ansible node1 -m yum_repository -a "name=myyum description=hello baseurl=ftp://192.168.1.1/centos gpgcheck=no"

# 新建yum源配置文件 /etc/yum.repos.d/myyum.repo
# yum源文件名为myyum,内容如下
[myyum]
baseurl=ftp://192.168.1.1/centos
gpgcheck=0
name=hello

# 修改yum源文件内容
ansible node1 -m yum_repository -a "name=myyum description=test baseurl=ftp://192.168.1.1/centos gpgcheck=yes"


# 删除yum源文件
ansible node1 -m yum_repository -a "name=myyum state=absent"

6.9、yum模块

可以安装、卸载、升级软件包

state:present(安装)|absent(卸载)|latest(升级)

# 安装Yum包
ansible node1 -m yum -a "name=unzip state=present"
# 升级
ansible node1 -m yum -a "name=unzip state=latest"

6.10、service模块

服务管理模块,启动关闭,重启服务等。

state:started stopped restarted

enable:yes 设置开机启动

ansible node1 -m yum -a "name=httpd"
# 启动服务并设置开启启动
ansible node1 -m service -a "name=httpd state=started enable=yes"

6.11、逻辑卷相关模块

  • lvg模块:创建、删除卷组(vg),修改卷组大小
  • state:present|absent
  • lvol模块
# 安装lvm2软件包
ansible node1 -m yum -a "name=lvm2"
# 创建myvg卷组,卷组由/dev/vdb1组成
ansbile node1 -m lvg -a "vg=myvg pvs=/dev/vdb1 pvs=/dev/vdb1"

6.5、sudo授权

普通用户以管理员身份执行命令

# 修改/etc/sudoers
vim /etc/sudoers 或者visudo


# 格式
# NOPASSWORD 加在命令前面,就不需要sudo时候输入密码
用户或组  主机列表=(提权身份) [NOPASSWD]:命令列表

root	ALL=(ALL)	ALL
%wheel	ALL=(ALL)	ALL
		任何主机以root身份	
jerry	ALL=(root)	/usr/bin/systemctl,/usr/bin/xxx

# 查看自己有哪些授权
sudo -l

配置sudo提权

ansible all -m user -a "name=alex password={{'123456'|password_hash('sha512')}}"

ansible all -m lineinfile -a "path=/etc/sudoers line='alice ALL=(ALL) /usr/bin/systemctl'"

7、ansible配置文件进阶

vim ~/ansible/ansible.cfg

[defaults]
inventory=~/ansible/hosts
remote_user=alice
# host_key_checking=False
[privilege_escalation]
become=True # 是否需要切换用户
become_method=sudo # 如何切换用户
become_user=root # 切换成什么用户
become_ask_pass=no # sudo是否需要输入密码


# 普通用户
for i in node1 node2 node3
do
	ssh-copy-id alice@$i
done

主机清单文件

多个变量空格隔开

vim ~/ansible/hosts

[test]
node1 ansible_ssh_port=220 

[proxy]
node2 ansible_ssh_user=alice ansible_ssh_port=220

[webserver]
node[3:4] ansible_ssh_pass=密码

[database]
node5 ansible_ssh_private_key_file=密钥文件

8、ansible playbook

特点

  • 将经常需要执行的任务写入一个文件(剧本)
  • 剧本可包含多个任务
  • 随时调用剧本
  • playbook按照yaml格式编写
  • 适合执行周期性经常执行的复杂任务

playbook语法格式

  • playBook文件由一个或多个play组成
  • 每个playbook包含:host\task\variables\roles\handlers
  • ansible-playbook运行playbook

第一个playbook

---
- hosts: all
  tasks: 
    - name: this is first playbook
      ping: 

运行命令:

ansible-playbook ~/ansible/test.yaml

  • hosts由一个或者多个主机组成
  • tasks由一个或者多个任务组成,按照顺序执行
---
- hosts: test,webserver
  tasks:
    - name: this is first playbook
      ping:
    - name: Run a shell command
      shell: touch ~/shell.txt
  • 使用-f指定并发量

ansible-playbook ~/ansible/test.yml -f 5

案例:一个playbook多个play

---
- hosts: test
  tasks:
    - name: this is first play
      ping: 
- hosts: webserver
  tasks: 
    - name: this is second play
      ping:

案例:创建用户

---
- hosts: 
  tasks: 
    - name: create system user
    user: 
      name: john
      uid: 1040
      shell: /bin/bash
      #group: daemon
      groups: daemon,sys
      password: "{{'123'|password_hash('sha512')}}"
      

案例:删除用户

---
- hosts: webserver
  tasks:
    - name: delete user john
      user: 
        name: john
        state: absent

案例:创建卷组和逻辑卷

---
- hosts: test
  tasks: 
    - name: create a new primary partition with a Size of 1GB
      parted:
        device: /dev/sdb
        number: 1
        state: present
        part_end: 1GiB
    - name: create a new primary partition with a Size of 1GB
      parted:
        device: /dev/sdb
        number: 2 # 分区编号为2
        state: present
        part_start: 1GiB # 分区从硬盘的第一个G开始分
        part_end: 3GiB
    - name: create a volume group on top of /dev/sdb11
      lvg: 
        vg: my_vg
        pvs: /dev/sdb1
    - name: create a logical volume of 512m
      lvol:
        vg: my_vg
        lv: my_lv
        size: 512m

案例:软件安装管理

---
- hosts: 
  tasks:
    - name: update list package
      yum: 
        name: 
          - httpd   
          - mariadb
          - mariadb-server
    - name: install dev tool package group
      yum: 
        name: "@Development tools"
    - name: update software
      yum: 
        name: '*'
        state: latest

9、特殊模块

9.1、setup

  • ansible_facts采集被管理端的系统信息
  • 收集的信息被保存在变量中
  • 每次执行playbook,默认第一个任务就是Gathering Facts
  • 使用setup模块可以查询收集到的facts信息

ansible node1 -m setup

过滤filter

支持通配符。

ansible node1 -m setup -a “filter=ip

9.2、debug模块

可以显示获取facts里的变量。

debug模块可以显示变量的值,辅助排错。

debug模块有2个参数,var和msg。引用变量需要{{}}。

---
- hosts: 
  tasks: 
    - debug: 
        var: ansible_all_ipv4_address
    - debug: 
        msg: "主机名是:{{ansible_hostname}}"
    - debug: 
        var: ansible_ap1.options

10、ansible定义变量

定义变量方法十几种,下面是优先级由低到高。

10.1、inventory变量(主机清单定义)

[test] # 主机定义变量
node1 myvar1="hello world" myvar2="hello jack"

[webserver]
node[3:4]
[webserver:vars] # 组定义变量
yourname="jackjob"
---
- hosts: node1
  tasks: 
    - name: create a file with var.
      shell: echo "{{myvar1}}" > /tmp/"{{myvar2}}"
- hosts: webserver
  tasks:
    - name: create a user with var.
      user: 
        name: "{{youname}}"

10.2、Host facts 变量(可以直接调用ansible收集的信息)

---
- hosts: node1
  tasks:
    - name: use facts info.
      copy: 
        content: "{{ansible_hostname}}:{{ansible_bios_version}}"
        dest: /tmp/facts.txt

10.3、Register变量(可以将某个命令的执行结果保存在变量中)

---
- hosts: node1
  tasks: 
    - name: save the result to a variable.
      shell: hostname
      register: myvar
    - name: 
      debug: 
        # msg: "{{myvar}}"
        # 通过.可以获取部分
        msg: "{{myvar.end}}"

10.4、Playbook变量(vars关键字定义变量)

---
- hosts: node1
  vars: 
    ipname: heal
    ipass: "123456"
  tasks: 
    - name: user variable create user
      user:
        name: "{{ipname}}"
        password: "{{ipass|password_hash('sha512')}}"

10.5、Playbook提示变量(根据提示输入变量值)

---
- hosts: test
  vars_prompt: 
    - name: iname
      prompt: "请输入用户名"
      private: no	# 回显用户名
    - name: ipasswd
      prompt: "请输入密码"
      private: yes	# 不显示密码
  tasks: 
    - name: create a user.
      user: 
        name: "{{iname}}"
        password: "{{ipasswd|password_hash('sha512')}}"

10.6、变量文件 (剧本调用 vars_files)

---
uname: jack
ipass: "123456"
---
- hosts: node1
  vars_files: variables.yml
  tasks: 
    - name: create user
      user: 
        name: "{{uname}}"
        password: "{{upwd | password_hash('sha512')}}"

10.7、命令行变量

---
- hosts: 
  tasks: 
    - name: create user
      user: 
        name: "{{name}}"
        password:"{{pwd|password_hash('sha512')}}"

ansible-playbook cmd.yml -e name=”zhangsan” -e pwd=”123456″

11、自动化运维

11.1、ansible模块应用

1、firewalld模块

---
- hosts: test1
  tasks: 
    - name: install firewalld.
      yum:
        name: firewalld
        state: present
    - name: run firewalld.
      service: 
        name: firewalld
        state: started
        enable: yes
    - name: set firewall rule.
      firewalld: 
        port: 80/tcp
        permanent: yes
        state: enable

2、template模块

  • copy可以把文件拷贝给远程主机。
  • copy拷贝常量文件,template拷贝变量文件
  • 希望每个主机拷贝的变量不一致
  • 可以利用jinja2模版读取变量

使用facts自带变量

#index.html
welcome to {{ansible_hostname}} on {{ansible_eth0.ipv4.address}}

---
- hosts: webserver
  tasks: 
    - name: use template copy index.html to webserver.
      template: 
        src: ~/ansible/template/index.html
        dest: /var/www/html/index.html

使用自定义变量

# index.j2
{{welcome}}  {{iname}}

---
- hosts: webserver
  vars: 
    welcome: "hello",
    iname: "jack"
  tasks: 
    - name: use template copy file
      template: 
        src: ~/index.j2
        dest: /tmp/

11.2、error处理机制

默认ansible遇到error会立刻停止playbook。

---
- hosts: node1
  ignore_errors: true # 针对全局忽略出错
  tasks: 
    - name: start server
      service: 
        name: haha # 没有此应用
        state: started
      ignore_errors: true # 针对某个服务忽略出错。

11.3、handlers

任务之间存在依赖关系。

  • 通过handler定义一组任务
  • 某个任务触发handlers时,才执行相应的任务
  • 多个notify触发执行handlers任务,也仅执行一次
  • 仅当任务状态为changed时,handlers任务才执行
  • handlers任务在所有其他任务都执行后才执行。
---
- hosts: node1
  tasks: 
    - name: create direct
      file:
        path: /tmp/subdir/
        state: directory
      notify: touch file
  handlers:
    - name: touch file
      file: 
        path: /tmp/subdir/12.txt
        state: touch
    
    

11.4、条件判断

  • when可以定义判断条件,条件为真时,才执行某个任务。

  • 常见条件操作符

==、!=、>、>=、<、<=

  • 多个条件and 或 or分割

  • when表达式调用变量不使用{{}}

  • > 是不保留换行符的,无论多少行都认为是一行

---
- hosts: node1
  tasks: 
    - name: check mem size
      service: 
        name: NetworkManager
        state: stopped
      when: ansible_memfree_mb < 700
---
- hosts: 
  tasks: 
    - name: touch a file
      file: 
        path: /tmp/when.txt
        state: touch
      when: > # 支持多行输入,不保留换行符
        ansible_distribution == "ReadHat"
        and
        ansible_distribution_major_version == "8"

11.5、block任务块(任务多合一)

将多个任务合并为一个组。

---
- hosts: node1
  tasks: 
    - name: define a gourp of tasks
      block:
        - name: install httpd
          yum: 
            name: httpd
            state: present
        - name: start httpd
          service: 
            name: httpd
            state: started
      when: ansible_distribution == "RedHat"

rescue定义block任务执行失败时要执行的其他任务。

always定义无论block任务是否成功,都要执行的任务。

---
- hosts: node1
  tasks: 
    - block: 
        - name: touch a file test1.txt
          file: 
            path: /tmp/test1.txt
            state: touch
      rescue: 
        - name: touch a file test2.txt
          file: 
            path: /tmp/test2.txt
            state: touch
      always: 
        - name: touch a file test3.txt
          file: 
            path: /tmp/test3.txt
            state: touch

11.6、loop循环

  • item是关键字
# 数组

---
- hosts: webserver
  tasks: 
    - name: mkdir multi dir
      file: 
        path: /tmp/{{item}}
        state: directory
      loop: 
        - School
        - Legend
        - Life
# 对象

---
- hosts: test
  tasks: 
    - name: create multi user.
      user: 
        name: "{{item.iname}}"
        password: "{{item.ipass|password_hash('sha512')}}"
      loop: 
        - {iname:'term',ipass:'123456'}
        - {iname:'amy', ipass:'654321'}

12、ansible vault

  • Ansible有时需要访问敏感数据,如密码、key等。

  • ansible-vault可以加密和解密数据。

    • encrypt 加密
    • decrypt 解密
    • view 查看
    • rekey 修改密码
echo 123456 > data.txt

ansible-vault encrypt data.txt

ansible-vault view data.txt

absible-vault rekey data.txt # 修改密码

# 加密解密输入密码麻烦,将密码写入文件。 pass.txt为密码文件
ansible-vault encrypt --vault-id=pass.txt data.txt

ansible-vault decrypt --vault-id=pass.txt data.txt

传送敏感数据到远程主机

# 电脑存放时候先加密,进行传输再解密

ansible-vault encrypt --vault-id=pass.txt data.txt

ansible test -m copy --vault-id=pass.txt -a "src=data.txt dest=/tmp/ mode=0600"

playbook调用敏感数据

iname: cloud
ipass: '123456'

密码文件加密

ansible-vault encrypt variables.yml

---
- hosts: test
  vars_files: variables.yml
  tasks: 
    - name: include vault data,create user.
      user: 
        name: "{{iname}}"
        password: "{{ipass|password_hash('sha512')}}"

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

或者

ansible-playbook –vault-id=pass.txt vault.yml

13、ansible roles

一般情况我们需要实现不同功能,需要编写大量的playbook文件,并且playbook还会调用其他文件(如变量文件)。管理起来很复杂。

ansible 是1.2版本支持Roles。

Roles是管理ansible文件的一种规范(目录结构)。

roles会按照标准规范,自动到特定的目录和文件中读取数据。

目录结构

ansible/roles

└── issue

├── README.md

├── defaults

│ └── main.yml

├── files

├── handlers

│ └── main.yml

├── meta

│ └── main.yml

├── tasks

│ └── main.yml

├── templates

├── tests

│ ├── inventory

│ └── test.yml

└── vars

└── main.yml

defaults/main.yml 定义变量的缺省值、默认值,优先级低。
files目录 存储静态文件的目录
handlers/main.yml 定义handlers
meta/main.yml 写作者、版本等描述信息
tasks/main.yml 定义任务的地方
templates目录 存放动态数据文件的地方,模版文件
vars/main.yml 定义变量,优先级高

创建Role项目

ansible-galaxy可以创建、管理roles。

mkdir ~/ansible/roles

ansible-galaxy init ~/ansible/roles/issue

tree ~/ansible/roles/issue
This is the system {{ansible_hostname}}
Todays date is : {{ansible_date_time.date}}
Contact to {{admin}}
---
admin: yoyo@ted.cn
---
- name: delete issue file
  template: 
    src: issue.j2
    dest: /etc/issue

调用role

  • 1、在role相同目录下创建一个playbook调用
---
- hosts: webserver
  roles:
    - issue
    - role2 # 支持多个role
  • 2、在ansible.cfg设置roles_path=路径

img

在线共享role网站

https://galaxy.ansible.com/

ansible-galaxy search 'httpd'

# 查看roles基本信息
ansible-galaxy info acandid.httpd

# 下载特定roles
ansible-galaxy install acandid.httpd -p ~/ansible/roles

# 列出本地roles
ansible-galaxy list -p roles

14、综合案例

部署LNMP环境

  1. 拷贝nginx源码包到roles/files下面
  2. 编写安装nginx脚本
#!/bin/bash
conf="/usr/local/nginx/conf/nginx.conf"
yum -y install gcc pcre-devel openssl-devel make 
cd /tmp/
tar -xf nginx-1.16.1.tar.gz
cd nginx-1.16.1
./configure --with-http_ssl_module
make && make install
sed -i '65,71s/#//' $conf
sed -i '/SCRIPT_FILENAME/d' $conf
sed -i 's/fastcgi_params/fastcgi.conf' $conf
---
- name: copy nginx-1.16.1.tar.gz to webserver
  copy: 
    src: nginx-1.16.1.tar.gz # files下面
    dest: /tmp/
- name: install nginx through shell script
  script: install_nginx.sh # 也在files下面
    creates: /usr/local/nginx/sbin/nginx  # 条件判断,文件存在,不执行脚本
- name: copy index.html to webserver
  template: 
    src: index.html
    dest: /usr/local/nginx/html/index.html
- name: install php
  yum: 
    name: 
      - php
      - php-fpm
      - php-mysqlnd
      - mariadb-devel
- name: run all service
  block: 
    - service: 
        name: php-fpm
        state: started
    - shell: /usr/local/nginx/sbin/nginx
      args: 
        creates: /usr/local/nginx/logs/nginx.pid

调用剧本

---
- hosts: webserver
  roles: 
    - lnmp

ansible-playbook lnmp.yaml

原文地址:http://www.cnblogs.com/20190707wdd/p/16801788.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性