• ansible12:角色Roles


    简单介绍

      roles可以理解为ansible的一种规范,使用这种规范编写playbook,可以让我们条例更加清晰,合理拆分将变量、文件、任务、ansible其它工作等分别存储在不同的目录中,方便快速定位。

    • 官方文档给出的角色目录拆解过于分散,我以“个人习惯”稍稍精简,拿redis举例:

      roles/						# 总的角色目录
      ├── redis					# redis角色目录,目录名代表角色名。
      │   ├── defaults/main.yaml	# 存放指定角色所用到的默认变量,以便在没有设置变量值时有默认值可以使用,此文件中定义的变量优先级是最低的。
      │   ├── files				# 存放执行角色所需要文件。
      │   ├── handlers/main.yaml	# 当角色调用handlers时,默认会在此目录中的main.yml文件中查找对应的handler。
      │   ├── meta/main.yaml		# 存放一些元数据,比如作者信息、本角色作用等等。
      │   ├── tasks/main.yaml		# 角色执行的任务的主要列表。
      │   ├── templates			# 存放角色相关的模板文件。
      │   └── vars/main.yaml		# 存放需要修改的变量,优先级较高。 
      └── redis.yaml				# 调用角色的playbook。
      
    • 上述规范可以不用遵守,你自己看得懂也可以;使用上面规范也不是全部目录都必须使用,按需即可,一般情况至少会有一个tasks目录。

    • 上面目录结构可以看出,角色调用文件(redis.yaml)和角色目录(redis)是同级的,这是因为角色调用文件会从下面位置查找角色目录:

      • 同级目录。
      • 同级目录的roles目录。
      • 当前用户的~/.ansible/roles目录。
      • 也可以编辑/etc/ansible/ansible.cfg的“roles_path”配置项来查找角色目录。
      • 上面情况都不符合的情况也可使用绝对路径调用角色。如: - role: "/server/ansible/roles/"
    • 变量调用说明:

      • 角色中定义的默认变量是全局生效的。
      • 调用角色的剧本(就是上面的redis.yaml,以下内容中称角色调用剧本)中定义的变量也是默认全局生效的,但是可以通过修改ansible.cfg配置文件将全局属性修改为private,见下方例1。
      • 变量定义优先级:ansible-playbppk -e > 角色本身的vars/main.yaml > 角色调用剧本 > 角色本身的defaults/main.yaml > 同一个角色调用剧本中上一个调用角色的defaults/main.yaml(见例2)。

    举例说明

    1. 例1:rolrs的公/私有变量。

        0 16:59:38 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr1/tasks/main.yaml 
      - debug:
          msg: "hello {{ var1 }}!"
        0 16:59:45 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr1/defaults/main.yaml 
      var1: "natasha"
        0 16:59:51 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/tasks/main.yaml 
      - debug:
          msg: "hello {{ var1 }}!"
        0 16:59:56 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/defaults/main.yaml 
      var1: "maria"
        0 16:59:59 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml 
      - hosts: ck-node1
        roles:
        - role: tr1
          vars:
            var1: "selina"
        - role: tr2
        0 17:01:59 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      ...
      TASK [tr1 : debug] ***********************************************************************************************************************
      ok: [ck-node1] => {
          "msg": "hello selina!"
      }
      
      TASK [tr2 : debug] ***********************************************************************************************************************
      ok: [ck-node1] => {
          "msg": "hello selina!"
      }
      ...
      # 正常情况下,vars下的变量应该只对tr1角色生效,但从结果上看var1变量对tr1和tr2角色都生效了,这是因为默认情况下,角色中的变量是全局生效的。想要解决这个问题,需要修改ansible配置文件。
        0 17:10:11 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # vim /etc/ansible/ansible.cfg
      private_role_vars = yes		# 取消此行的注释。
      # 再执行就达到预想的效果了。
        0 17:10:54 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
    2. 例2:变量调用优先级,五种情况对比,以tr3角色为例。

      # 各角色内的tasks/main.yaml文件保持不变。
        0 18:17:00 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr1/defaults/main.yaml 
      var1: "tr1-defaults-var1"
        0 18:17:02 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/defaults/main.yaml 
      var1: "tr2-defaults-var2"
        0 18:17:04 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr3/defaults/main.yaml 
      var1: "tr3-defaults-var3"
      
      • 第一种:所有的位置都定义了v1变量,执行时使用-e参数,-e参数优先级最高。
        0 18:25:08 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr3/vars/main.yaml
      var1: "tr3-vars-var1"
        0 18:29:14 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml 
      - hosts: ck-node1
        roles:
        - role: tr1
        - role: tr2
        - role: tr3
          vars:
            var1: "tr-var1"
        0 18:30:57 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook -e var1="command-e-var1" tr.yaml
      
      • 第二种:所有的位置都定义了v1变量时,执行时不是用-e,tr3/vars/main.yaml优先级高。
        0 18:31:49 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
      • 第三种:取消定义tr3/vars/main.yaml后,角色调用剧本优先级高。
        0 18:32:07 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # 
      m -r tr3/vars
        0 18:35:48 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
      • 第四种:取消定义tr3/vars/main.yaml和角色调用剧本后,角色本身的defaults/main.yaml的优先级高。
        0 18:38:27 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml
      - hosts: ck-node1
        roles:
        - role: tr1
        - role: tr2
        - role: tr3
        0 18:38:28 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
      • 第五种:取消定义tr3/vars/main.yaml、角色调用剧本、tr3/defaultss/main.yaml后,同一个角色调用剧本中上一个调用角色的defaults/main.yaml优先级高。
        0 18:38:31 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # 
      m -r tr3/defaults
        0 18:40:10 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml
      - hosts: ck-node1
        roles:
        - role: tr2
        - role: tr1		# 特意把tr1和tr2的调用位置换换,方便查看效果。
        - role: tr3
        0 18:40:11 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
    3. 例3:默认情况下,在同一个角色调用剧本中,无法重复调用一个角色,想要解决这个问题,有两种方式:

      • 第一种方法:为角色添加allow_duplicates属性。
      # 依然使用上面的测试文件,只修改tr.yaml。
        0 18:41:45 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml
      - hosts: ck-node1
        roles:
        - role: tr1
        - role: tr2
        - role: tr2		# 此次调用不会显示内容。
        0 18:41:47 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      # 为角色添加allow_duplicates属性。
        0 18:43:41 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/meta/main.yaml
      allow_duplicates: true
        0 18:43:49 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
      • 第二种方法:此种方法只针对需要传参的角色。
      # 依然使用上面的测试文件,删除meta。
        0 18:44:02 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # 
      m -r tr2/meta
        0 18:44:53 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml
      - hosts: ck-node1
        roles:
        - role: tr1
        - role: tr2
          vars:
            var1: peiqian
        - role: tr2
          vars:
            var1: zhujiu
        0 18:44:54 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
      
    4. 例4,部署redis。

      # 这里把调用文件放在roles目录同级,方便区分。
        0 15:18:45 root@ck-ansible,172.16.2.9:/server/ops_ansible # tree ./
      ./
      ├── redis.yaml
      └── roles
          └── redis
              ├── defaults
              │   └── main.yaml
              ├── files
              │   ├── bin
              │   │   ├── redis-benchmark
              │   │   ├── redis-check-aof -> redis-server
              │   │   ├── redis-check-rdb -> redis-server
              │   │   ├── redis-cli
              │   │   ├── redis-sentinel -> redis-server
              │   │   ├── redis-server
              │   │   └── redis-shutdown
              │   ├── redis.service
              │   └── redis.sh
              ├── tasks
              │   ├── main.yaml
              │   ├── redis_common.yaml
              │   └── start_redis.yaml
              └── templates
                  └── redis.conf.j2
      # 变量定义
        0 15:20:02 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/defaults/main.yaml 
      redis_dirs: 
        - "/usr/local/redis/conf"
        - "/server/logs/redis"
        - "/server/data/redis"
      
      redis_files: 
        - { src: 'files/bin',dest: '/usr/local/redis/',mode: '0755' }
        - { src: 'files/redis.sh',dest: '/etc/profile.d/' }
        - { src: 'files/redis.service',dest: '/etc/systemd/system/' }
      # redis依赖文件(事先编译好的redis相关二进制文件)。
        0 15:20:29 root@ck-ansible,172.16.2.9:/server/ops_ansible # ll roles/redis/files/bin/
      总用量 18848
      -rwxr-xr-x 1 root root 4833392 5月   7 12:07 redis-benchmark
      lrwxrwxrwx 1 root root      12 5月   7 12:07 redis-check-aof -> redis-server
      lrwxrwxrwx 1 root root      12 5月   7 12:07 redis-check-rdb -> redis-server
      -rwxr-xr-x 1 root root 5003408 5月   7 12:07 redis-cli
      lrwxrwxrwx 1 root root      12 5月   7 12:07 redis-sentinel -> redis-server
      -rwxr-xr-x 1 root root 9450240 5月   7 12:07 redis-server
      -rwxr-xr-x 1 root root    1118 10月  4 20:24 redis-shutdown
      # redis的systemd文件和环境变量文件
        0 15:20:32 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/files/redis.service 
      [Unit]
      Description=Redis persistent key-value database
      After=network.target
      After=network-online.target
      Wants=network-online.target
      
      [Service]
      Type=forking
      ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
      ExecStop=/usr/local/redis/bin/redis-shutdown
      
      [Install]
      WantedBy=multi-user.target
        0 15:22:08 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/files/redis.sh
      #set redis environment
      export REDIS_HOME=/usr/local/redis
      export PATH=${REDIS_HOME}/bin:${PATH}
      # 配置文件模板
        0 15:22:43 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/templates/redis.conf.j2 
      daemonize yes
      port 6379
      bind {{ ansible_host }}
      pidfile /usr/local/redis/redis.pid
      logfile /server/logs/redis/redis.log
      dir /server/data/redis
      requirepass '123456'
      # 任务执行。
        0 15:23:26 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/tasks/main.yaml 
      ---
      - include: redis_common.yaml
      - include: start_redis.yaml
        0 15:25:07 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/tasks/redis_common.yaml 
      ---
      - name: create services user
        user:
          name: sn_pub
          uid: 8888
          createhome: no 
          shell: /sbin/nologin
      
      - name: create redis dir
        file:
          path: "{{ item }}"
          state: directory
          recurse: yes
          owner: sn_pub
          group: sn_pub
        loop: "{{ redis_dirs }}"
      
      - name: copy redis conf.j2
        template:
          src: templates/redis.conf.j2
          dest: /usr/local/redis/conf/redis.conf
      
      - name: copy redis depend files
        copy:
          src: "{{ item.src }}"
          dest: "{{ item.dest }}"
          mode: "{{ item.mode | default(omit) }}"
          owner: sn_pub
          group: sn_pub
        loop: "{{ redis_files }}"
      
      - name: load redis.sh
        shell: source /etc/profile.d/redis.sh
        0 15:25:11 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/tasks/start_redis.yaml 
      ---
      - name: start redis
        systemd:
          daemon_reload: yes
          name: redis
          state: started
          enabled: yes
      # 调用redis角色执行部署redis
        0 15:25:15 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat redis.yaml 
      - hosts: ck-node1
        roles:
          - role: redis
        0 15:26:00 root@ck-ansible,172.16.2.9:/server/ops_ansible # ansible-playbook redis.yaml
      


    写作不易,转载请注明出处,谢谢~~

  • 相关阅读:
    06-图3 六度空间
    06-图2 Saving James Bond
    06-图1 列出连通集
    05-树9 Huffman Codes
    数据结构学习笔记04树(堆 哈夫曼树 并查集)
    05-树8 File Transfer
    05-树7 堆中的路径
    十天学会单片机Day1点亮数码管(数码管、外部中断、定时器中断)
    设计模式—— 四:接口隔离原则
    设计模式—— 一:单一职责原则
  • 原文地址:https://www.cnblogs.com/ccbloom/p/15508709.html
Copyright © 2020-2023  润新知