The following configurations take the following table environment as an example
role | host name | IP address | Group name | CPU |
Control master node | ansiblecontrol | 192.168.242.10 | --- | 2C |
Managed node | web1 | 192.168.242.11 | webservers | 2C |
Managed node | web2 | 192.168.242.12 | webservers | 2C |
Ansible installation
Installation premise
Install Ansible
Ansible environment preparation
Role name | IP |
master.zjm.com | 192.168.242.10 |
node1.zjm.com | 192.168.242.11 |
node2.zjm.com | 192.168.242.12 |
Source code installation: source code installation requires python2 6 or above, which depends on modules paramiko, PyYAML, Jinja2, httplib2, simplejson and pycrypto. The above modules can be through pip or easy_install to install
PIP installation: pip is a tool specially used to manage Python modules. Ansible will update it to the PIP warehouse every time it is officially released. Therefore, by installing or updating ansible through pip, it will be safer to get the latest stable version.
Install using yum or up2date
Installing EPEL repository for CentOS 7
[root@master ~]# yum install -y epel-release
Install ansible using yum or up2date
[root@master ~]# yum install -y ansible
View the version of ansible
[root@master ~]# ansible --version ansible 2.9.23 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /bin/ansible python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Determine whether ansible works normally in ad-hoc mode
[root@master ~]# ansible localhost -m ping localhost | SUCCESS => { "changed": false, "ping": "pong" }
Configure running environment
Configure Ansible environment
Ansible configuration files store configuration data in ini format. In ansible, almost all configuration items can be accessed through
Use public key authentication
~/. ansible.cfg or / etc / ansible / ansible CFG configuration items:
[defaults] host_key_checking = False
Or directly set the environment variables in the operating system of the control host as follows:
$export ANSIBLE_HOST_KEY_CHECKING=False
Configure SSH password less access for Linux hosts
[root@master ~]# vi /etc/hosts [root@master ~]# tail -3 /etc/hosts 192.168.242.10 master 192.168.242.11 node1 192.168.242.12 node2
1. Create key on control host
[root@master ~]# ssh-keygen -f ~/.ssh/id_rsa -P '' -q [root@master ~]# ls -l ~/.ssh total 8 -rw-------. 1 root root 1679 Aug 11 23:02 id_rsa -rw-r--r--. 1 root root 393 Aug 11 23:02 id_rsa.pub
2. Issue the key to the managed node
[root@master ~]# ssh-copy-id node1 [root@master ~]# ssh-copy-id node2
3. Verify that SSH keyless configuration is successful
[root@master ~]# for name in node{1,2}; do ssh $name hostname; done node1 node2
Ansible Inventory
In large-scale configuration management, we need to manage different machines of different businesses. The information of these machines is stored in the Inventory component of ansible. In our work, the host for configuration deployment must be stored in the Inventory first, so that ansible can be used to operate it, The default ansible Inventory is a static INI format file / etc/ansible/hosts. Of course, ansible can also be used_ The hosts environment variable is specified or temporarily set with the - i parameter when running ansible and ansible playbook
Define hosts and host groups
Specific definition examples
[root@master ~]# vi /etc/ansible/hosts [root@master ~]# tail -11 /etc/ansible/hosts 192.168.242.11 ansible_ssh_pass='123' 192.168.242.12 ansible_ssh_pass='123' [docker] 192.168.242.1[1:2] [docker:vars] ansible_ssh_pass='123' [ansible:children] docker
The first and second lines define a host as 192.168 242.11/12, the SSH login password is defined using the Inventory built-in variable
The third line defines a docker group. The fourth line defines that there are two hosts 192.168 under the docker group 242.11/192.168. 242.12 ':' can be used to represent consecutive multiple, for example, 1:5, from one to five
Line 5 and 6: for the docker group, the Inventory built-in variable is used to define the SSH login password
Line 78: define an ansible group, which contains the docker group
[root@master ~]# ansible 192.168.242.11:192.168.242.12 -m ping -o 192.168.242.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"} 192.168.242.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"} [root@master ~]# ansible docker -m ping -o 192.168.242.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"} 192.168.242.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"} [root@master ~]# ansible ansible -m ping -o 192.168.242.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"} 192.168.242.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
Dynamic Inventory
In the actual application deployment, there will be a large number of host lists. It will be very cumbersome to manually maintain these lists. In fact, Ansible also supports dynamic Inventory. Dynamic Inventory is Ansible. The host lists and variable information in all Inventory files can be pulled from the outside
[root@master ~]# vi hosts.py [root@master ~]# cat hosts.py #!/usr/bin/env python3 import argparse import sys import json def lists(): r = {} h = [ '192.168.242.1' + str(i) for i in range(0,2) ] hosts = {'host': h} r['docker'] = hosts return json.dumps(r,indent=3) def hosts(name): r = {'ansible_ssh_pass': '123'} cpis=dict(r.items()) return json.dumps(cpis) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-l', '--list' , help='hosts list' , action='store_true') parser.add_argument('-H', '--host', help='hosts vars') args = vars(parser.parse_args()) if args['list']: print(lists()) elif args['host']: print(hosts(args['host'])) else: parser.print_help()
Test script
[root@master ~]# chmod +x hosts.py [root@master ~]# ./hosts.py -l { "docker": { "host": [ "192.168.242.10", "192.168.242.11", "192.168.242.12" ] } } [root@master ~]# ./hosts.py -H 192.168.242.12 {"ansible_ssh_pass": "123"}
Ansible composition introduction
[root@master ~]# tree /etc/ansible/ /etc/ansible/ ├── ansible.cfg #ansible configuration file ├── hosts #Resource manifest file └── roles 1 directory, 2 files
Host connectivity test
#Modify the configuration of hosts and groups [root@master ~]# cat >> /etc/ansible/hosts << EOF > [webservers] > node[1:2] > EOF #Test a host [root@master ~]# ansible node1 -m ping node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } #Test a set of hosts [root@master ~]# ansible webservers -m ping node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } node2 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
Batch execute command
#Use ansible to output "hello ansible" on the remote machine“ #Using shell modules [root@master ~]# ansible webservers -m shell -a '/bin/echo hello ansible!' -o node2 | CHANGED | rc=0 | (stdout) hello ansible! node1 | CHANGED | rc=0 | (stdout) hello ansible! #Using the command module [root@master ~]# ansible webservers -a '/bin/echo hello ansible!' -o node1 | CHANGED | rc=0 | (stdout) hello ansible! node2 | CHANGED | rc=0 | (stdout) hello ansible! #Using raw module [root@master ~]# ansible webservers -m raw -a '/bin/echo hello ansible!' node1 | CHANGED | rc=0 >> hello ansible! Shared connection to node1 closed. node2 | CHANGED | rc=0 >> hello ansible! Shared connection to node2 closed.
Get help
Ansible doc: used to view module information
//Parameter - 1 lists the available modules
[root@master ~]# ansible-doc -l fortios_router_community_list Configure community lists in Fortinet's FortiOS and FortiGate azure_rm_devtestlab_info Get Azure DevTest Lab facts ecs_taskdefinition register a task definition in ecs avi_alertscriptconfig Module for setup of AlertScriptConfig Avi RESTful Object tower_receive Receive assets from Ansible Tower netapp_e_iscsi_target NetApp E-Series manage iSCSI target configuration azure_rm_acs Manage an Azure Container Service(ACS) instance fortios_log_syslogd2_filter Filters for remote system server in Fortinet's FortiOS and FortiGate
//-s) list the actions supported by a module
[root@master ~]# ansible-doc -s shell - name: Execute shell commands on targets shell: chdir: # Change into this directory before running the command. cmd: # The command to run followed by optional arguments. creates: # A filename, when it already exists, this step will *not* be run. executable: # Change the shell used to execute the command. This expects an absolute path to the executable. free_form: # The shell module takes a free form command to run, as a string. There is no actual parameter named 'free form'. See the examples on how to use this module. removes: # A filename, when it does not exist, this step will *not* be run. stdin: # Set the stdin of the command directly to the specified value. stdin_add_newline: # Whether to append a newline to stdin data. warn: # Whether to enable task warnings.
[root@master ~]# ansible-doc -v shell Using /etc/ansible/ansible.cfg as config file > SHELL (/usr/lib/python2.7/site-packages/ansible/modules/commands/shell.py) The `shell' module takes the command name followed by a list of space-delimited arguments. Either a free form command or `cmd' parameter is required, see the examples. It is almost exactly like the [command] module but runs the command through a shell (`/bin/sh') on the remote node. For Windows targets, use the [win_shell] module instead. * This module is maintained by The Ansible Core Team * note: This module has a corresponding action plugin.
ansible: used to execute ad-hoc commands
[root@master ~]# ansible localhost -a date localhost | CHANGED | rc=0 >> Thu Aug 12 00:22:39 CST 2021
[root@master ~]# ansible node1 -m ping -vv ansible 2.9.23 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] Using /etc/ansible/ansible.cfg as config file Skipping callback 'actionable', as we already have a stdout callback. Skipping callback 'counter_enabled', as we already have a stdout callback. Skipping callback 'debug', as we already have a stdout callback. Skipping callback 'dense', as we already have a stdout callback. Skipping callback 'dense', as we already have a stdout callback. Skipping callback 'full_skip', as we already have a stdout callback. Skipping callback 'json', as we already have a stdout callback. Skipping callback 'minimal', as we already have a stdout callback. Skipping callback 'null', as we already have a stdout callback. Skipping callback 'oneline', as we already have a stdout callback. Skipping callback 'selective', as we already have a stdout callback. Skipping callback 'skippy', as we already have a stdout callback. Skipping callback 'stderr', as we already have a stdout callback. Skipping callback 'unixy', as we already have a stdout callback. Skipping callback 'yaml', as we already have a stdout callback. META: ran handlers node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } META: ran handlers META: ran handlers