Exemples de réseaux locaux UDN pour la virtualisation d' Red Hat OpenShift

Associez les machines virtuelles de virtualisation d' OpenShift aux sous-réseaux d' IBM Cloud VPC, en utilisant les réseaux CUDN Localnet pour un trafic basé sur des VLAN et isolé par espace de noms.

Ce tutoriel explique comment créer un exemple d'application à trois niveaux à l'aide de sous-réseaux Virtual Private Cloud (VPC), de réseaux définis par l'utilisateur (CUDN), de réseaux locaux et d'espaces de noms sur Red Hat OpenShift on IBM Cloud sur IBM Cloud. Cet exemple montre comment associer directement des serveurs virtuels fonctionnant sur la virtualisation d' Red Hat OpenShift à des sous-réseaux VPC à l'aide de réseaux « localnet » s'appuyant sur des réseaux locaux virtuels (VLAN). Pour plus d'informations sur les types de réseaux, consultez la section « Réseaux Open Virtual Network(OVN)» dans le guide « Red Hat OpenShift » destiné aux administrateurs d' vSphere®.

Présentation

Cet exemple présente le déploiement d'une application à trois couches, avec des segments réseau distincts pour les couches Web, base de données et application. Chaque niveau utilise un sous-réseau VPC dédié et un CUDN « localnet » doté d'un identifiant VLAN unique. Les couches Web et base de données sont placées dans un même espace de noms (green), tandis que la couche applicative est placée dans un espace de noms distinct (red) afin d'illustrer l'isolation basée sur les espaces de noms.

Informations sur le réseau, l'espace de noms et le serveur virtuel

Le tableau suivant résume la configuration réseau présentée en exemple.

Exemple de configuration du réseau local CUDN, de l'espace de noms et des serveurs virtuels
Réseau local CUDN Espace de nom ID de VLAN Sous-réseau VPC Serveurs virtuels
vlan20-prod green 20 198.18.0.0/24 plant-web00, plant-web01
vlan21-db green 21 198.18.1.0/24 plant-db00, plant-db01
vlan22-app red 22 198.18.2.0/24 plant-app00, plant-app01

Schéma de la configuration finale

Configuration d'une application à trois niveaux avec Localnet
Configuration d'une application à trois niveaux avec Localnet

Chaque bloc de code figurant dans ce guide peut être copié dans un fichier et exécuté à l'aide de la commande « oc apply -f <file-name>.yml ». Dans les formats PDF et Word, certains blocs de code peuvent s'étendre sur plusieurs pages, et certaines lignes longues peuvent être coupées dans ces formats.

Dans ce guide, l'abréviation « ic » est utilisée pour désigner « ibmcloud » dans les commandes de l'interface en ligne de commande (CLI) de IBM Cloud. Définissez « alias ic=ibmcloud » dans votre shell, ou remplacez « ic » par « ibmcloud » dans les commandes suivantes.

Avant de commencer

Assurez-vous de disposer des éléments suivants :

  • Un compte « IBM Cloud » disposant des autorisations nécessaires pour gérer les ressources VPC et « Red Hat OpenShift ».
  • L'interface CLI d' IBM Cloud est installée.
  • Les plug-ins « container-service » et « vpc-infrastructure » sont installés.

Le plug-in « container-service » fournit les commandes « ic ks » utilisées par l'assistant pour associer des interfaces réseau virtuelles VLAN (VNI) au cluster. Le plug-in « vpc-infrastructure » fournit les commandes « ic is » utilisées par l'assistant pour créer des sous-réseaux VPC, des interfaces réseau virtuelles (VNI) et d'autres éléments d'infrastructure.

Si vous devez installer les plug-ins CLI requis, utilisez les commandes suivantes.

ibmcloud plugin install container-service
ibmcloud plugin install vpc-infrastructure

Vérifier les conditions préalables du réseau

Si vous utilisez Red Hat OpenShift on IBM Cloud, consultez la page Red Hat OpenShift on IBM Cloud pour prendre connaissance des prérequis réseau OVN UDN/CUDN avant de commencer. Le service de virtualisation Red Hat OpenShift intègre ces prérequis par défaut.

Création d'un espace de noms et d'un réseau secondaire CUDN Localnet pour le niveau « green »

Les réseaux Localnet peuvent coexister avec des réseaux principaux de type « Layer 2 », des réseaux secondaires de type « Layer 2 » et d'autres réseaux Localnet au sein d'un espace de noms. Chaque réseau local nécessite un VLAN ID. Actuellement, vous ne pouvez utiliser qu'un seul sous-réseau par VLAN.

Le VLAN ne crée pas de domaine d' Layer 2 s entre les travailleurs. Le VLAN est utilisé au sein de chaque nœud de travail, et non au sein du VPC.

Créez l'espace de noms green ainsi que les réseaux vlan20-prod et vlan21-db. Appliquez le manifeste à l'aide de la commande « oc apply -f step1.yml ».

---
apiVersion: v1
kind: Namespace
metadata:
  name: green
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
  name: "vlan20-prod"
spec:
  namespaceSelector:
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: In
      values:
      - "green"
  network:
    topology: Localnet
    localnet:
      role: "Secondary"
      physicalNetworkName: "vpc-vlans"
      ipam:
        mode: Disabled
      vlan:
        mode: Access
        access:
          id: 20
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
  name: "vlan21-db"
spec:
  namespaceSelector:
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: In
      values:
      - "green"
  network:
    topology: Localnet
    localnet:
      role: "Secondary"
      physicalNetworkName: "vpc-vlans"
      ipam:
        mode: Disabled
      vlan:
        mode: Access
        access:
          id: 21

Gardez à l'esprit les points suivants :

  • Le sous-réseau n'est pas défini dans la configuration d' Localnet.
  • N'utilisez pas VLAN 1.
  • Utilisez des VLAN compris entre 2 et 500. Les VLAN 501 à 4094 sont actuellement restreints.

Création d'un nouvel espace de noms et d'un réseau secondaire CUDN Localnet pour le niveau « red »

Créez l'espace de noms red et le réseau vlan22-app. Appliquez le manifeste à l'aide de la commande « oc apply -f step2.yml ».

---
apiVersion: v1
kind: Namespace
metadata:
  name: red
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
  name: "vlan22-app"
spec:
  namespaceSelector:
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: In
      values:
      - "red"
  network:
    topology: Localnet
    localnet:
      role: "Secondary"
      physicalNetworkName: "vpc-vlans"
      ipam:
        mode: Disabled
      vlan:
        mode: Access
        access:
          id: 22

Création d'adresses IP réservées et de VNI dans votre compte VPC

Cette étape consiste à créer une adresse IP réservée dans chaque sous-réseau, puis à créer le VNI à l'aide de cette adresse IP réservée et à attribuer une adresse de type « MAC address » à chaque interface réseau virtuelle (VNI).

Gardez à l'esprit les points suivants :

  • L' VLAN ID e n'est pas jointe à cette étape.
  • Vous devez rechercher le groupe de sécurité à utiliser à cette étape. Exécutez la commande « ic is sgs » pour afficher la liste des groupes de sécurité disponibles.
  • Vous pouvez exécuter cette étape de manière groupée.
  • Le nombre maximal est de 256 VNI par hôte. Veillez à ce que le taux d'utilisation reste inférieur à 85 % afin de permettre le basculement et les migrations depuis d'autres hôtes.

Création d'adresses IP réservées dans chaque sous-réseau

Commencez par créer une adresse IP réservée dans chaque sous-réseau pour vos serveurs virtuels :

ic is subnet-reserved-ip-create zone1-vm-prod --address 198.18.0.20 --name zone1-web00 --auto-delete false
ic is subnet-reserved-ip-create zone1-vm-db --address 198.18.1.20 --name zone1-db00 --auto-delete false
ic is subnet-reserved-ip-create zone1-vm-app --address 198.18.2.20 --name zone1-app00 --auto-delete false

Création de VNI à l'aide des adresses IP réservées

Créez maintenant les VNI en utilisant les noms d'adresses IP réservées à l'étape précédente :

ic is virtual-network-interface-create --name zone1-web00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-prod --vpc my-vpc --rip zone1-web00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
ic is virtual-network-interface-create --name zone1-db00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-db --vpc my-vpc --rip zone1-db00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
ic is virtual-network-interface-create --name zone1-app00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-app --vpc my-vpc --rip zone1-app00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default

Association du VNI du VLAN au cluster

Récupérez l'identifiant de chaque VNI que vous avez créé à l'étape précédente, puis utilisez le plug-in « IBM Cloud » ( container-service ) pour associer le VNI au cluster. Vous avez besoin de l'identifiant du cluster, que vous pouvez obtenir en exécutant la commande « ic ks cluster ls ».

Gardez à l'esprit les points suivants :

  • Si un travailleur dépasse son quota VNI, l'opération associée échoue.
  • Les VNI peuvent être associées au cluster (également appelées « floating ») ou à un nœud de travail spécifique.

Recherchez les identifiants VNI.

ic is vni zone1-web00 | awk '$1 ~ /^ID/ {print $NF}'
ic is vni zone1-db00 | awk '$1 ~ /^ID/ {print $NF}'
ic is vni zone1-app00 | awk '$1 ~ /^ID/ {print $NF}'

Associez chaque VNI au cluster correspondant à son identifiant VLAN. Remplacez l'ID du cluster et les ID VNI par les valeurs propres à votre environnement.

ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_web00> --vlan 20
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_db00>  --vlan 21
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_app00> --vlan 22

Ajout de serveurs virtuels aux espaces de noms

Le manifeste suivant est un exemple très YAML e de création d'un serveur virtuel. Vous pouvez mettre à jour ce manifeste pour chaque espace de noms et chaque réseau. Vous devez disposer de l' MAC address pour chaque VNI que vous avez créé. Exécutez la commande « ic is vnis » pour les répertorier, puis mettez à jour le champ « macAddress » dans le modèle afin que l'adresse DHCP fonctionne correctement.

Utilisez les commandes suivantes pour trouver l' MAC address pour chaque VNI.

ic is vni zone1-web00 | awk '/^Mac Address/ {print $NF}'
ic is vni zone1-db00  | awk '/^Mac Address/ {print $NF}'
ic is vni zone1-app00 | awk '/^Mac Address/ {print $NF}'

Exemple de résultat pour chaque VNI. Vos valeurs diffèrent :

02:00:01:00:98:A0
02:00:02:00:98:A5
02:00:02:00:98:AA

Avant d'appliquer les manifestes, gardez à l'esprit les points suivants :

  • Mettez à jour le mot de passe dans chaque manifeste.
  • Pour vous connecter, vous devez saisir une véritable clé publique SSH dans le champ « ssh_authorized_keys ».
  • Vous ne pouvez pas utiliser SSH avec un mot de passe.
  • Remplacez chaque valeur « macAddress » par l'adresse MAC du VNI correspondant que vous avez identifié dans les commandes précédentes. L'adresse « macAddress » doit correspondre au VNI afin que DHCP attribue l'adresse IP attendue.

Appliquez chacun des manifestes suivants à l'aide de la commande « oc apply -f <file-name>.yml ». Utilisez les liens suivants pour accéder directement à chaque manifeste.

plant-web00 de serveurs virtuels dans l'espace de noms green sur vlan20-prod

# Bare YAML to stand up a Red Hat OpenShift on IBM Cloud virtual machine
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: "plant-web00"
  namespace: "green"
  annotations:
    description: "example vm plant-web00"
  labels:
    app: "plant-web00-green-server"
    kubevirt.io/dynamic-credentials-support: 'true'
    vm.kubevirt.io/template: "centos-stream9-server-small"
    vm.kubevirt.io/template.namespace: openshift
    vm.kubevirt.io/template.revision: '1'
    vm.kubevirt.io/template.version: v0.34.0
spec:
  dataVolumeTemplates:
    - apiVersion: cdi.kubevirt.io/v1beta1
      kind: DataVolume
      metadata:
        creationTimestamp: null
        name: "plant-web00-green-server"
      spec:
        sourceRef:
          kind: DataSource
          name: "centos-stream9"
          namespace: openshift-virtualization-os-images
        storage:
          resources:
            requests:
              storage: 30Gi
  runStrategy: RerunOnFailure
  template:
    metadata:
      annotations:
        vm.kubevirt.io/flavor: "small"
        vm.kubevirt.io/os: "centos-stream9"
        vm.kubevirt.io/workload: "server"
      labels:
        kubevirt.io/domain: example
        kubevirt.io/size: "small"
    spec:
      domain:
        cpu:
          cores: 1
          sockets: 1
          threads: 1
        devices:
          disks:
            - disk:
                bus: virtio
              name: rootdisk
            - disk:
                bus: virtio
              name: cloudinitdisk
          interfaces:
            - model: virtio
              name: default
              state: up
              bridge: {}
              macAddress: 02:00:01:00:98:A0 # <- replace with the MAC of VNI zone1-web00
          networkInterfaceMultiqueue: true
          rng: {}
        memory:
          guest: "2Gi"
      hostname: "plant-web00"
      networks:
        - name: default
          multus:
            networkName: vlan20-prod
      terminationGracePeriodSeconds: 180
      volumes:
        - dataVolume:
            name: "plant-web00-green-server"
          name: rootdisk
        - cloudInitNoCloud:
            userData: |-
              #cloud-config
              user: admin
              password: "aRandomPassword9292"
              ssh_authorized_keys:
                 - "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
              chpasswd: { expire: False }
              runcmd:
                - [ dnf, install, -y, epel-release ]
                - [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
          name: cloudinitdisk

plant-db00 de serveurs virtuels dans l'espace de noms green sur vlan21-db

---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: "plant-db00"
  namespace: "green"
  annotations:
    description: "example vm plant-db00"
  labels:
    app: "plant-db00-green-server"
    kubevirt.io/dynamic-credentials-support: 'true'
    vm.kubevirt.io/template: "centos-stream9-server-small"
    vm.kubevirt.io/template.namespace: openshift
    vm.kubevirt.io/template.revision: '1'
    vm.kubevirt.io/template.version: v0.34.0
spec:
  dataVolumeTemplates:
    - apiVersion: cdi.kubevirt.io/v1beta1
      kind: DataVolume
      metadata:
        creationTimestamp: null
        name: "plant-db00-green-server"
      spec:
        sourceRef:
          kind: DataSource
          name: "centos-stream9"
          namespace: openshift-virtualization-os-images
        storage:
          resources:
            requests:
              storage: 30Gi
  runStrategy: RerunOnFailure
  template:
    metadata:
      annotations:
        vm.kubevirt.io/flavor: "small"
        vm.kubevirt.io/os: "centos-stream9"
        vm.kubevirt.io/workload: "server"
      labels:
        kubevirt.io/domain: example
        kubevirt.io/size: "small"
    spec:
      domain:
        cpu:
          cores: 1
          sockets: 1
          threads: 1
        devices:
          disks:
            - disk:
                bus: virtio
              name: rootdisk
            - disk:
                bus: virtio
              name: cloudinitdisk
          interfaces:
            - model: virtio
              name: default
              state: up
              bridge: {}
              macAddress: 02:00:01:00:98:A5 # <- replace with the MAC of VNI zone1-db00
          networkInterfaceMultiqueue: true
          rng: {}
        memory:
          guest: "2Gi"
      hostname: "plant-db00"
      networks:
        - name: default
          multus:
            networkName: vlan21-db
      terminationGracePeriodSeconds: 180
      volumes:
        - dataVolume:
            name: "plant-db00-green-server"
          name: rootdisk
        - cloudInitNoCloud:
            userData: |-
              #cloud-config
              user: admin
              password: "aRandomPassword9292"
              ssh_authorized_keys:
                 - "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
              chpasswd: { expire: False }
              runcmd:
                - [ dnf, install, -y, epel-release ]
                - [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
          name: cloudinitdisk

plant-app00 de serveurs virtuels dans l'espace de noms red sur vlan22-app

---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: "plant-app00"
  namespace: "red"
  annotations:
    description: "example vm plant-app00"
  labels:
    app: "plant-app00-red-server"
    kubevirt.io/dynamic-credentials-support: 'true'
    vm.kubevirt.io/template: "centos-stream9-server-small"
    vm.kubevirt.io/template.namespace: openshift
    vm.kubevirt.io/template.revision: '1'
    vm.kubevirt.io/template.version: v0.34.0
spec:
  dataVolumeTemplates:
    - apiVersion: cdi.kubevirt.io/v1beta1
      kind: DataVolume
      metadata:
        creationTimestamp: null
        name: "plant-app00-red-server"
      spec:
        sourceRef:
          kind: DataSource
          name: "centos-stream9"
          namespace: openshift-virtualization-os-images
        storage:
          resources:
            requests:
              storage: 30Gi
  runStrategy: RerunOnFailure
  template:
    metadata:
      annotations:
        vm.kubevirt.io/flavor: "small"
        vm.kubevirt.io/os: "centos-stream9"
        vm.kubevirt.io/workload: "server"
      labels:
        kubevirt.io/domain: example
        kubevirt.io/size: "small"
    spec:
      domain:
        cpu:
          cores: 1
          sockets: 1
          threads: 1
        devices:
          disks:
            - disk:
                bus: virtio
              name: rootdisk
            - disk:
                bus: virtio
              name: cloudinitdisk
          interfaces:
            - model: virtio
              name: default
              state: up
              bridge: {}
              macAddress: 02:00:01:00:98:AA # <- replace with the MAC of VNI zone1-app00
          networkInterfaceMultiqueue: true
          rng: {}
        memory:
          guest: "2Gi"
      hostname: "plant-app00"
      networks:
        - name: default
          multus:
            networkName: vlan22-app
      terminationGracePeriodSeconds: 180
      volumes:
        - dataVolume:
            name: "plant-app00-red-server"
          name: rootdisk
        - cloudInitNoCloud:
            userData: |-
              #cloud-config
              user: admin
              password: "aRandomPassword9292"
              ssh_authorized_keys:
                 - "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
              chpasswd: { expire: False }
              runcmd:
                - [ dnf, install, -y, epel-release ]
                - [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
          name: cloudinitdisk

Vérification de la configuration du réseau

IBM Il est recommandé d'utiliser un hôte de saut Linux® situé dans le même VPC que le cluster pour ces tests. Depuis l'hôte « Jump », utilisez SSH pour vous connecter à chaque serveur virtuel à l'aide de la clé publique que vous avez spécifiée lors de la configuration du serveur virtuel.

Configurez le transfert de l'agent SSH ou utilisez une nouvelle clé hébergée sur l'hôte relais. Ne copiez pas votre clé privée d'un système à l'autre.

Depuis une session de terminal, utilisez SSH pour vous connecter au serveur virtuel de la couche web :

ssh admin@198.18.0.20

Depuis une autre session de terminal, utilisez SSH pour vous connecter au serveur virtuel de la couche base de données :

ssh admin@198.18.1.20

Depuis une autre session de terminal, utilisez SSH pour vous connecter au serveur virtuel de la couche applicative :

ssh admin@198.18.2.20

Tests

Effectuez les tests suivants pour vérifier la configuration du réseau.

  1. Lancez un serveur « HTTP » simple sur chaque serveur virtuel.

    • Depuis 198.18.0.20, exécutez darkhttpd /usr/share/doc/bash --daemon.
    • Depuis 198.18.1.20, exécutez darkhttpd /usr/share/doc/bash --daemon.
    • Depuis 198.18.2.20, exécutez darkhttpd /usr/share/doc/bash --daemon.
  2. Depuis 198.18.0.20, exécutez curl -v http://198.18.1.20:8080.

  3. Depuis 198.18.1.20, exécutez curl -v http://198.18.0.20:8080.

  4. Depuis le serveur virtuel « jump », exécutez la commande « curl -v http://198.18.2.20:8080 ».

  5. Depuis 198.18.1.20, lancez un serveur iperf3: iperf3 -s -p 9090.

  6. Depuis 198.18.0.20, connectez-vous au serveur iperf3 dans l'espace de noms green: iperf3 -c 198.18.1.20 -p 9090.

  7. Effectuer un ping depuis 198.18.1.20 vers 198.18.0.20 et inversement.

  8. Réexécutez les tâches précédentes en utilisant 198.18.2.20 et l'adresse IP du serveur virtuel « jump ».

Mise en œuvre d'une politique multi-réseaux et réexécution des tests

Appliquez une politique multi-réseau qui n'autorise que le port 8080 d' TCP pour le réseau vlan20-prod. Enregistrez le manifeste suivant dans un fichier nommé « my-policy.yml ». Ensuite, exécutez la commande « oc apply -f my-policy.yml » pour l'appliquer.

---
apiVersion: k8s.ovn.org/v1alpha1
kind: MultiNetworkPolicy
metadata:
  name: allow-8080-tcp
  namespace: green
  annotations:
    k8s.v1.cni.cncf.io/policy-for: vlan20-prod
spec:
  podSelector: {}
  ingress:
    - ports:
        - protocol: TCP
          port: 8080
  egress:
    - ports:
        - protocol: TCP
          port: 8080
  policyTypes:
    - Ingress
    - Egress

Relancez les tests sur plant-web00 à l'adresse vlan20-prod. TCP Le port 8080 fonctionne toujours, mais les autres types de trafic, tels que ping et le test iperf3 sur le port 9090, ne fonctionnent plus sur cette connexion réseau.

Exécutez la commande « oc delete -f my-policy.yml » pour supprimer la stratégie et rétablir la connectivité. Les tests sont à nouveau réussis.