redfish + ansible +idrac = ztp?dell 服务器批量部署流程

随便逛了逛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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。