一、概述

本文为ansible的安装过程和简单的入门使用

1.1 简介

Ansible 是一个开源的基于 OpenSSH 的自动化配置管理工具。可以用它来配置系统、部署软件和编排更高级的 IT 任务,比如持续部署或零停机更新。Ansible 的主要目标是简单和易用,并且它还高度关注安全性和可靠性。基于这样的目标,Ansible 适用于开发人员、系统管理员、发布工程师、IT 经理,以及介于两者之间的所有人。Ansible 适合管理几乎所有的环境,从拥有少数实例的小型环境到有数千个实例的企业环境。

使用 Ansible 无须在被管理的机器上安装代理,所以不存在如何升级远程守护进程的问题,也不存在由于卸载了守护进程而无法管理系统的问题。

1.2 主要功能

管理员可以通过 Ansible 在成百上千台计算机上同时执行指令(任务)。
对于管理员来说,经常需要执行下面的任务:

维护现存的比较复杂的服务器时,手动登录的方式很容易遗漏一些操作,或者是执行一些未预期的操作。
手动初始化新的服务器耗时耗力!
对于这两种情况,如果完全通过 shell 脚本实现。脚本会过于复杂,极难维护。当然我们也可以使用同类的工具,比如 Puppet and Chef。这两个工具的特点是:需要学习新的知识栈(其实 Ansible 也是有学习成本的)。

相比 Puppet 和 Chef 使用 Ansible 可以延续之前使用 shell 脚本的工作习惯和方式,因而其学习成本会低一些。下面是 Ansible 的一些优势:
1、可以逐行的执行 shell 命令。
2、不需要另外的客户端工具(linux 一般会自带 ssh 工具)。
3、相同的配置只被执行一次(多次执行同一配置不会出问题)。
但是因为许多服务器都是在内网环境,我们想安装Ansible就不是很便捷,所以就整合了下面的安装包,方便在离线环境进行安装

二、环境介绍

名称

型号

备注

Thinkpad

X250

宿主计算机

window10

教育版64位18363

主操作系统

WSL

1.0

介质

Linux

ubuntu18.04LTS

子操作系统

ansible

2.9.10

运维工具

python

2.7.17

编译器操作系统自带

Centos7

7.9.2009

远程主机

三、准备工作

宿主计算机安装window10 操作系统并且使用WSL安装linux ubuntu18.04 LTS,启动ssh服务

四、安装程序

安装程序部分主要包括安装ansible程序,及ansible程序依赖的库文件和ssh服务

4.1 安装依赖

4.1.1 查看ssh是否启动

#service ssh status

wget 安装ansible windows安装ansible_wget 安装ansible

4.1.2 安装ssh

ubuntu18.04系统自带ssh,不需要安装,启动即可

4.1.3 启动ssh

#service ssh start

4.2 安装ansible

ansible分为在线安装和离线安装两种形式

4.2.1 在线安装

更新操作系统源文件

#apt update

安装组件库

#apt install software-properties-common

更新ansible源文件

#apt-add-repository --yes --update ppa:ansible/ansible

安装ansible程序

#apt install ansible

查看版本信息

#ansible --version

4.2.2 离线安装

针对不具备互联网接入情况下,需要使用离线安装方式进行安装。

tar -xzvf ansible_v2.9.9_install.tar.gz     # 解压安装包,
cd ansible_v2.9.9_install					# 进入解压目录
chmod +x ansible_v2.9.0_install.sh			# 赋权执行权限
sh ansible_v2.9.0_install.sh				# 安装执行

五、使用ansible

5.1 主控端生成密匙

#ssh-keygen -t rsa

5.2 分发密匙

5.2.1、单台分发

ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.114

提示输入分发端服务器的root账号密码

输入完毕后,在分发端的#/root/.ssh/生成authorized_keys文件,并且在文件中存储了主控端的rsa值,具备以下数据后,从主控端可以免密登陆分发端主机。

5.2.2、批量分发

修改/etc/ansible/ansible.cfg配置文件

编辑hosts文件

添加如下内容

[jgxt]
192.168.4.12    ansible_ssh_user=root    ansible_ssh_pass="xxxxxxxx"
192.168.4.13    ansible_ssh_user=root    ansible_ssh_pass="xxxxxxxx"
192.168.4.15    ansible_ssh_user=root    ansible_ssh_pass="xxxxxxxx"
192.168.4.16    ansible_ssh_user=root    ansible_ssh_pass="xxxxxxxx"

或者

[jgxt]

192.168.4.12

192.168.4.13

192.168.4.15

192.168.4.16

[jgxt:vars]

ansible_ssh_user=root

ansible_ssh_pass="xxxxxxxx"

编写yml文件

---

- hosts: jgxt
  user: root
  tasks:
    - name: ssh-copy
      authorized_key: user=root key="{{ lookup('file', '/root/.ssh/id_rsa.pub')}}"
      tags:
        - sshkey

5.3 编辑被控端信息

#/etc/ansible/hosts文件中输入分发端主机信息

主机名

IP地址

备注

shalter

192.168.1.20

主控

jgxt1

192.168.1.12

jgxt1

jgxt3

192.168.1.15

jgxt3

mysql

192.168.1.115

mysql

devops

192.168.1.114

devops

5.4 测试使用

5.5 执行命令

5.5.1 拷贝数据

主控端拷贝命令到被控端,分批量拷贝和单台拷贝,单台拷贝需要指定要拷贝的主机分组,批量拷贝使用分组或者使用全部参数对数据进行拷贝

将tasks.yml文件从主控端当前目录拷贝至jgxt1服务器的/data/file/目录下,backup参数作用如果当前目录下没有此文件,直接拷贝,如果当前文件夹下有此文件,则将原文件重命名后拷贝此文件。

#ansible jgxt1 -m copy -a "desc=tasks.yml dest=/data/file/ backup=yes"
5.5.2 拉取数据

拉取数据为从被控端的指定目录下的文件拉取到主控端的指定目录下

#ansible jgxt3 -m fetch -a "src=/data/file/task.yml  dest=/root/devops/backup/192.168.1.12/data/file/"
5.5.3 发送命令

查看被控端jgxt1主机/data/file目录下的文件

#ansible jgxt1 -m shell -a "ls -all /data/file/"

5.6 实操环节

部署前端应用、后台应用和配置文件

5.6.1 前端应用部署

前端应用使用的是VUE编码实现,部署方式为解压部署文件至对应的目录即可

前端服务器jgxt1 IP地址192.168.1.12

前端应用目录/data/docker/volumes/isgs-app_nginx-www/_data/

部署步骤:

  1. 将现有文件备份
  2. 上传部署升级包文件
  3. 解压缩升级包文件

以升级tasks.zip文件举例

ansible jgxt1 -m shell -a "chdir=/data/docker/volumes/isgs-app_nginx-www/_data/ mv tasks tasks"

ansible jgxt1 -m copy -a "src=tasks.zip dest=/data/docker/volumes/isgs-app_nginx-www/_data/"

ansible jgxt1 -m shell -a "chdir=/data/docker/volumes/isgs-app_nginx-www/_data/ unzip tasks.zip"

至此前端程序部署完毕。刷新浏览器缓存进行验证。

5.6.2 后端应用部署

后端应用使用的java程序编码实现,部署方式使用docker方式部署。

后端服务器jgxt3 IP地址192.168.1.125

后端应用目录/data/images/

部署步骤:

  1. 拷贝现有文件至升级目录
  2. 删除当前镜像
  3. 加载新的镜像文件
  4. 重新打标签
  5. 推送镜像到服务
  6. 重新加载配置应用服务

以升级tasks.tar文件举例

ansible jgxt3 -m copy -a "src=tasks.tar dest=/data/images/ backup=yes"

ansible jgxt3 -m shell -a "docker rmi -f tasks_IMAGE ID"

ansible jgxt3 -m shell -a "docker load < tasks.tar"

ansible jgxt3 -m shell -a "docker tag isgs/tasks:1.0 192.168.1.15:5000/gajg/tasks:1.0 " 

ansible jgxt3 -m shell -a "docker push 192.168.1.15:5000/gajg/tasks:1.0"

ansible jgxt1 -m shell -a "docker stack deploy --with-registry-auth -c tasks.ym."

5.6.3 配置文件部署

配置文件为yml格式编写,为后端应用程序的部署配置。

服务器jgxt1 IP地址192.168.1.12

应用目录/data/file/

部署步骤:

  1. 将配置文件拷贝至服务器目录

以升级tasks.yml文件举例

ansible jgxt1 -m copy -a “src=tasks.yml dest=/data/file backuo=yes”

5.7 拓展环节

5.7.1 场景概述

使用以上命令在一定程度上可以避免登陆多台服务器,在主控端统一操作即可,但是很长的命令行在一定程度上还是有操作成本和错误的发生,为了解决以上问题,使用python实现实操环节中的程序部署,进而提高部署的效率和减少错误率。

5.7.2 设计思路

设计实现思路如下:

  1. 将升级文件统一下载拷贝至统一的目录
  2. 获取文件夹中的文件类型
  3. 判断文件,后台文件以.tar结尾,前端文件以.zip,配置文件以yml结尾
  4. 将判断的文件拷贝至对应的服务器目录
  5. 根据不通的文件进行不同的操作。
  6. 操作完毕输出升级完毕。

5.7.3 编码实现

伪代码实现:

#!/bin/bash
# -*- coding=utf8 -*-

import os
import sys

def oper_tar_file(name):
  '''
  stup 1 拷贝现有文件
       2 删除当前镜像 --==
       3 加载新的镜像文件
       4 重新打标签
       5 推送镜像到服务器
       6 重新加载部署
  '''
  print("=前端配置文件:" + name[:-4] + " 已开始升级部署=")
  pass
  print("=前端配置文件:" + name[:-4] + " 已升级部署完毕=")
      
def oper_zip_file(name):
  '''
  stup: 1 将文件拷贝至目录
        2 将原文件重命名备份
        3 解压缩包文件
  '''
  print("=前端配置文件:" + name[:-4] + " 已开始升级部署=")
  pass
  print("=前端配置文件:" + name[:-4] + " 已升级部署完毕=")

def oper_yml_file(name):
  '''
  stup: 1 将文件拷贝至目录(如存在文件重命名文件)
  '''
  print("=配置文件:" + name[:-4] + " 已开始升级部署=")
  cmd_copy = 'ansible jgxt1 -m copy -a ' + '\"src=' + name + ' dest=/data/file/ backup=yes\"'
  print("=配置文件:" + name[:-4] + " 已升级部署完毕=")
  
def judge_file_type():
    path = os.getwcd()
      for root,dirs,files in os.walk(path,topdown=True):
    for name in files:
      if name[-3:] == "tar":
        oper_tar_file(name)
      elif name[-3:] == "zip":
        oper_zip_file(name)
      elif name[-3:] == "yml":
        oper_yml_file(name)
      else:
        print(name + " 不是一个升级不是文件")

def main():
  judge_file_type()

if __name__ == "__main__":
  main()

编码优化:

序号 优化项 解决思路
1 删除当前镜像 通过名称匹配REPOSITORY项并获取IMAGE ID
2 文件夹会产生冗余文件 建议设置时间策略将冗余文件删除
3 判断文件 如果checksum跟上一次一直,则不执行命令
4 异常捕获 异常信息日志记录

5.8 验证截图

5.8.1 数据包获取

由于是内网环境部署,需要研发将程序包提前通过网络情况发送过来(奶牛快传、邮箱、worlmhole)

5.8.2 创建部署目录

将部署包解压至目录,本人是按日期-数字(一天可能会发多次,每次数字加一)

将deploy.py文件克隆拷贝至本级目录

5.8.3 执行脚本

打开终端,切换到此目录,或者鼠标右键,在弹出的右键快捷菜单中点击“Open in Windows Terminal”

输入bash切换至ubuntu系统

运行脚本

# python deploy.py