天天看點

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
               

繼續閱讀