********************* Ocean Stack simulator ********************* Architecture ============ .. graphviz:: 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`` .. code-block:: 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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`: .. code-block:: shell 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: .. code-block:: shell 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``: .. code-block:: 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: .. code-block:: yaml 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: .. code-block:: yaml 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``: .. code-block:: 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 ----------------------------- .. code-block:: sh confiture dns .. code-block:: sh confiture dhcp .. code-block:: sh 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: .. code-block:: shell 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 .. Collecte des MACs ----------------- .. todo:: Useless devrait être intégré dans confiture Après avoir lancé le simulateur et vous être connecté sur le premier nœud, la première chose à faire est de collecter les MACs sur le réseau de management (réseau `pv1`) au travers de l'interface ``ens4`` d'*ocean1*. Pour cela, démarrez l'interface et assignez vous la première IP:: ip link set ens4 up ip a a 10.0.0.1/24 dev ens4 Puis collectez les MACs à l'aide de *tshark*, en parallèle faites un reset de toute vos VMs pour accélerer le processus: .. code-block:: sh tshark -i ens4 -T fields -e eth.src > mac .. code-block:: sh clush -R exec -w vm[1-17] pcocc reset -j %JOBID% %h Vous devriez avoir, à terme, les MACs de tous les équipements connectés soit 17 MACs:: $ sort -u mac | wc -l 17 BMGR ^^^^ Installation """""""""""" Installation du RPM: .. code-block:: shell yum install -y bmgr Initialiser la DB: .. code-block:: shell 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: .. code-block:: shell echo 'WSGIScriptAlias /bmgr "/var/www/bmgr/bmgr.wsgi"' >> /etc/httpd/conf/httpd.conf systemctl enable --now httpd Tester: .. code-block:: shell bmgr host list Configuration """"""""""""" Ajout des nœuds: .. code-block:: shell bmgr host add ocean[1-8,20-23],esw[1-2],i[1-2]esw[1-2] Ajout des profils associés: .. code-block:: shell 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: .. code-block:: shell 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*): - http://pkg/mirror/pub/linux/ocean/2.7/ocean/x86_64 - http://pkg/mirror/pub/linux/ocean/2.7/centos-os/x86_64 - http://pkg/mirror/pub/linux/ocean/2.7/centos-updates/x86_64 - http://pkg/mirror/pub/linux/ocean/2.7/centos-extras/x86_64 .. todo:: Lorax removes grubby which is required by anaconda (provides ``new-kernel-pkg`` command) Installer puis lancer `lorax`: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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): .. code-block:: shell 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: .. code-block:: shell ssh-keygen -b 4096 cp ~/.ssh/id_rsa.pub /var/www/html/authorized_keys Configurer bmgr: .. code-block:: shell 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: .. code-block:: shell 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 DHCP Initial (dnsmasq) -------------------- .. todo:: Devrait utiliser la conf générée par confiture Dans le contexte du simulateur, ces MACs sont générées par pcocc et correspondent aux IDs des VMs. Ainsi nous pouvons générer une configuration dnsmasq minimale. Avec d'abord un fichier faisant le mapping MAC/Nom: .. code-block:: shell # /etc/ethers 52:54:01:00:00:00 ocean1 52:54:01:00:00:01 ocean2 52:54:01:00:00:02 ocean3 52:54:01:00:00:03 ocean4 52:54:01:00:00:04 ocean5 52:54:01:00:00:05 ocean6 52:54:01:00:00:06 ocean7 52:54:01:00:00:07 ocean8 52:54:01:00:00:08 esw1 52:54:01:00:00:09 esw2 52:54:01:00:00:0a i1esw1 52:54:01:00:00:0b i1esw2 52:54:01:00:00:0c i2esw1 52:54:01:00:00:0d i2esw2 52:54:01:00:00:0e ocean20 52:54:01:00:00:0f ocean21 52:54:01:00:00:10 ocean22 52:54:01:00:00:11 ocean23 Les entrées DHCP statiques: .. code-block:: shell # /etc/dnsmasq_static_hosts.conf 10.0.0.1 ocean1 ocean1.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.2 ocean2 ocean2.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.3 ocean3 ocean3.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.4 ocean4 ocean4.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.5 ocean5 ocean5.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.6 ocean6 ocean6.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.7 ocean7 ocean7.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.8 ocean8 ocean8.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.9 esw1 esw1.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.10 esw2 esw2.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.11 i1esw1 i1esw1.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.12 i1esw2 i1esw2.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.13 i2esw1 i2esw1.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.14 i2esw2 i2esw2.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.15 ocean20 ocean20.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.16 ocean21 ocean21.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.17 ocean22 ocean22.pcocc.c-inti.ccc.ocre.cea.fr 10.0.0.18 ocean23 ocean23.pcocc.c-inti.ccc.ocre.cea.fr Et la configuration de *dnsmasq*: .. code-block:: shell # /etc/dnsmasq.conf bogus-priv no-resolv no-poll local=/pcocc.c-inti.ccc.ocre.cea.fr/ no-hosts addn-hosts=/etc/dnsmasq_static_hosts.conf read-ethers expand-hosts domain=pcocc.c-inti.ccc.ocre.cea.fr dhcp-range=10.0.0.2,10.0.0.200,72h Et le changement dans ``resolv.conf``: .. code-block:: shell [...] nameserver 10.0.0.1 [...] Serveur DNS ^^^^^^^^^^^ Installer le serveur DNS: .. code-block:: shell yum install -y bind Puis copier la configuration générée par confiture: .. code-block:: shell 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: .. code-block:: shell host ocean1 127.0.0.1 host ocean1-mngt 127.0.0.1 Activer le forward DNS en modifiant la configuration : .. code-block:: diff --- /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``: .. code-block:: none ; 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: .. code-block:: shell yum install -y dhcp Puis copier la configuration générée par confiture: .. code-block:: shell 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: .. code-block:: shell 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``: .. code-block:: shell 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): .. code-block:: shell bmgr alias_set ipxe_dkfull ipxe_dkfull_deploy ocean[2-8,20-23] autodelete Puis faire un reset d'`ocean2`: .. code-block:: shell pcocc reset -j %JODIB% vm1 Si tout ce passe bien, déployer le reste: .. code-block:: shell clush -R exec -w vm[2-7,14-17] pcocc reset -j %JODIB% %h Pour tester le bon déploiement: .. code-block:: shell 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é: .. code-block:: shell 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): .. code-block:: shell 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: .. code-block:: shell 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: .. code-block:: shell 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`: .. code-block:: shell 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 : .. code-block:: shell git config --global user.email "root@vm0" git config --global user.name "root" Configurer le hostname et l'IP de ``vm0``: .. code-block:: shell hostnamectl set-hostname ocean1 .. todo:: Configurer le forward DNS. Generer la CA et les certificats des nœuds : .. code-block:: shell 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 : .. code-block:: shell 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`` : .. code-block:: shell 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`` : .. code-block:: shell 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 : .. code-block:: yaml # /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` : .. code-block:: shell r10k deploy environment -pv systemctl start puppetserver Installer et configurer l'ENC de ``puppet-addons`` : .. code-block:: shell 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`: .. code-block:: shell 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 : .. code-block:: yaml # 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: .. code-block:: yaml # 80-top-mngt.yaml phy_mngt_interface: ens5 phy_data_interface: ens7 .. code-block:: yaml # 80-worker-mngt.yaml phy_mngt_interface: ens4 phy_data_interface: ens5 .. code-block:: yaml # 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: .. code-block:: shell 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