Ocean Stack simulator

Architecture

digraph "arch" {
compound=true;
ranksep="1.2 equally";
rankdir="TB";
newrank="true";
sep="+1";
"top1" -> "topswitch1"[label="pv2", headlabel="1"]
"top2" -> "topswitch2"[label="pv6", headlabel="1"]
"worker1" -> "topswitch1"[label="pv3", headlabel="2"]
"worker2" -> "topswitch2"[label="pv7", headlabel="2"]
"worker3" -> "topswitch1"[label="pv4", headlabel="3"]
"worker4" -> "topswitch2"[label="pv8", headlabel="3"]
"worker5" -> "topswitch1"[label="pv5", headlabel="4"]
"worker6" -> "topswitch2"[label="pv9", headlabel="5"]
"topswitch1" -> "topswitch2"[label="pv30",constraint=false,headlabel="9",taillabel="9"]
"topswitch2" -> "topswitch1"[label="pv31",constraint=false,headlabel="10",taillabel="10"]

subgraph cluster20 {
  subgraph clustersw20{
  "islet 20 switch 1";  "islet 20 switch 2";
  "islet 20 switch 1" -> "islet 20 switch 2"[label="pv32",constraint=false,headlabel="5",taillabel="5"];
  "islet 20 switch 2" -> "islet 20 switch 1"[label="pv33",constraint=false,headlabel="6",taillabel="6"];
  }
  subgraph clusterisma20{
  isma20; isma21;
  "islet 20 switch 1" -> "isma20"[label="pv18",headlabel="2",taillabel="3"];
  "islet 20 switch 1" -> "isma21"[label="pv19",headlabel="2",taillabel="4"];
  "islet 20 switch 2" -> "isma20"[label="pv20",headlabel="3",taillabel="3"];
  "islet 20 switch 2" -> "isma21"[label="pv21",headlabel="3",taillabel="4"];
  }
}
"topswitch1" -> "islet 20 switch 1"[label="pv10",taillabel="5",headlabel="1"];
"topswitch2" -> "islet 20 switch 1"[label="pv14",taillabel="5",headlabel="2"];
"topswitch1" -> "islet 20 switch 2"[label="pv11",taillabel="6",headlabel="1"];
"topswitch2" -> "islet 20 switch 2"[label="pv15",taillabel="6",headlabel="2"];

subgraph cluster22 {
  subgraph clustersw22{
  "islet 22 switch 1"; "islet 22 switch 1";
  "islet 22 switch 1" -> "islet 22 switch 2"[label="pv34",constraint=false,headlabel="5",taillabel="5"];
  "islet 22 switch 2" -> "islet 22 switch 1"[label="pv35",constraint=false,headlabel="5",taillabel="6"];
  }
  subgraph clusterisma22{
  isma22; isma23;
  "islet 22 switch 1" -> "isma22"[label="pv22",headlabel="2",taillabel="3"];
  "islet 22 switch 1" -> "isma23"[label="pv23",headlabel="2",taillabel="4"];
  "islet 22 switch 2" -> "isma22"[label="pv24",headlabel="3",taillabel="3"];
  "islet 22 switch 2" -> "isma23"[label="pv25",headlabel="3",taillabel="4"];
  }
}

"topswitch1" -> "islet 22 switch 1"[label="pv12",headlabel="1",taillabel="7"];
"topswitch2" -> "islet 22 switch 1"[label="pv16",headlabel="2",taillabel="7"];
"topswitch1" -> "islet 22 switch 2"[label="pv13",headlabel="1",taillabel="8"];
"topswitch2" -> "islet 22 switch 2"[label="pv17",headlabel="2",taillabel="8"];
}

Pcocc

Configuration Pcocc

Plaquer le fichier de configuration suivant dans ~/.pcocc/templates.d/deep_blue.yaml

siteprep:
    # When using saved image
    image: "user:ocean_site_prep"
    qemu-bin: '/usr/bin/qemu-lite-system-x86_64'

#Common templates
scratch:
  resource-set: cluster-isolated
  # Empty disk
  ## qemu-img create empty 50G
  ## pcocc  image import empty user:scratch
  image: "user:scratch"
  remote-display: spice
switch:
  resource-set: ocean-topswitch1
  # NXOS Image : https://software.cisco.com/download/home/286312239/type/282088129/release/9.2(3)?i=!pp
  # BIOS compiled from: github.com/tianocore/edk2
  image: "user:nxosv_9.2.2"
  custom-args: ['-cpu','qemu64', '-bios', '/path/to/edk2/Build/OvmfX64/DEBUG_GCC48/FV/OVMF.fd']
  disk-model: ide
  nic-model: e1000

########
## Networks
# PV is bbone
# PV1 is mngt
# PV[2-25] are 40G network cables
# PV[30-35] are 100G network cables (between switches)
#####

# pcocc alloc -p sandy -c 8 bbone,top1,top2,worker1,worker2,worker3,worker4,worker5,worker6,topswitch1,topswitch2,islet1-switchA,islet1-switchB,islet2-switchA,islet2-switchB,isma1A,isma1B,isma2A,isma2B

### The Cluster

top1:
  # PV + PV1 + PV2
  resource-set: ocean-top1
  # Resized image:
  ## pcocc image copy global:cloud-ocean2.7 user:cloud-ocean2.7-large
  ## pcocc image resize user:cloud-ocean2.7-large 50G
  image: "user:cloud-ocean2.7-large"
  user-data: "%{env:CCCSCRATCHDIR}/cloud-init/generic"
  disk-model: ide
  nic-model: e1000
top2:
  # PV + PV1 + PV6
  resource-set: ocean-top2
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
worker1:
  # PV1 + PV3
  resource-set: ocean-worker1
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
worker2:
  # PV1 + PV7
  resource-set: ocean-worker2
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
worker3:
  # PV1 + PV4
  resource-set: ocean-worker3
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
worker4:
  # PV1 + PV8
  resource-set: ocean-worker4
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
worker5:
  # PV1 + PV5
  resource-set: ocean-worker5
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
worker6:
  # PV1 + PV9
  resource-set: ocean-worker6
  image: "user:scratch"
  custom-args: ['-boot','order=nc']
  disk-model: ide
  nic-model: e1000
topswitch1:
  # PV1 + PV[2-5] + PV[10-13] + PV[30-31]
  inherits: switch
  resource-set: ocean-topswitch1
topswitch2:
  # PV1 + PV[6-9] + PV[14-17] + PV[30-31]
  inherits: switch
  resource-set: ocean-topswitch2
islet1-switchA:
  # PV1 + PV[10,14] + PV[18-19] + PV[32-33]
  inherits: switch
  resource-set: ocean-islet1-switchA
islet1-switchB:
  # PV1 + PV[11,15] + PV[20-21]+ PV[32-33]
  inherits: switch
  resource-set: ocean-islet1-switchB
islet2-switchA:
  # PV1 + PV[12,16] + PV[22-23] + PV[34-35]
  inherits: switch
  resource-set: ocean-islet2-switchA
islet2-switchB:
  # PV1 + PV[13,17] + PV[24-25] + PV[34-35]
  inherits: switch
  resource-set: ocean-islet2-switchB
isma1A:
  # PV1 + PV[18,20]
  resource-set: ocean-isma1A
  custom-args: ['-boot','order=nc']
  image: "user:scratch"
  disk-model: ide
  nic-model: e1000
isma1B:
  # PV1 + PV[19,21]
  resource-set: ocean-isma1B
  custom-args: ['-boot','order=nc']
  image: "user:scratch"
  disk-model: ide
  nic-model: e1000
isma2A:
  # PV1 + PV[22,24]
  resource-set: ocean-isma2A
  custom-args: ['-boot','order=nc']
  image: "user:scratch"
  disk-model: ide
  nic-model: e1000
isma2B:
  # PV1 + PV[23,25]
  resource-set: ocean-isma2B
  custom-args: ['-boot','order=nc']
  image: "user:scratch"
  disk-model: ide
  nic-model: e1000
###

Certaines images peuvent ne pas être présentes dans votre environnement. L’origine des images NXOS (entre autres) sont indiquées en commentaire.

Lancement

Pour lancer toutes les VMs du simulateur:

pcocc alloc -c 16 -p sandy -t 600 top1,top2,worker1,worker2,worker3,worker4,worker5,worker6,topswitch1,topswitch2,islet1-switchA,islet1-switchB,islet2-switchA,islet2-switchB,isma1A,isma1B,isma2A,isma2B

Ainsi les ID de VMs et images associées sont comme suit:

ID

Role

vm0

top1

vm1

top2

vm2

worker1

vm3

worker2

vm4

worker3

vm5

worker4

vm6

worker5

vm7

worker6

vm8

topswitch1

vm9

topswitch2

vm10

islet1-switchA

vm11

islet1-switchB

vm12

islet2-switchA

vm13

islet2-switchB

vm14

isma1A

vm15

isma1B

vm16

isma2A

vm17

isma2B

En plus des réseaux virtuels, la première interface de chaque VM est connectée à un même réseau virtuel géré par pcocc, ce sera l’équivalent d’un réseau de management.

De même, toutes les VMs représentant des serveurs sont des VMs vierges de toute image à l’exception de top1 qui est basée sur une image cloud-ocean2.7, vous pouvez donc vous connecter dès le début sur top1 (pcocc ssh centos@vm0)

Off-site Prep

Choix d’archictures réseau

Le réseau de Ocean Stack sera architecturé de telle sorte à assurer un niveau de sécurité minimum ie. contrôler au mieux les flux émanants des nœuds utilisateur.

Ainsi, 3 VLANs seront utilisés:

VLAN 1

Nœuds de management et équipements. Tout les switchs pourront êtres trunkés sur le VLAN 1

VLAN 2

Nœuds utilisateurs du premier ilôt et équipements inséparables de ceux-ci (BMCs). Les switchs de chaque ilôt pourront être trunkés avec ce VLAN

VLAN 3

Nœuds utilisateurs du second ilôt et équipements inséparables de ceux-ci (BMCs). Les switchs de chaque ilôt pourront être trunkés avec ce VLAN

Pour l’exercice, il est simulé que chaque ilôt possède 5 racks de type Sequana 2, ainsi les sous-réseaux sont définis comme suit.

Top management

VLAN 1

  • 10.1.0.0/24

Équipements

VLAN 1

  • 10.4.0.0/24

Data

VLAN 1

  • 10.5.0.0/24

Services

VLAN1

  • 10.3.0.0/24

Nœuds ilôt 1

VLAN 2

  • 10.2.2.0/25

  • 10.2.2.128/25

  • 10.2.3.0/25

  • 10.2.3.128/25

  • 10.2.4.0/25

BMC ilôt 1

VLAN 2

  • 10.4.2.0/25

  • 10.4.2.128/25

  • 10.4.3.0/25

  • 10.4.3.128/25

  • 10.4.4.0/25

Équipements ilôt 1

VLAN 1

  • 10.4.1.0/24

Nœuds ilôt 2

VLAN 3

  • 10.2.6.0/25

  • 10.2.6.128/25

  • 10.2.7.0/25

  • 10.2.7.128/25

  • 10.2.8.0/25

BMC ilôt 2

VLAN 3

  • 10.4.6.0/25

  • 10.4.6.128/25

  • 10.4.7.0/25

  • 10.4.7.128/25

  • 10.4.8.0/25

Équipements ilôt 2

VLAN 1

  • 10.4.5.0/24

Le nommage des nœuds et équipements se fera de façon classique:

Nom original

Nom final

top[1-2],worker[1-6]

ocean[1-8]

isma[1-2]A,isma[1-2]B

ocean[20-23]

topswitch[1-2]

esw[1-2]

islet[1-2]-switch[A,B]

i[1-2]esw[1-2]

s[1-10]wel[0-2]-[1-2]

i[1-2]r[1-5]esw[1-3]

s[1-10]bmc[1-96]

ocean[1000-1959]-ipmi

s[1-10]compute[1-96]

ocean[1000-1959]

s[1-10]pmc1

i[1-2]r[1-5]pmc

s[1-10]hmc[1-3]

i[1-2]r[1-5]hmc[1-3]

s[1-10]wmc[1-3]

i[1-2]r[1-5]wmc[1-3]

s[1-10]emc[1-2]

i[1-2]r[1-5]emc[1-2]

Les adresses devront alors être allouées de la sorte 1:

Nom

IP

ocean[1-8,20-23]-adm

10.1.0.[1-8,20-23]

ocean[1-8,20-23]-data

10.5.0.[1-8,20-23]

esw[1-2],i[1-2]esw[1-2]

10.4.0.[1-6]

i[1-2]r[1-5]esw[1-3]

10.4.[1,5].[1-15]

i[1-2]r[1-5]pmc

10.4.[1,5].[16-20]

i[1-2]r[1-5]hmc[1-3]

10.4.[1,5].[21-35]

i[1-2]r[1-5]wmc[1-3]

10.4.[1,5].[36-50]

i[1-2]r[1-5]emc[1-2]

10.4.[1,5].[51-60]

ocean[1000-1095]

10.2.2.[1-96]

ocean[1096-1191]

10.2.2.[128-223]

ocean[1192-1287]

10.2.3.[1-96]

ocean[1288-1383]

10.2.3.[128-223]

ocean[1384-1479]

10.2.4.[1-96]

ocean[1480-1575]

10.2.6.[1-96]

ocean[1576-1671]

10.2.6.[128-223]

ocean[1672-1767]

10.2.7.[1-96]

ocean[1768-1863]

10.2.7.[128-223]

ocean[1864-1959]

10.2.8.[1-96]

ocean[1000-1095]-ipmi

10.4.2.[1-96]

ocean[1096-1191]-ipmi

10.4.2.[128-223]

ocean[1192-1287]-ipmi

10.4.3.[1-96]

ocean[1288-1383]-ipmi

10.4.3.[128-223]

ocean[1384-1479]-ipmi

10.4.4.[1-96]

ocean[1480-1575]-ipmi

10.4.6.[1-96]

ocean[1576-1671]-ipmi

10.4.6.[128-223]

ocean[1672-1767]-ipmi

10.4.7.[1-96]

ocean[1768-1863]-ipmi

10.4.7.[128-223]

ocean[1864-1959]-ipmi

10.4.8.[1-96]

1

Le cacul des ranges est aisé avec l’option --split de nodeset

Insertion des objets dans RackTables

Tout d’abord les allées et racks:

hwdb obj add -t Row A
hwdb obj add -t Row B
hwdb obj add -t Row C
hwdb obj add -t Rack --container A A1
hwdb obj add -t Rack --container B B[1-5]
hwdb obj add -t Rack --container C C[1-5]

Préparer l’insertion des Sequana:

hwdb port type restore /usr/share/doc/confiture-0.0.1/examples/rt_dumps/ptypes.dump
hwdb port compat restore --csv /usr/share/doc/confiture-0.0.1/examples/rt_dumps/pcompat.dump
hwdb obj model restore /usr/share/doc/confiture-0.0.1/examples/rt_dumps/models.dump

Puis les insérer, d’abord le premier puis les autres en parallèle:

hwdb cell add --rack B1 --prefix s1 templates/sequana2.hw.yaml
hwdb cell add --rack C1 --prefix s6 templates/sequana2.hw.yaml &
hwdb cell add --rack B2 --prefix s2 templates/sequana2.hw.yaml &
hwdb cell add --rack C2 --prefix s7 templates/sequana2.hw.yaml &
hwdb cell add --rack B3 --prefix s3 templates/sequana2.hw.yaml &
hwdb cell add --rack C3 --prefix s8 templates/sequana2.hw.yaml &
hwdb cell add --rack B4 --prefix s4 templates/sequana2.hw.yaml &
hwdb cell add --rack C4 --prefix s9 templates/sequana2.hw.yaml &
hwdb cell add --rack B5 --prefix s5 templates/sequana2.hw.yaml &
hwdb cell add --rack C5 --prefix s10 templates/sequana2.hw.yaml &

Renommer les équipements:

hwdb obj update --newnames ocean[1000-1095] s1compute[1-96]
hwdb obj update --newnames ocean[1096-1191] s2compute[1-96]
hwdb obj update --newnames ocean[1192-1287] s3compute[1-96]
hwdb obj update --newnames ocean[1288-1383] s4compute[1-96]
hwdb obj update --newnames ocean[1384-1479] s5compute[1-96]
hwdb obj update --newnames ocean[1480-1575] s6compute[1-96]
hwdb obj update --newnames ocean[1576-1671] s7compute[1-96]
hwdb obj update --newnames ocean[1672-1767] s8compute[1-96]
hwdb obj update --newnames ocean[1768-1863] s9compute[1-96]
hwdb obj update --newnames ocean[1864-1959] s10compute[1-96]
hwdb obj update --newnames i1r[1-5]pmc s[1-5]pmcm
hwdb obj update --newnames i2r[1-5]pmc s[6-10]pmcm
hwdb obj update --newnames i1r[1-5]hmc[1-3] s[1-5]hmc[1-3]
hwdb obj update --newnames i2r[1-5]hmc[1-3] s[6-10]hmc[1-3]
hwdb obj update --newnames i1r[1-5]wmc[1-3] s[1-5]wmc[1-3]
hwdb obj update --newnames i2r[1-5]wmc[1-3] s[6-10]wmc[1-3]
hwdb obj update --newnames i1r[1-5]emc[1-2] s[1-5]emc[1-2]
hwdb obj update --newnames i2r[1-5]emc[1-2] s[6-10]emc[1-2]

Insérer les serveurs et les switchs:

hwdb obj add -t 'server' --model 'SuperMicro' 'X10DRS' --container A1 --slots 1-16/2 --size 2 ocean[1-8]
hwdb obj add -t 'server' --model 'SuperMicro' 'X10DRS' --container A1 --slots 20-27/2 --size 2 ocean[20-23]
hwdb obj add -t 'network switch' --model 'Cisco' 'Nexus 93180YC-EX' --container A1 --slots 31-32 esw[1-2]
hwdb obj add -t 'network switch' --model 'Cisco' 'Nexus 93180YC-EX' --container A1 --slots 34-37 i[1-2]esw[1-2]

Insérer les ports des serveurs et switchs:

hwdb port add -t hardwired 1000Base-T ocean[1-8],ocean[20-23] GigabitEthernet1
hwdb port add -t SFP+ 10GBase-SR ocean[1-8],ocean[20-23] 10GEthernet1
hwdb port add -t SFP+ 10GBase-SR ocean[20-23] 10GEthernet2
hwdb port add -t SFP+ 10GBase-SR esw[1-2],i[1-2]esw[1-2] 10GEthernet[1-36]

Connecter les serveurs:

hwdb port link ocean[1,3,5,7] 10GEthernet1 esw1 10GEthernet[1-4]
hwdb port link ocean[2,4,6,8] 10GEthernet1 esw2 10GEthernet[1-4]
hwdb port link ocean20 10GEthernet[1-2] i1esw[1-2] 10GEthernet3
hwdb port link ocean21 10GEthernet[1-2] i1esw[1-2] 10GEthernet4
hwdb port link ocean22 10GEthernet[1-2] i2esw[1-2] 10GEthernet3
hwdb port link ocean23 10GEthernet[1-2] i2esw[1-2] 10GEthernet4

Puis les switchs:

hwdb port link esw1 10GEthernet[9-10] esw2 10GEthernet[9-10]
hwdb port link esw1 10GEthernet[5-8] i[1-2]esw[1-2] 10GEthernet1
hwdb port link esw2 10GEthernet[5-8] i[1-2]esw[1-2] 10GEthernet2
hwdb port link i1esw1 10GEthernet[5-6] i1esw2 10GEthernet[5-6]
hwdb port link i2esw1 10GEthernet[5-6] i2esw2 10GEthernet[5-6]

Et enfin les sequana:

hwdb port link s[1-5]wel[0-2]-1 10GEthernet19 i1esw1 10GEthernet[22-36]
hwdb port link s[1-5]wel[0-2]-2 10GEthernet19 i1esw2 10GEthernet[22-36]
hwdb port link s[6-10]wel[0-2]-1 10GEthernet19 i2esw1 10GEthernet[22-36]
hwdb port link s[6-10]wel[0-2]-2 10GEthernet19 i2esw2 10GEthernet[22-36]

Définir les lags statiques vPC:

hwdb port update --label lag=vpc1 esw[1-2] 10GEthernet5
hwdb port update --label lag=vpc2 esw[1-2] 10GEthernet6
hwdb port update --label lag=vpc3 esw[1-2] 10GEthernet7
hwdb port update --label lag=vpc4 esw[1-2] 10GEthernet8
hwdb port update --label lag=1 i1esw1 10GEthernet[1-2]
hwdb port update --label lag=2 i1esw2 10GEthernet[1-2]
hwdb port update --label lag=3 i2esw1 10GEthernet[1-2]
hwdb port update --label lag=4 i2esw2 10GEthernet[1-2]

Pour finir, activer l’option82:

hwdb port update --label "shared=BMC opt82=VENDOR1;" ocean[1000-1959] GigabitEthernet1
hwdb port update --label "opt82=VENDOR2; suffix=ipmi" ocean[1000-1959] BMC
hwdb port update --label "opt82" ocean[1-8,20-23] 10GEthernet1
j=1; for i in $(nodeset -e s[1-10]wel[0-2]-[1-2],esw[1-2],i[1-2]esw[1-2]); do hwdb obj update --label "swid=$j" $i; let "j++"; done

Préparation des fichiers de conf

Les fichiers addresses.yaml, vlans.yaml et networks.yaml sont directement retranscriptibles depuis la description faite plus haut. Le fichier switches.yaml est assez verbeux en l’état, il faut donc user de hiera pour arriver à une syntaxe lisible.

Ainsi, il faut ajouter un nouveau niveau dans hiera.yaml:

---
:backends:
   - yaml
:hierarchy:
   - "hiera/%{::hostname}"
   - "hiera/%{::configname}"
   - "hiera/%{::configname}.2"
   - hiera/defaults
:yaml:
 :datadir: "%{::hiera_cwd}"

Puis créer un fichier switches.2.yaml gérant les paramètres communs:

n9k_conf:
  type: cisco_n9k
  domain:
    name: "%{hiera('cluster_domain')}"
  ntpservers:
    - "${address('ntp-adm')}"
  auth:
    enable: "$1$abcd."
    users:
        admin:
          privilege: 0
          password: "abcd"
  ports:
    Vlan:
      defaults:
        options:
          - "ip helper-address ${address('dhcp-adm')}"
      1: {}
    RackTables:
      defaults:
        vlan:
          mode: access

switches:
  esw1: "%{alias('n9k_conf')}"
  esw2: "%{alias('n9k_conf')}"
  i1esw1: "%{alias('n9k_conf')}"
  i1esw2: "%{alias('n9k_conf')}"
  i2esw1: "%{alias('n9k_conf')}"
  i2esw2: "%{alias('n9k_conf')}"

Et enfin un switches.yaml avec la configuration spécifique à chaque switch:

switches:
  esw1:
    ports:
      Vlan:
        1:
          addresses:
            - "${address('esw1')}/24"
        20: {}
        22: {}
  esw2:
    ports:
      Vlan:
        1:
          addresses:
            - "${address('esw2')}/24"
        20: {}
        22: {}
  i1esw1:
    ports:
      Vlan:
        1:
          addresses:
            - "${address('i1esw1')}/24"
        20: {}
  i1esw2:
    ports:
      Vlan:
        1:
          addresses:
            - "${address('i1esw2')}/24"
        20: {}
  i2esw1:
    ports:
      Vlan:
        1:
          addresses:
            - "${address('i2esw1')}/24"
        22: {}
  i2esw2:
    ports:
      Vlan:
        1:
          addresses:
            - "${address('i2esw2')}/24"
        22: {}

Remarquer que le fichier ne prends pas en compte les switchs de rack Sequana, il est utile de faire l’exercice avec ceux-ci également. Néammoins, pour ne pas faire une documentation trop verbeuse ceci ne sera pas fait ici.

Pour terminer, il faut configurer le nom de domain dans defaults.yaml:

cluster_domain: 'pcocc.c-inti.ccc.ocre.cea.fr'
dns_servers:
  - "dns.%{hiera('cluster_domain')}"
ntp_servers:
 - "ntp.%{hiera('cluster_domain')}"
tftp_server: "tftp.%{hiera('cluster_domain')}"

Génération des configurations

confiture dns
confiture dhcp
confiture switches

Installation

Déploiement serveurs

Addresse IP

Après avoir lancé le simulateur et vous être connecté sur le premier nœud, la première chose à faire est de démarrer l’interface et y assigner la première IP:

ip link set ens5 up
ip link set ens7 up
ip a a 10.0.0.1/24 dev ens5
ip a a 10.1.0.1/24 dev ens7
ip a a 10.5.0.1/24 dev ens7

BMGR

Installation

Installation du RPM:

yum install -y bmgr

Initialiser la DB:

systemctl enable mariadb
systemctl start mariadb
mysql << EOF
CREATE USER 'bmgr_user'@'localhost' IDENTIFIED BY 'bmgr_pass';
CREATE database bmgr;
GRANT ALL PRIVILEGES ON bmgr.* TO 'bmgr_user'@'localhost';
EOF
FLASK_APP=bmgr.app flask initdb

Ajouter le script WSGI dans apache:

echo 'WSGIScriptAlias /bmgr "/var/www/bmgr/bmgr.wsgi"' >> /etc/httpd/conf/httpd.conf
systemctl enable --now httpd

Tester:

bmgr host list
Configuration

Ajout des nœuds:

bmgr host add ocean[1-8,20-23],esw[1-2],i[1-2]esw[1-2]

Ajout des profils associés:

bmgr profile add n9k
bmgr host update --profiles n9k esw[1-2],i[1-2]esw[1-2]
bmgr profile add ocean_mngt
bmgr profile add ocean_mngt_top
bmgr profile add ocean_mngt_worker
bmgr profile add ocean_mngt_isma
bmgr host update --profiles ocean_mngt ocean[1-8,20-23]
bmgr host update --profiles ocean_mngt_top ocean[1-2]
bmgr host update --profiles ocean_mngt_worker ocean[3-8]
bmgr host update --profiles ocean_mngt_isma ocean[20-23]

Test:

bmgr resource list
bmgr alias list
bmgr resource render ipxe_boot ocean1
bmgr alias add ipxe_boot ipxe_boot_deploy
bmgr resource render ipxe_boot ocean1
bmgr resource render kickstart ocean2
bmgr resource render poap_config esw1

Serveur de déploiement

Image

Pour créer l’image de boot utilisée par les nœuds au kickstart, nous allons utiliser lorax comme outil pour créer les fichiers nécessaires au boot PXE.

Pour cela lister les URL des dépots Ocean (ocean, centos-os, centos-updates et centos-extras):

Todo

Lorax removes grubby which is required by anaconda (provides new-kernel-pkg command)

Installer puis lancer lorax:

yum install -y lorax
lorax -p Ocean -v 2.7 -r 1 -s http://pkg/mirror/pub/linux/ocean/2.7/ocean/x86_64 -s http://pkg/mirror/pub/linux/ocean/2.7/centos-os/x86_64 -s http://pkg/mirror/pub/linux/ocean/2.7/centos-updates/x86_64 -s http://pkg/mirror/pub/linux/ocean/2.7/centos-extras/x86_64 /var/www/html/boot

Configurer bmgr avec le path vers les images créées:

bmgr profile update ocean_mngt -a initrd http://ocean1-mngt/boot/images/pxeboot/initrd.img
bmgr profile update ocean_mngt -a kernel http://ocean1-mngt/boot/images/pxeboot/vmlinuz -a install_tree http://ocean1-mngt/boot

Enfin, cloner les dépôts de base nécessaires au kickstart:

yum install -y createrepo
reposync -p /var/www/html/boot/packages -r ocean_centos_update -r ocean_centos -r ocean -r ocean-missing -n -m
createrepo -g /var/www/html/boot/packages/ocean_centos/comps.xml /var/www/html/boot/
Dépôts

Configurer Apache pour proxifier les dépôts de RPM:

cat > /etc/httpd/conf.d/mirror.conf << EOF
ProxyPass /mirror http://r0conf:8080/mirror
ProxyPassReverse /mirror http://r0conf:8080/mirror
EOF
systemctl reload httpd

Enfin, configurer bmgr avec les bons dépôts (pour le kickstart):

bmgr profile update ocean_mngt -a ks_repos http://ocean1-mngt/mirror/pub/linux/ocean/2.7/ocean/x86_64/,http://ocean1-mngt/mirror/pub/linux/ocean/2.7/centos-os/x86_64/,http://ocean1-mngt/mirror/pub/linux/ocean/2.7/centos-updates/x86_64/,http://ocean1-mngt/mirror/pub/linux/ocean/2.7/centos-extras/x86_64/,http://ocean1-mngt/mirror/pub/linux/ocean/2.7/epel/x86_64/,http://ocean1-mngt/mirror/pub/linux/ocean/2.7/greyzone/x86_64/
SSH

Générer et créer un fichier authorized_keys disponible via HTTP:

ssh-keygen -b 4096
cp ~/.ssh/id_rsa.pub /var/www/html/authorized_keys

Configurer bmgr:

bmgr profile update ocean_mngt -a ks_authorized_keys_url http://ocean1-mngt/authorized_keys
Finalisation BMGR

Finaliser la configuration des profils BMGR avec la configuration matérielle des nœuds à déployer:

bmgr profile update ocean_mngt -a ks_rootpwd toto
bmgr profile update ocean_mngt -a ks_drive sda
bmgr profile update ocean_mngt -a ks_selinux_mode disabled
bmgr profile update ocean_mngt -a ks_firewall_mode disabled
bmgr profile update ocean_mngt -a ks_extras_pkgs emacs-nox
bmgr profile update ocean_mngt -a kickstart http://ocean1-mngt/bmgr/api/v1.0/resources/kickstart/
bmgr profile update ocean_mngt_top -a netdev ens5
bmgr profile update ocean_mngt_worker -a netdev ens4
bmgr profile update ocean_mngt_isma -a netdev ens4
bmgr profile update ocean_mngt -a console ttyS0,115200

Serveur DNS

Installer le serveur DNS:

yum install -y bind

Puis copier la configuration générée par confiture:

mkdir /var/named/primary
cp zones/* /var/named/primary/
cp named.conf /etc/named.conf
chown -R named:named /var/named/*
systemctl start named

Tester:

host ocean1 127.0.0.1
host ocean1-mngt 127.0.0.1

Activer le forward DNS en modifiant la configuration :

--- /tmp/ocean_siteprep/named.conf2019-05-06 05:54:27.407311494 +0000
+++ /etc/named.conf2019-05-06 06:30:18.242311494 +0000
@@ -8,7 +8,8 @@
     allow-query { any; };
     allow-query-cache { any; };
     transfers-out 150;
-    recursion no;
+    recursion yes;
+    forwarders { 10.200.255.253;};
 };

 logging {

Puis modifier le resolv.conf:

; generated by /usr/sbin/dhclient-script
search pcocc.c-inti.ccc.ocre.cea.fr. c-inti.ccc.ocre.cea.fr. ccc.ocre.cea.fr. cea.fr.
nameserver 127.0.0.1
sortlist 10.1.177.5 10.100.177.5 10.1.0.0/255.255.0.0 10.2.0.0/255.255.0.0 10.3.0.0/255.255.0.0 10.100.0.0/255.248.0.0 192.168.0.0/255.255.0.0

Serveur DHCP

Installer le serveur DHCP:

yum install -y dhcp

Puis copier la configuration générée par confiture:

cp dhcpd.conf /etc/dhcp/dhcpd.conf
systemctl start dhcpd

Vérifications

Mettre ocean2 en mode déploiement, puis vérifier les scripts iPXE et kickstart:

bmgr alias_set ipxe_dkfull ipxe_dkfull_deploy ocean2 autodelete
bmgr resource_get ipxe_dkfull ocean2
bmgr resource_get ipxe_dkfull ocean2
bmgr resource_get kickstart ocean2
ksvalidator http://localhost/bmgr/api/v1.0/resources/kickstart/ocean2

De même pour ocean3:

bmgr alias_set ipxe_dkfull ipxe_dkfull_deploy ocean3 autodelete
bmgr resource_get ipxe_dkfull ocean3
bmgr resource_get ipxe_dkfull ocean3
bmgr resource_get kickstart ocean3
ksvalidator http://localhost/bmgr/api/v1.0/resources/kickstart/ocean3

Déploiement des serveurs

Mettre tous les nœuds en mode déploiement (permanent):

bmgr alias_set ipxe_dkfull ipxe_dkfull_deploy ocean[2-8,20-23] autodelete

Puis faire un reset d’ocean2:

pcocc reset -j %JODIB% vm1

Si tout ce passe bien, déployer le reste:

clush -R exec -w vm[2-7,14-17]  pcocc reset -j %JODIB% %h

Pour tester le bon déploiement:

clush -o'-o StrictHostKeyChecking=no' -bw 10.0.0.[2-8,20-23] 'uname -a'

Todo

Désactiver les dépôts CentOS en post, importer les clefs GPG utilisées. clush -bw ocean[2-8,20-23] ‘yum install -y –nogpgcheck –disablerepo=* –enablerepo=KS*; yum-config-manager –save –disable base extras updates; yum-config-manager –setopt gpgcheck=0 –save; yum install –nogpgcheck -y /tmp/puppet4-4.10.12-1.ocean2.el7.noarch.rpm’

Todo

Les NXOS virtuel supportent mal la commande pcocc reset, ils tombent dans le bootload (shell >loader), dans ce cas il faut exécuter la commande boot nxos.9.2.2.bin. Ceci tant qu’ils ne sont pas configurés

Auto provisioning des switchs Nexus

Serveur TFTP

Mettre en place un serveur TFTP avec le script poap.py en place à la racine, générer le md5sum embarqué:

yum install xinetd tftp-server tftp
systemctl enable --now xinetd tftp
cp /tmp/poap.py /var/lib/tftpboot/
cd /var/lib/tftpboot/
f=poap.py ; cat $f | sed '/^#md5sum/d' > $f.md5 ; sed -i "s/^#md5sum=.*/#md5sum=\"$(md5sum $f.md5 | sed 's/ .*//')\"/" $f
Images et configuration NXOS

Mettre en place avec le bon nommage les images et configurations (générées par Confiture):

mkdir /var/www/html/poap/
cp /tmp/ocean_siteprep/*confg /var/www/html/poap/
cp /tmp/nxos.9.2.2.bin /var/www/html/poap/
cd /var/www/html/poap/
for i in *confg; do mv $i $(echo $i | sed -n 's/\(.*\)_confg/conf_\1.cfg/p'); done
for i in *.cfg *.bin; do md5sum $i > $i.md5; done
BMGR

Mettre à jour le profil de configuration des switchs avec les détails du POAP:

bmgr profile_setattr n9k config_server 10.0.0.1
bmgr profile_setattr n9k os_name nxos
bmgr profile_setattr n9k os_version 9.2.2
bmgr profile_setattr n9k poap_config_path /poap/
bmgr profile_setattr n9k poap_mode hostname
bmgr profile_setattr n9k update_image true

Tester la configuration:

bmgr resource_get poap_config esw1
Déploiement

Le déploiement d’effectue automatiquement au boot, il suffit donc de suivre son bon déroulement avec pcocc console. En cas de soucis (ou pour redéployer) et si vous avez un shell sur le switch vous pouvez recommencer le process complet avec un write erase suivi d’un reload.

Bootstrap de la couche d’administration

Puppet

Sur le nœud utiliser comme serveur de bootstrap temporaire, installez Puppet:

yum install -y git puppet-global puppet4 rubygem-r10k puppetserver puppet4-server rubygem-hocon emacs emacs-yaml-mode vim puppet-extras

Todo

yum install -y git /tmp/pkgs/puppet-global*rpm /tmp/pkgs/puppet4*rpm /tmp/pkgs/puppetserver*rpm /tmp/pkgs/puppet-extras*rpm rubygem-hocon rubygem-r10k emacs-nox emacs-yaml-mode vim

Configurez un commiter git temporaire :

git config --global user.email "root@vm0"
git config --global user.name "root"

Configurer le hostname et l’IP de vm0:

hostnamectl set-hostname ocean1

Todo

Configurer le forward DNS.

Generer la CA et les certificats des nœuds :

puppet ca generate ocean1.$(facter domain)
puppet cert clean ocean1.$(facter domain)
puppet certificate generate --dns-alt-names ocean1-mngt.$(facter domain),ocean1-mngt,ocean1 ocean1.$(facter domain) --ca-location local
clush -bw ocean[2-8,20-23] -R exec puppet certificate generate --ca-location local %h.$(facter domain)
clush -bw ocean[2-8,20-23] -R exec puppet cert sign %h.$(facter domain)

Deployer les certificats

Puis créer les dépôts nécéssaires, cccenv d’abord :

git init cccenv
cd cccenv
mkdir -p {modules/empty/manifests,files,hiera}
touch modules/empty/manifests/empty.pp
git add modules
git commit -m 'Initial Commit'
git init --bare /var/lib/puppet-cccenv
git remote add origin /var/lib/puppet-cccenv
git push -u origin HEAD:master
cd -

Puis domain :

git init domain
cd domain
mkdir -p files/pcocc.c-inti.ccc.ocre.cea.fr all-nodes nodes hiera
ln -sf ../../all-nodes files/pcocc.c-inti.ccc.ocre.cea.fr/all-nodes
ln -sf ../../nodes files/pcocc.c-inti.ccc.ocre.cea.fr/nodes
git add files all-nodes nodes hiera
git commit -m 'Initial Commit'
git init --bare /var/lib/puppet-domain
git remote add origin /var/lib/puppet-domain
git push -u origin HEAD:master
cd -

Et enfin global :

git clone --mirror /usr/share/puppet-global /var/lib/puppet-global
git clone /var/lib/puppet-global global
cd global
git remote add upstream /usr/share/puppet-global
cd -

Configurer r10k afin de déployer les modules et manifests des différents dépôts :

# /etc/puppetlabs/r10k/r10k.yaml
---
:cachedir: /var/cache/r10k
:sources:
  :global:
    remote: /var/lib/puppet-global
    basedir: /etc/puppetlabs/code/environments
:deploy:
  purge_whitelist: [  ".resource_types/*", ".resource_types/**/*" ]

Puis déployer et demarrer puppetserver :

r10k deploy environment -pv
systemctl start puppetserver

Installer et configurer l’ENC de puppet-addons :

yum install -y --enablerepo ocean_greyzone puppet-addons
cat > /etc/puppetlabs/puppet/puppet.conf << EOF
[master]
  node_terminus = exec
  external_nodes = /sbin/puppet-external
EOF
systemctl reload puppetserver
cat > /etc/puppet/puppet-groups.yaml << EOF
environments:
  master: "ocean1"
roles:
  puppetserver: "ocean1"
EOF

Puis appliquez la configuration d’ocean1:

puppet-apply --server $(facter fqdn)

Configuration réseau

L’application initiale de la configuration réseau est toujours un peu délicate. Tout d’abord il faut configurer les différentes interfaces dans Puppet.

Dans le dépôt domain, dans un profil 90-spom configurer les interfaces réseaux pour tout les nœuds de management :

# 90-spom.yaml
classes:
- net

net::ifcfgs:
  "%{hiera('phy_mngt_interface')}":
    mode: 'bridge-slave'
    mtu: 1400
    peerdns: false
    bridge: "%{hiera('mngt_interface')}"
  "%{hiera('phy_data_interface')}":
    mode: 'bridge-slave'
    mtu: 1400
    peerdns: false
    bridge: "%{hiera('data_interface')}"
  "%{hiera('mngt_interface')}":
    type: 'bridge'
    mode: 'fromdns'
    dnssuffix: '-mngt'
    mask: '255.255.255.0'
  "%{hiera('data_interface')}":
    type: 'bridge'
    mode: 'fromdns'
    dnssuffix: '-data'
    mask: '255.255.255.0'
  "%{hiera('adm_interface')}":
    type: 'bridge'
    mode: 'fromdns'
    dnssuffix: '-adm'
    mask: '255.255.255.0'

mngt_interface: br_mngt
data_interface: br_data
adm_interface: br_data:1

Puis pour les profils 80-worker-mngt, 80-top-mngt et 80-islet-mngt configurer les interfaces physiques:

# 80-top-mngt.yaml
phy_mngt_interface: ens5
phy_data_interface: ens7
# 80-worker-mngt.yaml
phy_mngt_interface: ens4
phy_data_interface: ens5
# 80-islet-mngt.yaml
phy_mngt_interface: ens4
phy_data_interface: ens5

Todo

Il faut appliquer une clef resources vide si non existante. ie “99-common: resources: {}”

Un moyen d’appliquer la configuration sur les nœuds dejà deployés est la suivante:

ssh ocean2-mngt ifup ens7
ssh ocean2-mngt ifup br_data
ssh ocean2 ifdown ens5
ssh ocean2 ifup ens5
ssh ocean2 ifup br_mngt
clush -bw ocean[3-8,20-23]-mngt ifup ens5
clush -bw ocean[3-8,20-23]-mngt ifup br_data
clush -bw ocean[3-8,20-23] ifdown ens4
clush -bw ocean[3-8,20-23] ifup ens4
clush -bw ocean[3-8,20-23] ifup br_mngt
clush -bw ocean[3-8,20-23] uname
clush -bw ocean[3-8,20-23]-mngt uname