Esempi di Localnet UDN per la virtualizzazion Red Hat OpenShift

Collegare le macchine virtuali di virtualizzazion OpenShift alle sottoreti IBM Cloud VPC utilizzando le reti CUDN Localnet per il traffico supportato da VLAN e isolato a livello di namespace.

Questo tutorial illustra come creare un'applicazione a tre livelli di esempio utilizzando sottoreti Virtual Private Cloud (VPC), reti definite dall'utente in cluster (CUDN), reti locali e spazi dei nomi su Red Hat OpenShift on IBM Cloud all'indirizzo IBM Cloud. L'esempio illustra come collegare direttamente alle sottoreti VPC i server virtuali in esecuzione su Virtualizazion Red Hat OpenShift, utilizzando reti localnet basate su reti locali virtuali (VLAN). Per ulteriori informazioni sui tipi di rete, consultare la sezione " Reti Open Virtual Network(OVN)" all'indirizzo Red Hat OpenShift, destinata agli amministratori di vSphere®.

Panoramica

L'esempio illustra l'implementazione di un'applicazione a tre livelli con segmenti di rete distinti per i livelli web, database e applicativo. Ogni livello utilizza una sottorete VPC dedicata e una rete locale CUDN con un ID VLAN univoco. I livelli web e database sono collocati in un unico spazio dei nomi (green), mentre il livello applicativo è collocato in uno spazio dei nomi separato (red) per illustrare l'isolamento basato sugli spazi dei nomi.

Dettagli relativi alla rete, allo spazio dei nomi e al server virtuale

La tabella seguente riassume la struttura di rete dell'esempio.

Esempio di struttura di Localnet CUDN, spazio dei nomi e server virtuali
Localnet CUDN Namespace ID VLAN Sottorete VPC Server virtuali
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

Schema della configurazione finale

Configurazione di un'applicazione a tre livelli con Localnet
Configurazione di un'applicazione a tre livelli con Localnet

Ogni blocco di codice presente nella guida può essere copiato in un file e applicato tramite il comando oc apply -f .yml``. Alcuni blocchi di codice potrebbero estendersi su più pagine nei formati PDF e Word, mentre alcune righe lunghe potrebbero andare a capo in tali formati.

La guida utilizza " ic " come abbreviazione di " ibmcloud " nei comandi della CLI di IBM Cloud. Definisci alias ic=ibmcloud nella tua shell oppure sostituisci ibmcloud al posto di ic nei comandi che seguono.

Prima di iniziare

Assicurati di disporre dei seguenti elementi:

  • Un account IBM Cloud con autorizzazione alla gestione delle risorse VPC e Red Hat OpenShift.
  • La CLI di IBM Cloud è stata installata.
  • I plug-in container-service e vpc-infrastructure sono stati installati.

Il plug-in " container-service " fornisce i comandi " ic ks " utilizzati dalla guida per associare le interfacce di rete virtuali (VNI) VLAN al cluster. Il plug-in " vpc-infrastructure " mette a disposizione i comandi " ic is " utilizzati dalla guida per creare sottoreti VPC, interfacce di rete virtuali (VNI) e altre componenti dell'infrastruttura.

Se è necessario installare i plug-in CLI richiesti, utilizzare i seguenti comandi.

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

Verifica i prerequisiti di rete

Se si utilizza Red Hat OpenShift on IBM Cloud, consultare Red Hat OpenShift on IBM Cloud per verificare i prerequisiti di rete OVN UDN/CUDN prima di iniziare. Il servizio di virtualizzazione Red Hat OpenShift include questi prerequisiti per impostazione predefinita.

Creazione di uno spazio dei nomi e di una rete secondaria CUDN Localnet per il livello “green”

Le reti Localnet possono coesistere con reti primarie di tipo “ Layer 2 ”, reti secondarie di tipo “ Layer 2 ” e altre reti Localnet all’interno di uno spazio dei nomi. Ogni rete locale richiede un VLAN ID. Al momento è possibile utilizzare una sola sottorete per ogni VLAN.

La VLAN non crea un dominio Layer 2 tra i lavoratori. La VLAN viene utilizzata all'interno di ciascun nodo di lavoro, non all'interno della VPC.

Creare lo spazio dei nomi green e le reti vlan20-prod e vlan21-db. Applicare il manifesto con il comando 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

Si prega di tenere presenti le seguenti considerazioni:

  • La sottorete non è definita nella configurazione di Localnet.
  • Non utilizzare VLAN 1.
  • Utilizzare VLAN comprese nell'intervallo da 2 a 500. Le VLAN da 501 a 4094 sono attualmente soggette a restrizioni.

Creazione di un altro spazio dei nomi e di una rete secondaria CUDN Localnet per il livello rosso

Crea lo spazio dei nomi red e la rete vlan22-app. Applicare il manifesto con il comando 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

Creazione di indirizzi IP riservati e VNI nel proprio account VPC

Questo passaggio crea un indirizzo IP riservato in ciascuna sottorete, quindi crea il VNI utilizzando tale indirizzo IP riservato e assegna un nome di rete virtuale ( MAC address ) a ciascuna interfaccia di rete virtuale (VNI).

Si prega di tenere presenti le seguenti considerazioni:

  • In questa fase non viene collegato il cavo di alimentazione " VLAN ID ".
  • È necessario individuare il gruppo di sicurezza da utilizzare in questa fase. Eseguire il comando ic is sgs per visualizzare l'elenco dei gruppi di sicurezza disponibili.
  • È possibile eseguire questa operazione in blocco.
  • Il limite massimo è di 256 VNI per host. Mantenere l'utilizzo al di sotto dell'85% per consentire il failover e le migrazioni da altri host.

Creazione di indirizzi IP riservati in ciascuna sottorete

Per prima cosa, crea un indirizzo IP riservato in ciascuna sottorete per i tuoi server virtuali:

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

Creazione di VNI utilizzando gli indirizzi IP riservati

Ora crea i VNI utilizzando i nomi IP riservati nel passaggio precedente:

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

Associazione del VNI della VLAN al cluster

Recupera l'ID di ciascun VNI creato nel passaggio precedente, quindi utilizza il plug-in " IBM Cloud " ( container-service ) per associare il VNI al cluster. È necessario l'ID del cluster, che è possibile ottenere eseguendo il comando ic ks cluster ls``.

Si prega di tenere presenti le seguenti considerazioni:

  • Se un worker supera la propria quota VNI, l'operazione ad esso associata fallisce.
  • Le VNI possono essere associate al cluster (note anche come “ floating ”) o a un singolo worker.

Cerca gli ID 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}'

Collegare ogni VNI al cluster con l'ID VLAN corrispondente. Sostituisci l'ID del cluster e gli ID VNI con i valori del tuo ambiente.

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

Aggiunta di server virtuali agli spazi dei nomi

Il seguente manifesto è un esempio " YAML " per la creazione di un server virtuale. È possibile aggiornare questo manifesto per ogni namespace e rete. È necessario disporre dell' MAC address per ogni VNI che hai creato. Esegui il comando ic is vnis per visualizzarne l'elenco, quindi aggiorna il campo macAddress nel modello in modo che DHCP funzioni correttamente.

Utilizza i seguenti comandi per individuare l' MAC address per ciascun 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}'

Esempio di output per ogni VNI. I vostri valori sono diversi:

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

Prima di applicare i manifesti, tieni presenti le seguenti considerazioni:

  • Aggiornare la password in ogni manifesto.
  • Per effettuare l'accesso, è necessario inserire una chiave pubblica SSH valida nel campo " ssh_authorized_keys ".
  • Non è possibile utilizzare SSH con la password.
  • Sostituisci ogni valore “ macAddress ” con l’indirizzo MAC del VNI corrispondente che hai individuato nei comandi precedenti. L' macAddress e deve corrispondere al VNI affinché DHCP assegni l'indirizzo IP previsto.

Applicare ciascuno dei seguenti manifesti utilizzando il comando oc apply -f .yml``. Utilizza i seguenti link per passare direttamente a ciascun manifesto.

plant-web00 del server virtuale nello spazio dei nomi green su 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 del server virtuale nello spazio dei nomi green su 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 del server virtuale nello spazio dei nomi red su 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

Verifica della configurazione di rete

IBM Si consiglia di utilizzare un host di salto Linux® nella stessa VPC del cluster per questi test. Dal server host, utilizzare SSH per connettersi a ciascun server virtuale con la chiave pubblica specificata durante la configurazione del server virtuale.

Configurare l'inoltro dell'agente SSH oppure utilizzare una nuova chiave ospitata sull'host di transito. Non copiare la chiave privata da un sistema all'altro.

Da una sessione di terminale, utilizzare SSH per connettersi al server virtuale del livello web:

ssh admin@198.18.0.20

Da un'altra sessione di terminale, utilizzare SSH per connettersi al server virtuale del livello database:

ssh admin@198.18.1.20

Da un'altra sessione di terminale, utilizzare SSH per connettersi al server virtuale del livello applicativo:

ssh admin@198.18.2.20

Test

Eseguire i seguenti test per verificare la configurazione di rete.

  1. Avvia un semplice server HTTP su ciascun server virtuale.

    • Da 198.18.0.20, esegui darkhttpd /usr/share/doc/bash --daemon.
    • Da 198.18.1.20, esegui darkhttpd /usr/share/doc/bash --daemon.
    • Da 198.18.2.20, esegui darkhttpd /usr/share/doc/bash --daemon.
  2. Da 198.18.0.20, esegui curl -v http://198.18.1.20:8080.

  3. Da 198.18.1.20, esegui curl -v http://198.18.0.20:8080.

  4. Dal server virtuale "jump", esegui il comando curl -v http://198.18.2.20:8080.

  5. Da 198.18.1.20, avvia un server iperf3: iperf3 -s -p 9090.

  6. Da 198.18.0.20, connettiti al server iperf3 nel namespace green: iperf3 -c 198.18.1.20 -p 9090.

  7. Esegui un ping da 198.18.1.20 a 198.18.0.20 e viceversa.

  8. Esegui nuovamente le operazioni precedenti utilizzando 198.18.2.20 e l'indirizzo IP del server virtuale Jump.

Applicazione di una politica multi-rete ed esecuzione dei test

Applicare una politica multi-rete che consenta l'accesso solo all' TCP, porta 8080, per la rete vlan20-prod. Salva il seguente manifesto in un file denominato “ my-policy.yml ”. Quindi, esegui il comando oc apply -f my-policy.yml per applicarlo.

---
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

Esegui nuovamente i test su plant-web00 all'indirizzo vlan20-prod. TCP La porta 8080 funziona ancora, ma il resto del traffico, come ping e il test iperf3 sulla porta 9090, non funziona più su quella connessione di rete.

Eseguire il comando oc delete -f my-policy.yml per rimuovere il criterio e ripristinare la connettività. I test sono stati superati di nuovo.