• 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
    ...
    ##########


     

  • 相关阅读:
    多家大厂JAVA面试题整理分布式+微服务+高并发+性能优调+框架源码
    字符串基础面试题
    深入浅出排序算法之希尔排序
    leetcode713. 乘积小于 K 的子数组
    CARLA编译问题 总结
    「认识AI:人工智能如何赋能商业」【29】主流的机器学习工具
    卢湘仪离心机仪器盛装亮相2022第十届生物发酵展12月新国际博览中心与您相约
    51-41 Stable Video Diffusion,高质量视频生成新时代
    数据可观察性如何帮助数据目录计划
    独立站,如何提高网站转化率
  • 原文地址:https://blog.csdn.net/qq_28608175/article/details/133675174