Linux笔记:自动化运维之部署管理:Fabric、SSH免密码登录、Ansible、Paramiko的应用

连接服务器的远程终端工具

  • SecureCRT 收费
  • Xshell 收费
  • mtputty 免费(windows下的putty的外壳程序,下载后放入putty同级,可以对多台服务器进行有效管理)

测试服务器代码的部署

  • 代码完成后,需要进行测试, 就需要将我们的代码部署到测试服务器上!
  • 测试服务器上创建一个git仓库,同步最新的项目代码!
  • 每次需要测试时, 通过代码更新, 将最新代码同步即可!

生产服务器代码的部署

  • 测试完成后, 我们需要对测试过的代码进行生产环境部署
  • 本地打包, 如: $ tar -zcf ../new.tar.gz . ,上传到生产服务器, 如:$scp new.tar.gz [email protected]:/root,
  • 备份线上代码,如:$mv /data/webroot/project1 /data/webroot/project1_v1
  • 解压到部署目录, 如: $cd /data/webroot/project1/, $tar -zxf /root/new.tar.gz
  • 再次进行线上测试验收
  • 如果有问题,那么进行回滚操作:将刚才部署到线上代码修改为project1_v2,将之前备份的代码目录project1_v1还原为project1即可!
  • 或者更好的回滚操作, 创建软链接:$ln -s project1_v1 project1, 然后重启uwsgi服务即可!
  • 通过软链接的形式, 这样以后有多个版本都可以通过删除软链接, 重新创建软链接的形式, 无缝切换, 方便,高效,安全,快捷!

使用Fabric批量的自动化部署

  • 如果多台服务器,手动部署将会变得工作量巨大而又麻烦,我们可以通过使用Fabric批量部署管理
  • Fabric的安装:$pip3 install fabric3
  • 编写fabfile.py文件, 不要修改名称,默认是这个,修改后还需重新指定
    from fabric.api import *
    import datetime
    
    env.user='root'
    env.hosts=['192.168.55.66', '192.168.55.67']
    
    def demo1():
        # local 表示在本机执行
        # 通过执行 `fab demo1` 即可创建一个demo1文件
        local('touch demo1') # 这里面直接使用shell命令
    
    def demo2():
        # run表示在远程机器执行
        # `fab demo2 -H 192.168.55.66`
        run('touch demo2')
        # 除了run之外,我们要传递文件到远程服务器上使用put(), 要在远程服务器上改变当前文件夹,则需要使用cd()命令
    
    def pack():
        '''定义一个打包命令'''
        local('rm -f temp.tar.gz') # 先执行删除操作
        local('cd project1 && git pull origin master') # 拉取最新代码
        local('cd project1 && tar -czf ../temp.tar.gz --exclude=.git . ') # 打包除了.git目录外的所有文件
    
    def deploy():
        '''部署文件'''
        remote_temp_tar = '/tmp/temp.tar.gz'
        run('rm -rf ' + remote_temp_tar) # 先删除远程文件
        put('temp.tar.gz', remote_temp_tar) # 传输当前压缩文件
    
        # 定义一个远程文件夹,用于创建和解压, 并且保留不同版本
        tag = datetime.datetime.now().strftime('%Y%M%D%H%M%S')
        remote_dist_dir = '/data/deploy/project1@' + tag
        run('mkdir -p ' + remote_dist_dir)
    
        # 开始解压缩
        with cd(remote_dist_dir):
            run('tar -zxf ' + remote_temp_tar)
    
        # 为了程序不报错, 创建文件夹
        run('mkdir -p /data/webroot')
        # 定义和创建软链接
        link = '/data/webroot/project1'
        run('rm -rf' + link)
        run('ln -s %s %s ' % (remote_dist_dir, link))
    
        # 重启uwsgi服务
        with settings(warn_only=True):
            run('pkill uwsgi') # 结束进程时,可能没有启动,会出错,此处通过with来处理该异常
            run('/usr/local/bin/uwsgi --ini /data/uwsgi.ini')
    
    
  • 注意在部署前要确保服务器上存在/data/uwsgi.ini配置文件
  • 同时也需要手动输入密码进行操作
  • 执行 $fab pack 本机打包
  • 执行 $fab deploy 远程部署
  • 也可以同时执行 $fab pack deploy

批量运维管理

  • 目前我们需要管理的机器越来越多了,如果每次连接都要手动输入密码,那么就没法称之为自动化了, 那么就需要对这些机器进行科学的管理

1 ) SSH免密码登录 原理

  • RSA非对称加密算法

    • Public Key 公钥 (公开出去)
    • Private Key 私钥 (自己保管)
    • 它们之间成对使用, 公钥加密的数据,只有对应的私钥才能解密;使用私钥加密的数据,只有对应的公钥才能解密
    • 由于加密和解密过程中使用了2个不同的密钥,所以我们称之为非对称加密算法
    • 无法通过公钥计算出私钥是什么
  • 利用RSA算法来实现免密码登录

    • 生成密钥对之后,我们把公钥放在服务器上,即可实现免密码登录
    • 服务器是如何进行身份验证呢?服务器通过公钥加密一段随机的内容,只要客户端能正确解密,就可以确定身份了
    • 因为拥有对应私钥的人才能解密成功,所以我们的私钥绝对不能泄露
    • 首先我们需要使用$ssh-keygen来生成我们的一对密钥(公钥、私钥), 默认生成在/root/.ssh/id_rsa
    • 使用ssh-copy-id命令将我们的公钥放到服务器上, $ssh-copy-id [email protected], 第一次连接需要输入密码 (假设66主机为我们的服务器)
    • 备注:ssh-copy-id命令不需进入/root/.ssh/目录,即可进行拷贝
    • 退出后再次进行连接ssh [email protected], 无需密码即可登录
    • 进行验证,登录66服务器主机,切换到/root/.ssh/ 进行查看 ls, 发现有了一个文件authorized_keys, 使用cat命令查看该文件,经过对比可知,它和我们客户端的公钥id_rsa.pub完全一致, 如果想要取消授权,我们只需要将authorized_keys这个文件删除即可!

2 ) SSH免密码登录 应用

  • 我们的客户端A想要同时连接多台机器C、D、E,存在防火墙,就需要进行相关的安全部署设计
  • 我们可以建立一台目标机器, 设为B, 通过B去控制连接C、D、E, 来响应客户端A
  • 我们将B上的公钥拷贝到C、D、E上后,只要A可以连接上B, 那么就可以控制C、D、E
  • 只需要做好B主机的安全措施即可!

3 ) Ansible运维工具的使用

  • Ansible是一个python开发的远程运维工具
  • 我们可以很方便的同时在多台服务器上进行维护任务,使用起来很简单
  • 官网:https://www.ansible.com
  • 安装:$apt install -y ansible
  • 查看版本:$ansible --version, 通过输出信息,可以看到它的默认配置文件在 /etc/ansible/ansible.cfg
  • 我们想要通过ansible来批量管理我们的机器, 我们就需要在其中配置好我们的机器列表, $cd /etc/ansible/ && ls 看到有个hosts文件
  • hosts文件就是用来配置机器列表的, 编辑它:$vi hosts, 我们使用[]来表示分组, 将我们需要批量部署的机器ip地址写进去
    # web服务器分组
    [web]
    192.168.55.66
    192.168.55.67
    # 数据库服务器分组
    [db]
    192.168.55.68
    
  • 保存后,我们就可以使用ansible对这些机器进行管理了
  • 首先我们通过uptime命令来打印机器时间和负载情况
  • 然后通过ansible的命令$ansible all -m raw -a "uptime"
    • all 代表机器列表中所有的机器, 我们可以将其替换成上面的web、db等我们配置好的分组
    • -m 表示使用模块
    • raw 表示ansible中的raw模块来执行我们的原生命令
    • -a 是这个模块需要的参数
    • "uptime" 就是这个例子中具体的参数
  • 备注:我们执行这条命令前要确保所有配置的机器都可以进行SSH免密码登录
  • 我们继续测试命令, $ansible all -m ping
    • 注意ping模块需要目标主机上安装python
    • 上面的检测是必须项,如果满足条件就可以使用ansible提供的其他模块了
    • 如果没有安装,我们可以通过$ansible all -m raw -a "apt update && apt install -y python"
    • 注意apt安装软件如果已经安装会自动跳过,不会产生问题
  • 我们继续测试命令, $ansible all -m script -a "./test.sh"
    • script 模块是将本机的脚本文件传送到目标机器然后去执行它
    • 可以在test.sh中编写一句简单的输出测试echo test
    • raw模块一样,不需要主机有python环境,我们可以利用这一特性,用于初始化裸机操作,比如:基础软件的安装
  • 我们继续测试命令, $ansible all -m command -a "uptime"
    • command 模块需要目标主机上有python运行环境的,是ansible的默认模块
    • 可以省略-m command, 即:$ansible all -a "uptime"
    • 列出根目录:$ansible all -a "ls /"
    • 查看磁盘空间:$ansible all -a "df -h"
    • 查看内存空间:$ansible all -a "free -m"
  • 我们继续测试命令, $ansible all -m copy -a "src=./test.sh dest=/tmp"
    • 用于拷贝文件的命令, 将当前文件夹下的test.sh文件拷贝到目标主机的/tmp目录下
    • src和dest分别表示源文件和目标文件
  • 我们继续测试命令, $ansible all -m file -a "path=/tmp/test.sh mode=0755"
    • 改变目标主机上的文件权限,用于执行远程文件
    • 默认创建的文件权限是-rw-r--r--, 不可以执行, 使用file模块改变了文件的权限
  • 我们继续测试命令, $ansible all -m shell -a "/tmp/test.sh"
    • shell模块用于执行shell脚本和script模块类似
    • 这条命令需要该文件有执行的权限
  • 我们继续测试命令, $ansible all -m fetch -a "src=/var/log/auth.log dest=./down"
    • fetch模块用于将远程机器上的文件auth.log下载回来,存放于当前目录下的down目录中
    • 备注:如果当前没有down目录,则会自动创建

4 ) Paramiko的使用

  • 使用Paramiko来编写自己的python程序来满足一些其他工具无法或很难实现的功能

  • Paramiko模块基于SSHv2版本协议, 封装了SSH客户端和sftp客户端, 我们可以很方便的使用它来连接远程的主机

  • 编写一个python程序,连接到远程主机, 执行一个命令获取远程主机的可用内存数据, 然后在python中做更多处理:监控、报警等等

  • 安装paramiko, $pip3 install paramiko

  • 创建一个run.py的文件

    import paramiko
    
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # ssh.connect(hostname='192.168.55.66', username='root', password='root') # 备注,此处password明文传输非常不安全,建议不写密码,先处理好SSH免密码登录
    ssh.connect(hostname='192.168.55.66', username='root') 
    # command = "free -m"
    command = "free -m | awk '/^Mem/{print $7}'" # 使用awk来过滤数据,这里输出第7列的数据
    stdin, stdout, stderr = ssh.exec_command(command)
    res = stdout.read().decode()
    print(res)
    
  • 执行该段代码, $python3 run.py 即可获取数据

自动化运维的专业知识

  • 网络相关知识
  • linux操作系统
  • 各种服务器软件的安装配置
  • python编码能力及相关web框架
  • 通过web界面发布指令来执行监控,备份,发布代码等
发布了403 篇原创文章 · 获赞 198 · 访问量 69万+

猜你喜欢

转载自blog.csdn.net/Tyro_java/article/details/104206658