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 # \rm -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 # \rm -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 # \rm -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
    


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

posted @ 2021-11-04 16:07  merlee  阅读(133)  评论(0编辑  收藏  举报