私有云shell脚本创建虚机

目录

一、环境介绍:

二、创建/克隆虚机流程

三、虚机IP信息初始化脚本

四、路坦力创建/克隆虚机

五、开机启动脚本


一、环境介绍:

  1.  私有云是基于路坦力的超融合解决方案实现,路坦力nutanix版本号是:5.2.0
  2.  nutanix官网资料参考地址:  https://portal.nutanix.com/page/documents/details?targetId=Command-Ref-AOS-v5_20:acl-acli-vm-auto-r.html
  3.  通过路坦力的模板机创建/克隆,生成新的虚拟机
  4.  路坦力创建/克隆生成的虚拟机是不存在IP信息的,也不能在创建/克隆的时候设置IP信息;需要在启动生成虚机后,手动或者通过脚本设置IP信息。
  5.  生成后的虚机的IP信息初始化设置实现方法(脚本自动初始化IP)是:在使用模板机创建/克隆虚机前,传递一个IP信息到模板机指定位置保存,然后仅仅在生成后的虚机第一次开机启动的时候才执行IP信息初始化脚本
  6. 模板机环境: centos6
  7. 初始化脚本是保存在模板机,并且设置了开机执行脚本,但是模板机重启是不会通过判断条件,而是直接退出脚本,即模板机重启是不会执行初始化脚本
  8. 创建虚机的脚本是保存在能通过ssh访问到路坦力集群执行命令的客户机上(建议不要把脚本直接保存在路坦力集群的节点上,直接执行脚本)

二、创建/克隆虚机流程

  1. 执行创建虚机的脚本完成虚机创建虚机(并自动启动虚机)
  2. 虚机启动自动自行IP初始化脚本(仅在虚机第一次启动时候执行)

      说明:

        1、我的环境是将创建虚机以及IP初始化脚本以及其他脚本集成到蓝鲸自动化运维平台,做成流程了来实现自动化创建虚机。

        2、在我的环境和场景,初始化虚机完成后,其实还做了oracle数据库初始化和脱敏等效果(仅在创建虚机第一次启动时候才执行),这部分内容仅适合我自己的环境并且涉及安全信息,所以在这我抽取了创建虚机和IP初始化的部分内容展示。

三、虚机IP信息初始化脚本

#!/bin/bash
# cat newip.sh
# create by @tudou

# 克隆前需要将 newip 写入到 /tmp/newip.txt 文件,否则失败
# 模板机的IP: 192.168.51.123

# echo "192.168.51.133" > /tmp/newip.txt
# ssh [email protected] 'echo "192.168.51.133" > /tmp/newip.txt'

# 模板机克隆出来的虚机并且是第一次开机才继续执行脚本
function NewVM(){
# 网卡个数,超过2个就是新虚拟机,模板机只有2个网卡,网卡名是 eth1
net_count=$(egrep DRIVERS  /etc/udev/rules.d/70-persistent-net.rules |wc -l)

# 模板机克隆出来的虚拟机网卡名字是 eth2 ,否则不执行不执行脚本

ifconfig eth2

#  不存在 eth2 网卡/网卡设备数量小于3,就异常退出程序
if [[ $? -ne 0 || $net_count -lt 3 ]];then
   echo "不存在网卡 eth3; 网卡设备个数小于3,可能不是从模板/快照隆创建虚机"
   exit 1
fi

# 仅在第一次开启才执行更新IP脚本
if [ -f /var/log/firstboot ];then
   echo "已执行过更新IP操作,退出程序"
   exit 1
fi

}

# 检查是否存在 传入的 IP等参数的文件
function CheckNewIP(){
#newip_file=/tmp/newip_$(date +%F).txt
newip_file=/tmp/newip.txt

newip=$(cat $newip_file)



if [ -f $newip_file ]; then
   echo $newip

   # 判断IP已否已被占用,避免IP冲突
   ping ${newip} -c 2 -t 3 -i 2
   if [ $? ! -eq 0 ];then
      echo "你的IP已被使用,不能完成初始化IP"
      exit 1
   fi

   if [[ $newip == "192.168.51.123" ]];then
      echo "新建虚拟机IP不能和模板机相同" 
      echo "您输入的IP是: $newip"
      exit 1
   fi
else 
  echo "快照创建新的虚拟机,需要先设定一个保存初始化IP的newip文件: $newip_file" 
  exit 1
fi
} 

# 读取传入的参数
function GetValue(){

eth_name=${eth_name:-eth2}  # 网卡名
dns1=${dns1:-192.168.200.254}    # DNS 地址   

# 网卡物理地址
hwaddr=$(cat /etc/udev/rules.d/70-persistent-net.rules | grep --color=auto 'eth3' | cut -d '"' -f 8| tr '[a-z]' '[A-Z]')

new_ip_3=$(cat $newip_file |awk -F. '{print $3}')
echo "正在获取新的网络参数..."
if [[ $new_ip_3 == "30" ]]||[[ $new_ip_3 == "31" ]]; then
  gateway="192.168.30.1"
  netmask="255.255.254.0"
  echo "当前网关地址:$gateway 子网掩码是: $netmask"
elif [[ $new_ip_3 == "2" ]]; then
  gateway="192.168.2.1"
  netmask="255.255.255.0"
  echo "当前网关地址:$gateway 子网掩码是: $netmask"
  # elif [[ $new_ip_3 == "1" ]]; then
else
  echo "ERROR,当前ip地址不在有效范围内,请核实"
  exit 1
fi

echo "新主机IP是: $newip"
echo "新主机网关是: $gateway"
echo "新主机DNS1是: $dns1 "
echo "新主机子网掩码是: $netmask"
echo "新主机网卡名是: $eth_name"
echo "新主机网卡物理地址是: $hwaddr"
}

function NetworkInfo(){
  # 修改网卡配置文件

  cat << EOF > /etc/sysconfig/network-scripts/ifcfg-$eth_name
TYPE="Ethernet"
BOOTPROTO="static"
ONBOOT="yes"
DEFROUTE="yes"
IPV6INIT="no"
IPV4_FAILURE_FATAL="no"
NAME="$eth_name"
IPADDR="$newip"
NETMASK="$netmask"
GATEWAY="$gateway"
HWADDR=$hwaddr
DNS1="$dns1"
EOF
}

# 防火墙规则
function IptablesRules(){

iptables_file=/oracle/scripts/eas/iptables
if [ -f $iptables_file ];then
    cat $iptables_file > /etc/sysconfig/iptables
    service iptables restart
 else
   echo "not exit file: $iptables_file" 
   echo "不能存在自动义的防火墙规则,使用模板机默认的防火墙规则"
fi
}

# CentOS 6 系统就执行该函数
function SystemCentOS6(){
  
  #rm -f /etc/sysconfig/network-scripts/ifcfg-Auto_eth*
  if [ -f /etc/sysconfig/network-scripts/ifcfg-Auto_eth1 ];then
    rm -f /etc/sysconfig/network-scripts/ifcfg-Auto_eth1 
  fi
  if [ -f /etc/sysconfig/network-scripts/ifcfg-Auto_eth2 ];then
    rm -f /etc/sysconfig/network-scripts/ifcfg-Auto_eth2 
  fi

  # 配置网卡信息 
  NetworkInfo

  # 重启网络服务
  service network restart
  
  # 更改完成IP 生成一个标签,防止重启虚拟会重复执行更新IP脚本,只能第一次启动才能执行
  touch /var/log/firstboot

  # 设置防火墙
  IptablesRules

}

# 根据系统类型来选择执行函数
function ChangeNetwork(){

  if [ -f /etc/redhat-release ]; then
      if grep -q "release 6" /etc/redhat-release ; then
          echo "it is CentOS6 system" 
          SystemCentOS6
      else
          echo "not CentOS6 system" 
      fi
  else
      echo "unknown system,exit script" 
      exit 1
  fi
}

# 判断是新克隆的虚拟机才执行
NewVM
# 判断存在传参文件,且IP与正式环境不冲突才执行
CheckNewIP
# 读取传入的参数,生成网卡必要的信息
GetValue
# 执行更改网卡信息
# NetworkInfo 和 IptablesRules 被 SystemCentOS6 调用
# SystemCentOS6 被 ChangeNetwork 调用
ChangeNetwork


# 待优化部分可以这样子做
# 定义变量,设置 root 密码
# passwd=abcQWE$(date +%Y%m%d)
# echo "$passwd" |passwd --stdin root

# 将 初始化结果: IP 信息 、root登录密码等通过企业微信通知

四、路坦力创建/克隆虚机

#!/bin/bash
# cat clone_vm.sh
# 执行脚本前需要先新虚机名
# 全局变量: new_clone_name

newip=$1
new_clone_name=$2

# 若是 new_clone_name 没有传入参数,则使用默认值
eas_test=$(date +%m%d%H%M)
new_clone_name=${new_clone_name:-Test_ISS_${eas_test}_Oracle}

# 模板虚拟机名字(模糊匹配):
# 模板机是 EAS 备库 (192.168.51.123)
template_machine=Oracle_EAS

############################################################

export PATH=/usr/local/nutanix/bin/:$PATH
# 创建日志文件
files_dir=/tmp/task
mkdir -p ${files_dir}
aclilog=${files_dir}/$(date +%Y%m%d%H%M%S).log


# 创建快照
function CreateSnapshot(){
  # 获取模板虚机名称:192.168.51.123
  template_machine_name=$(acli vm.list |grep -E  "${template_machine}" |awk '{print $1}')
  
  # 创建快照
  #new_snapshot_name=${new_snapshot_name}
  new_snapshot_name=${template_machine_name}_$(date +%Y%m%d%H%M%S)
  acli vm.snapshot_create ${template_machine_name}  snapshot_name_list=${new_snapshot_name} |tee -a $aclilog
  sleep 5s
  
}

# 使用快照克隆虚机
function CloneVM(){
  echo "克隆虚机:" |tee -a $aclilog
  acli vm.clone ${new_clone_name} clone_from_snapshot=${new_snapshot_name} |tee -a $aclilog
  sleep 5s
   
  # 创建虚机完成后,自动删除快照
  echo "yes" |acli snapshot.delete ${new_snapshot_name} |tee -a $aclilog
  
  # 启动虚机
  # acli vm.on ${new_clone_name}
}

CheckResult(){

  # 验证虚拟是否成功创建
  echo "新创建的虚机名称"
  acli vm.list |grep -E ${new_clone_name}
  if [ $? -eq 0 ];then
     echo "创建虚机成功"
     # 启动虚机
     acli vm.on ${new_clone_name}

     result1="创建虚机成功"
     result2="新建虚机名是: ${new_clone_name}"
     result3="新建虚机的IP是: ${newip}"
  else
     result="创建虚机失败"
     result2="您想要创建的虚机名字是:${new_clone_name}"
     result3="您想要创建虚机的IP是: ${newip}"
  fi
  
}

# 定义企业微信机器人发送函数
function Send_Wechat(){

  #企业微信机器人秘钥:
  webhook_key="替换成您的企业微信秘钥"
  echo "基础设施企微群通知"
  local webhook_url="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=$webhook_key"

  messages="创建虚机结果:"
  curl $webhook_url \
    -H 'Content-Type: application/json' \
    -d "{\"msgtype\": \"text\", \"text\": {\"content\": \"$messages $result1\n$result2\n$result3\"}}"
}
# 调用函数执行脚本
#CloneName
CreateSnapshot
CloneVM
CheckResult
Send_Wechat

五、开机启动脚本

        每次开机都会执行开机启动脚本,然后它会根据脚本里面的内判断是第一开机启动才继续执行,否则会退出执行脚本,防止脚本重复执行导致异常。

# 开机自动执行脚本设置
chmod a+x /etc/rc.local
chmod a+x /scripts/newip.sh
echo "sh /scripts/newip.sh |tee -a /tmp/newip_\$(date +%F).log" >> /etc/rc.local

你可能感兴趣的:(linux,运维,服务器)