ansible

安装

与salt对比

  • 相同
    • 都是为了同时在多台机器上执行相同的命令
    • 都是python开发
  • 不同
    • agent(saltstack需要安装、ansible不需要)
    • 配置(salt配置麻烦,ansible基本不用配置)
    • 学习路线(salt比较陡峭,ansible比较平缓)
    • 第三方工具(salt比较少)
    • 开源社区的对接(salt比较少)
    • 现有用户(salt还是ansible少一些)
    • 二次开发扩展的能力(ansible比较差,尤其是2.0以后)
    • 大规模并发(200以内一样,200以上salt会好一些,当然我们也可以对ansible做一些配置使其在200以上追上salt)
    • Windows的支持(salt会好很多)

安装

yum install -y ansible

查看ansible生成的命令,用到的命令

ansible            
ansible-doc        
ansible-galaxy(下载第三方插件)        
 ansible-playbook

查看ansible 安装生成的

rpm -ql ansible |more
/etc/ansible
/etc/ansible/ansible.cfg #配置文件
/etc/ansible/hosts #主要文件

hosts文件详解

cat /etc/ansible/hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character #注释为#
#   - Blank lines are ignored #空白行被忽略
#   - Groups of hosts are delimited by [header] elements #主机组名被写在[]里面
#   - You can enter hostnames or ip addresses #你可以写ip地址也可以写hostnames
#   - A hostname/ip can be a member of multiple groups #一个主机可以被多个主机组包含

可以在hosts文件中填写的内容

 ansible_ssh_host
  ansible通过ssh连接的IP或者FQDN
ansible_ssh_port
  SSH连接端口
ansible_ssh_user
  默认SSH连接用户
ansible_ssh_pass
  SSH连接的密码(这是不安全的,ansible极力推荐使用--ask-pass选项或使用SSH keys)
ansible_sudo_pass
  sudo用户的密码
ansible_connection
  SSH连接的类型:local,ssh,paramiko,在ansible 1.2之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(支持的前提)
ansible_ssh_private_key_file
  SSH连接的公钥文件

生成秘钥

ssh-keygen
一路回车就可以

将公钥复制到远程主机上

ssh-copy-id root@192.168.226.101
 

查看ansible的命令帮助

ansible <host-pattern> [options]

-a MODULE_ARGS 模块参数
-m MODULE_NAME 模块名称

-f forks 指定一次执行的机器

-C 测试

--list-hosts 查看运行的机器

-v 输出详细信息

第一个ansible程序

ansible test -m ping

获取文档

ansible-doc --help
-s 指定模块名称
-l 列出所有的模块

操作日志

/var/log/message

命令相关

shell command script
command模块 [执行远程命令]
    ansible all -a 'echo "hello world"'
    ansible all -a 'pwd'
    ansible all -a 'echo "oldboy"|passwd --stdin user1' #直接输出结果
script模块 [在远程主机执行主控端的shell/python脚本 ]  (使用相对路径)
ansible all -m script -a 'a.sh'  #执行本地脚本
ansible all -a 'ls /'       #查看文件目录
shell模块 [执行远程主机的shell/python脚本,支持管道]
ansible all -m shell -a 'echo oldboy|passwd --stdin user1'  #设置密码
ansible all -m shell -a 'cat /etc/shadow|grep user1'    #查看用户
ansible all -m shell -a 'python a.py'  #执行远程脚本

文件相关

copy
  dest 目标地址
  src 本地地址  
  mode 权限 wrx/755
  owner  属主
  group  属组
  backup
  content   直接写内容,可以用转移符号
    ansible all -m copy -a 'dest=/data src=/data/a.txt'   #复制单个文件
    ansible all -m copy -a 'src=/etc/init.d dest=/data/'   
    ansible all -m copy -a 'src=/etc/init.d/ dest=/data'  #如果带/则复制里面的内容,不带/则复制目录,如果是目录的话,则会递归复制
    ansible all -m copy -a 'content="hello world" dest=/data/test.txt' 直接输入内容
file
  path
  src
  state
    file file代表拷贝后是文件
    link link代表最终是个软链接
    directory directory代表文件夹
    hard hard代表硬链接
    touch touch代表生成一个空文件
    absent absent代表删除
        ansible all -m file -a 'dest=/data/html state=directory'   #创建目录
        ansible all -m file -a 'dest=/data/html2 state=link src=/etc'  #创建软链接
        ansible all -m file -a 'dest=/data/a.txt state=touch'
        ansible all -m file -a 'dest=/data/a.txt state=absent' 删除
fetch   
    dest
    src
    ansible 10.211.55.14 -m fetch -a 'src=/data/test.txt dest=/data'

软件相关

pip
ansible all -m pip -a 'name=django==1.11'
ansible all -m pip -a "name='django==1.11' state=absent"#卸载 

yum name state absent #卸载 installed #安装 latest #安装最新的版本 present #安装 removed #卸载 ansible all -m yum -a 'name=python-pip state=latest' ansible all -m yum -a 'name=nginx state=latest' ansible all -m yum -a 'name=nginx state=absent'

service

name
state
 ansible all -m service -a 'name=nginx state=started'
 ansible all -m service -a 'name=nginx state=stopped'

cron

name
weekday 周
hour 时
day 天
minute 分钟
month 月
job
state
  absent  #删除
  present  #创建
ansible all -m cron -a 'name=testjob  minute=1 job=ntpdate'
ansible all -m cron -a 'name=testjob  state=absent'

user

name
password
shell
state
uid
group
groups
update_password 
home
ansible all -m user -a 'name=usertest'
ansible all -m user -a 'name=usertest state=absent'

group

gid
name
state  #present 创建  absent 删除
system #是否是系统组
ansible all -m group -a 'name=usertest '
ansible all -m group -a 'name=usertest state=absent'

playbook 剧本

操作都是幂等的

  • 什么是幂等的
    • 操作过以后就不会操作了

为什么要用playbook

  • 有一个更好的知识沉淀
  • 有一些好的功能

知识回顾

ymal

格式

  • 字典:
    • key : value 冒号后面必须有空格
  • 列表:
    • -

建议一个文件处理一个对应一组相关的任务

 ansible-playbook [options] playbook.yml
  -C # 干跑,检查
  -f FORKS # 用来做并发,来指定并发数
  --list-hosts #列出执行命令的主机
  --syntax-check # 检查语法
  --list-tasks #列出playbook要执行的任务列表
  -t TAGS, #指定要运行到tags
   -e EXTRA_VARS #给playbook传递变量
#单个playbook
- hosts: web  #指定要运行命令的主机
  remote_user: root # 指定运行命令的用户
  tasks: #任务列表
  - name: mkdir # 任务1,name是必须的
    file: path=/data state=directory # 指定的模块: 模块的参数
  - name: copyfile
    copy: src=/etc/fstab dest=/data/f
##多个playbook
- hosts: web
  remote_user: root
  tasks:
  - name: mkdir
    file: path=/data state=directory
  - name: copyfile
    copy: src=/etc/fstab dest=/data/f

- hosts: db
  remote_user: root
  tasks:
  - name: wget
    shell: "wget -O /data/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo"
##指定tags 这样就可以单独调用yml文件中的设置了tags的任务 调用方法  nasible-playbook -t copyfile a.yml
- hosts: web
  remote_user: root
  tasks:
  - name: mkdir
    file: path=/data state=directory
  - name: copyfile
    copy: src=/etc/fstab dest=/data/f
    tags: copyfile

任务是从上到下依次执行,每台机器都执行完才执行下一个任务

变量引入

  • 写一个playbook,需要多次创建,比如每次需要创建的不同的用户

第一种设置变量的方法

## 传递变量 -e"key=value"
- hosts: web
  remote_user: root
  tasks:
  - name: yum {{pkg_name}} pkg
    yum: name={{pkg_name}}

第二种设置变量的方法

- hosts: web
  remote_user: root
  vars:
    - pkg_name: memcached
  tasks:
  - name: yum {{pkg_name}} pkg
    yum: name={{pkg_name}}

第三种设置变量的方法

#在hosts文件里面写,值可以不同
[web]
192.168.19.9 pkg_name=nginx
192.168.19.26 pkg_name=redis

第四种设置变量的方法

[web:vars]
pkg_name=nginx

第五种传参方式

第五种传参方式: 通过register注册,直接用.stdout来获取值
- hosts: db
  remote_user: root
  tasks:
  - name: installbc
    yum: name=bc
  - name: sum
    shell: echo 20+21|bc
    register: sum 
  - name: echo 
    shell: echo {{sum}} > /tmp/sum.txt
  - name: createuser
    user: name=alex{{sum.stdout}}

变量的应用顺序

-e > yml文件 > hosts文件 #命令行里面是最高的,hosts文件是最低的

条件

when 条件判断

- hosts: cache
  remote_user: root
  tasks:
  - name: copyfile1
    copy: content='大弦嘈嘈如急雨' dest=/tmp/a.txt
    when: ansible_os_family=="RedHat" #只有为真的时候才会执行上面的操作
  - name: copyfile2
    copy: content='小弦切切如私语' dest=/tmp/b.txt
    when: ansible_os_family=="OpenBSD"

循环

with_items 循环添加

- hosts: cache
  remote_user: root
  tasks:
  - name: create user
    user: name={{item}} ## 循环下面的with_items
    with_items:
    - yuchao
    - yantao
  - name: create group
    group: name={{item}}## 循环下面的with_items
    with_items:
    - yuchao2
    - yantao2

循环嵌套

- hosts: cache
  remote_user: root
  tasks:
  - name: create group
    group: name={{item}}
    with_items:
    - yuchao4
    - yantao4
  - name: create user
    user: name={{item.name}}  group={{item.group}} #可以通过字典取值
    with_items:
    - {"name":yuchao3,"group":yuchao4}
    - {"name":yantao3,"group":yuchao4}    

服务启动

- hosts: web
  remote_user: root
  vars:
  - pkg_name: nginx
  tasks:
  - name: yum {{pkg_name}} pkg
    yum: name={{pkg_name}} state=installed
  - name: start
    service: name={{pkg_name}} state=started

handlers(每次变更文件需要重启服务)

- hosts: web
  remote_user: root
  vars:
  - pkg_name: nginx
  tasks:
  - name: yum {{pkg_name}} pkg
    yum: name={{pkg_name}} state=installed
  - name: copyfile
    copy: src=nginx.conf dest=/etc/nginx/nginx.conf 
    notify: restart #变更后才会触发handlers的任务
  handlers:
  - name: restart
    service: name={{pkg_name}} state=restarted

template

基于janja2语言

- hosts: cache
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis
  - name: copyfile
    template: src=redis.conf.j2 dest=/etc/redis.conf ## 模板基于jinja2
  - name: start
    service: name=redis state=started
  #模板文件放在templates(在yml文件同级目录创建 ),可以直接用相对路径去调用配置文件    

roles

作用:

  • 结构清晰
  • 可以重用
tasks #目录是必须的,存放任务
templates #是存放模板
vars #用来存放变量    ### 切记,不能加-,加-报错
files #用来存放文件
mkdir -p {nginx,uwsgi,mysql}/{tasks,templates,vars,files} #创建目录结构的命令
 hosts: web
  remote_user: root
  roles:
  - role: nginx
    tags: [ 'web','nginx']  # 指定tags
  - { role: http,tags: [ 'web','http']} # 指定tags
  用 -t 来调用
- hosts: web
  remote_user: root
  roles:
  - role: nginx
    tags: [ 'web','nginx']
    when: ansible_distribution_major_version== "7" # 条件
  - role: http
    tags: [ 'web','http']
    when: ansible_distribution_major_version== "6" # 条件

 

Ansible Galaxy

Ansible Galaxy 是一个自由网站,网站提供所有类型的由社区开发的 roles,这对于实现你的自动化项目是一个很好的参考。网站提供这些 roles 的排名、查找以及下载。

应用实例

你现在已经学过 tasks 和 handlers,那怎样组织 playbook 才是最好的方式呢?简单的回答就是:使用 roles ! Roles 基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers。基于 roles 对内容进行分组,使得我们可以容易地与其他用户分享 roles 。
如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。

production                # inventory file for production servers 关于生产环境服务器的清单文件
stage                     # inventory file for stage environment 关于 stage 环境的清单文件

group_vars/
   group1                 # here we assign variables to particular groups 这里我们给特定的组赋值
   group2                 # ""
host_vars/
   hostname1              # if systems need specific variables, put them here 如果系统需要特定的变量,把它们放置在这里.
   hostname2              # ""

library/                  # if any custom modules, put them here (optional) 如果有自定义的模块,放在这里(可选)
filter_plugins/           # if any custom filter plugins, put them here (optional) 如果有自定义的过滤插件,放在这里(可选)

site.yml                  # master playbook 主 playbook
webservers.yml            # playbook for webserver tier Web 服务器的 playbook
dbservers.yml             # playbook for dbserver tier 数据库服务器的 playbook

roles/
    common/               # this hierarchy represents a "role" 这里的结构代表了一个 "role"
        tasks/            #
            main.yml      #  <-- tasks file can include smaller files if warranted
        handlers/         #
            main.yml      #  <-- handlers file
        templates/        #  <-- files for use with the template resource
            ntp.conf.j2   #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- files for use with the copy resource
            foo.sh        #  <-- script files for use with the script resource
        vars/             #
            main.yml      #  <-- variables associated with this role
        defaults/         #
            main.yml      #  <-- default lower priority variables for this role
        meta/             #
            main.yml      #  <-- role dependencies

    webtier/              # same kind of structure as "common" was above, done for the webtier role
    monitoring/           # ""
    fooapp/               # ""

site.yml

在 site.yml 中,我们包含了一个定义了整个基础设施的 playbook.注意这个 playbook 是非常短的, 因为它仅仅包含了其他 playbooks.记住, playbook 不过就是一系列的 plays:

---
# file: site.yml
- include: webservers.yml
- include: dbservers.yml

在诸如 like webservers.yml 的文件中(同样也在顶层结构),我们仅仅将 Web 服务器组与对应的 role 行为做映射.同样值得注意的是这也非常的短小精悍.例如:

---
# file: webservers.yml
- hosts: webservers
  roles:
    - common
    - webtier

理念是我们能够通过 “运行”(running) site.yml 来选择整个基础设施的配置.或者我们能够通过运行其子集 webservers.yml 来配置. 这与 Ansible 的 “–limit” 类似,而且相对的更为显式:

ansible-playbook site.yml --limit webservers
ansible-playbook webservers.yml

接下来的示例任务文件展示了一个 role 是如何工作的.我们这里的普通 role 仅仅用来配置 NTP,但是如果我们想的话,它可以做更多:

---
# file: roles/common/tasks/main.yml

- name: be sure ntp is installed
  yum: pkg=ntp state=installed
  tags: ntp

- name: be sure ntp is configured
  template: src=ntp.conf.j2 dest=/etc/ntp.conf
  notify:
    - restart ntpd
  tags: ntp

- name: be sure ntpd is running and enabled
  service: name=ntpd state=running enabled=yes
  tags: ntp

这是个处理文件样例.作为一种审核,它只有当特定的任务报告发生变化时会被触发,并在每个 play 结束时运行:

---
# file: roles/common/handlers/main.yml
- name: restart ntpd
  service: name=ntpd state=restarted



笔记:

 

    aaa={"a":11,"b":34,"c":12,"d":23}
    1.实现k,v替换
    2.按照value排序(("a":11),("c":12),("d":23),("b":34))

昨日内容回顾

file 在被控机上创建文件夹或者文件,软链接,硬链接

- path
- src
  目标源文件
- state
  - link
  - hard
  - directory
  - touch
  - absent
  - file
- mode
- group
- owner

fetch 拉取远程主机的文件,以远程主机的ip地址或者hostname创建目录,并保存目录的机构

- src
- dest

yum 安装linux软件包

- name
- state

pip 安装python的三方包

- name
- chdir
- state

service 操作服务

- name
- state
  - started
  - stopped
  - restarted
  - reloaded
- enabled

cron 定时任务

- minute
- hour
- day
- month
- weekday
- job
- name
- disabled
- 分钟最好不要用*

user 创建用户

- name
- home
- uid
- group
- groups
- password
- shell zsh 内建命令 外部命令
- system
- remove
- state

group 创建用户组

- gid
- name
- state
- system



web组

1. 创建alex10用户,指定用户的家目录为/opt/alex10,指定用户的id为3000,指定用户的附加组为root
   ansible web -m user -a "name=alex10,home=/opt/alex10,uid=3000,groups=root"
2. 创建wusir10用户组
   ansible web -m group -a "name=wusir10"
3. 将本地的/etc/fstab 复制到远程,并指定属主是alex10,属组是wusir10
   ansible web -m copy -a "src=/etc/fstab dest=/tmp owner=alex10 group=wusir10"
4. 安装redis并启动,设置开机自启动
   ansible web -m yum -a "name=redis"
   ansible web -m service -a "name=redis  enabled=yes state=started"
5. 安装django
   ansible web -m pip -a "name=django==1.11"
6. 设置计划任务每天凌晨2点半备份/etc/目录
   ansible web -m cron -a "minute=30 hour=2 job='tar zcf /tmp/etcdate +%F.tar.gz /etc' name=backup"
7. 将被控节点上的网卡文件拉取到本地的/tmp目录下
   ansible web -m fetch -a "src=/etc/sysconfig/network-scripts/ifcfg-ens33 dest=/tmp"
8. 在被控节点上创建软链接,源文件为/etc/fstab,目标文件为/tmp/f
   ansible web -m file -a "path=/tmp/f src=/etc/fstab state=link"
9. 安装开发包组
   ansible web -m yum -a "name='@Development Tools'"

补充

    echo `date +%F`
    echo $(date +%F)
    a=10
    echo '$a'
    $a
    echo "$a"
    10

Ad-hoc 在命令行直接执行的

playbook

yaml

xml

json

- 字典 key:value
- 列表 [] -
      - alex
      - wusir
      - yantao
      - yuchao 
        
      [alex,wusir,yantao,yuchao]
  

playbook格式

    Usage: ansible-playbook [options] playbook.yml [playbook2 ...]
    -C, --check #白跑,执行但是不会有结果
    --list-hosts #列出符合的主机
    -f FORKS, --forks=FORKS #做并发
    --syntax-check #检查语法
    -k, --ask-pass #输入密码
    

单个playbook

    - hosts: web
      remote_user: root
      tasks:
      - name: createuser
        user: name=alex20 home=/opt/alex20 uid=4000

多个playbook

    - hosts: web
      remote_user: root
      tasks:
      - name: createuser
        user: name=alex20 home=/opt/alex20 uid=4000 
      - name: copyfile
        copy: src=/etc/fstab dest=/tmp/fs
    

幂等性 不管执行多少次,得到的结果都是一样的

    - hosts: web
      remote_user: root
      tasks:
      - name: createuser
        user: name=alex20 home=/opt/alex20 uid=4000
      - name: copyfile
        copy: src=/etc/fstab dest=/tmp/fs
    - hosts: db
      tasks:
      - name: copyfile
        copy: src=/etc/fstab dest=/tmp/fs                         

传参

第一种方式

    - hosts: web
      tasks:
      - name: create{{user}}
        user: name={{user}}
    ansible-playbook -e user=wusir20 p3.yml

第二种方式

    [web]
    192.168.226.[101:102] user=alex30
    192.168.226.104  user=alex100
    



第三种方式

    [web:vars]
    user=alex31

第四种方式

    - hosts: web
      vars:
      - user: alex32
      tasks:
      - name: create{{user}}
        user: name={{user}}

第五种传参方式

    - hosts: web
      tasks:
      - name: yum
        yum: name=bc
      - name: sum
        shell: echo 11+22|bc
        register: user
      - name: echo
        shell: echo {{user.stdout}} > /tmp/echo.txt 
      - name: create{{user.stdout}}
        user: name=alex{{user.stdout}}
    

优先级

    -e > playbook > hosts

setup

    ansible_all_ipv4_addresses #所有的ipv4地址
    ansible_all_ipv6_addresses #所有的ipv6地址
    ansible_architecture #系统的架构
    ansible_date_time #系统时间
    ansible_default_ipv4 #默认的ipv4地址
        address ip地址
        alias 网卡名称
        broadcast 广播地址
        gateway 网关
        netmask 子网掩码
        network 网段
    ansible_default_ipv6 #默认的ipv6地址
    ansible_device_links #系统的磁盘信息
    ansible_distribution #系统名称
    ansible_distribution_file_variety #系统的基于公司
    ansible_distribution_major_version #系统的主版本
    ansible_distribution_version #系统的全部版本
    ansible_dns #系统的dns 默认udp 端口53
    ansible_domain #系统的域 ldap
    ipv4 #ipv4地址
    ansible_env #系统的环境
    ansible_fqdn #系统的完整主机名
    ansible_hostname #系统的简写主机名
    ansible_kernel #系统的内核版本
    ansible_machine #系统的架构
    ansible_memtotal_mb #系统的内存
    ansible_memory_mb #系统的内存使用情况
    ansible_mounts #系统的挂载信息
    ansible_os_family #系统家族
    ansible_pkg_mgr #系统的包管理工具
    ansible_processor #系统的cpu
    ansible_processor_cores #每颗cpu的核数
    ansible_processor_count #cpu的颗数
    ansible_processor_vcpus #cpu的个数=cpu的颗数*每颗cpu的核数
    ansible_python #系统python信息
    ansible_python_version #系统python的版本
    ansible_system #系统名字
    

tags

    - hosts: web
      tasks:
      - name: install
        yum: name=redis
      - name: copyfile
        copy: dest=/etc/redis.conf src=/etc/redis.conf
        tags: copy
      - name: start
        service: name=redis state=started
    ansible-playbook -t copy p7.yml# -t 是先给任务打上标签,然后可以只运行这一个任务,别的任务不运行

handlers

    - hosts: web
      tasks:
      - name: install
        yum: name=redis
      - name: copyfile
        copy: dest=/etc/redis.conf src=/etc/redis.conf
        tags: copy
        notify: restart#当copyfile任务运行完成时会出发这个restart任务
      - name: start
        service: name=redis state=started
      handlers:#这个是restart任务
      - name: restart
        service: name=redis state=restarted

template

绝对路径

    - hosts: web
      tasks:
      - name: install
        yum: name=redis
      - name: copyfile
        template: dest=/etc/redis.conf src=/etc/redis.conf
        tags: copy
        notify: restart
      - name: start
        service: name=redis state=started
      handlers:
      - name: restart
        service: name=redis state=restarted

mv redis.conf{,.j2} = mv redis.conf redis.conf.j2

相对路径

    - hosts: web
      tasks:
      - name: install
        yum: name=redis
      - name: copyfile
        template: dest=/etc/redis.conf src=redis.conf.j2
        tags: copy
        notify: restart
      - name: start
        service: name=redis state=started
      handlers:
      - name: restart
        service: name=redis state=restarted
    在当前目录下创建一个templates的目录,就可以使用相对路径

yy 复制一行

# yy 复制多行

p 粘贴

dd 删除一行

# dd 删除多行

d$ 从当前位置删除到结尾

when

    - hosts: web
      tasks:
      - name: copyfile
        copy: content="大弦嘈嘈如急雨" dest=/tmp/a.txt
        when: ansible_distribution_major_version=="7"
      - name: copyfile
        copy: content="小弦切切如私语" dest=/tmp/a.txt
        when: ansible_distribution_major_version=="6"
    

    - hosts: web
      tasks:
      - name: copyfile
        copy: content="大弦嘈嘈如急雨" dest=/tmp/a.txt
        when: user=="4"
      - name: copyfile
        copy: content="小弦切切如私语" dest=/tmp/a.txt
        when: user=="3"
    

with_items

    - hosts: web
      tasks:
      - name: createuser
        user: name={{item}}
        with_items:
        - alex50
        - wusir50
        - taibai50



    - hosts: web
      tasks:
      - name: createuser
        user: name={{item}}
        with_items:
        - alex51
        - wusir51
        - taibai51
      - name: creategroup
        group: name={{item}}
        with_items:
        - alex60
        - wusir60
        - taibai60
    

嵌套循环

    - hosts: web
      tasks:
      - name: crateuser
        user: name={{item.name}}  group={{item.group}}
        with_items:
        - {"name":alex52,"group":alex60}
        - {"name":wusir52,"group":wusir60}
        - {"name":taibai52,"group":taibai60}

今日内容总结

yaml

- 字典 key:value
- 列表 :[] -

传参:

- -e
- host文件ip地址后面写
- hosts文件里面[web:vars]
- playbook vars
- register  获取值stdout
- -e > playbook > hosts文件

setup

tags 打一个标签,可以指定单独的标签运行

handlers 被触发的任务,notify 触发

template 可以动态的传递参数,在setup获取

when 判断

with_items 循环
ansible-playbook日记
1. 创建alex10用户,指定用户的家目录为/opt/alex10,指定用户的id为3000,指定用户的附加组为root
   ansible db -m user -a "name=alex10 uid=3000 home='/opt/alex10' groups=root "

二  创建wusir10用户组

1. 创建wusir10用户组

三  将本地的/etc/fstab 复制到远程,并指定属主是alex10,属组是wusir10

    1.ansible db -m copy -a "src=/etc/fstab dest=/tmp owner=alex group=wusir10"

四 安装redis并启动,设置开机自启动

    1  ansible db -m yum -a "name='redis'  "

    2 ansible db -m service -a "name='redis' enabled = yes"

五  安装django

    1 ansible db -m yum -a " name='python2-pip' "

    2 ansible db -m pip -a "name='django==1.11' "

六 设置计划任务每天凌晨2点半备份/etc/目录

    1. ansible db -m cron -a "name='etc_backup_copy' hour=2 minute=30 job='cp -rf /etc /tmp/etc_back' "

七 将被控节点上的网卡文件拉取到本地的/tmp目录下

  1 ansible db -m fetch -a "dest=/tmp src=/etc/sysconfig/network-scripts/ifcfg-ens33"

八 在被控节点上创建软链接,源文件为/etc/fstab,目标文件为/tmp/f

  1 ansible db -m file -a "state=link src=/etc/fstab path=/tmp/f"

九 安装开发包组 
ansible 作业及答案 二
一 安装ansible 

1. yum install -y wget #下载wget
2. wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/rpel-7.repo 
3. yum install -y ansible  

二 获取db组/opt目录下文件 

    1   ansible db -m command -a "ls /opt"

    2   ansible db -m command -a "chdir=/ ls"

三 .创建xiaoqiang2用户,并设置密码为xiaoqiang 

     1 ansible db -m shell -a "useradd xiaoqiang3"#创建新用户

    2.ansible db -m shell -a "echo 'xiaoqiang' | passwd xiaoqiang3"#这条命令既可以修改用户密码也可以给新用户设置密码



四..在/tmp目录下生成xiaoqiang.txt文件,文件的内容为"大弦嘈嘈如急雨,小弦切切如私语,嘈嘈切切错杂弹,大珠小珠落玉盘" 

    1 ansible db -m shell -a "touch /tmp/xiaoqiang.txt"

    2 ansible db -m copy -a " content='大弦嘈嘈如急雨,小弦切切如私语,嘈嘈切切错 杂弹,大珠小珠落玉盘' dest=/tmp/xiaoqiang.txt"

五 将本地的网卡配置文件复制到远程机器上,并命名为network,用户为xiaoqiang2,用户组为xiaoqiang2,权限为744 

    1.  ansible db -m copy -a " src=/etc/sysconfig/network-scripts/ifcfg-ens33    dest=/tmp/network       group=xiaoqiang3   owner=xiaoqiang3 mode=755  "

六 将/etc/rc3.d目录复制到远程机器上,指定用户名为alex,权限为755 

    1.  ansible db -m copy -a "src=/etc/rc3.d   owner=alex mode=755   dest=/tmp/rc3.d   "

七 将/etc/rc6.d目录下的文件复制到远程机器上 

    1.  ansible db -m copy -a "src=/etc/rc3.d/   owner=alex mode=755   dest=/tmp/rc3.d   "

八  写一个脚本获取web组的系统内核版本号 

1. cd /tmp
2. vi a.sh
3. 在文本中写入  #!/bin/bash     cat /proc/version   wq!保存退出
4. 在管控机上执行  ansible db -m script -a "/tmp/a.sh"
    
ansible 作业及答案 一
一 :         创建alex61,alex62,alex63用户,分别指定用户的家目录为/opt/alex61,/opt/alex62,/opt/alex63,指定用户的id为3000,3001,3002,指定用户的附加组为root 

    - hosts: db
      tasks:
      - name: createuser
        user: name={{item.name}} home={{item.home}} uid={{item.uid}} groups=root
        with_items:
        - {"name":alex61,"home":/opt/alex61,"uid":3000}
        - {"name":alex62,"home":/opt/alex62,"uid":3001}
        - {"name":alex63,"home":/opt/alex63,"uid":3002}
                                



二  创建wusir10用户组 

    - hosts: db
      tasks:
      - name: create group
        group: name=wusir51

三 将本地的/etc/fstab 复制到远程,并指定属主是alex10,属组是wusir10

    - hosts: db
      tasks:
      - name: copy
        copy: src=/etc/fstab dest=/tmp owner=alex62 group=wusir51

四4.安装nginx并启动,设置开机自启动,指定监听地址为ip地址

    - hosts: db
      tasks:
      - name: install nginx
        yum: name=nginx
      - name: copyfile
        template:  src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
        notify: restart nginx
        tags: copy
      - name: power up
        service: name=nginx enabled=yes state=started
      - name: restart nginx
        service: name=nginx state=restarted

    server {
            listen       {{ansible_default_ipv4.address}}:80 default_server;
            server_name  _;
            root         /usr/share/nginx/html;
    
            # Load configuration files for the default server block.
            include /etc/nginx/default.d/*.conf;

五.安装django

    - hosts: db
      tasks:
      - name: setup django
        pip: name='django==1.11'

六设置计划任务每天凌晨2点半备份/etc/目录

    - hosts: db
      tasks:
      - name: backup etc
        cron: hour=2 minute=30 job='tar zcv /tmp/a.tar.gz /etc/' name='backup etc'



七.将被控节点上的网卡文件拉取到本地的/tmp目录下

    - hosts: db
      tasks:
      - name: fetch
        fetch: src=/etc/sysconfig/network-scripts/ifcfg-ens33 dest=/tmp

八.在被控节点上创建软链接,源文件为/etc/fstab,目标文件为/tmp/f 

    - hosts: db
      remote_user: root
      tasks:
      - name: link
        file: src=/etc/fstab path=/tmp/f state=link

九安装开发包组

    - hosts: db
      tasks:
      - name: deve tools
        yum: name='@Development Tools'

十 在centos6里面添加“飞流直下三千尺”,centos7里面添加“疑是银河落九天”

    - hosts: db
      remote_user: root
      tasks:
      - name: centos 6
        copy: content='飞流直下三千尺' dest=/tmp/as.txt
        when: ansible_distribution_major_version == '6'
      - name: centos 7
        copy: content='疑是银河落九天' dest=/tmp/as.txt
        when: ansible_distribution_major_version == '7'
ansible-playbook作业及答案

安装

 

#下载wget
yum install -y wget
#将epel源下载到本地
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#安装ansible
yum install -y ansible

ansible 命令格式

Usage: ansible <host-pattern> [options]
-a MODULE_ARGS, #模块参数
-C, --check # 干跑,白跑
-f FORKS, --forks=FORKS #指定并发,默认5个
--list-hosts #列出主机
-m MODULE_NAME# 模块名称
--syntax-check #检查语法
-k #密码

ping走什么协议 ICMP

rpm -ql ansible|more # 查看ansible生成的文件
/etc/ansible
/etc/ansible/ansible.cfg #配置文件
/etc/ansible/hosts 
/etc/ansible/roles #空文件夹

ansible配置主机配置文件

/etc/ansible/hosts

[web]
192.168.226.[101:102]
[db]
192.168.226.102
192.168.226.103
[cache]
192.168.226.103

生成秘钥

ssh-keygen
一路回车就可以

将公钥复制到远程主机上

ssh-copy-id root@192.168.226.101

ansible 底层是通过ssh实现的

## www[001:006].example.com  代表 www001-www006(包含)

ansible的第一个命令

ansible 192.168.226.101 -m ping #单独机器的ping
ansible 192.168.226.101,192.168.226.102 -m ping #多个机器的ping
ansible all -m ping #全部机器
ansible web -m ping #单个的组
ansible web,db -m ping #多个组的并集
ansible 'web:&db' -m ping #多个组的交集
ansible 'web:!db' -m ping #多个组的差集,在前面但是不在后面

host-pattern的格式

  • 单个的ip地址
  • 多个的ip地址,用,分割
  • 单个组
  • 多个组全部 all表示
    • 并集
      • web,db
      • ‘web:db’
    • 交集 ‘web:&db’
    • 差集 ‘web:!db’

ansible-doc 命令格式

ansible-doc [-l|-F|-s] [options] [-t <plugin type> ] [plugin]
-j #以json的方式返回数据
 -l, --list #列出所有的模块
 -s, --snippet #以片段式显示模块信息
 #直接查看完整信息

command

ansible web -m command -a "pwd"
ansible web -m command -a "ls"
ansible web -m command -a "chdir=/tmp pwd" #切换目录并执行命令
ansible web -m command -a "creates=/tmp pwd" #因为tmp目录存在,pwd不会执行
ansible web -m command -a "creates=/tmp2 pwd" #因为tmp2不存在,pwd执行
ansible web -m command -a "removes=/tmp2 pwd" #因为tmp2不存在pwd不执行
ansible web -m command -a "removes=/tmp pwd" #因为tmp目录存在,pwd会执行
echo "1234" |passwd --stdin alex #设置用户的密码

shell

ansible web -m shell -a "echo '1234' |passwd --stdin alex"
ansible web -m shell -a "chdir=/tmp pwd" shabang
ansible 192.168.226.101 -m shell -a "bash a.sh" #执行shell脚本
ansible 192.168.226.101 -m shell -a "/root/a.sh" # 执行shell脚本,文件要有执行的权限
ansible 192.168.226.101 -m shell -a "/root/a.py" #执行Python文件

script

ansible db -m script -a "/root/a.sh" #执行本地的文件,管控机的文件
ansible db -m script -a "creates=/root/a.sh /root/a.sh" # 判断被控机上的文件是否存在,如果不存在,就执行,如果存在,就跳过
ansible db -m script -a "creates=/tmp /root/a.sh" #判断被控机上的文件

copy

backup #创建一个备份文件,以时间结尾
content #直接往文件里面写内容
dest #目标地址
group #属组
mode# 文件的权限 W 2 R 4 X 1
owner #属主
src #源地址
ansible web -m copy -a "src=/etc/fstab dest=/tmp/f" #复制本地文件到远程主机,并修改文件名,多次执行不会改变,因为checksum值是一样的
ansible web -m copy -a "src=a.sh dest=/tmp/a.sh backup=yes" #复制本地文件,并备份
ansible web -m copy -a "src=a.sh dest=/tmp/a.sh backup=yes group=alex mode=755"# 复制本地文件到远程主机,并指定属组和权限
ansible web -m copy -a "src=/etc/init.d dest=/tmp backup=yes group=alex mode=755" #复制本地的目录到远程主机,修改目录权限,则目录里面的文件也会跟着变更
ansible web -m copy -a "src=/etc/init.d/ dest=/tmp backup=yes group=alex mode=755" #复制本地目录下的所有文件,
ansible web -m copy -a "content='大弦嘈嘈如急雨,小弦切切如私语,嘈嘈切切错 杂弹,大珠小珠落玉盘' dest=/tmp/b" #直接往文件里面写内容,覆盖写,慎用

今日内容总结

安装:epel源

命令格式

ansible host-pattern options

host-pattern

  • 单个的ip地址
  • 多个的ip地址,用,分割
  • 单个组
  • 多个组全部 all
    • 交集 'web:&db'
    • 并集
      • 'web:db'
      • web,db
    • 差集 ‘web:!db’

command

  • chdir
  • creates
  • removes

shell 支持特殊字符 <>|&$;

  • chdir
  • creates
  • removes

script 执行本地的脚本,判断被控机上是否存在文件

  • chdir
  • creates
  • removes

copy

  • backup 备份,以时间结尾
  • content 直接往文件里面写内容
  • dest 目标文件,被控机的路径
  • src 源文件,直接写目录,则复制整个目录,如果目录后面以/结尾,则复制的目录下的所有文件
  • owner 属主
  • group 属组
  • mode 权限
 

FILE

group # 属组
mode #权限
owner #属主
path #路径
state =link
state =hard
state
directory 目录
file
touch 空文件
absent 删除
link 软连接
hard 硬链接
ansible web -m file -a "path=/alex5 state=directory owner=alex" #创建目录,并制定属主
ansible web -m file -a "path=/tmp/wusir.txt state=touch mode=777" #创建文件,并指定权限
ansible web -m file -a "path=/tmp/cron src=/var/log/cron state=link" #创建软链接,链接的是自己的文件
ansible web -m file -a "path=/tmp/cron state=absent" # 删除软连接
ansible web -m file -a "path=/alex5 state=absent" #删除文件夹

补充


软连接 快捷方式  ln -s   源文件修改软连接修改 源文件删除软连接失效 可以跨分区
硬链接 硬盘的位置 ln     源文件修改硬链接修改 源文件删除硬链接不变 不可以跨分区
复制   开辟新空间 cp     源文件修改cp的不变   源文件删除不变 可以跨分区

fetch


dest 目标地址
src 源地址
ansible web -m fetch -a "src=/var/log/cron dest=/tmp" #拉取远程主机的文件,并以主机ip地址或者主机名为目录,并且保留了原来的目录结构

yum

补充

1.yum跟rpm有什么关系,有什么区别
rpm redhat package manager
yum 可以解决依赖关系
2.yum源怎么配置
[epel]    #名称
name=Extra Packages for Enterprise Linux 7 - $basearch  #全名或者描述信息
baseurl=http://mirrors.aliyun.com/epel/7/$basearch  # 源url地址
failovermethod=priority
enabled=1  #是否启用,1启用,0不启用
gpgcheck=0  #是否检验key文件,0不校验 1校验
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
3.yum怎么安装包组
yum grouplist #查包组信息

disablerepo #禁用某个源
enablerepo #启用某个源
name #包名
state
install
remove
ansible web -m yum -a "name=python2-pip" #安装软件包
ansible web -m yum -a "name=python2-pip,redis" #安装多个包
ansible web -m yum -a "name='@Development Tools'" #安装包组
ansible web -m yum -a "name=nginx state=absent" #卸载

pip

补充


pip freeze > a.txt #将本地环境导出 #原生centos命令

pip install -r a.txt  #安装所有的包
pip list #查看所有的包
pip uninstall flask #卸载
# 下载包
Python setup.py build
python setup.py install

chdir #切换目录
name #包名
requirements #导出的文件
virtualenv #虚拟环境
ansible db -m pip -a "name='django==1.11' "#指定版本安装 否则安装最新版
ansible db -m pip -a "name='django'state=absent "#卸载
 

service

补充


启动
systemctl start redis centos7 #原生centos命令

service redis start centos6
开机自启动
systemctl enable redis centos7
chkconfig redis on centos6
0 关机  1单用户 3命令行 5图形界面 6重启
ps -ef|grep redis #查进程
ss
-t tcp
-u udp
-n 以端口形式显示
-l 显示所有已经启动的端口
-p 显示pid
ssh 22
http 80
https 443
mysql  3306
redis 6379
mongodb 27017
oracle 1521
tomcat 8080
windows 远程桌面 3389
ftp 20 21
django 8000
flask  5000
enabled #开机启动
name #服务名称
state  
  started
  stopped
  restarted
  reloaded
user #启动的用户
ansible web -m service -a "name=redis state=started" #启动
ansible web -m service -a "name=redis state=stopped" #关闭
ansible web -m service -a "name=redis enabled=yes" #设置开机自启动

cron

补充


crontab
* * * * * job
分 时 日 月 周 任务
3/* * * * * job 每隔3分钟执行一次
4 10-12 * * * job 10点-12点第4分钟执行,包括12点
0-59 0-23 1-31 1-12 0-7
分钟最好不要用*
分钟最好不要用*
分钟最好不要用*
分钟最好不要用*
尽量写绝对路径
* * * * * tar zcf /tmp/etc.tar.gz /etc
#原生centos命令

备份
同步时间
删除文件
-e 编辑
-l 查看
-r 删除
day 天
disabled 禁用crontab,表现形式加#
hour 小时
job 任务
minute 分钟
month 月
name 名字,描述信息
user 用户
weekday 周
添加时名字必须不同,不加名称为None
ansible web -m cron -a "minute=12 name=touchfile job='touch /tmp/xiaoqiang.txt'"# 创建
ansible web -m cron -a "name=touchfile state=absent" #删除
ansible web -m cron -a "minute=12 name=touchfile2 job='touch /tmp/xiaoqiang.txt' disabled=yes" #注释
ansible web -m cron -a "name=None state=absent" #删除名称为空的计划任务

user

补充


tail /etc/passwd
tail /etc/shadow
id alex2
useradd #原生centos命令
-d 设置用户家目录
useradd -d /opt/alex2 alex2
-g 设置用户的属组
useradd -g alex2 alex3
-G, --groups 附加组
useradd -G alex2,root alex4
-r, --system 系统账号
useradd -r alex5 # 系统账号没有家目录
-s, --shell #设置用户登录后的shell
useradd -s /sbin/nologin alex8
-u, --uid UID #设置用户的id
useradd -u 2000 alex9
设置了用户的id以后,在设置用户则从最大的id开始往后数
用户分类
超级管理员 root 0
普通用户
系统用户 启动一些服务或者进程,不能登录  1-999 centos7 1-499 centos6 从大到小
登录用户 可以登录的用户 1000-65535 centos7 500-65535 centos6
从小到大
userdel
userdel alex8 默认不删除家目录
-r 删除用户的家目录
userdel -r alex9 删除用户并删除用户的家目录

group 属组
groups 附加组
home 设置家目录
name 用户名
remove 删除用户并删除用户的家目录
shell 用户登录后的shell
system 系统用户
uid 用户的id
ansible web -m user -a "name=alex10 shell=/sbin/nologin home=/opt/alex10 uid=3000 groups=root" #创建用户,并指定用户的shell,家目录,uid,以及附加组
ansible web -m user -a "name=alex11 shell=/sbin/nologin home=/opt/alex11"
ansible web -m user -a "name=alex12 system=yes" #创建系统用户
ansible web -m user -a "name=alex12 state=absent" #删除用户,单不删除家目录
ansible web -m user -a "name=alex11 state=absent remove=yes" # 删除用户并删除用户的家目录

group

补充


groupadd #原生centos命令
-g 设置id
-r 系统组
超级管理员组 root 0
普通组
系统组  1-999 centos7 1-499 centos6 从大到小
登录用户组 1000-65535 centos7 500-65535 centos6
从小到大
查看
tail /etc/group
groupadd -g 3000 wusir10
groupadd -r wusir11

gid 组id
system 系统组
name 名称
ansible web -m group -a "name=wusir10 system=yes gid=5000" 创建系统组
ansible web -m group -a "name=wusir11" 创建普通的组
ansible web -m group -a "name=wusir11 state=absent" #删除组