ansible Automated Deployment resolution

preface

The automation tool "three swordsmen": ansible saltstack puppet. This paper analyzes some application module services encountered in the deployment of ansible architecture.

I. overview of ansible

1.1 introduction to ansible

1.Ansible Can be managed at the same time Redhat Tied Linux,Debian Tied Linux,as well as Window host. The management node is only connected to the remote host when executing the script. There is no special synchronization mechanism, so exceptions such as power failure will not affect the ansible. 

2.ansible It is a new automatic operation and maintenance tool based on Python Development, a collection of many operation and maintenance tools(puppet,cfengine, chef,func,fabric) It realizes the functions of batch system configuration, batch program deployment, batch run command and so on.

3.ansible It works based on modules and has no batch deployment capability. The real mass deployment is ansible Running modules, ansible It just provides a framework. Mainly including:
  a.Connection plug-in connection plugins:Responsible for communication with the monitored end (remote connection through ssh Port 22)
  b.host inventory:Specifies the host of the operation. It is the host of monitoring defined in the configuration file
  c.Core modules of various modules,command modular,Custom module
  d.With the help of plug-ins, log mail recording and other functions can be completed
  e.playbook: When the script performs multiple tasks,It is not required to allow the node to run multiple tasks at once

4.ansible Schema of: used by default when connecting to other hosts ssh agreement

II. Installation and deployment of ansble environment

Equipment:

Management end master: 20.0.0.10
 Managed end node1: 20.0.0.11
 Managed end node2: 20.0.0.12

2.1 deployment preparation:

1. rename

[root@server1 ~]# hostnamectl set-hostname master
[root@server1 ~]# su
[root@server2 ~]# hostnamectl set-hostname node1
[root@server2 ~]# su
[root@client1 ~]# hostnamectl set-hostname node2
[root@client1 ~]# su

2. turn off the firewall
For all devices

[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0

2.2 deployment process

2.2.1 installing ansibke

On the master
Get yum source support

[root@master ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

Install epel extension source

[root@master ~]# yum install epel-release

[root@master ~]# yum -y install ansible install ansible
[root@master ~]# ansible --version view ansible version
[root@master ~]# rpm -q ansible view installed ansible information
[root@master ~]# rpm -qc ansible view profile information
[root@master ~]# rpm -ql ansible view all relevant file information


1. install the tree structure to view files

[root@master ~]# yum -y install tree
[root@master ~]# tree /etc/ansible
/etc/ansible
├── ansible.cfg    ansible Configuration file for
├── hosts             ansible The main warehouse of is used to store the relevant information of the remote host to be managed, and the host list
└── roles              role

2.2.2 configuration host list

[root@master ~]# vi /etc/ansible/hosts
 Add, define label name
[webserver]
20.0.0.11
[mysql]
20.0.0.12

2.2.3 configure key verification

[root@master ~]# SSH keygen -t RSA generate key
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):    Generate key storage location
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):   Set password encryption for key, password abc123
Enter same passphrase again:  Confirm password again abc123
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:vBwgnptNmeeOrnbTOrwMOfybBwlcdyHRBZZq+v1IUd0 root@master
The key's randomart image is:
+---[RSA 2048]----+
|        oo+=.    |
|      . .o+  . . |
|   ..... o  . . E|
|   .oo =o  .     |
|    o.++S .      |
|   . *++ o .     |
|    B..++..      |
|    .==++...     |
|   ..+XB. ...    |
+----[SHA256]-----+
[root@master ~]# ls -a   
[root@master ~]# cd .ssh/
[root@master .ssh]# ls view generated key
id_rsa  (Private key) id_rsa.pub(Public key)

id_rsa  (Private key): contains password, identity information and data verification method( hash Hash), cannot push back
id_rsa.pub(Public key): cannot push backward

Resolution:
Public key: the QR code of the canteen (public)
Private key: the code scanning payment password for students (not public)

Send public key to node1,2

[root@master .ssh]# ssh-copy-id root@20.0.0.11
 Input receiver root Party password 123456
[root@master .ssh]# ssh-copy-id root@20.0.0.12

View the obtained key information on node1

[root@node1 ~]# ls -a
[root@node1 ~]# cd .ssh/
[root@node1 .ssh]# ls 
[root@node1 .ssh]# cat authorized_keys 

2.2.3.1 ansible syntax

ansible Host identification/ip -m modular -a 'parameter'

View the time information of node2

[root@node2 ~]# date
2021 Monday, January 11, 2012 22:31:55 CST

On the master

[root@master .ssh]# ansible mysql -m command -a 'date'
                                      command
Enter passphrase for key '/root/.ssh/id_rsa': Enter key password abc123
20.0.0.12 | CHANGED | rc=0 >>
 ip address      state     Status code (0 means normal execution)     
2021 Monday, January 11, 2012 22:33:21 CST
[root@master .ssh]# ansible 20.0.0.12 -m command -a 'date'

2.2.4 setting password free login

[root@master .ssh]# ssh-agent bash
[root@master .ssh]# ssh-add
[root@master .ssh]# ansible all -m command -a 'date'
[root@master .ssh]# ansible all  -a 'date' 
No-m Module, default to command modular
[root@master .ssh]# ansible all -m command -a 'ls /'

Three ansible command line modules

3.1 command module

[root@master .ssh]# Ansible doc -s command view the parameter information that can be added to the current module

3.2 cron planning task module

Two states( state): present Indicates addition (can be omitted), absent Indicates removal
[root@master .ssh]# Ansible doc -s cronview cron module information

[root@master .ssh]# ansible mysql -m cron -a 'minute="*/1" job="/usr/bin/echo wow >> /opt/wow.txt" name="cron_wow"'
Schedule string generation every 1 minute wow Write the appended label as mysql(node2)of/opt/wow.txt Directory, task name is cron_wow

20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "cron_wow"
    ]
}

[root@master .ssh]# Ansible MySQL -a'crontab -l'view the planned task list
20.0.0.12 | CHANGED | rc=0 >>
#Ansible: cron_wow
*/1 * * * * /usr/bin/echo wow >> /opt/wow.txt
 Time sharing day month week

On node2

[root@node2 ~]# cd /opt
[root@node2 opt]# ls 
[root@node2 opt]# cat wow.txt view task plan effect

3.2.1 deleting a task plan

[root@master .ssh]# ansible mysql -m cron -a 'name="cron_wow" state=absent'
absent: Delete, remove
[root@master .ssh]# ansible mysql -a 'crontab -l' 

3.3 user module

user Module is requested is useradd(Add), userdel(Delete), usermod(User attribute modification) three instructions

Check whether the tree user exists on node1,2

[root@node1 .ssh]# id tree
id: tree: no such user
[root@node2 .ssh]# id tree
id: tree: no such user

3.3.1 create user command

Execute on the master

[root@master .ssh]# ansible all -m user -a 'name="tree"'

View on node1,2

[root@node1 .ssh]# id tree
uid=1001(tree) gid=1001(tree) group=1001(tree)

[root@node2 .ssh]# id tree
uid=1001(tree) gid=1001(tree) group=1001(tree)

3.3.2 deleting a user

Delete users on webserver (node1) labeled

[root@master .ssh]# ansible webserver -m user -a 'name="tree" state=absent'
20.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "force": false, 
    "name": "tree", 
    "remove": false, 
    "state": "absent"
}

View on node1

[root@node1 .ssh]# id tree
id: tree: no such user

3.4 group module

group Module is requested is groupadd,groupdel,groupmod Three instructions
[root@master .ssh]# ansible mysql -m group -a 'name=apple gid=1050 system=yes'
When the label is mysql(node2)Create owner on apple,group id 1050
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 1050, 
    "name": "apple", 
    "state": "present", 
    "system": true
}

View on node2

[root@node2 opt]# getent group | grep apple
apple:x:1050:

3.4.1 adjust user master and group settings

[root@master .ssh]# ansible mysql -m user -a 'name=tree uid=1050 system=yes group=apple'
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1050, 
    "home": "/home/tree", 
    "move_home": false, 
    "name": "tree", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1050
}

View on node2

[root@node2 opt]# id tree
uid=1001(tree) gid=1001(tree) group=1001(tree)
[root@node2 opt]# getent group | grep apple
apple:x:1050:
[root@node2 opt]# id tree
uid=1050(tree) gid=1050(apple) group=1050(apple)

3.5 copy module

Copy the files on the management side to the remote host

[root@master .ssh]# ansible mysql -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=tree mode=600'
Copy local disc auto mount file to label mysql(node2)Up, target location/opt/fstab.bak,Its owner is tree,Permission is read / write 600

20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "0080709750eb031954504c7d7ec690d5aa4a831b", 
    "dest": "/opt/fstab.bak", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "3dad79cde026184246d6ec77b56f0a51", 
    "mode": "0600", 
    "owner": "tree", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 617, 
    "src": "/root/.ansible/tmp/ansible-tmp-1610380847.75-66045-213200507422952/source", 
    "state": "file", 
    "uid": 1050
}

View on node2

[root@node2 opt]# ls 
[root@node2 opt]# ll
[root@node2 opt]# cat fstab.bak view content

[root@master .ssh]# ansible mysql -m copy -a 'content="this is a pingguo" dest=/opt/pingguo.txt'
Create a file with content

20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "ee28bd867be88ca865cdee4b61363b7fa28b87f8", 
    "dest": "/opt/pingguo.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "5c21b429ebbd579eac9796a4c29ecb3c", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 17, 
    "src": "/root/.ansible/tmp/ansible-tmp-1610381693.93-66230-115822261710168/source", 
    "state": "file", 
    "uid": 0
}

View on node2

[root@node2 opt]# ls 
[root@node2 opt]# cat pingguo.txt 

3.6 file management module

You can operate to change file attributes, create soft connections, create and delete files,Create directory

3.6.1 changing file attributes

[root@master .ssh]# ansible mysql -m file -a 'owner=root group=tree mode=755 path=/opt/fstab.bak'
Change owner to root,Genus group is tree,The permission is 755, and the target file location is/opt/fstab.bak
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 1001, 
    "group": "tree", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/opt/fstab.bak", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 617, 
    "state": "file", 
    "uid": 0
}

View on node2

[root@node2 opt]# ll

3.6.2 create soft links

[root@master .ssh]# ansible mysql -m file -a 'path=/fstab.link src=/opt/fstab.bak state=link'
Label is mysql(node2)Create a soft link on, and the file location is under the root directory/fstab.link,Source file is/opt/fstab.bak .Status information is a link
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/fstab.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:root_t:s0", 
    "size": 14, 
    "src": "/opt/fstab.bak", 
    "state": "link", 
    "uid": 0
}

View on node2

[root@node2 opt]# ls /
[root@node2 opt]# ll /

3.6.3 deleting files

[root@master .ssh]# ansible mysql -m file -a 'path=/opt/fstab.bak state=absent'
    Label is mysql(node2)File location on/opt/fstab.bak,Status is remove delete
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "path": "/opt/fstab.bak", 
    "state": "absent"
}

View on node2

[root@node2 opt]# ls 
[root@node2 opt]# ll /

3.6.4 creating files

[root@master .ssh]# ansible mysql -m file -a 'path=/opt/aaa state=touch'
Label is mysql(node2)Upper file location is/opt/aaa,Status is touch
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/opt/aaa", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}

View on node2

[root@node2 opt]# ls 

3.7 ping module

every time ansible Before implementing automated deployment, you need to check whether all nodes are connected to master The management end remains connected
[root@master .ssh]# ansible all -m ping

3.8 yum install module

Check whether httpd software is installed on node2

[root@node2 ~]# rpm -q httpd
 Package not installed httpd 

On the master

[root@master ~]# ansible mysql -m yum -a 'name=httpd'

View on node2

[root@node2 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64

3.8.1 uninstalling software

[root@master ~]# ansible mysql -m yum -a 'name=httpd state=absent'

View on node2

[root@node2 ~]# rpm -q httpd
 Package not installed httpd 

3.9 service module

3.9.1 the label is that the software installed on mysql (node2) is named httpd

[root@master ~]# ansible mysql -m yum -a 'name=httpd'
[root@master ~]# ansible mysql  -a 'systemctl status httpd'
Label is mysql(node2)View on httpd Service status
20.0.0.12 | FAILED | rc=3 >>   rc If it is not 0, it means that the status is abnormal and the service is not started
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:httpd(8)
           man:apachectl(8)non-zero return code
           
[root@master ~]# ansible mysql  -m service -a 'name=httpd state=started enabled=true'
Label is mysql(node2)upper httpd Service status on, self start

3.9.2 the status of firewall on mysql (node2) is closed

[root@master ~]# ansible mysql -m service -a 'name=firewalld state=stopped'

3.9.3 viewing firewall status

[root@master ~]# ansible mysql  -a 'systemctl status firewalld'
20.0.0.12 | FAILED | rc=3 >>
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)non-zero return code

Access on Browser
node2 ip address
http://20.0.0.12

3.9.4 add Web page file

[root@master ~]# ansible mysql -m copy -a 'content="this is a tree" dest=/var/www/html/index.html'
                                                             Create generation, specific content              target
20.0.0.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "d2540e88c7f86770127460388df9b0fa99327a24", 
    "dest": "/var/www/html/index.html", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "af784489edee36d2b28f7faea3cb7567", 
    "mode": "0644", 
    "owner": "root", 
    "size": 14, 
    "src": "/root/.ansible/tmp/ansible-tmp-1610449191.21-70221-48380936468909/source", 
    "state": "file", 
    "uid": 0
}

Access again on the browser

4.0 shell script module

chdir: Specify the working directory. When executing the corresponding command, you will enter the chdir In the directory specified by the parameter (i.e cd Command)
Condition judgment:
creates: Specify a file. When the specified file exists, the corresponding command will not be executed
removes: Use this parameter to specify a file. When the specified file does not exist, the corresponding command will not be executed

4.0.1 differences between command and shell module

View files on node2

[root@node2 ~]# cd /opt/
[root@node2 opt]# ls 

[root@master ~]# ansible mysql -m command -a 'echo this is tree > /opt/tree.txt'
20.0.0.12 | CHANGED | rc=0 >>
this is tree > /opt/tree.txt
[root@master ~]# ansible mysql -m command -a 'echo this is tree >> /opt/tree.txt'
20.0.0.12 | CHANGED | rc=0 >>
this is tree >> /opt/tree.txt

The default command does not recognize redirection, and the symbol is appended

View files on node2

Output this is tree redirection /opt/tree Txt down

[root@master ~]# ansible mysql -m shell -a 'echo this is tree > /opt/tree.txt'
20.0.0.12 | CHANGED | rc=0 >>

Output this is tree append /opt/tree Txt down

[root@master ~]# ansible mysql -m shell -a 'echo this is tree >> /opt/tree.txt'

View on node2

[root@node2 opt]# ls 
[root@node2 opt]# cat tree.txt 
[root@node2 opt]# cat tree.txt 

4.0.2 on the label mysql (node2), under cd (enter) /usr/local directory, output and redirect this is apple to the apple file

[root@master ~]# ansible mysql -m shell -a 'chdir=/usr/local echo this is apple > apple.txt'
20.0.0.12 | CHANGED | rc=0 >>

View on node2

[root@node2 opt]# cd
[root@node2 ~]# cd /usr/local/
[root@node2 local]# ls -lh
[root@node2 local]# cat apple.txt 

4.1 script module

Create scripts on the ansible management side

[root@master ~]# cd /opt/
[root@master opt]# ls -lh view
[root@master opt]# vi script.sh
 add to
#!/bin/bash
echo "fruits trees" > /opt/script.txt

[root@master opt]# ls -lh
[root@master opt]# chmod +x script.sh add permissions
[root@master opt]# ls -lh
[root@master opt]# ansible all -m script -a 'script.sh'
Add script to all nodes

View on node1,2

4.2 setup module (obtain node information)

[root@master opt]# ansible mysql -m setup
 View label mysql(node2)Node information for
 Can be used for system equipment patrol inspection



IV. resolution of defined node group name variable settings in Inventory

ansible The default host list is/etc/ansible/hosts file
 The host list can be set manually or through the Dynamic Inventory Dynamic generation

1. url http://www.baidu.com:80/new
url:Resource location
 agreement://Host name Secondary domain name Top level domain name (root domain): port / virtual directory

Common hostname usage FQDN(Fully qualified domain name): www.baidu.com   (host name+domain name)

Domain name: baidu.com

Enter host list

[root@master ~]# vi /etc/ansible/hosts 

[webserver]  Square brackets set group name
20.0.0.11
[mysql]
20.0.0.12

www1.example.org  Define monitored hosts,This can be the host name or IP address,Hostname needs to be modified/etc/hosts file
www2.example.org:2222   Define the remote connection port after the colon. The default is ssh 22 port of
 For hosts with similar names, you can identify each host in the form of a list
 www[001:006].example.com

Converted to 6 nodes, data redundancy

www001.example.com
www002.example.com
www003.example.com
www004.example.com
www005.example.com
www006.example.com

For hosts with similar names, you can identify each host in the form of a list

[webserver]
www[01 :50].example.org ansible ssh user-root ansible_ssh_pass=123456
                                                                   ssh Login as user
[dbbservers]
db-[a:fJ.example.org //Support matching abc 

4.1 variables in inventory

4.1 host variables

Assign corresponding variable values to nodes

[webserver]
www1.magedu.com http_ port=80 maxRequestsChild=808
www2.magedu.com http_ port= 8080 maxRequestsChild=909

4.2 group variables

[servers:vars]
ntp_ server=ntp.example.org
nfs_ server=nfs.example.org

4.3 group nesting

[apache]  group
http1.example.org   Contains two nodes
http2.example.org  
[nginx]    group
ngx1.example.org   Contains two nodes
ngx2.example.org  
[webserverschildren]
apache
nginx

4.4 inventory variable parameters

      parameter                                            explain
ansible_ ssh host                   Remote host name to be connected.If it is different from the alias of the host you want to set, you can set it through this variable.
ansible ssh port                    ssh Port number if it is not the default port number,Set by this variable.
ansible ssh_user                    default ssh user name
ansible_ssh_pass                   ssh password(This is not safe,We strongly recommend using--ask-pass or SSH secret key)
ansible_ssh_private_key_file       ssh Private key file used for multiple keys,And you don't want to use SSH Agency situation.
ansible ssh_common args             This setting is attached to sftp,scp and ssh Default command line for (turn on function first)
ansible_sftp_extra_args             This setting is appended to the default sftp Command line. (extended command line)
ansible_scp_extra_args              This setting is appended to the default scp Command line.
ansible ssh extra args              This setting is appended to the default ssh Command line.
ansible ssh pipelining              Determine whether to use SSH The Conduit. This can override ansible.cfg Settings in.

VPN:With the help of the public network, the tunnel encryption is enabled, and the transmission data is also encrypted;
  Wall climbing: the tunnel establishes a connection relationship, and a ip Address packet header
 Domestic pair DNS Filter

ansible shell type                    Of the target system shell type.By default,Execution and use of commands'sh' grammar,Can be set to'csh' or'fish'.
ansible python interpreter            Target host's python route.Applicable to:There are multiple in the system Python,Or the command path is not/usr/bin/python"such as*
ansible * interpreter                 there"*"Can be ruby or perl Or other language interpreters, and ansible python interpreter similar
ansible shell executable              This will set ansible The controller will use on the target machine shell,cover ansible.cfg The default is/bin/sh. 

summary

1.ansible It works based on modules. Different modules correspond to different service operation configurations, ansible This enables batch system configuration, batch program deployment, batch run commands and other functions.

2.Project example
 How to handle when the root partition capacity is insufficient and approaches the critical value?

Solution:
a.First, the root partition cannot be created LVM,So it cannot be extended
b.The root partition will accumulate a large number of log files, which are stored in the/var/log/...Under, you can free up space by deleting old logs and backing up new logs
c.If it still fails, you can copy the large files in the root partition to other partitions, and the partition is LVM Created in```Create a soft link on the original root partition to solve the capacity problem

3.When ansible use ping Module, when checking node connectivity, if not success Status, indicating connectivity problems
 Solution:

   a.Check the network connectivity, whether ping Valid
   b.see master On the management end vi /etc/ansible/hosts Whether the label name is correct
   c.View on node.ssh There is a problem with the key in. Delete the key file and retransmit it
   rm -rf authorized_keys 
   d,View the ssh Whether the service is enabled on the port

4.shell Multiple statements can be written in a script, and shell Can recognize redirection, append, default command Command not recognized

Posted by pvechi on Fri, 03 Jun 2022 13:39:22 +0530