随便逛了逛dell的技术方案,发现了dell 在github发布了一些 通过redfish 来管理idrac的ansible 模块,在ansible 的文档里,已经加入到核心支持库了,要升级到最新的2.7才可以用,简单玩了玩,基本dell idrac的功能,通过redfish 都可以调用,另外redfish 可以同样用于hp和其他品牌的服务器,已经是下一代的ipmi的替代标准版了
首先简单说说批量部署的想法
手头只有dell的服务器,因为都有idrac,通过ansible。可以实现idrac的一些管理和配置
首先找dell销售拿服务器的序列号列表,
根据序列号定义机器的角色,分配的IP
然后根据序列号就可以直接push 配置给指定的机器,
当然这个还需要在dhcp等服务器做一些配置
dell出厂的服务器一般两种配置,一种是idrac地址写死了192.168.1.120,一种是启动了dhcp搜寻,根据dhcp给自己配地址
那我们的实现方式,对应写死地址的idrac:
首先配置一个机器不停扫描192.168.0.120 这个地址,这个是idrac默认ip,如果发现ip 可达,直接通过ansible 根据序列号,改成自己想要的idrac ip,然后配置pxe启动,重启机器,同时,读取机器的网卡地址,写到dhcp的列表里,push mac 地址给cobbler,或者其他maas 等等,,按需求装系统。
如果是dhcp的,下面也写了实现方法,其实思路差不多
等会记录一下实现的源码
另外dell 的ome 也是一种部署方法,或者是idrac 自带的远程挂载虚拟介质的功能,不过
1.dell的ome 部署功能要licence,,这个比较扯
2.虚拟介质配合ansible 可以绕过license,,也可以批量部署,不过缺点是必须要为每种不同的配置,打包不同的iso,这个显然不如cobbler灵活
还有就是foreman,以及maas等实现方式了
-------后来-----------------
当然如果dell出厂没有设定idrac使用dhcp分配地址的话,还需要用我上面的思路,以前的思路是用ansible-pull,现在高端的玩法是用awx +curl,不过需要部署一个ansible tower,用通过触发ansible tower提供的api,调用playbook完成预订的工作
先写一部分用ansible 设置idrac ip的方法
简书不会发布代码块,,直接给github的连接 https://github.com/bjmingyang/ansible/blob/master/set-idrac-ip
本来准备用redfish做,不过redfish做ip更改比较麻烦
因为dell加入了默认密码警告,如果还是用默认密码的话,要修改ansible 文件
SVCTAG: "{{ svctag.stdout_lines[0]}}" 改成 SVCTAG: "{{ svctag.stdout_lines[1]}}"
或者用
ansible -i hosts.drac all -m raw -a "racadm set iDRAC.Tuning.DefaultCredentialWarning 0" -f 20
关闭默认密码警告
---
- hosts: all
name: set iDRAC Ipaddr
gather_facts: False
vars:
svctag_test: 8H730S2
network_configs:
1234567:
ip: 192.168.192.86
3444555:
ip: 192.168.192.85
netmask: 255.255.255.0
gateway: 192.168.192.254
XXXX111:
ip: 172.16.9.111
netmask: 255.255.252.0
gateway: 172.16.8.10
ip: 10.10.10.65
XXXFWS2:
ip: 10.10.10.68
netmask: 255.255.255.0
tasks:
- name: get dell server service-tag
raw: racadm getsvctag
register: svctag
- name: show svctag
debug:
msg="{{ svctag }}"
- name: show network
debug:
msg="{{ network_configs[svctag_test].ip }}"
- name: set idrac ip svctag to vars
set_fact:
SVCTAG: "{{ svctag.stdout_lines[0]}}"
- name: show SVCTAG
debug:
msg="{{ SVCTAG }}"
- name: show network 2
debug:
msg="{{ network_configs[SVCTAG].ip }}"
#msg="{{ network_configs[SVCTAG] }}"
#msg="{{ hostvars[inventory_hostname][network_configs][SVCTAG] }}"
#msg="{{ lookup('vars', network_configs )[SVCTAG]}}"
- name: set dell server idrac ip form service-tag
raw: racadm config -g cfgLanNetworking -o cfgNicIpAddress "{{ network_configs[SVCTAG].ip }}"
when: SVCTAG is defined
- name: set dell server idrac netmask form service-tag
raw: racadm config -g cfgLanNetworking -o cfgNicNetmask "{{ network_configs[SVCTAG].netmask }}"
when: SVCTAG is defined
- name: set dell server idrac gw form service-tag
raw: racadm config -g cfgLanNetworking -o cfgNicGateway "{{ network_configs[SVCTAG].gateway }}"
when: SVCTAG is defined
idrac 8 开始用racadm set 来代替了racadm config, 因此要用下面的替代上面ansible 相应的模块
- name: set dell server idrac ip form service-tag
raw: racadm setniccfg -s "{{ network_configs[SVCTAG].ip }}" "{{ network_configs[SVCTAG].netmask }}" "{{ network_configs[SVCTAG].gateway }}"
ignore_errors: yes
简单解说一下,这个还是要用dell的racadm来做,基本思路是用racadm 首先获取 dell server的 序列号,然后根据实现定义好的期望的ip
对这个的地址设置。原来想用mac地址对机器进行标识后来想想还是序列号最靠谱。
另外序列号和playbook写到一个文件里可能会显得有点乱,可以用
vars_files:
- 15server.yaml
隔离playbook和序列号的ip对应列表
至于实现的方法就是 因为dell的idrac默认地址都是192.168.0.120 ,设置时候,需要有一个网卡地址配置成192.168.0.0 这个网段的ip,
然后在hosts里写 192.168.0.120 ansible_ssh_pass=calvin
如果设置多台机器就写个小循环,for i in {0..100};do ansible-playbook -i hosts idrac.yml -u root; arp -d 192.168.0.120 ;done
默认跑100次,设置好一个ip,自动切换到另外一个机器,多跑几遍就行,另外一个问题,是idrac 9 的开始新版本,默认地址是0.0.0.0,其实是自动通过dhcp来获取drac地址,这个时候就需要配置dhcp服务器给idrac分配地址,然后在用ansible来配置ip。这个有手册
下面的部分是从dell文档里抄来的,主要是自动部署服务器的raid等配置,修改了文档里面的几个坑,让你复制粘贴就能跑
option myname code 43 = text;
subnet 192.168.0.0 netmask 255.255.255.0 {
# default gateway
option routers 192.168.0.1;
option subnet-mask 255.255.255.0;
range dynamic-bootp 192.168.0.2 192.168.0.15;
option nis-domain "domain.org";
option domain-name "domain.org";
option domain-name-servers 192.168.1.1;
option time-offset -18000; #Eastern Standard Time
option vendor-class-identifier "iDRAC";
set vendor-string = option vendor-class-identifier;
#option myname "-f system_config.xml -i 192.168.0.130 -u user -p password -n cifs -s 2 -d 0 -t 500";
option myname "-f R640-config.xml -i 10.10.11.254 -n /config -s nfs -d 0 -t 500";
}
当通过dhcp分配了idrac的网段,并设置好网卡以后,我们可以用redfish,自动配置其他我们需要配置的项目
首先配置一个dhcp服务器,配置如上
因为是抄的dell的配置,所以要修改cifs的字段为nfs,根据下面的文档,修改如下
option myname " -f http_share/system_config.xml -i 192.168.1.101 -s http"
-s 就是协议
-i 主机
-f 文件
具体看下面
17 输入必须发送到 iDRAC 的字符串值(以及标准 DHCP 提供的 IP 地址)。该字符串值可帮助导入正确的 SCP 文件。
有关该选项的 DATA 条目、字符串值设置,请使用具有以下字母选项和值的文本参数:
• Filename (–f) — 表示导出的服务器配置文件 (SCP) 的名称。
• Sharename (-n)—指示网络共享的名称。
• ShareType (-s)—
除了支持基于 NFS 和 CIFS 的文件共享,iDRAC 固件 3.00.00.00 或更高版本还支持通过使用 HTTP 或 HTTPS 访问配置文 件。-s option 标志更新为:
-s (ShareType):类型 nfs 或 0 适用于 NFS;cifs 或 2 适用于 CIFS;http 或 5 适用于 HTTP;https 或 6 适用于 HTTPS(强 制)。
• IPAddress (-i) — 指示文件共享的 IP 地址。
注: Sharename (-n)、ShareType (-s) 和 IPAddress (-i) 是必须传递的必要属性。-n 不是 HTTP 或 HTTPs 所必
需的。
• Username (-u) — 指示访问网络共享所需的用户名。仅 CIFS 需要此信息。
• Password (-p) — 指示访问网络共享所需的密码。仅 CIFS 需要此信息。
• ShutdownType (-d) — 指示关机的模式。0 表示正常关机,1 表示强制关机。
注: 默认设置为 0。
• Timetowait (-t) — 指示主机系统关闭之前等待的时间。默认设置为 300。
• EndHostPowerState (-e) — 指示主机的电源状态。0 表示关闭,1 表示打开。默认设置为 1。
注: ShutdownType (-d)、Timetowait (-t) 和 EndHostPowerState (-e) 是可选的属性。 NFS: -f system_con g.xml -i 192.168.1.101 -n /nfs_share -s 0 -d 1
CIFS: -f system_con g.xml -i 192.168.1.101 -n cifs_share -s 2 -u <USERNAME> -p <PASSWORD> -d 1 -t 400 HTTP: -f system_con g.json -i 192.168.1.101 -s 5
HTTP: -f http_share/system_con g.xml -i 192.168.1.101 -s http HTTP: -f system_con g.xml -i 192.168.1.101 -s http -n http_share
52 设置受管系统
HTTPS: -f system_con g.json -i 192.168.1.101 -s https
然后就可以用上面的ansible文件来根据主机的序列号重新分配idrac的地址。因为上面有例子就不写了,然后通过redfish或者ssh
来获取网卡的mac地址,根据网卡的地址建立不同的profile,安装不同的配置
假设用sshpass
例子如下
获取第一个网卡的mac地址
for i in {40..54};do sshpass -p calvin ssh -o StrictHostKeyChecking=no root@10.10.100.$i "racadm getsysinfo"|grep "NIC.Integrated.1-1-1";done >new_mac.txt
简单的小循环,在cobbler里创建不同的profile
export x=111;for i in `cat new_mac.txt |awk -F" " '{print $4}'`;do cobbler system add --name=install_$x --profile=centos7_5 --ip-address=192.168.100.$x --interface=em1 --netboot-enabled=1 --mac-address=$i --static=1 --netmask=255.255.255.0 --gateway=192.168.14.254;x=`echo $x + 1|bc`;done
--static=1 --netmask=255.255.255.0 --gateway=192.168.14.254
基本这样就算完成了
上门还漏掉了如何生成配置文件,这个其实很简单,直接在idrac导出就行,之前的机器可以在github里找到dell 库,找到redfish
地址
github.com/dell/iDRAC-Redfish-Scripting/blob/master/Redfish%20Python/ImportSystemConfigurationNetworkShareREDFISH.py
用下面的例子生成
python ExportSystemConfigurationNetworkShareREDFISH.py -ip 192.168.100.86 -u root -p calvin -t ALL -xf XML --ipaddress 192.168.4.99 --sharetype NFS --sharename /mnt/iso --filename SCP_export_R740XD
实际我是用下面的命令搞定,因为导入all的话,会出现错误,主要是要避免导入网络的配置。
python ImportSystemConfigurationNetworkShareREDFISH.py -ip 10.10.110.173 -u root -p calvin -t System,BIOS,LifecycleController,RAID --ipaddress 10.10.110.254 --sharetype NFS --sharename /config --filename R640-config.xml
或者
racadm -u xxx.xxx.xxx.xxx -r root –p calvin –f iDRAC_config.xml –t xml
这里面有个坑,,就是导出的时候,不要选择all,要排除掉nic,否则会出
Configure: Import Server Configuration Profile Completed with Errors (100%)
的提示,,我也不知道为什么
redfish 主要可以结合ansible,设置所有的机器从网卡启动,不过这个ssh+racadm 用ansible的raw 模块也可以,更多的是另外一种实现方法,然后就是cobbler的ks里面写ansible的调用了,不过还是首先需要在ansible tower里面创建playbook,然后用curl去触发调用。实现完全自动化。
贴一下drac的实现网络启动的raw命令
racadm set BIOS.OneTimeBoot.OneTimeBootMode OneTimeBootSeq
racadm set BIOS.OneTimeBoot.OneTimeBootSeqDev NIC.Integrated.1-1-1
racadm get BIOS.BiosBootSettings.BootMode
racadm set BIOS.BiosBootSettings.BootMode Bios
racadm jobqueue create BIOS.Setup.1-1 –r Graceful
racadm jobqueue create BIOS.Setup.1-1
racadm serveraction powercycle
新的drac命令比较坑,不是实时生效的,要创建一个job,启动的时候,会自动先运行你这个job,然后看情况,自动重启
或者继续向下走
基本ansible 可以这些写
ansible new -m raw -a "racadm set BIOS.OneTimeBoot.OneTimeBootMode OneTimeBootSeq" -k
ansible new -m raw -a "racadm set BIOS.OneTimeBoot.OneTimeBootSeqDev NIC.Integrated.1-1-1" -k
ansible new -m raw -a "racadm jobqueue create BIOS.Setup.1-1" -k
ansible new -m raw -a "racadm serveraction powercycle" -k
不过我感觉整体这一套基本已经过时,用foreman的裸机部署似乎应该更简单,未来docker的环境下,也许部署coreos对于云环境来说更合适。
应狐狸总的需求,我贴上我用ansible做的多重指派的playbook,仅供参考:
---
# tasks file for dell-install
# - name: check ipmitool package
# yum:
# name: ipmitool
# state: latest
- name: get system mac-address
raw: racadm getsysinfo
register: raw_macaddress
- name: get system mac-address 1
shell: {{ raw_macaddress }}.NIC.Integrated.1-1-1
- name: add host record
shell: cobbler system add --name=install_{{ ansible_hostname }} --hostname={{ ansible_fqdn }} --profile=centos7:1:daodao --static=1 --ip-address={{ ansible_default_ipv4.address }} --gateway={{ ansible_default_ipv4.gateway }} --name-servers=192.168.14.66 192.168.14.61 --interface=em1 --netboot-enabled=1 --mac-address={{ ansible_default_ipv4.macaddress }}
delegate_to: 192.168.14.210
- name: cobbler sync
shell: cobbler sync
delegate_to: 192.168.14.210
- name: get idrac address
shell: ipmitool lan print 1|grep "IP Address"|grep -v Source|cut -c 27-40
register: idracaddress
- name: set idrac ip to vars
set_fact:
Idracaddr: "{{ idracaddress.stdout }}"
#Idracaddr: "{{ idracaddress.stdout |ipv4('address') }}"
#Idracaddr: "{{ idracaddress.stdout|regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}"
- name: debug
debug:
msg="{{ Idracaddr }}"
- name: set reboot system to pxe
raw: racadm set BIOS.OneTimeBoot.OneTimeBootMode OneTimeBootSeq
delegate_to: "{{ Idracaddr }}"
- name: set reboot system to pxe us nic-1
raw: racadm set BIOS.OneTimeBoot.OneTimeBootSeqDev NIC.Integrated.1-1-1
delegate_to: "{{ Idracaddr }}"
- name: set reboot system to pxe jobqueue
raw: racadm jobqueue create BIOS.Setup.1-1
delegate_to: "{{ Idracaddr }}"
- name: reboot system to pxe
raw: racadm serveraction powercycle
delegate_to: "{{ Idracaddr }}"
- name: pause 10 minutes
pause:
minutes: 10
- name: remove host record
shell: cobbler system remove --name=install_{{ ansible_hostname }}
delegate_to: 192.168.14.210
- name: cobbler sync
shell: cobbler sync
delegate_to: 192.168.14.210