Ansible 小手冊系列 二十(常常遇到的問題)

(1). 怎麼爲任務設置環境變量?javascript

- name: set environment shell: echo $PATH $SOME >> /tmp/a.txt environment: PATH: "{{ ansible_env.PATH }}:/thingy/bin" SOME: value 

(2). 不一樣的用戶登陸不一樣的主機?java

在主機清單裏設置node

[webservers`]
asdf.example.com  ansible_port=5000   ansible_user=alice  ansible_pass=123456
jkl.example.com   ansible_port=5001   ansible_user=bob   ansible_pass=654321

也能夠指定鏈接類型python

[testcluster]
localhost           ansible_connection=local /path/to/chroot1 ansible_connection=chroot foo.example.com bar.example.com 

(3). 經過跳轉主機訪問沒法訪問的主機nginx

ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user@gateway.example.com"' ansible_ssh_common_args: '-o ProxyCommand="sshpass -f /etc/tpasswd ssh xx@10.10.10.1 -p 66677 nc %h %p"' 

(4). 關閉cowsay功能web

export ANSIBLE_NOCOWS=1 

(5). 關閉ssh在首次鏈接時出現檢查keys 的提示redis

export ANSIBLE_HOST_KEY_CHECKING=False 

(6). 查看主機名的全部清單變量?shell

ansible -m debug -a "var=hostvars['hostname']" localhost 

(7). 經過拼接字符串,來獲取接口ip地址ruby

{{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }} 

(8). 獲取組中第一個主機的ip地址bash

{{ hostvars[groups['webservers'][0]]['ansible_eth0']['ipv4']['address'] }} 

(9). 在任務中設置變量

- set_fact: headnode={{ groups[['webservers'][0]] }} - debug: msg={{ headnode}} 

(10). 如何獲取shell變量?

vars:
  local_home: "{{ lookup('env','HOME') }}" tasks: - debug: var=local_home 

在ansible1.4版本以上,可使用如下方式獲取

- debug: var=ansible_env.HOME 

(11). 在模板中如何遍歷某一組內的全部主機?

{% for host in groups['db_servers'] %} {{ host }} {% endfor %} 

獲取ip地址

{% for host in groups['db_servers'] %} {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }} {% endfor %} 

(12). 加密hosts主機清單文件

有時候咱們主機清單裏面會有些密碼信息,可是不想讓別人看到。這種狀況能夠用ansible-vault來達到此目的。

[root@node1 ansible]# cat db_hosts localhost ansible_connection=local [root@node1 ansible]# ansible-vault encrypt db_hosts New Vault password: Confirm New Vault password: Encryption successful [root@node1 ansible]# ansible -i db_hosts localhost -m ping ERROR! Decryption failed Decryption failed [root@node1 ansible]# ansible -i db_hosts --ask-vault-pass localhost -m ping Vault password: localhost | SUCCESS => { "changed": false, "ping": "pong" } [root@node1 ansible]# cat db_hosts $ANSIBLE_VAULT;1.1;AES256 61663966666265363465653064386666326234353433346163633838366532366236313032303636 6437313333333936396164663031633566613233343161650a333163333732616130343762636135 30303864663138643661393234336433313465623830333832663165393964353961323261373130 3135626236626435640a396338616563646532623966333337366365636665663563666432333539 61663632633130623733316232353836663366623136636432616332376266383263356264303765 6133616235363066356164653232326139643862653464623037 

(13). service 模塊啓動服務沒效果?
首先檢查下service httpd status的信息,是否是有

httpd is stopped 

這種字符,沒有的話,在服務啓動腳本里,在case語句裏添加如下方法

status)
    status -p ${pidfile} $httpd
    RETVAL=$?
    ;;
# bash變量 # httpd=${HTTPD-/usr/sbin/httpd} # pidfile=${PIDFILE-/var/run/httpd/httpd.pid} 

從而達到service http status有stopped的字樣。

(14). 遞歸目錄中的模版文件

- name: Copying the templated jinja2 files
  template: src={{item}} dest={{RUN_TIME}}/{{ item | regex_replace(role_path+'/templates','') | regex_replace('\.j2', '') }} with_items: "{{ lookup('pipe','find {{role_path}}/templates -type f').split('\n') }}" 

(15). 目標主機的python爲2.7版本,且須要使用yum模塊
須要增長下列變量,指定python版本爲2.6

- hosts: servers
  vars:
    - ansible_python_interpreter: /usr/bin/python2.6.6 

(16). 遠程遍歷拷貝文件

- name    : get files in /path/ shell : ls /path/* register: path_files - name: fetch these back to the local Ansible host for backup purposes fetch: src : /path/"{{item}}" dest: /path/to/backups/ with_items: "{{ path_files.stdout_lines }}" 

(17). 獲取主機清單中組的ip地址

- shell: "ping -c 1 {{item}} | grep icmp_seq | gawk -F'[()]' '{print $2}'" with_inventory_hostnames: test2 register: testip - debug: "msg={{ item.stdout }}" with_items: "{{ testip.results }}" 

(18). 保留ansbile遠程執行的模塊文件,並調試模塊

添加ANSIBLE_KEEP_REMOTE_FILES=1 環境變量

`$ ANSIBLE_KEEP_REMOTE_FILES=1 ansible localhost -m ping -a 'data=debugging_session' -vvv` 
sing module file /usr/lib/python2.6/site-packages/ansible/modules/core/system/ping.py <localhost> ESTABLISH LOCAL CONNECTION FOR USER: root <localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo ~/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932 `" && echo ansible-tmp-1489477306.61-275734926719932="` echo ~/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932 `" ) && sleep 0' <localhost> PUT /tmp/tmpv4EenK TO /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/ping.py <localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/ /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/ping.py && sleep 0' <localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/ping.py && sleep 0' localhost | SUCCESS => { "changed": false, "invocation": { "module_args": { "data": "debugging_session" }, "module_name": "ping" }, "ping": "debugging_session" } 

模塊文件是由base64編碼的字符串文件,可以使用explode將字符串轉換成可執行的python文件

$ python /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/ping.py explode Module expanded into: /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/debug_dir $ tree /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/debug_dir/ /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/debug_dir/ ├── ansible │ ├── __init__.py │ └── module_utils │ ├── basic.py │ ├── __init__.py │ ├── pycompat24.py │ ├── six.py │ └── _text.py ├── ansible_module_ping.py └── args 

ansible_module_ping.py 是模塊自己的代碼。
args文件包含一個JSON字符串。 該字符串是一個包含模塊參數和其餘變量的字典。
ansible目錄包含由ansible_module_ping模塊使用的ansible.module_utils的代碼文件。
若是修改了debug_dir文件中的代碼以後,須要使用execute執行代碼

$ python /root/.ansible/tmp/ansible-tmp-1489477306.61-275734926719932/ping.py execute {"invocation": {"module_args": {"data": "debugging_session"}}, "changed": false, "ping": "debugging_session"} 

(19). 提高權限

Ansible ad-hoc命令

ansible -i hosts node1 -m shell -a "whoami" --become --become-method=su --become-user=root --ask-su-pass SU password: 192.168.77.130 | SUCCESS | rc=0 >> root 

Ansible-playbook命令

cat test.yml
---
- hosts: node1
  gather_facts: no
  tasks:
  - name: I'm become to root.
    shell: whoami
    register: w become: true become_user: "root" become_method: "su" - debug: var=w.stdout [root@base ~]# ansible-playbook -i hosts test.yml --ask-su-pass SUDO password: PLAY [node1] **************************************************************************************************************************************** TASK [I'm become to root.] ************************************************************************************************************************** changed: [192.168.77.130] TASK [debug] **************************************************************************************************************************************** ok: [192.168.77.130] => { "w.stdout": "root" } PLAY RECAP ****************************************************************************************************************************************** 192.168.77.130 : ok=2 changed=1 unreachable=0 failed=0 

若是不想在執行過程當中輸入提高用戶的密碼,能夠在hosts文件中配置ansible_become_pass變量設置密碼。

# cat hosts [node1] 192.168.77.130 ansible_ssh_user=test ansible_ssh_pass=123456 ansible_become_pass=123456 

參數解釋

  • become 開啓提高權限
  • become-method 提高權限的方式,有sudo,su,runas等。
  • become-user 提高權限的用戶
  • ansible_become_pass 提高權限的用戶密碼
  • ask-su-pass 告訴程序提高權限的用戶密碼

(20). 變量嵌套

在動態取變量的時候,咱們第一時間就會寫出"{{ t_var[{{ n }}] }}"的引用命令,但這類引用在jinja2的語法中是錯誤的,可使用下列方式解決此引用問題。

- hosts: localhost
  gather_facts: no
  vars:
   - t_var: ['1','2'] - n: "1" tasks: - shell: "echo {% if n %} {% set number = n | int %} {{ t_var[number]}} {% endif %}" 
ansible-playbook test.yml -vv
Using /etc/ansible/ansible.cfg as config file
 [WARNING]: provided hosts list is empty, only localhost is available


PLAYBOOK: test.yml ***************************************************************************************************************
1 plays in test.yml PLAY [localhost] ***************************************************************************************************************** META: ran handlers TASK [command] ******************************************************************************************************************* task path: /etc/ansible/test.yml:10 changed: [localhost] => {"changed": true, "cmd": "echo 2 ", "delta": "0:00:00.012834", "end": "2017-09-12 10:40:44.959595", "rc": 0, "start": "2017-09-12 10:40:44.946761", "stderr": "", "stderr_lines": [], "stdout": "2", "stdout_lines": ["2"]} META: ran handlers META: ran handlers PLAY RECAP *********************************************************************************************************************** localhost : ok=1 changed=1 unreachable=0 failed=0 

(21). 環境變量找不到的問題

咱們在ansible直接執行命令,不帶有絕對路徑,就會報出找不到命令的提示信息:

ansible node2 -m shell -a "openresty -v" 192.168.77.130 | FAILED | rc=127 >> /bin/sh: openresty: 未找到命令 

此時咱們應該使用下列命令避免。

ansible node2 -m shell -a "source /etc/profile; openresty -v" 192.168.77.130 | SUCCESS | rc=0 >> nginx version: openresty/1.11.2.3 

ansible 的ssh登錄屬於交互式的非登錄shell

詳細說明請移步到 ssh鏈接遠程主機執行腳本的環境變量問題

(22). 獲取redis的info信息

- hosts: localhost
  gather_facts: false tasks: - name: "query redis info" expect: command: "telnet 127.0.0.1 6379" responses: "Escape": - "auth test\ninfo\nquit\n" ignore_errors: true register: result - name: "show the variable" debug: var: result
相關文章
相關標籤/搜索