Lernprogramm: Bereitstellen von Azure IoT Einsatz in einem mehrschichtigen Netzwerk mit privater Konnektivität

In diesem Lernprogramm wird beschrieben, wie Sie Azure IoT Einsatz in einer physischen Netzwerktopologie mit explizitem Proxyrouting und privater Konnektivität für Azure Dienste über ExpressRoute bereitstellen. Diese Bereitstellung verwendet Private Link, um Dienste wie Event Grid zu erreichen, und macht keine öffentlichen Endpunkte auf einer Netzwerkebene verfügbar.

Dieses Szenario wurde mithilfe physischer Computer in einem segmentierten Purdue/ISA-95-Netzwerk überprüft, das die Ebenen 2 bis 4 umfasst. Der Azure Firewall Expliziter Proxy wird in einem Azure VNet bereitgestellt, wobei die Verbindung über ExpressRoute bereitgestellt wird.

In diesem Artikel erfahren Sie:

  • Erstellen von Azure-Ressourcen und Vorbereiten einer gestuften Netzwerkumgebung
  • Vorbereiten von Kubernetes-Clustern auf jeder Netzwerkebene
  • Konfigurieren privater Endpunkte und DNS für Azure-Dienste
  • Arc-enable Cluster mit einem Azure Arc-Gateway und explizitem Proxy-Routing
  • Bereitstellen von Azure IoT Einsatz auf Arc-fähigen Clustern
  • Zuweisen von RBAC-Rollen, die für Azure IoT Einsatz Komponenten erforderlich sind
  • Überprüfen des End-to-End-Telemetrieflusses von OPC UA-Quellen zu Azure Event Grid
  • Überwachen und Überprüfen der Netzwerkisolation, der privaten Konnektivität und der RBAC-Zuordnungen

Voraussetzungen

  • Ein Azure-Abonnement. Falls Sie kein Abonnement besitzen, können Sie ein kostenloses Konto erstellen, bevor Sie beginnen.
  • Ihre Mandanten-ID.
  • Ausreichende Berechtigungen zum Erstellen privater Endpunkte, Privates DNS Zonen und Rollenzuweisungen (in der Regel Owner oder Contributor + Benutzerzugriffsadministrator). In diesem Lernprogramm werden benutzerdefinierte Rollen verwendet, die im Anhang definiert sind.
  • Ein Kubernetes-Cluster , der auf jeder Netzwerkebene (Ebene 2, Ebene 3 und Ebene 4) bereitgestellt wird, mit Geräten oder virtuellen Computern, denen statische IPs zugewiesen wurden.
  • Eine vorhandene Netzwerksegmentierung zwischen Ebenen (z. B. Firewalls, die nur L2 ↔ L3 ↔ L4-Kommunikation zulassen) mit DNS-Auflösung über die Ebenen hinweg durch CoreDNS.
  • Azure Private Endpunkte für Event Grid, Speicher (für das Schema-Register) und Key Vault, zugewiesene private IPs, die über ExpressRoute oder gleichwertiges privates Routing zugänglich sind.
  • Azure Firewall Explicit Proxy auf Ebene 4 (Ports 8080/8443), erreichbar von Ebene 4 über ExpressRoute. Der gesamte ausgehende HTTP/HTTPS-Datenverkehr von Ebene 4 fließt über diesen Proxy.
  • Azure CLI, kubectl und Docker auf dem Computer installiert, mit dem Sie Ressourcen bereitstellen und Kubernetes-Cluster verwalten.
  • (Optional) Vertrautheit mit dem Purdue-Modell, das die Ebenen industrieller Steuerungssysteme definiert und häufig in Fertigungsumgebungen verwendet wird.

Hinweis

Im überprüften Telemetriefluss wird nur HTTPS (Port 8443) verwendet. In Kundenumgebungen kann Ebene 4 stattdessen über einen unternehmenseigenen Proxy geleitet werden.

Die Azure CLI Beispiele in diesem Artikel verwenden Umgebungsvariablen, sodass Sie jeden Wert einmal festlegen und dann die Befehle as-iskopieren und einfügen können. Wenn Sie die Azure IoT Einsatz Codespaces-Umgebung aus dem Quickstart verwenden, sind diese Variablen bereits für Sie festgelegt und Sie können diesen Schritt überspringen. Ansonsten setze die folgenden Umgebungsvariablen in deiner Shell, bevor du die Befehle ausführst.

Die folgenden Skripte legen die am häufigsten verwendeten Umweltvariablen fest:

Umgebungsvariable Description
SUBSCRIPTION_ID Die ID des Abonnements, das Ihre Azure IoT Einsatz-Instanz enthält.
RESOURCE_GROUP Der Name der Ressourcengruppe, die Ihre Azure IoT Einsatz-Instanz enthält.
AIO_INSTANCE_NAME Der Name Ihrer Azure IoT Einsatz Instanz. Um deine Instanzen aufzulisten, führe az iot ops list -o table.
CLUSTER_NAME Der Name des Azure Arc-fähigen Kubernetes-Clusters, der deine Instanz hostet.
LOCATION Die Azure-Region zur Nutzung für neue Ressourcen, zum Beispiel eastus.
SUBSCRIPTION_ID=<subscription-id>
RESOURCE_GROUP=<resource-group-name>
AIO_INSTANCE_NAME=<instance-name>
CLUSTER_NAME=<cluster-name>
LOCATION=<region>

Du musst nur die Variablen festlegen, die dieser Artikel verwendet. Dieser Artikel könnte zusätzliche Umgebungsvariablen für die von Ihnen gewählten Ressourcennamen verwenden. Der Artikel erklärt, wie man sie dort platziert, wo sie eingeführt werden.

Dieses Tutorial verwendet außerdem die von Ihnen gewählten Netzwerk- und Azure-Ressourcen, darunter VNET_RESOURCE_GROUP, VNET_NAME, SUBNET_NAME, EVENT_GRID_NAMESPACE, STORAGE_ACCOUNT_NAMEKEY_VAULT_NAMEDNS_RESOLVER_NAMEDNS_RESOLVER_ENDPOINT_NAMEDNS_RESOLVER_SUBNET_NAMEPROXY_SERVERPROXY_PORTPRIVATE_DNS_ZONECUSTOM_LOCATIONS_OIDARC_GATEWAY_RESOURCE_IDL2_CLUSTER_NAMEL3_CLUSTER_NAMEIDENTITY_CLIENT_IDSTORAGE_ACCOUNT_RESOURCE_IDEVENT_GRID_NAMESPACE_RESOURCE_IDENVOY_POD_LABELK3S_SERVICE_NAMEL4_HOST_IPL3_HOST_IPL3_PROXY_PORTund . Stelle jede einzelne ein, bevor du die zugehörigen Befehle ausführst.

Architekturzusammenfassung

Diese Bereitstellung richtet sich an das Purdue-Modell, wobei eine physisch segmentierte, mehrstufige Architektur implementiert wird, die die Ebenen 2 bis 4 umfasst.

Jede Ebene wird durch Netzwerkfirewalls getrennt, die die Kommunikation nur auf benachbarte Ebenen beschränken (z. B. L2 ↔ L3 ↔ L4), wodurch eine enge Segmentierung sichergestellt wird. Ausgehender Datenverkehr zu Azure wird über einen expliziten Proxy und eine Private Link (optional über ein Azure Arc-Gateway) geleitet, sodass auf keiner Ebene internetfreigestellte Endpunkte verwendet werden.

Diagramm, das die

Überprüfte Komponenten

Ebene Komponenten Purpose
L2 CoreDNS, Azure IoT Einsatz Dataflows, Azure IoT Einsatz MQTT Broker Erfasst Telemetrie aus OPC UA-Quellen, wendet die anfängliche Anreicherung an und leitet Daten nach oben weiter.
L3 CoreDNS, Envoy Proxy, Azure IoT Einsatz Dataflows, Azure IoT Einsatz MQTT Broker Aggregiert und transformiert Daten, löst DNS auf, um L4 zu erreichen und Telemetrie sicher weiterzuleiten
L4 Stellvertreter des Gesandten Leitet erweiterte Telemetrie über den expliziten Azure Firewall-Proxy an Event Grid weiter und private Endpunkte über ExpressRoute

Hinweis

Dieses Tutorial verwendet eine Level-4-Egress-Topologie : L4 benutzt nur einen Envoy-Proxy, ist nicht Arc-fähig und leitet den Datenverkehr durch, anstatt ihn zu beenden. Die oberste Azure IoT Einsatz-Instanz befindet sich bei L3, und ihr Datenfluss sendet Telemetrie über den L4 Envoy-Proxy in die Cloud. Diese Architektur ist gültig. Das geschichtete Netzwerk für Azure IoT Einsatz beschreibt die allgemeine Architektur, bei der Azure IoT Einsatz (einschließlich eines MQTT-Brokers und Datenflusses) ebenfalls auf L4 laufen und dort Telemetrie beenden kann. Wählen Sie die Architektur, die zu Ihrer Umgebung passt.

Bereiten Sie Ihre mehrschichtige Netzwerkumgebung vor

Jede Ebene des Netzwerks (Ebene 2, 3 und 4) verwendet statische IPs und strenge Firewallregeln, um die Isolation zu erzwingen. Jede Ebene kommuniziert nur mit ihrer angrenzenden Ebene (z. B. L2 ↔ L3 ↔ L4), wobei die Purdue-Modellzonen implementiert werden.

Schritt 1: Erstellen Azure Ressourcen

Erstellen Sie vor der Bereitstellung am Edge die folgenden Azure Ressourcen:

Deaktivieren Sie nach dem Erstellen dieser Ressourcen den öffentlichen Netzwerkzugriff auf Key Vault, das Speicherkonto und den Event Grid-Namespace.

Von Bedeutung

Die Schema-Registrierung hat eine bekannte Einschränkung beim Deaktivieren des öffentlichen Zugriffs bei der Erstellung. Details finden Sie unter "Bekannte Einschränkungen ".

Schritt 2: Zuweisen statischer IPs für jede Ebene

Stellen Sie einen Computer (physisch oder virtuell) pro Netzwerkebene mit den folgenden Anforderungen bereit:

  • Weisen Sie statische IPs innerhalb eines freigegebenen Adressbereichs zu.
  • Alle Geräte führen Ubuntu Server 24.04 aus.
  • Geräte auf L2 und L3 sind arcfähig und hosten ihre jeweiligen Azure IoT Einsatz Instanzen.

Konfigurieren Sie statische IPs mit Netplan. Beispiel: Bearbeiten /etc/netplan/01-netcfg.yaml:

network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 172.22.232.X/24
      routes:
        - to: default
          via: 172.22.232.1
      nameservers:
        addresses:
          - 168.63.129.16

Wenden Sie die Konfiguration an:

sudo netplan apply

Hinweis

Hier gezeigte IPs sind Beispiele aus dem Validierungslabor und sind nicht über das Internet zugänglich. Ersetzen Sie diese durch IPs, die für Ihr eigenes Netzwerk geeignet sind. Der 168.63.129.16 Nameserver ist nur innerhalb eines Azure VNet erreichbar. Wenn Ihr L4-Knoten lokal ist, finden Sie unter On-premises deployments eine Alternative mit Azure Privates DNS Resolver.

Ebene Purpose Beispiel hostname Beispiel-IP Hinweise
L2 OPC UA simulator, Azure IoT Einsatz (MQTT Broker, Dataflows), Azure Arc, CoreDNS p3tiny-01 172.22.232.X Arc-fähig, Azure IoT Einsatz bereitgestellt
L3 Azure IoT Einsatz (MQTT Broker, Dataflows), CoreDNS, Azure Arc p3tiny-02 172.22.232.Y Arc-fähig, Azure IoT Einsatz bereitgestellt
L4 Envoy Proxy (nur Ausgang, ausgehender Zugriff) p3tiny-03 172.22.232.Z Arc-fähig, verarbeitet den Ausgang durch den expliziten Azure Firewall-Proxy über ExpressRoute

Schritt 3: Erzwingen der Netzwerkisolation zwischen Ebenen

Verwenden Sie Firewalls oder Richtlinien auf Hostebene (z. B. UFW), um die Kommunikation nur mit angrenzenden Systemen durchzusetzen.

Kommunikationspfad Access
L2 ↔ L3 Zulassen
L3 ↔ L4 Zulassen
L2 ↔ L4 Blockieren
L2/L3 → Internet Blockieren
L4 → Azure Zulassen durch den expliziten Azure Firewall-Proxy über ExpressRoute

Beispiel für UFW-Regeln für den L2-Host (nur L3 zulassen, alles andere verweigern):

sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow from 172.22.232.Y  # Allow L3
sudo ufw allow to 172.22.232.Y    # Allow L3
sudo ufw deny from 172.22.232.Z   # Block L4
sudo ufw deny to 172.22.232.Z     # Block L4
sudo ufw enable

Wiederholen Sie diesen Vorgang mit den entsprechenden Regeln auf jedem Host. Weitere Optionen finden Sie in der UFW-Dokumentation .

Schritt 4: Nur Azure gebundenen Datenverkehr über L4 weiterleiten

Nur der Knoten der Ebene 4 initiiert ausgehenden Datenverkehr und leitet ihn an den Azure Firewall Explicit Proxy über ExpressRoute weiter, der ihn dann über Private Link an Azure Dienste weiterleitet.

  1. Stellen Sie den Envoy-Proxy auf dem L4-Computer bereit. Beispielkonfigurationen finden Sie unter Configure-Infrastruktur.

  2. Weiterleiten von HTTPS-Datenverkehr an den Azure Firewall Explicit Proxy:

    • IP: 10.254.0.68
    • Ports: 8080 (HTTP), 8443 (HTTPS)
  3. Stellen Sie sicher, dass L4 den Proxy erreichen kann:

    curl -v --proxy http://10.254.0.68:8443 https://management.azure.com
    

Hinweis

Diese Überprüfung hat HTTP(S)-Datenverkehr über den Proxy verwendet. Wenn Ihr Proxy MQTT oder andere Nicht-HTTP-Protokolle unterstützt, können diese auch in einer ähnlichen Konfiguration verwendet werden.

Vorbereiten von Kubernetes-Clustern

Stellen Sie einen K3s-Cluster auf jedem Computer auf den Ebenen 2, 3 und 4 bereit. Anweisungen finden Sie unter Vorbereiten Sie Ihren Azure Arc-fähigen Kubernetes-Cluster.

Überprüfen Sie nach der Installation, ob jeder Cluster bereit ist:

kubectl get nodes

Hinweis

Level 4 läuft nur mit Envoy Proxy und benötigt weder Azure IoT Einsatz noch Azure Arc. Eine leichte K3s-Installation reicht aus.

Konfigurieren Sie Azure Private Link, um sich sicher mit Event Grid, Azure Storage und Azure Key Vault zu verbinden, indem Sie Private Endpoints und CoreDNS-basierte Namensauflösung verwenden. Der gesamte Datenverkehr zu diesen Diensten bleibt auf privaten IPs ohne Internetexposition.

Schritt 1: Erstellen privater Endpunkte

Erstellen Sie einen privaten Endpunkt für den Event Grid-Namespace:

az network private-endpoint create \
  --name pe-eventgrid \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --subnet "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/$SUBNET_NAME" \
  --private-connection-resource-id "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.EventGrid/namespaces/$EVENT_GRID_NAMESPACE" \
  --group-id topicspace \
  --connection-name pe-conn-eventgrid

Erstellen Sie einen privaten Endpunkt für das Azure Storage Konto:

az network private-endpoint create \
  --name pe-storage-blob \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --subnet "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/$SUBNET_NAME" \
  --private-connection-resource-id "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT_NAME" \
  --group-id blob \
  --connection-name pe-conn-storage-blob

Create a private endpoint for the Azure Key Vault Instance:

az network private-endpoint create \
  --name pe-keyvault \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --subnet "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/$SUBNET_NAME" \
  --private-connection-resource-id "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$KEY_VAULT_NAME" \
  --group-id vault \
  --connection-name pe-conn-keyvault

Schritt 2: Erstellen Sie private DNS-Zonen

Erstellen Sie für jeden Dienst die entsprechende Azure Privates DNS Zone, und verknüpfen Sie ihn mit dem virtuellen Netzwerk der Ebene 4. CoreDNS bei L3 (und optional L2) leitet Anforderungen an den internen DNS-Resolver (168.63.129.16) von Azure weiter, wodurch Namen basierend auf der DNS-Zonenverbindung der L4-Zone aufgelöst werden.

Erstellen Sie die DNS-Zonen:

# Event Grid
az network private-dns zone create \
  --resource-group $RESOURCE_GROUP \
  --name privatelink.ts.eventgrid.azure.net

# Azure Blob Storage
az network private-dns zone create \
  --resource-group $RESOURCE_GROUP \
  --name privatelink.blob.core.windows.net

# Azure Key Vault
az network private-dns zone create \
  --resource-group $RESOURCE_GROUP \
  --name privatelink.vaultcore.azure.net

Verknüpfen Sie jede Zone mit dem virtuellen Netzwerk der Ebene 4:

az network private-dns link vnet create \
  --resource-group $RESOURCE_GROUP \
  --zone-name privatelink.ts.eventgrid.azure.net \
  --name link-eventgrid-l4 \
  --virtual-network "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME" \
  --registration-enabled false

az network private-dns link vnet create \
  --resource-group $RESOURCE_GROUP \
  --zone-name privatelink.blob.core.windows.net \
  --name link-storage-l4 \
  --virtual-network "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME" \
  --registration-enabled false

az network private-dns link vnet create \
  --resource-group $RESOURCE_GROUP \
  --zone-name privatelink.vaultcore.azure.net \
  --name link-keyvault-l4 \
  --virtual-network "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME" \
  --registration-enabled false

az network private-endpoint dns-zone-group create \
  --resource-group $RESOURCE_GROUP \
  --endpoint-name pe-eventgrid \
  --name eventgrid-zone-group \
  --private-dns-zone "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Network/privateDnsZones/privatelink.ts.eventgrid.azure.net" \
  --zone-name eventgrid

az network private-endpoint dns-zone-group create \
  --resource-group $RESOURCE_GROUP \
  --endpoint-name pe-storage-blob \
  --name storage-zone-group \
  --private-dns-zone "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net" \
  --zone-name blob

az network private-endpoint dns-zone-group create \
  --resource-group $RESOURCE_GROUP \
  --endpoint-name pe-keyvault \
  --name keyvault-zone-group \
  --private-dns-zone "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Network/privateDnsZones/privatelink.vaultcore.azure.net" \
  --zone-name keyvault

Die vollständige Liste der private DNS Zonennamen finden Sie unter Azure Privates DNS Zone values.

Schritt 3: Aktivieren der DNS-Auflösung für Azure Private Endpoint

Stellen Sie CoreDNS für L2 und L3 bereit, um private Azure Domänenabfragen an 168.63.129.16 weiterzuleiten, Azure internen DNS-Resolver für private Endpunktdomänen. Anweisungen zur Bereitstellung finden Sie unter Configure infrastructure.

Hinweis

168.63.129.16 ist der interne Drahtserver-DNS Azure und kann nur innerhalb eines Azure-VNet erreichbar sein. In diesem Labor ist L4 eine VM, die im VNet gehostet wird, sodass CoreDNS-Abfragen von L2/L3 über Envoy bei L3 und L4 weitergeleitet werden und letztendlich 168.63.129.16 über das L4 VNet erreichen.

Lokale Bereitstellungen

Wenn Ihr L4-Knoten lokal ist (nicht innerhalb eines Azure-VNet), ist 168.63.129.16 nicht erreichbar. Stellen Sie stattdessen einen Azure Privates DNS Resolver mit einem eingehenden Endpunkt im selben VNet bereit, in dem Ihre Privates DNS Zonen verknüpft sind:

  1. Erstellen Sie einen Privates DNS Resolver im VNet:

    az dns-resolver create \
      --name $DNS_RESOLVER_NAME \
      --resource-group $RESOURCE_GROUP \
      --location $LOCATION \
      --id "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME"
    
  2. Erstellen eines eingehenden Endpoints (dies ermöglicht eine private IP, die über ExpressRoute geroutet werden kann):

    az dns-resolver inbound-endpoint create \
      --name $DNS_RESOLVER_ENDPOINT_NAME \
      --dns-resolver-name $DNS_RESOLVER_NAME \
      --resource-group $RESOURCE_GROUP \
      --location $LOCATION \
      --ip-configurations "[{\"private-ip-allocation-method\":\"Dynamic\",\"id\":\"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$VNET_RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/$DNS_RESOLVER_SUBNET_NAME\"}]"
    
  3. Notieren Sie sich die private IP, die dem eingehenden Endpunkt zugewiesen ist (z. B 10.254.1.4. ). Verwenden Sie diese IP-Adresse anstelle von 168.63.129.16 in der CoreDNS-Konfiguration und im Netplan-Namensserver, wie unten angegeben.

Weitere Informationen finden Sie unter What is Azure DNS Private Resolver?.

CoreDNS ConfigMap

Erstellen Sie eine ConfigMap mit der CoreDNS Corefile.Create a ConfigMap with the CoreDNS Corefile. Ersetzen Sie 168.63.129.16 durch Ihre ip-Adresse des Privates DNS Resolver-Endpunkts, wenn Ihr L4-Knoten lokal ist:

kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  Corefile: |
    eventgrid.azure.net {
      forward . 168.63.129.16
    }
    blob.core.windows.net {
      forward . 168.63.129.16
    }
    vaultcore.azure.net {
      forward . 168.63.129.16
    }
    . {
      forward . /etc/resolv.conf
    }
EOF

Starten Sie CoreDNS neu, um die Änderungen zu übernehmen:

kubectl rollout restart deployment coredns -n kube-system

Hinweis

Diese Konfiguration stellt sicher, dass nur Event Grid, Speicher und Key Vault in private Endpunkt-IPs aufgelöst werden.

Schritt 4: Überprüfen der DNS-Auflösung und -Konnektivität

Bestätigen Sie ab L4 die DNS-Auflösung.

nslookup $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net
nslookup $STORAGE_ACCOUNT_NAME.blob.core.windows.net

Bestätigen Sie die Datenverkehrsflüsse über Envoy und Private Link, nicht über das öffentliche Internet:

curl -v https://$EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net

Überprüfen Sie Folgendes:

  • FQDNs werden in private IPs aufgelöst.
  • Datenverkehr fließt über Envoy und Private Link, nicht über öffentliche Endpunkte.

Hinweis

Azure Arc erfordert eine funktionierende DNS-Auflösung (über CoreDNS), um das Onboarding abzuschließen.

Arc-fähige Cluster mit einem Azure Arc-Gateway (optional)

Wenn DNS-Auflösung und private Konnektivität eingerichtet sind, aktivieren Sie die Arc-Unterstützung für Ihre Kubernetes-Cluster hinter dem expliziten Proxy. Dieser Schritt verbindet jeden Cluster mit Azure Arc und verknüpft ihn mit der in Schritt 1 erstellten Azure Arc-Gateway-Ressource.

Schritt 1: Festlegen von Proxyumgebungsvariablen

Auf der Azure Arc-Gateway-VM, die die Azure Arc-Dienste hostet, setzen Sie die Proxy-Umgebungsvariablen. Die HTTPS_PROXY Variable muss auf den expliziten Firewallproxy Ihres Netzwerks verweisen:

export HTTP_PROXY=http://$PROXY_SERVER:$PROXY_PORT
export HTTPS_PROXY=http://$PROXY_SERVER:$PROXY_PORT
export NO_PROXY=localhost,127.0.0.1,.svc,.local,$PRIVATE_DNS_ZONE

Schritt 2: Abrufen der Dienstprinzipalobjekt-ID

Der Parameter --custom-locations-oid benötigt die Objekt-ID (OID) des Azure Arc Custom Locations Service Principal.

So finden Sie sie im Azure-Portal:

  1. Wechseln Sie zu Microsoft Entra ID.
  2. Wählen Sie Unternehmensanwendungen aus.
  3. Suchen Sie nach Azure Arc Kubernetes Custom Locations.
  4. Öffnen Sie die Anwendung, wechseln Sie zu "Eigenschaften", und kopieren Sie die Objekt-ID.

Schritt 3: Verbinden Sie den Cluster mit dem Azure Arc-Gateway

Verbinden Sie den Cluster hinter dem Proxy und verknüpfen Sie ihn mit dem Azure Arc-Gateway:

az connectedk8s connect \
  --name $CLUSTER_NAME \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --custom-locations-oid $CUSTOM_LOCATIONS_OID \
  --enable-oidc-issuer \
  --enable-workload-identity \
  --disable-auto-upgrade \
  --proxy-https $HTTPS_PROXY \
  --proxy-http $HTTP_PROXY \
  --proxy-skip-range $NO_PROXY \
  --gateway-resource-id $ARC_GATEWAY_RESOURCE_ID

Hinweis

Lass es --gateway-resource-id weg, wenn du kein Azure Arc-Gateway verwendest (zum Beispiel wenn du ExpressRoute nur mit privaten Endpunkten verwendest).

Schritt 4: Verifiziere die Azure Arc-Konnektivität

  1. Führe es auf dem Azure Arc Gateway-Pod aus, kubectl logs um zu bestätigen, dass es Azure erreicht.
  2. Überprüfen Sie, ob die DNS-Auflösung und der TLS-Handshake über den Proxy erfolgreich sind.

Bereitstellen von Azure IoT Einsatz

Stellen Sie mit Arc-fähigen Clustern in L2 und L3 Azure IoT Einsatz auf jeder Ebene bereit. Dadurch wird die vom System zugewiesene verwaltete Identität erstellt, die für RBAC-Zuordnungen im nächsten Abschnitt erforderlich ist.

Von Bedeutung

Verwenden Sie das --skip-ra-Flag beim Erstellen der Schema-Registry. Dadurch wird verhindert, dass die CLI versucht, Rollenzuweisungen durchzuführen, die Eigentümer-Rechte erfordern. Details finden Sie unter "Bekannte Einschränkungen ".

Wechseln Sie für jeden arcfähigen Cluster (L2 und L3) zum Clusterkontext, und führen Sie die Schritte in Deploy Azure IoT Einsatz aus:

# For Level 2
kubectl config use-context $L2_CLUSTER_NAME
# Follow deploy instructions, then repeat for Level 3
kubectl config use-context $L3_CLUSTER_NAME

Überprüfen Sie nach jeder Bereitstellung, ob alle Pods laufen.

kubectl get pods -n azure-iot-operations

Hinweis

Ebene 4 führt nicht Azure IoT Einsatz aus. Nur Envoy-Proxy wird auf dieser Ebene bereitgestellt.

RBAC-Rollen zuweisen

Azure IoT Einsatz erfordert bestimmte rollenbasierte Zugriffssteuerungszuweisungen (RBAC), damit Komponenten mit Azure Diensten wie Blob Storage und Ereignisraster interagieren können.

Hinweis

Diese Berechtigungen wurden von Administratoren mit erhöhten Berechtigungen manuell im Labor zugewiesen. Verwenden Sie für den Produktivbetrieb die Azure Policy-Automatisierung.

Erforderliche Rollenzuweisungen

Weisen Sie diese Rollen der systemzugewiesenen verwalteten Identität von Azure IoT Einsatz auf jedem Arc-fähigen Cluster (L2 und L3) zu. In diesem validierten Szenario ist L4 ein reines Envoy-Pass-Through und hat keine verwaltete Identität.

Identität Rolle Geltungsbereich Hinweise
L2/L3 Azure IoT Einsatz – systemseitig zugewiesene verwaltete Identität Storage Blob-Mitwirkender Speicherkonto mit Schemadateien Für die Schemaregistrierung
L3 Azure IoT Einsatz – systemseitig zugewiesene verwaltete Identität EventGrid TopicSpaces-Herausgeber Event Grid-Namespace L3 veröffentlicht auf Event Grid über L4 Envoy-Passthrough
L3 Azure IoT Einsatz – systemseitig zugewiesene verwaltete Identität EventGrid-TopicSpaces-Abonnent Event Grid-Namespace L3 abonniert Event Grid über L4 Envoy Pass-Through

Weisen Sie jede Rolle mithilfe von Azure CLI zu:

# Storage Blob Contributor (for Schema Registry)
az role assignment create \
  --assignee $IDENTITY_CLIENT_ID \
  --role "Storage Blob Contributor" \
  --scope $STORAGE_ACCOUNT_RESOURCE_ID

# Event Grid Publisher
az role assignment create \
  --assignee $IDENTITY_CLIENT_ID \
  --role "EventGrid TopicSpaces Publisher" \
  --scope $EVENT_GRID_NAMESPACE_RESOURCE_ID

# Event Grid Subscriber
az role assignment create \
  --assignee $IDENTITY_CLIENT_ID \
  --role "EventGrid TopicSpaces Subscriber" \
  --scope $EVENT_GRID_NAMESPACE_RESOURCE_ID

Mehrschichtiger Anreicherungskontext

Jede Azure IoT Einsatz Netzwerkschicht trägt Geschäftsmetadaten zur ausgehenden Telemetrie bei:

Ebene Fügt metadatenfeld hinzu
L2 product
L3 line-config, factory-code

In diesem validierten Szenario fügt der Dataflow von L3 sowohl line-config als auch factory-code hinzu, bevor er über L4 Envoy weitergeleitet wird. Diese mehrschichtige Anreicherung ermöglicht nachgeschalteten Systemen, den Fertigungskontext zu verstehen, ohne Edgegeräte mit vollständigen Metadaten zu belasten.

Hinweis

In Bereitstellungen, in denen L4 auch Azure IoT Einsatz ausführt (mit eigener verwalteter Identität Arc-fähig), können die Rollen factory-code-Anreicherung und Event Grid RBAC stattdessen auf L4 zugewiesen werden.

Überprüfen des Telemetrieflusses

Vergewissern Sie sich vor der Überprüfung des End-to-End-Flusses, dass jede Komponente auf der richtigen Ebene ausgeführt wird.

Schritt 1: Überprüfen der Komponentenbereitschaft

CoreDNS (L2, L3): Vergewissern Sie sich, dass CoreDNS-Pods ausgeführt werden und die DNS-Auflösung funktioniert:

kubectl get pods -n kube-system -l k8s-app=kube-dns
dig $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net

Envoy Proxy (L3, L4): Überprüfen Sie, ob Pods ausgeführt werden:

kubectl config use-context $L3_CLUSTER_NAME
kubectl get pods -l app=$ENVOY_POD_LABEL

Azure IoT Einsatz MQTT Broker (L2, L3): Überprüfen, ob Listener aktiv sind:

kubectl get service $K3S_SERVICE_NAME -n azure-iot-operations

Schritt 2: Überprüfen des Verbindungspfads

Der End-to-End-Telemetriefluss folgt diesem Pfad:

  1. Telemetrieerfassung (L2): OPC UA-Konnektoren auf L2 veröffentlichen Telemetriedaten an Azure IoT Einsatz-Dataflows, die sie an den MQTT-Broker weiterleiten.
  2. L2 bis L3: MQTT Broker bei L2 veröffentlicht Nachrichten an L3 mithilfe von MQTT.
  3. L3 bis L4: MQTT Broker bei L3 veröffentlicht Nachrichten upstream mit MQTT über WebSocket.
  4. DNS-Auflösung (L3): Azure IoT Einsatz Dataflows und CoreDNS bei L3 auflösen private Dienstnamen, um L4 zu erreichen.
  5. Proxyweiterleitung (L3 bis L4): Envoy Proxy on L3 leitet MQTT-Datenverkehr an Envoy Proxy auf L4 weiter.
  6. Egress (L4): Envoy Proxy on L4 sendet Datenverkehr an den Azure Firewall Explicit Proxy auf Port 8443 über ExpressRoute.
  7. Private routing: Der Proxy leitet Anforderungen an Azure Dienste über private Endpunkte weiter.
  8. Cloud integration: Services wie Event Grid themenräume, Azure Storage und Azure Key Vault werden privat über Azure Private Link aufgerufen. Der Zugriff auf öffentliche Netzwerke ist für alle Azure Dienste in der Bereitstellung deaktiviert.

Themenbereiche von Event Grid

Daten werden über MQTT mithilfe von WebSocket (/mqtt Pfadsuffix) im Event Grid veröffentlicht. Der Azure IoT Einsatz Dataflow von L3 authentifiziert sich mit seiner vom System zugewiesenen verwalteten Identität (die über EventGrid TopicSpaces Publisher- und Abonnentenrollen verfügt) und sendet Datenverkehr über den Envoy-Proxy auf L3, der an den Envoy-Proxy auf L4 weiterleitet. Ausgehender Datenverkehr von Ebene 4 wird über den Azure Firewall Explicit Proxy (Port 8443) weitergeleitet, der dann über ExpressRoute an den privaten Event Grid-Endpunkt weitergeleitet wird. Level 4 fungiert als ein reines Pass-Through und authentifiziert nicht.

Telemetrie wird anhand von Schemas überprüft, die in Blob Storage definiert sind und durch die Azure IoT Einsatz-Datenflüsse, die auf L2 und L3 laufen, durchgesetzt werden.

Beispielausgabe

{
  "Temperature": {
    "Value": 98.2,
    "SourceTimestamp": "2025-08-05T13:45:22Z"
  },
  "EnergyUse": {
    "Value": 212,
    "SourceTimestamp": "2025-08-05T13:45:22Z"
  },
  "Weight": {
    "Value": 229,
    "SourceTimestamp": "2025-08-05T13:45:22Z"
  },
  "product": "flakes",
  "line-config": "cereal",
  "factory-code": "1032"
}

Audit und Überprüfung nach der Bereitstellung

Von Bedeutung

Dieser Abschnitt enthält empfohlene Überwachungsverfahren. Lassen Sie Ihr Netzwerk- und Sicherheitsteam diese Schritte überprüfen, bevor Sie sie in der Produktion verwenden.

Überprüfen Sie nach der Bereitstellung, ob Netzwerkisolation, private Konnektivität und RBAC-Zuordnungen ordnungsgemäß konfiguriert sind.

Schritt 1: Überprüfen der Netzwerkisolation zwischen Ebenen

Stellen Sie sicher, dass keine Datenlecks zwischen nicht benachbarten Schichten auftreten (z. B. sollte L2 nicht direkt L4 erreichen).

  1. Versuchen Sie von einem L2-Host, die L4-Host-IP direkt zu erreichen. Die Verbindung sollte eine Zeitüberschreitung verursachen oder abgelehnt werden:

    curl -v --connect-timeout 5 https://$L4_HOST_IP:8443
    
  2. Bestätigen Sie von einem L2-Host, dass die Verbindung mit L3 funktioniert:

    curl -v --connect-timeout 5 https://$L3_HOST_IP:$L3_PROXY_PORT
    
  3. Überprüfen Sie Firewallprotokolle, um keinen unerwarteten layerübergreifenden Datenverkehr zu bestätigen.

Schritt 2: Bestätigen von Datenverkehrsrouten über private Endpunkte

Überprüfen Sie, ob der gesamte an Azure gebundene Datenverkehr über private Endpunkte und nicht das öffentliche Internet geleitet wird.

  1. Lösen Sie von L4 Azure Dienst-FQDNs auf, und bestätigen Sie, dass sie private IPs zurückgeben:

     nslookup $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net
     nslookup $STORAGE_ACCOUNT_NAME.blob.core.windows.net
     nslookup $KEY_VAULT_NAME.vault.azure.net
    

    Jedes Ergebnis sollte eine IP in Ihrem privaten Adressbereich zurückgeben (z. B. 10.254.x.x), keine öffentliche IP.

  2. Überprüfen Sie das Azure Portal für jeden privaten Endpunkt, um zu bestätigen, dass der Verbindungsstatus Approved angezeigt wird.

  3. Überprüfen Sie in den Azure Firewall-Protokollen, ob ausgehender Datenverkehr von L4 nur an private Endpunkt-IPs weitergeleitet wird.

Schritt 3: RBAC-Zuweisungen validieren

Vergewissern Sie sich, dass die erforderlichen Rollenzuweisungen vorhanden sind:

# Check Storage Blob Contributor
az role assignment list \
  --scope $STORAGE_ACCOUNT_RESOURCE_ID \
  --role "Storage Blob Contributor" \
  --output table

# Check Event Grid Publisher
az role assignment list \
  --scope $EVENT_GRID_NAMESPACE_RESOURCE_ID \
  --role "EventGrid TopicSpaces Publisher" \
  --output table

# Check Event Grid Subscriber
az role assignment list \
  --scope $EVENT_GRID_NAMESPACE_RESOURCE_ID \
  --role "EventGrid TopicSpaces Subscriber" \
  --output table

Stellen Sie sicher, dass die systemseitig zugewiesene verwaltete Identität von Azure IoT Einsatz als Zuweisungsberechtigter für jede Rolle aufgeführt ist.

Schritt 4: Stellen Sie sicher, dass sich die DNS nur auf private IP-Adressen auflöst.

Stellen Sie sicher, dass in jeder Ebene mit CoreDNS-Implementierung Azure-Dienstnamen auf private IPs aufgelöst werden.

# From L2
dig $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net
dig $STORAGE_ACCOUNT_NAME.blob.core.windows.net

# From L3
dig $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net
dig $STORAGE_ACCOUNT_NAME.blob.core.windows.net

Wenn eine Abfrage eine öffentliche IP zurückgibt, überprüfen Sie Ihre CoreDNS-Weiterleitungsregeln und Privates DNS Zonenverbindung.

Bekannte Einschränkungen

Allgemeine Einschränkungen im Zusammenhang mit der Plattformüberprüfung, der Proxyunterstützung und der Schemaregistrierung finden Sie unter Known-Einschränkungen bei der Bereitstellung von Azure IoT Einsatz mit privater Konnektivität.

Die folgenden Einschränkungen gelten speziell für das Mehrschicht-Netzwerklernprogramm:

  • Ebene 1: Die L1-Geräteebene wird in diesem Bereitstellungsfluss nicht verwendet.
  • Stufe 4 Arc: Stufe 4 unterstützt Arc nicht; nur „Envoy Proxy“ wird auf dieser Ebene implementiert.
  • Sovereign clouds: Dieses Szenario wurde nur in Azure öffentlichen Cloud überprüft. Souveräne Cloudumgebungen (z. B. Azure Government, Azure betrieben von 21Vianet) verwenden unterschiedliche Endpunkte und Privates DNS Zonennamen und wurden nicht überprüft.
  • Out-of-scope configurations: Szenarien, die Azure VNets mit externen Firewalls, transparenten Proxys oder reinen Cloud-VNet-Bereitstellungen umfassen, wurden nicht überprüft und liegen außerhalb des Supportumfangs.

Anhang

Referenz für Schlüsselressourcen in Azure

Subscription: <subscription-id>
Tenant: <tenant-id>

Azure Arc clusters:
- Level2: <L2-cluster-name>
- Level3: <L3-cluster-name>

Storage Containers (schemas):
- L2: <L2-schema-container-name>
- L3: <L3-schema-container-name>

Event Grid Namespace: <eventgrid-namespace-name>
Private Endpoint (Event Grid Topic Spaces): <pe-eventgrid-name> (IP: <private-ip-eventgrid>)

Schema Registries:
- L2: <L2-schema-registry-name>
- L3: <L3-schema-registry-name>

Azure IoT Operations Instances:
- L2: <L2-instance-name>
- L3: <L3-instance-name>

Benutzerdefinierte Rollendefinitionen

ACX–Secrets Store Extension Owner: Gewährt Berechtigungen zum Registrieren und Verwalten des Secrets Store CSI-Treibers, zur Konfiguration der Azure Key Vault geheimen Anbieterklassen und zum Verwalten von vom Benutzer zugewiesenen verwalteten Identitäten.

{
  "roleName": "ACX-Secrets Store Extension Owner",
  "assignableScopes": ["/subscriptions/<subscription-id>"],
  "permissions": [
    {
      "actions": [
        "Microsoft.SecretSyncController/register/action",
        "Microsoft.SecretSyncController/unregister/action",
        "Microsoft.SecretSyncController/azureKeyVaultSecretProviderClasses/read",
        "Microsoft.SecretSyncController/azureKeyVaultSecretProviderClasses/write",
        "Microsoft.SecretSyncController/azureKeyVaultSecretProviderClasses/delete",
        "Microsoft.Insights/alertRules/*",
        "Microsoft.Resources/deployments/*",
        "Microsoft.ManagedIdentity/userAssignedIdentities/assign/action",
        "Microsoft.ManagedIdentity/userAssignedIdentities/write",
        "Microsoft.ManagedIdentity/userAssignedIdentities/revokeTokens/action"
      ]
    }
  ]
}

AdaptiveCloud_AIO–Mitwirkende: Gewährt Berechtigungen zum Verwalten von Rollenzuweisungen und Verbundidentitätsanmeldeinformationen für vom Benutzer zugewiesene verwaltete Identitäten innerhalb der Ressourcengruppe.

{
  "roleName": "AdaptiveCloud_AIO-Contributors",
  "assignableScopes": ["/subscriptions/<subscription-id>/resourceGroups/<resource-group>"],
  "permissions": [
    {
      "actions": [
        "Microsoft.Authorization/roleAssignments/read",
        "Microsoft.Authorization/roleAssignments/write",
        "Microsoft.Authorization/roleAssignments/delete",
        "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/read",
        "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/write"
      ]
    }
  ]
}

Hinweis

In Umgebungen, die Azure Policy Automatisierung verwenden, sind diese manuellen Rollendefinitionen für OT-Teams möglicherweise nicht erforderlich. Richtlinien können vorab nach Bedarf die Rollen „Mitwirkender“ oder „Mitwirkender an Storage-Blobdaten“ zuweisen.