ansible学习笔记分享

yum install ansible -y   #安装,注意yum源问题

yum源:
yum  install  epel-release  -y
mv  /etc/yum.repos.d/epel.repo  /etc/yum.repos.d/epel.repo.bak >> /dev/null
yum clean all  
rpm -Uvh http://mirrors.ustc.edu.cn/epel/epel-release-latest-7.noarch.rpm
yum makecache

cd /etc/ansible/   切换目录
cat ansible.cfg |grep -v "^#"  |grep  -v "^$"   #检查生效的配置文件
vim hosts   #编辑主机清单文件,在文件末尾添加如下:(这个是默认清单文件位置,也可以ansible -i或者ansible-playbook    -i 指定)
[pxg]
192.168.137.155
192.168.137.162  
以上意思为:主机组pxg包含这两个IP的主机

定义嵌套组
通过创建后缀为:children的主机组名称来实现,例子如下:
[web]
web1.example.com
web2.example.com
[db]
db1.example.com
db2.example.com
[all:children]
web
db   

上述例子可以改成 
[web]
web[1:2].example.com
[db]
db[1:2].example.com
[webdb:children]
web
db  

ansible    pxg --list   ###清单验证:看看pxg清单有哪些主机
ansible    all --list-hosts  ##查看所有默认清单
ansible      all  -i  /tmp/inventory    --list-hosts  ###含义自己猜
ansible     localhost    --list-hosts     //清单中不用写,也可以列出本地机器

ansible配置文件
优先级从高到低:ANSIBLE_CONFIG环境变量指定的配置文件,运行ansible命令所在的目录的ansible.cfg文件,
用户主目录是否有.ansible.cfg,最后全局配置文件/etc/ansible/ansible.cfg
配置文件示例:
配置例子
[defaults]
inventory = ./inventory  ######主机清单文件位置
remote_user = testuser   ######指定登录受管主机的用户,不指定则为当前用户  
                         受控主机上/etc/sudoers.d目录创建新文件testuser写入:testuser   ALL=(ALL)   NOPASSWD:ALL
                         注意:如果不写nopasswd,配置文件中become_ask_pass无论设置什么,都将提示你输入密码
ask_pass = false        #######是否提示输入密码,如果使用ssh公钥验证则可以是false
deprecation_warnings=false   #######拒绝警告

[privilege_escalation]   #####privilege_escalation 配置ansible如何在受管主机上执行特权升级
become = true    #######是否默认在受管主机上切换用户,通常切换为root
become_method = sudo  #########如何切换,默认sudo提权,也可以是su直接切换用户
become_user = root   #######切换成什么用户,默认root
become_ask_pass = false   #####是否为切换提示输入密码,默认为false

注意:如果没有配置文件存在的话,那么将按照主控机的当前用户进行远程登录操作


#管理机需要免密登录被管理机器
ssh-keygen   #生成key,不要设置密码
cd   /root/.ssh
ssh-copy-id -i id_rsa.pub  192.168.137.155   #传输key,
ssh-copy-id -i id_rsa.pub  192.168.137.162   #传输key,

ansible all -m ping  ###测试所有主机是否支持标准模块ping
ansible-doc  -l   #查询模块
ansible-doc    模块名字     //模块使用的相关介绍
例如:
ansible-doc  shell  ##查看shell模块
- chdir
        Change into this directory before running the command.
        [Default: (null)]
        type: path
        version_added: 0.6

- cmd
        The command to run followed by optional arguments.
        [Default: (null)]
        type: str

- creates
        A filename, when it already exists, this step will *not* be run.
        [Default: (null)]
        type: path
......

ansible   pxg    -m    service    -a  'enabled=true  name=httpd  state=started'  
##调用service模块,对pxg主机清单执行,启动并设置随机启动httpd服务

ansible  pxg  -m  yum  -a   'name=vsftpd  state=present'  ###安装软件包vsftpd
如果是卸载的话,将present改成absent

#更改文件所属的用户、组、权限
#ansible   pxg     -m    file   -a  'owner=test  group=test  mode=644   path=/tmp/1.file'

ansible pxg -m command -a 'ifconfig'  #查看两台被管理机器的网络信息
 ansible pxg -m command -a 'systemctl status firewalld.service' #查看被管控机的防火墙状态
ansible pxg -m shell -a 'systemctl status firewalld.service && ifconfig'   #查看被管控机的防火墙状态和网络信息

ansible pxg -m copy -a "src=/root/apache.sh dest=/root/apache.sh"  #将管理机root下的脚本拷贝到被管理机的root下
ansible  pxg  -m  copy  -a  "content='12121212'   dest=/tmp/1  owner=root mode=660"  ###自己猜
ansible  pxg -m  copy  -a  'src=/tmp/1 dest=/tmp/2 remote_src=yes owner=root mode=660'
ansible pxg -m shell  -a "sh  /root/apache.sh  chdir=/root/"#在被管理机器上运行拷贝的脚本

#创建新用户
ansible  web  -m  user  -a   'name="user1"'
ansible  web  -m  command  -a  'id user1'
可以通过状态state=present或absent来进行用户的创建和删除
例如:ansible  pxg  -m  user  -a   'name="user1" state=present'
     ansible  pxg  -m  user  -a   'name="user1" state=absent'

#建立周期性任务
# ansible   web   -m  cron  -a  'minute="*/10" job="/bin/echo hello" name="test cron job"’
可以通过状态state=present或absent来进行对应任务的创建和删除,name要对应上:
ansible web -m cron -a 'name="test cron job" state=absent'
ansible web -m cron -a 'name="test cron job" minute="0" hour="12" weekday="3" job="/bin/echo hello"'  #猜一下这个


##lineinfile模块
1)确保指定的”一行文本”存在于文件中,如果指定的文本本来就存在于文件中,则不做任何操作,如果不存在,默认在文件的末尾插入这行文本.
2)如果不止一行能够匹配正则,那么只有最后一个匹配正则的行才会被替换,被匹配行会被替换成 line 参数指定的内容。
受管机器上有个文件/tmp/1.file ,内容如下:
123
124
456
789
增加了一行内容
# ansible    web   -m  lineinfile  -a  'path=/tmp/1.file line="0000"  '
按正则来匹配查找
# ansible  web   -m  lineinfile   -a    'path=/tmp/1.file  regexp="^12" line="#12"’
提醒:backrefs=yes,那么当正则没有匹配到任何的行时,则不会对文件进行任何操作,相当于保持原文件不变
删除指定行
# ansible  web   -m  lineinfile   -a    'path=/tmp/1.file  regexp="^000"  state=absent '

############剧本###############3
新建剧本:
vim  useradd.yml
---                  ##开始符
- name: create  user  peng1 
  hosts: 
   - pxg
   - web
  become: yes
  tasks: 
  - name: create user  peng1
    user:
      name: peng1
      state: present
...    ###结束符

示例剧本2:
---
 - name: httpd-install
   hosts: pxg
   remote_user: root 
   tasks:
    - name: httpd-install
      yum:
         name: httpd
         state: present
         
    - name: httpd-start
      service:
         name: httpd
         enabled: true
         
 - name: mdb-start
   hosts: pxg
   remote_user: root
   tasks:
    - name: mdb-install
      yum:
         name: mariadb
         state: present
    - name: mdb-start
      service: 
         name: mariadb
         enabled: true
...

## 1、第一个name是对剧本的描述,hosts是要对哪些机器(主机组)进行任务的操作,tasks后面所跟的就是实际的执行操作
2、playbook会按照任务文件中的顺序进行执行
3、tasks后面的name是对任务的描述,可以不写,我们建议要写
4、service是该剧本中用到的模块
5、service后面的name和enabled是该模块的子项、参数。

##更复杂的剧本(创建用户)###
---
- name: 创建用户和设置属性示例
  hosts: your_target_host
  become: yes  # 如果需要提升权限来创建用户,请确保使用sudo权限

  tasks:
    - name: 创建用户 "user1"
      user:
        name: user1
        password: "$6$rounds=10000$saltstring$hashedpassword"  # 设置密码,请使用密码哈希值,不要直接明文密码;方法:openssl passwd -1 "your_password"
        state: present  # 确保用户存在

    - name: 设置用户 "user1" 的主组
      user:
        name: user1
        group: users  # 设置用户的主组

    - name: 设置用户 "user1" 的UID
      user:
        name: user1
        uid: 1001  # 设置用户的UID

#################################################################### 
 ansible-playbook  --syntax-check     useradd.yml   ###验证剧本语法
  ansible-playbook  -C     useradd.yml        ###空运行
 ansible-playbook      useradd.yml   ####运行剧本
 ansible pxg -m shell -a 'cat /etc/passwd |grep peng1'   ######查询结果  

###########ansible变量############
变量只能含有字母、数字和_
变量优先级:命令行>play范围>主机范围
命令行变量也称之为额外变量

ansible-playbook -C 06-vars-in-shell.yml -e service=httpd -e service2=httpd2  # 多个变量就多个-e即可,对应剧本如下:

- hosts: pxg
  remote_user: root
  tasks:
    - name: 'task1:  {{ service }}'
      shell: echo  {{ service }}
    - name: task2 start {{ service2 }}
      service: name={{ service2 }} state=started
# 执行任务时,输入:
# ansible-playbook  06-vars-in-shell.yml -e service=httpd  -e service2=httpd2

两种方法定义剧本中的变量:
1)将变量放在playbook的vars块中
- hosts: all
  vars: 
      user: peng
      home: /home/peng
2)通过vars_files指定外部文件,在外部文件中指定变量
- hosts: all
  vars_files: 
      - vars/users.yum
#######在users.yum文件中写入如下内容:
user: peng
      home: /home/peng
      
声明过的变量可以在playbook中用双括号{{ }}进行引用,
在任务执行时,Ansible会将变量替换为变量对应的值。
示例:
---
- name:deploy and start apache service
  hosts: pxg
  vars:
    web_pkg:httpd
    firewalld_pkg:firewalld
    web_service:httpd
    firewalld_service:firewalld
    rule:http
    
  tasks:
  - name: install vars package
    yum:
      name:
       - "{{web_pkg}}"
       - "{{firewalld_pkg}}"
      state: latest
  - name: start and enable firewall_service
    service:
      name: "{{firewalld_service}}"
      enabled: true
      state: started
  - name: start and enable web_service
    service:
      name: "{{web_service}}"
      enabled: true
      state: started
...
####示例完毕####

###########数组变量#########
如有如下变量:
user1_frist_name: peng
user1_last_name: xiaogang
user1_home_dir: /users/peng
user2_frist_name: bin
user2_last_name: zhengyu
user2_home_dir: /users/bin
上面的变量可以改成users的数组
users :
  peng: 
    frist_name: peng
    last_name: xiaogang
    home_dir: /users/peng
  bin: 
    frist_name: bin
    last_name: zhengyu
    home_dir: /users/bim
数组回显:
users.peng.last_name   回显xiaogang
由于变量被定义为python字典,可用一下替代语法
users['bin']['last_name']  回显zhengyu

#####变量的注册与使用######
示例:
---
- name: Installs a package and prints the result
  hosts: web
  tasks:
  - name: Install the pachage
    yum:
      name: httpd
      state: present
    register: install_result
  - debug: var=install_result
...
###
1、使用register注册变量install_result,来截获输出
2、通过debug模块,将变量install_result的值在终端屏幕输出
3、register经常和debug配合进行使用,用于调试等目的。

####事实变量######
每个剧本在运行每个play的第一个任务之前会先自动运行setup模块来收集事实。新的ansible版本中会被报告为
Gathering Facts任务,更早版本的ansible中报告为setup.

通过剧本打印出ansible_facts事实变量
---
  - name: fact print
    hosts: pxg
    tasks:
      - name: print facts
        debug:
          var: ansible_facts
...
#########
也可以通过ad-hoc命令使用setup模块打印出ansible_facts事实变量
ansible    pxg  -m  setup
事实变量调用:
1、可以在playbook中用双括号{{ }}进行引用
2、ansible_facts['default_ipv4']['address'] 也可以写成
ansible_facts.default_ipv4.address
3、yml中的ens34的地址获取还可以
写成:
ansible_facts['ens34']['ipv4']['address']

ansible_ens34['ipv4']['address']
###新版本写法:{{ ansible_facts.ens34.ipv4.address }}
旧版本写法:{{ ansible_ens34.ipv4.address }}
旧版本是否支持,与配置文件中default段中的inject_facts_as_vars参数有关
值为false时,不支持旧版本写法,目前默认为true.

######事实收集的开和关#######
1、在剧本中的每个play都可以设置gather_facts: no进行收集关闭。
2、事实收集关闭,并不影响模块setup的运行。
3、如果剧本不涉及事实变量的引用,可以考虑关闭,
     以提高运行速度和受管机的负载。
########自定义事实变量#########
默认情况下,自定义事实变量定义在后缀为.fact文件中,放在目录
/etc/ansible/facts.d下面
两种格式:
1)ini格式写法
[packages]
web_package = httpd
db_package = mariadb-server

[users]
user1 = joe
user2 = jane

2)json格式写法
{
 "packages": {
               "web_package": "httpd",
             "db_package":  "mariadb-server"
              },
              
 "users": {
           "user1": "joe",
           "user2": "jane" 
           }
 }          

########魔法变量#######
魔法变量不是事实变量,不能通过setup模块收集,但他们也都由ansible自动设置
常见的4个变量
ansible  localhost   -m  debug -a  'var=hostvars["localhost"]'
ansible   all  -m  debug  -a  'var=groups["pxg"]'

############任务控制#############
#####循环编写
示例:
---
- name: 不循环的写法
  hosts: pxg
  tasks:
  - name: 启动第一个模块vsftpd
    service:
      name: vsftpd
      state: started
  - name: 启动第二个模块httpd
    service: 
      name: vsftpd
      state: started
...
##########
---
- name: 变量提供列表loop方式循环启动两个模块
  hosts: pxg
  vars:
    all_services:
       - vsftpd
       - httpd
       
  tasks:
  - name: 变量提列表方式循环启动两个模块
    service:
      name: "{{ item }}"
      state: started
    loop: "{{ all_services }}"
...
#######
---
- name: loop方式循环启动两个模块
  hosts: pxg
  
  tasks:
  - name: 简单列表方式循环启动两个模块
    service:
      name: "{{ item }}"
      state: started
    loop: 
      - httpd
      - vsftpd
...
###############
#loop列表中的项也可以是一个key: value的形式(字典方式)
---
- name: 散列或字典loop方式循环管理两个模块
  hosts: pxg  
  tasks:
  - name: 散列或字典loop方式循环管理两个模块
    service:
      name: "{{ item.name }}"
      state: "{{ item.status }}"
    loop: 
      - name: httpd
        status: started
      - name:vsftpd
        status: stopped      
...
############条件任务##############
略(见单独文档)
###########处理程序################

#########大项目相关###########
##主机模式例子:
例子1:  确定db1.example.com服务器是否在inventory1清单中
# ansible    db1.example.com  -i   inventory1      --list-hosts

例子2: 使用all组列出inventory1清单中的所有主机
# ansible    all  -i   inventory1      --list-hosts

例子3: 使用*号进行匹配(包括主机组的名字也参与匹配),匹配条件用单引号包起来
# ansible    'web*'  -i   inventory1      --list-hosts

例子4: 排除某个主机,通过!形式进行,前后条件通过逗号分隔,条件不分先后
# ansible    'web*,!jupiter.lab.example.com'  -i   inventory1      --list-hosts

例子5: 主机组和主机可以混合编队(并集)
#ansible    'prod,web*'  -i   inventory1      --list-hosts

例子6: 通过符号&交集方式选择主机
# ansible    'dev,&web*'  -i   inventory1      --list-hosts

例子7: 确定出不属于任何组的主机
# ansible   ungrouped  -i  inventory1    --list-hosts

执行剧本指定清单文件
# ansible-playbook   -i   inventory2   inventory.yml   ###注意剧本中hosts指定的必须在inventory2 清单文件中

#########动态清单########
当Ansible与AWS等云服务器结合使用时,维护清单文件将是一项繁重的任务。
由于云产品auto_scaling(自动缩放扩容)等功能的使用,我们的云服务器可
能经常性的进行新增或删除,也有可能进行ip地址的变更。有一个简单
的解决方案就是ansible动态清单。动态清单可以由任何语言编写生成,比较
常见的是用Python编写,但不管哪一种语言,返回的内容都是json格式输出。

查看当前静态清单文件json格式输出
#ansible-inventory  --list   
#ansible-inventory  -i      diyinventory   --list   
#ansible-inventory   --graph
#####Python脚本清单例子####

#!/usr/bin/env python
import boto3
import json

# 配置 AWS 访问密钥和区域
aws_access_key = 'YOUR_AWS_ACCESS_KEY'
aws_secret_key = 'YOUR_AWS_SECRET_KEY'
aws_region = 'us-east-1'

# 创建 EC2 客户端
ec2 = boto3.client('ec2', aws_access_key_id=aws_access_key,
                   aws_secret_access_key=aws_secret_key, region_name=aws_region)

# 获取 EC2 实例信息
instances = ec2.describe_instances()

# 创建一个字典来存储动态清单信息
dynamic_inventory = {'all': {'hosts': []}, '_meta': {'hostvars': {}}}

# 遍历实例并添加到动态清单
for reservation in instances['Reservations']:
    for instance in reservation['Instances']:
        instance_id = instance['InstanceId']
        private_ip = instance['PrivateIpAddress']
        public_ip = instance['PublicIpAddress']

        # 设置实例的属性
        instance_info = {
            'ansible_ssh_host': private_ip,
            'ansible_ssh_user': 'ec2-user',  # 或者其他 SSH 用户名
            'ansible_ssh_private_key_file': '/path/to/your/private/key.pem'
        }

        # 添加到动态清单
        dynamic_inventory['all']['hosts'].append(instance_id)
        dynamic_inventory['_meta']['hostvars'][instance_id] = instance_info

# 将动态清单以 JSON 格式输出
print(json.dumps(dynamic_inventory))
注意:

  1. 你需要替换示例中的 YOUR_AWS_ACCESS_KEYYOUR_AWS_SECRET_KEY 为你的 AWS 访问密钥。
  2. 你需要替换 '/path/to/your/private/key.pem' 为你的 SSH 私钥文件路径。
  3. 这个示例脚本将输出一个 JSON 对象,包含了 Ansible 动态清单的结构,你可以将其保存到一个文件,例如 ec2.py

然后,你可以使用 ansible-playbook 命令来运行 Ansible 剧本,例如:

ansible-playbook -i ec2.py your_playbook.yml

#########配置并行(分叉)###########
查看现在的并行数配置:默认为5
ansible-config dump |grep -i forks 
ansible-config list |grep -i forks
####运行ansible和ansible-playbook时可以-f 或者 --forks选项指定并行数

###滚动更新###
serial:  主机数量或百分比

#####包含和导入####
剧本过长不容易维护和处理,可以将其分成小文件进行管理。也可采用模块化方式将多个
Playbook组合为一个主要的playbook,或者将文件中的任务列表插入play。这样可以更好的
在不同项目中重用play或任务序列。 

如下剧本:import_playbook.yml 导入两个剧本web.yml\ftp.yml
import_playbook.yml>>>>>>>
---
- name:start web
  import_playbook: web.yml
  
- name: start ftp
  import_playbook: ftp.yml
...
##
web.yml>>>>>>
---
- name: 启动web
  hosts: web
  tasks:
    - name: start httpd
      service:
        name:httpd
        state:started
...
#####
ftp.yml>>>>
---
- name: 启动web
  hosts: web
  tasks:
    - name: start vsftpd
      service:
        name:vsftpd
        state:started
...
########################
##使用import_tasks静态导入任务文件
---
- name: 启动web
  hosts: web
  tasks:
  - import_tasks: webserver_tasks.yml  ###任务由静态文件webserver_tasks.yml导入
...
####
webserver_tasks.yml>>>>>
- name: start web server
  service:
      name: httpd
      state:started   ###这只是个任务
#############
##使用include_tasks动态导入任务文件

##################
##变量参数化,提高剧本复用率

##########角色###########
角色其实就是tasks的集合,是已经定义好的任务合集。
yum list   rhel-system-roles  ##确认角色是否已经安装好
yum install   rhel-system-roles  -y ###安装角色  默认角色在/usr/share/ansible/roles目录

ansible-galaxy init Mariadb   ##创建角色Mariadb的目录结构
ansible-galaxy  list   ##列出本地找到的角色
ansible-galaxy  remove  Mariadb   ###删除本地角色Mariadb
ansible-galaxy search mysql  ###搜索mysql角色
ansible-galaxy install --force *  ##更新所有角色
ansible-galaxy install  5KYDEV0P5.skydevops-mysql  ###安装角色
可以写一个yml通过角色安装mysql
---
  - hosts: pxg
    remote_user: root
    roles:
      - 5KYDEV0P5.skydevops-mysql
...
##########


 

你可能感兴趣的:(ansible,学习,笔记)