Ansible上手指南

ansible上手指南

ansible可以用于批量化地配置管理系统,远程执行命令

ansible是一个同时管理多个主机的软件,必须是任意可以通过ssh登录的机器,基于python编写

  • 远程虚拟机
  • 物理机
  • 本机机器

ansible最大的特点是无需在被管理端安装客户端,仅仅使用ssh服务即可(不额外占用端口),不使用root也可以执行,并且可以使用yaml配置文件语法

此处有三台虚拟机,此处机器操作系统为CentOS8

node1  192.168.84.5		安装了ansible的机器
node2  192.168.84.6
node3 192.168.84.7

配置yum、epel源

此处机器操作系统为 CentOS8

请务必检查:(这里CentOS8与CentOS7是相同的)

本机 /etc/sysconfig/network-scripts/ifcfg-ens33 文件配置正确

DNS服务器正常,文件位置:/etc/resolv.conf

检查防火墙与SELinux服务

否则可能出现以下问题

[root@node2 yum.repos.d]# ping www.baidu.com
ping: www.baidu.com: 未知的名称或服务

导致 /etc/yum.repos.d/CentOS-Base.repo 文件

一、配置阿里云yum源

1.备份原有yum源配置文件

sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

2.下载阿里云CentOS 8 yum源配置文件

sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo

3.清理与生成缓存

#清理缓存
sudo yum clean all
#生成缓存
sudo yum makecache

二、配置EPEL源

1.安装EPEL源的GPG密钥

sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

2.安装EPEL源的yum配置文件

sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

3.替换EPEL源的yum配置文件为阿里云镜像

sudo sed -i 's|^#baseurl=https://download.fedoraproject.org/pub|baseurl=https://mirrors.aliyun.com|' /etc/yum.repos.d/epel*
sudo sed -i 's|^metalink|#metalink|' /etc/yum.repos.d/epel*

4.清理与生成缓存

#清理缓存
sudo yum clean all
#生成缓存
sudo yum makecache

三、检查可用的yum仓库

yum repolist

管理端安装ansible

#因为ansible无需额外配置,所以此处使用yum直接安装
#需提前配置好阿里云yum、epel源
yum install -y epel-release
yum install ansible libselinux-python -y

检查ansible的安装情况

#查询ansible软件安装情况,查询配置文件和可执行命令
[root@node1 ~]# rpm -ql ansible | grep -E '^/etc|^/usr/bin'
/etc/ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts
/etc/ansible/roles
/usr/bin/ansible
/usr/bin/ansible-2
/usr/bin/ansible-2.7
/usr/bin/ansible-config
/usr/bin/ansible-connection
/usr/bin/ansible-console
/usr/bin/ansible-console-2
/usr/bin/ansible-console-2.7
/usr/bin/ansible-doc
/usr/bin/ansible-doc-2
/usr/bin/ansible-doc-2.7
/usr/bin/ansible-galaxy
/usr/bin/ansible-galaxy-2
/usr/bin/ansible-galaxy-2.7
/usr/bin/ansible-inventory
/usr/bin/ansible-playbook
/usr/bin/ansible-playbook-2
/usr/bin/ansible-playbook-2.7
/usr/bin/ansible-pull
/usr/bin/ansible-pull-2
/usr/bin/ansible-pull-2.7
/usr/bin/ansible-vault
/usr/bin/ansible-vault-2
/usr/bin/ansible-vault-2.7

检查ansible版本

[root@node1 ~]# ansible --version
ansible 2.9.27
  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解释器版本为2.7.5
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

被管理端安装ansible模块

yum install epel-release libselinux-python -y

ansible使用

ansible配置文件

  • 位置: /etc/ansible/ansible.cfg

配置hosts文件(需要管理的主机)

  • vim /etc/ansible/hosts

    添加如下信息

[fishpie]	#分组名字,可以 [] 内自定义
192.168.84.6	#node2
192.168.84.7	#node3

ssh密码验证

直接利用ssh服务来管理需要操控的对象

-m  指定功能模块,默认就是command
-a  告诉模块需要执行的参数
-k  使用密码验证
-u  指定登录用户
#此处的fishpie就是hosts文件中的分组
ansible fishpie -m command -a 'hostname' -k -u root

可能会出现一下问题

[root@node1 ansible]# ansible fishpie -m command -a 'hostname' -k -u root
SSH password: 
192.168.84.6 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host.
192.168.84.7 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host.

解决方法:

  1. 将目标主机的指纹添加到SSH的known_hosts文件中
    ssh root@192.168.84.6 ssh root@192.168.84.7 …(手动全部连接一遍)
  2. 在Ansible的ansible.cfg配置文件中,禁用主机密钥检查
    在 /etc/ansible/ansible.cfg 文件中添加或放行 host_key_checking = False

第一种方法较为麻烦,但是稍微安全一些,在可信环境下,可以使用第二种

连接成功后

[root@node1 ansible]# ansible fishpie -m command -a 'hostname' -k -u root
SSH password: 
192.168.84.7 | CHANGED | rc=0 >>
node3
192.168.84.6 | CHANGED | rc=0 >>
node2

配置免密登录

方式一:直接在hosts文件添加ssh用户与密码(不是很安全)

  • vim /etc/ansible/hosts

    改动以下内容

[fishpie]	
192.168.84.6 ansible_user=root ansible_ssh_pass=123456	#指定ssh连接用户名与密码
192.168.84.7 ansible_user=root ansible_ssh_pass=123456  #指定ssh连接用户名与密码

此时执行命令可直接跳过指定用户与密码

[root@node1 ansible]# ansible fishpie -a 'hostname'
192.168.84.7 | CHANGED | rc=0 >>
node3
192.168.84.6 | CHANGED | rc=0 >>
node2

方式二:在管理机上创建被管理机的密钥对(更安全)

#在node1上创建ssh密钥对
#-f  指定生成的密钥文件的路径和文件名
#-P  参数用于指定密钥的密码(passphrase) ''标识不为密钥设置密码
ssh-keygen -f ~/.ssh/id_rsa -P '' > /dev/null 2>&1

编写公钥分发脚本 ssh_key_send.sh

#!/bin/bash
rm -rf ~/.ssh/id_rsa*
ssh-keygen -f ~/.ssh/id_rsa -P '' > /dev/null 2>&1
SSH_Pass=123456
Key_Path=~/.ssh/id_rsa.pub
for ip in 6 7
do
        sshpass -p$SSH_Pass ssh-copy-id -i $Key_Path "-o StrictHostKeyChecking=no" 192.168.84.$ip
done

执行情况

[root@node1 mysh]# chmod -x ssh_key_send.sh 
[root@node1 mysh]# sh ssh_key_send.sh 
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh -o ' StrictHostKeyChecking=no' '192.168.84.6'"
and check to make sure that only the key(s) you wanted were added.

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh -o ' StrictHostKeyChecking=no' '192.168.84.7'"
and check to make sure that only the key(s) you wanted were added.

此时也可以进行无密码连接(此时host文件仅仅配置了被管理机的ip地址)

[root@node1 ansible]# ansible fishpie -a 'hostname'
192.168.84.7 | CHANGED | rc=0 >>
node3
192.168.84.6 | CHANGED | rc=0 >>
node2

ansible模式(重点)

ad-hoc模式

  • -m command 命令(默认)
  • -m shell shell特性操作
  • -m copy 复制
  • -m yum 安装
  • -m user 用户操作
  • -m service 系统服务

关于cmmand模式与shell模式的区别:

  1. 命令执行方式:
    • command 模块直接在远程主机上执行指定的命令,不会通过shell进行处理。这意味着shell的特性,如变量替换、通配符展开等,不会生效
    • shell 模块通过shell(/bin/sh)来执行命令,因此shell的特性可以生效。这允许你使用环境变量、管道、重定向等shell功能
  2. 参数处理:
    • command 模块将给定的命令作为一个字符串,不会对其进行任何处理。你需要自己处理任何引号或转义字符
    • shell 模块会将给定的命令通过shell进行处理,因此你可以使用shell的语法,如管道、重定向等
  3. 安全性:
    • command 模块相对更安全,因为它不会解释shell的元字符,减少了注入攻击的风险
    • shell 模块使用shell来执行命令,如果命令来自不可信的源(如用户输入),可能存在安全风险
  4. 幂等性:
    • command 模块默认是幂等的,意味着重复执行相同的命令不会改变结果
    • shell 模块默认是非幂等的,因为shell命令可能会有副作用,重复执行可能导致不同的结果

例如:

使用command模块

ansible all -m command -a "ls /tmp"

使用shell模块

ansible all -m shell -a "ls /tmp | grep file"

用于处理临时、简单的任务

  • cpu负载情况,网络情况
  • 临时分发配置文件

示例:

在fishpie组显示系统运行时间

[root@node1 ansible]# ansible fishpie -m command -a 'uptime'
192.168.84.7 | CHANGED | rc=0 >>
 20:49:41 up  3:44,  2 users,  load average: 0.00, 0.03, 0.06
192.168.84.6 | CHANGED | rc=0 >>
 20:49:41 up  3:44,  2 users,  load average: 0.00, 0.01, 0.05

在fishpie组执行特定命令

[root@node1 ansible]# ansible fishpie -m shell -a "ls -l /home"
192.168.84.7 | CHANGED | rc=0 >>
总用量 0
drwx------. 4 fishpie fishpie 123 48 14:30 fishpie
192.168.84.6 | CHANGED | rc=0 >>
总用量 0
drwx------. 4 fishpie    fishpie    123 112 16:34 fishpie
drwx------. 2 fishpie123 sfishpie123  62 1014 2023 fishpie123

在fishpie组每台系统内文件传输

ansible fishpie -m copy -a "src=/etc/hosts dest=/tmp/hosts"

在fishpie组安装安装Apache httpd软件包

ansible fishpie -m yum -a "name=httpd state=present"

在fishpie组所有主机上创建 名为apple,密码为123456 的用户

ansible fishpie -m user -a "name=apple password=123456"

在fishpie组所有主机上启动Apache httpd服务

ansible fishpie -m service -a "name=httpd state=started"

playbook模式

用于处理具体且大量操作的任务

  • 一键部署rsync备份服务器
  • 一键部署lnmp环境

指定管理主机组的文件,然后创建 YAML 文件

示例:

一键部署LNMP环境(Linux、Nginx、MySQL、PHP)

创建名为lnmp的YAML文件,

---
- hosts: fishpie	#指定主机组
  become: yes	#在执行以下任务时权限升级(sudo)

  tasks:
    - name: Install nginx	#安装nginx
      yum:
        name: nginx
        state: present

    - name: Start nginx service	#启动nginx
      service:
        name: nginx
        state: started

    - name: Install MySQL	#安装MySQL
      yum:
        name: mariadb-server
        state: present

    - name: Start MySQL service	#启动MySQL
      service:
        name: mariadb
        state: started

    - name: Set MySQL root password	#设置MySQL的root密码
      mysql_user:
        name: root
        password: secret
        login_unix_socket: /var/lib/mysql/mysql.sock

    - name: Install PHP and related packages	#安装PHP和相关的包
      yum:
        name:
          - php
          - php-fpm
          - php-mysql
        state: present

    - name: Start PHP-FPM service	#启动PHP-FPM服务
      service:
        name: php-fpm
        state: started

    - name: Configure nginx for PHP	#配置Nginx以支持PHP
      template:
        src: default.conf.j2
        dest: /etc/nginx/conf.d/default.conf
      notify: Restart nginx

#当'Configure nginx for PHP'任务发出通知时,它会重启Nginx服务
  handlers:
    - name: Restart nginx	#重启nginx
      service:
        name: nginx
        state: restarted

在这个hosts文件目录下运行

ansible-playbook -i hosts lnmp.yml

ansible模块

command模块

查看模块支持的参数

  • ansible-doc -s <模块种类>

比如查看command模块支持的参数

[root@node1 ansible]# ansible-doc -s command
- name: Execute commands on targets
  command:
      argv:                  # Passes the command as a list rather than a string. Use `argv' to avoid quoting values that
                               would otherwise be interpreted incorrectly (for example "user
                               name"). Only the string or the list form can be provided, not
                               both.  One or the other must be provided.
      chdir:                 # Change into this directory before running the command.
      cmd:                   # The command to run.
      creates:               # A filename or (since 2.0) glob pattern. If it already exists, this step *won't* be run.
      free_form:             # The command module takes a free form command to run. There is no actual parameter named 'free
                               form'.
      removes:               # A filename or (since 2.0) glob pattern. If it already exists, this step *will* be run.
      stdin:                 # Set the stdin of the command directly to the specified value.
      stdin_add_newline:     # If set to `yes', append a newline to stdin data.
      strip_empty_ends:      # Strip empty lines from the end of stdout/stderr in result.
      warn:                  # Enable or disable task warnings.

可知command模块支持参数

chdir	    #执行命令前,先cd进入该参数指定的目录
cmd	        #直接执行命令
creates     #创建文件前先判断该文件是否存在,文件不存在才执行动作
free_form   #可以输入任何系统命令
removes     #删除文件前先判断该文件是否存在,文件不存在才执行动作

详细示例:

  1. chdir

    • 作用:在执行命令之前,先进入指定的目录。

    • 示例:

      - name: Run command in specific directory
        command:
          cmd: ls
          chdir: /var/www/html
      
    • 在远程主机的/var/www/html目录下执行ls命令。

  2. cmd

    • 作用:指定要执行的命令。

    • 示例:

      - name: Run a command
        command: /usr/bin/hostname
      
    • 在远程主机上执行/usr/bin/hostname命令。

  3. creates

    • 作用:指定一个文件名或(从Ansible 2.0开始)一个glob模式。如果指定的文件或模式已经存在,则该任务将不会运行。

    • 示例:

      - name: Install nginx
        command: yum install -y nginx
        creates: /usr/sbin/nginx
      
    • 如果/usr/sbin/nginx已经存在,则不会执行yum install -y nginx命令。

  4. free_form

    • 作用:这不是一个真正的参数,而是表示command模块接受一个自由格式的命令。你可以直接写命令而不用cmd参数。

    • 示例:

      - name: Run a command
        command: /usr/bin/hostname
      
    • 等同于使用cmd参数。

  5. removes

    • 作用:指定一个文件名或(从Ansible 2.0开始)一个glob模式。如果指定的文件或模式已经存在,则该任务将会运行。

    • 示例:

      - name: Remove file
        command: rm /tmp/file
        removes: /tmp/file
      
    • 如果/tmp/file存在,则会执行rm /tmp/file命令。

  6. stdin

    • 作用:将命令的标准输入直接设置为指定的值。

    • 示例:

      - name: Run command with stdin
        command: python
        stdin: print('Hello, World!')
      
    • 运行python命令,并将print('Hello, World!')作为标准输入传递给它。

  7. stdin_add_newline

    • 作用:如果设置为yes,则在标准输入数据的末尾添加一个新行。

    • 示例:

      - name: Run command with stdin
        command: python
        stdin: print('Hello, World!')
        stdin_add_newline: yes
      
    • 确保在标准输入的末尾有一个新行。

  8. strip_empty_ends

    • 作用:从结果的stdout/stderr中去除末尾的空行。

    • 示例:

      - name: Run command and strip empty lines
        command: /usr/bin/some_command
        strip_empty_ends: yes
      
    • 从命令的输出中删除末尾的空行。

  9. warn

    • 作用:启用或禁用任务警告。

    • 示例:

      - name: Run command without warnings
        command: /usr/bin/some_command
        warn: no
      
    • 禁用该任务的警告。

script模块

可以批量让所有被管理的机器执行脚本,且该脚本不需要在客户端上存在

模块参数

[root@node1 ansible]# ansible-doc -s script
- name: Runs a local script on a remote node after transferring it
  script:
      chdir:                 # Change into this directory on the remote node before running the script.
      cmd:                   # Path to the local script to run followed by optional arguments.
      creates:               # A filename on the remote node, when it already exists, this step will *not* be run.
      decrypt:               # This option controls the autodecryption of source files using vault.
      executable:            # Name or path of a executable to invoke the script with.
      free_form:             # Path to the local script file followed by optional arguments.
      removes:               # A filename on the remote node, when it does not exist, this step will *not* be run.

示例:

在/myscript目录下创建一个名为localhostname.sh的脚本,内容如下

pwd
hostname

添加执行权限

chmod -x localhostname.sh

使用该脚本

[root@node1 myscript]# ansible fishpie -m script -a "/myscript/localhostname.sh"
192.168.84.7 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.84.7 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.84.7 closed."
    ], 
    "stdout": "/root\r\nnode3\r\n", 
    "stdout_lines": [
        "/root", 	#返回的内容
        "node3"		#返回的内容
    ]
}
192.168.84.6 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.84.6 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.84.6 closed."
    ], 
    "stdout": "/root\r\nnode2\r\n", 
    "stdout_lines": [
        "/root", 
        "node2"
    ]
}
  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值