目录
一、环境介绍:
二、创建/克隆虚机流程
三、虚机IP信息初始化脚本
四、路坦力创建/克隆虚机
五、开机启动脚本
说明:
1、我的环境是将创建虚机以及IP初始化脚本以及其他脚本集成到蓝鲸自动化运维平台,做成流程了来实现自动化创建虚机。
2、在我的环境和场景,初始化虚机完成后,其实还做了oracle数据库初始化和脱敏等效果(仅在创建虚机第一次启动时候才执行),这部分内容仅适合我自己的环境并且涉及安全信息,所以在这我抽取了创建虚机和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 root@192.168.51.133 '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..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