Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa esercitazione descrive come distribuire Operazioni di Azure IoT in una topologia di rete fisicamente a più livelli con routing proxy esplicito e connettività privata ai servizi di Azure tramite ExpressRoute. Questa distribuzione usa collegamento privato per raggiungere servizi come Event Grid e non espone endpoint pubblici a nessun livello della rete.
Questo scenario è stato convalidato usando computer fisici in una rete segmentata Purdue/ISA-95 che si estende su livelli da 2 a 4. Il proxy esplicito Firewall di Azure viene distribuito in una rete virtuale Azure, con connettività fornita tramite ExpressRoute.
In questo articolo si apprenderà come:
- Crea risorse Azure e prepara un ambiente di rete multilivello
- Preparare i cluster Kubernetes a ogni livello di rete
- Configurare endpoint privati e DNS per i servizi di Azure
- Cluster abilitati ad Arc con gateway Azure Arc e routing proxy esplicito
- Distribuire Operazioni di Azure IoT nei cluster con abilitazione di Arc
- Assegnare i ruoli RBAC richiesti dai componenti di Operazioni di Azure IoT
- Convalidare il flusso di telemetria end-to-end dalle origini OPC UA alla Griglia di eventi di Azure
- Controllare e verificare l'isolamento della rete, la connettività privata e le assegnazioni RBAC (Controllo degli Accessi in Base al Ruolo)
Prerequisiti
- Sottoscrizione Azure. Se non se ne ha una, creare un account gratuito prima di iniziare.
- ID del tenant.
- Autorizzazioni sufficienti per creare endpoint privati, zone DNS privato e assegnazioni di ruolo (in genere Owner o Contributor + Amministratore accesso utente). Questa esercitazione usa ruoli personalizzati definiti nell'Appendice.
- Un cluster Kubernetes distribuito a ogni livello di rete (livello 2, livello 3 e livello 4), con dispositivi o macchine virtuali assegnati indirizzi IP statici.
- Segmentazione di rete esistente tra livelli (ad esempio, firewall che consentono solo la comunicazione L2 ↔ L3 ↔ L4) con risoluzione DNS tra livelli tramite CoreDNS.
- Azure Private Endpoints per Event Grid, Storage (per Schema Registry) e Key Vault, con indirizzi IP privati assegnati e accessibili tramite ExpressRoute o un routing privato equivalente.
- Proxy esplicito di Firewall di Azure al livello 4 (porte 8080/8443), raggiungibile tramite ExpressRoute da questo livello. Tutto il traffico HTTP/HTTPS in uscita dal livello 4 passa attraverso questo proxy.
- interfaccia della riga di comando di Azure, kubectl e Docker installati nel computer usato per distribuire le risorse e gestire i cluster Kubernetes.
- (Facoltativo) Familiarità con il modello Purdue, che definisce i livelli dei sistemi di controllo industriale e viene comunemente usato negli ambienti di produzione.
Annotazioni
Nel flusso di telemetria convalidato viene usato solo HTTPS (porta 8443). Negli ambienti dei clienti, il livello 4 potrebbe invece instradare tramite il proxy aziendale della tua organizzazione.
Gli esempi interfaccia della riga di comando di Azure in questo articolo usano variabili di ambiente così puoi impostare ogni valore una volta e poi copiare e incollare i comandi as-is. Se stai usando l'ambiente Operazioni di Azure IoT Codespaces dal quickstart, queste variabili sono già impostate per te e puoi saltare questo passaggio. Altrimenti, imposta le seguenti variabili di ambiente nella tua shell prima di eseguire i comandi.
I seguenti script impostano le variabili di ambiente più comunemente utilizzate:
| Variabile di ambiente | Descrizione |
|---|---|
SUBSCRIPTION_ID |
L'ID dell'abbonamento che contiene la tua istanza Operazioni di Azure IoT. |
RESOURCE_GROUP |
Il nome del gruppo di risorse che contiene la tua istanza Operazioni di Azure IoT. |
AIO_INSTANCE_NAME |
Il nome della tua istanza Operazioni di Azure IoT. Per elencare le tue istanze, esegui az iot ops list -o table. |
CLUSTER_NAME |
Il nome del cluster Kubernetes abilitato Azure Arc che ospita la tua istanza. |
LOCATION |
La regione Azure da utilizzare per nuove risorse, ad esempio eastus. |
SUBSCRIPTION_ID=<subscription-id>
RESOURCE_GROUP=<resource-group-name>
AIO_INSTANCE_NAME=<instance-name>
CLUSTER_NAME=<cluster-name>
LOCATION=<region>
Devi solo impostare le variabili utilizzate in questo articolo. Questo articolo potrebbe utilizzare variabili ambientali aggiuntive per i nomi delle risorse che scegli. L'articolo spiega come posizionarli dove vengono introdotti.
Questo tutorial utilizza anche variabili di ambiente per le risorse di rete e Azure che scegli, inclusi VNET_RESOURCE_GROUP, VNET_NAME, SUBNET_NAME, EVENT_GRID_NAMESPACESTORAGE_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_PORTe . Imposta ognuno prima di eseguire i comandi correlati.
Riepilogo dell'architettura
Questa distribuzione è allineata al modello Purdue, implementando un'architettura segmentata fisicamente multilivello che si estende sui livelli da 2 a 4.
Ogni livello è separato da firewall di rete che limitano la comunicazione ai livelli adiacenti (ad esempio, L2 ↔ L3 ↔ L4), garantendo una segmentazione stretta. Il traffico in uscita verso Azure viene instradato tramite un proxy esplicito e collegamento privato (opzionalmente tramite un gateway Azure Arc), assicurando che nessun endpoint esposto a internet venga utilizzato in nessun livello.
Componenti convalidati
| Livello | Components | Scopo |
|---|---|---|
| L2 | CoreDNS, Flussi di dati per Operazioni di Azure IoT, Broker MQTT per Operazioni di Azure IoT | Inserisce i dati di telemetria dalle origini OPC UA, applica l'arricchimento iniziale e inoltra i dati verso l'alto |
| L3 | CoreDNS, Envoy Proxy, Flussi di dati per Operazioni di Azure IoT, Broker MQTT per Operazioni di Azure IoT | Aggrega e trasforma i dati, risolve il DNS per raggiungere L4 e inoltra in modo sicuro i dati di telemetria |
| L4 | Delega Inviato | Inoltra i dati di telemetria arricchiti a Griglia di eventi tramite Proxy esplicito del Firewall di Azure e endpoint privato tramite ExpressRoute |
Annotazioni
Questa esercitazione usa una topologia di livello 4 solo in uscita: L4 esegue solo un proxy Envoy, non è abilitato per Arc e inoltra il traffico anziché terminarlo. L'istanza più avanzata di Operazioni di Azure IoT si trova a L3, e il suo flusso di dati invia telemetria al cloud tramite il proxy L4 Envoy. Questa architettura è valida. Il networking stratificato per Operazioni di Azure IoT descrive l'architettura generale, dove Operazioni di Azure IoT (inclusi un broker MQTT e un flusso di dati) può anch'esso eseguire in L4 e terminare la telemetria lì. Scegli l'architettura che si adatta al tuo ambiente.
Preparare l'ambiente di rete a più livelli
Ogni livello della rete (livello 2, 3 e 4) usa indirizzi IP statici e regole firewall rigorose per applicare l'isolamento. Ogni livello comunica solo con il livello adiacente ,ad esempio L2 ↔ L3 ↔ L4, implementando le zone del modello Purdue.
Passaggio 1: Creare risorse Azure
Prima di eseguire la distribuzione nella rete perimetrale, creare le risorse di Azure seguenti:
- Gruppi di risorse
- account di archiviazione BLOB di Azure con contenitori per gli schemi
- Azure Key Vault
- Spazio di nomi e spazio tematico della Griglia Eventi
- Azure Arc gateway resource
Dopo aver creato queste risorse, disabilitare l'accesso alla rete pubblica su Key Vault, sull'account di archiviazione e sullo spazio dei nomi di Event Grid.
Importante
Il Registro schemi presenta una limitazione nota con la disabilitazione dell'accesso pubblico in fase di creazione. Per informazioni dettagliate, vedere Limitazioni note .
Passaggio 2: Assegnare indirizzi IP statici per ogni livello
Distribuire una macchina (fisica o virtuale) per ogni livello di rete, con i requisiti seguenti:
- Assegnare indirizzi IP statici all'interno di uno spazio indirizzi condiviso.
- Tutti i dispositivi eseguono Ubuntu Server 24.04.
- I dispositivi in L2 e L3 sono abilitati per Arc e ospitano le rispettive istanze Operazioni di Azure IoT.
Configurare indirizzi IP statici usando Netplan. Ad esempio, modificare /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
Applicare la configurazione:
sudo netplan apply
Annotazioni
Gli indirizzi IP illustrati di seguito sono esempi del lab di convalida e non sono accessibili tramite Internet. Sostituire con gli indirizzi IP appropriati per la propria rete. Il server nameserver 168.63.129.16 è raggiungibile solo dall'interno di una rete virtuale Azure. Se il nodo L4 è locale, vedere Distribuzioni locali per un'alternativa usando Azure DNS privato Resolver.
| Livello | Scopo | Nome host di esempio | IP di esempio | Note |
|---|---|---|---|---|
| L2 | OPC UA simulator, Operazioni di Azure IoT (MQTT Broker, Dataflows), Azure Arc, CoreDNS | p3tiny-01 | 172.22.232.X | Abilitata per Arc, Operazioni di Azure IoT distribuita |
| L3 | Operazioni di Azure IoT (MQTT Broker, Dataflows), CoreDNS, Azure Arc | p3tiny-02 | 172.22.232.Y | Abilitata per Arc, Operazioni di Azure IoT distribuita |
| L4 | Envoy Proxy (solo in uscita, accesso esterno) | p3tiny-03 | 172.22.232.Z | Non abilitato per Arc, gestisce l'uscita tramite proxy esplicito di Firewall di Azure su ExpressRoute |
Passaggio 3: Applicare l'isolamento di rete tra i livelli
Usare firewall o criteri a livello di host (ad esempio UFW) per permettere la comunicazione esclusivamente adiacente.
| Percorso di comunicazione | Access |
|---|---|
| L2 ↔ L3 | Permetti |
| L3 ↔ L4 | Permetti |
| L2 ↔ L4 | Blocco |
| L2/L3 → Internet | Blocco |
| L4 → Azure | Consentire attraverso Firewall di Azure il proxy esplicito su ExpressRoute |
Regole UFW di esempio per l'host L2 (consenti solo L3, nega tutto il resto):
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
Ripetere per ogni host utilizzando le regole appropriate. Per altre opzioni, vedere la documentazione di UFW .
Passaggio 4: Instradare solo il traffico associato a Azure attraverso L4
Solo il nodo di livello 4 potrebbe avviare il traffico in uscita, inoltrandolo al proxy esplicito Firewall di Azure tramite ExpressRoute, che lo instrada ai servizi di Azure tramite collegamento privato.
Distribuire Envoy Proxy nel computer L4. Per le configurazioni di esempio, vedere Configurare l'infrastruttura.
Inoltrare il traffico HTTPS al proxy esplicito Firewall di Azure:
- IP:
10.254.0.68 - Porte:
8080(HTTP),8443(HTTPS)
- IP:
Verificare che L4 possa raggiungere il proxy:
curl -v --proxy http://10.254.0.68:8443 https://management.azure.com
Annotazioni
Questa convalida usava il traffico HTTP(S) tramite il proxy. Se il proxy supporta MQTT o altri protocolli non HTTP, questi possono essere usati anche in una configurazione simile.
Preparare i cluster Kubernetes
Distribuire un cluster K3s in ogni computer a livello 2, 3 e 4. Per istruzioni, vedere Prepare il cluster Kubernetes abilitato per Azure Arc.
Dopo l'installazione, verificare che ogni cluster sia pronto:
kubectl get nodes
Annotazioni
Il livello 4 usa solo Envoy Proxy e non richiede Operazioni di Azure IoT o Azure Arc. Un'installazione leggera di K3s è sufficiente.
Configurare collegamento privato e DNS
Configura collegamento privato di Azure per connettersi in modo sicuro a Event Grid, Archiviazione di Azure e Azure Key Vault utilizzando Private Endpoints e risoluzione dei nomi basata su CoreDNS. Tutto il traffico verso questi servizi rimane su INDIRIZZI IP privati, senza esposizione a Internet.
Passaggio 1: Creare endpoint privati
Creare un endpoint privato per l'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
Creare un endpoint privato per l'account Archiviazione di Azure:
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
Crea un endpoint privato per l'istanza di Azure Key Vault:
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
Passo 2: Creare zone DNS private
Per ogni servizio, creare la zona di Azure DNS privato appropriata e collegarla alla rete virtuale di livello 4. CoreDNS in L3 (e facoltativamente L2) inoltra le richieste al resolver DNS interno di Azure (168.63.129.16), che risolve i nomi in base al collegamento di zona DNS della zona L4.
Creare le zone DNS:
# 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
Collegare ogni zona alla rete virtuale di livello 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
Per l'elenco completo dei nomi delle zone DNS private, vedere Valori delle zone DNS private di Azure.
Passaggio 3: Abilitare la risoluzione DNS per gli Endpoint Privati di Azure
Distribuisci CoreDNS su L2 e L3 per inoltrare le query di dominio private di Azure a 168.63.129.16, il resolver DNS interno di Azure per i domini del Private Endpoint. Per istruzioni sulla distribuzione, vedere Configurare l'infrastruttura.
Annotazioni
168.63.129.16 è il DNS del server interno di Azure ed è raggiungibile solo dall'interno di una rete virtuale di Azure. In questo lab, L4 è una macchina virtuale ospitata dalla rete virtuale, quindi le query CoreDNS da L2/L3 vengono inoltrate tramite Envoy a L3 e L4, raggiungendo infine 168.63.129.16 la rete virtuale L4.
Distribuzioni locali
Se il nodo L4 è locale (non all'interno di una rete virtuale Azure), 168.63.129.16 non è raggiungibile. Distribuire invece un Azure DNS privato Resolver con un endpoint in ingresso nella stessa rete virtuale in cui sono collegate le zone DNS privato:
Creare un sistema di risoluzione DNS privato nella rete virtuale:
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"Creare un endpoint in ingresso (ottiene un indirizzo IP privato instradabile tramite ExpressRoute):
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\"}]"Si noti l'INDIRIZZO IP privato assegnato all'endpoint in ingresso , ad esempio
10.254.1.4. Utilizzare questo indirizzo IP al posto di168.63.129.16nella configurazione di CoreDNS e nel nameserver di Netplan di seguito.
Per ulteriori informazioni, vedere Cos'è DNS di Azure Private Resolver?.
CoreDNS ConfigMap
Creare un oggetto ConfigMap con il Corefile di CoreDNS. Sostituire 168.63.129.16 con l'ip dell'endpoint in ingresso del sistema di risoluzione DNS privato se il nodo L4 è locale:
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
Riavviare CoreDNS per selezionare le modifiche:
kubectl rollout restart deployment coredns -n kube-system
Annotazioni
Questa configurazione garantisce che Griglia di eventi, Archiviazione e Insieme delle credenziali di chiavi risolvano solo in indirizzi IP dell'endpoint privato.
Passaggio 4: Verificare la risoluzione e la connettività DNS
Da L4 confermare la risoluzione DNS:
nslookup $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net
nslookup $STORAGE_ACCOUNT_NAME.blob.core.windows.net
Verificare che il traffico passi attraverso Envoy e collegamento privato, non la rete Internet pubblica:
curl -v https://$EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net
Verifica che:
- I FQDN (nomi di dominio completi) vengono risolti in indirizzi IP privati.
- Il traffico passa attraverso Envoy e collegamento privato, non gli endpoint pubblici.
Annotazioni
Azure Arc richiede una risoluzione DNS funzionante (tramite CoreDNS) per completare l'onboarding.
Cluster abilitabili per Arc con gateway Azure Arc (opzionale)
Con la risoluzione DNS e la connettività privata implementata, abilita Arc per i cluster Kubernetes utilizzando il proxy esplicito. Questo passaggio collega ogni cluster ad Azure Arc e lo associa alla risorsa gateway Azure Arc creata nello Step 1.
Passaggio 1: Impostare le variabili di ambiente proxy
Sulla VM gateway Azure Arc che ospita i servizi Azure Arc, imposta le variabili dell'ambiente proxy. La HTTPS_PROXY variabile deve puntare al proxy esplicito del firewall della rete:
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
Passaggio 2: recuperare l'ID oggetto dell'entità di servizio
Il parametro --custom-locations-oid richiede l'Object ID (OID) del principale del servizio Azure Arc custom locations.
Per trovarla nel portale di Azure:
- Andare a Microsoft Entra ID.
- Selezionare Applicazioni aziendali.
- Cercare Percorsi personalizzati su Kubernetes con Azure Arc.
- Aprire l'applicazione, passare a Proprietà e copiare l'ID oggetto.
Passo 3: Collega il cluster con il gateway Azure Arc
Collega il cluster dietro il proxy e associalo al gateway Azure Arc:
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
Annotazioni
Ometti --gateway-resource-id se non usi un gateway Azure Arc (ad esempio, se usi ExpressRoute solo con endpoint privati).
Passo 4: Verifica la connettività di Azure Arc
- Esegui
kubectl logssul pod gateway di Azure Arc per confermare che raggiunge Azure. - Verificare che la risoluzione del DNS e l'handshake del TLS siano avvenuti correttamente tramite il proxy.
Distribuire Operazioni di Azure IoT
Con i cluster abilitati per Arc in L2 e L3, distribuire Operazioni di Azure IoT su ogni livello. In questo modo viene creata l'identità gestita assegnata dal sistema necessaria per le assegnazioni di controllo degli accessi in base al ruolo nella sezione successiva.
Importante
Usare il --skip-ra flag durante la creazione del Registro schemi. Ciò impedisce all'interfaccia della riga di comando di tentare assegnazioni di ruolo che richiedono diritti di proprietario. Per informazioni dettagliate, vedere Limitazioni note .
Per ogni cluster abilitato per Arc (L2 e L3), passare al contesto del cluster e seguire i passaggi descritti in Deploy Operazioni di Azure IoT:
# 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
Dopo ogni deployment, verificare che tutti i pod siano attivi:
kubectl get pods -n azure-iot-operations
Annotazioni
Il livello 4 non esegue Operazioni di Azure IoT. Solo il proxy Envoy viene distribuito a questo livello.
Assegna ruoli RBAC
Operazioni di Azure IoT richiede assegnazioni di controllo degli accessi in base al ruolo specifiche per consentire ai componenti di interagire con i servizi Azure come gestione rete virtuale di Azure e Griglia di eventi.
Annotazioni
Queste autorizzazioni sono state assegnate manualmente nel lab dagli amministratori con privilegi elevati. Per la produzione, usare l'automazione di Criteri di Azure.
Assegnazioni di ruolo obbligatorie
Assegnare questi ruoli all'identità gestita assegnata dal sistema Operazioni di Azure IoT in ogni cluster abilitato per Arc (L2 e L3). In questo scenario convalidato, L4 è un pass-through Envoy puro e non ha identità gestite.
| Identità | Ruolo | Ambito | Note |
|---|---|---|---|
| Sistema di identità gestita assegnata dal sistema per le operazioni IoT di Azure di livello L2/L3 | Collaboratore del BLOB di archiviazione | Account di archiviazione contenente i file di schema | Per Registro schema |
| Sistema di gestione Operazioni di Azure IoT L3 con identità gestita assegnata dal sistema | Editore di TopicSpaces di EventGrid | Namespace di Event Grid | L3 pubblica su Event Grid tramite il pass-through Envoy L4 |
| Sistema di gestione Operazioni di Azure IoT L3 con identità gestita assegnata dal sistema | Sottoscrittore EventGrid TopicSpaces | Namespace di Event Grid | L3 si sottoscrive a Event Grid tramite il pass-through di L4 Envoy |
Assegnare ogni ruolo usando interfaccia della riga di comando di Azure:
# 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
Contesto di arricchimento a più livelli
Ogni livello di rete per Operazioni di Azure IoT contribuisce con metadati aziendali alla telemetria in uscita:
| Livello | Aggiunge campo metadati |
|---|---|
| L2 | product |
| L3 |
line-config, factory-code |
In questo scenario convalidato, il flusso di dati di L3 aggiunge sia line-config che factory-code prima dell'inoltro tramite Envoy L4. Questo arricchimento a più livelli consente ai sistemi downstream di comprendere il contesto di produzione senza sovraccaricare i dispositivi perimetrali con metadati completi.
Annotazioni
Nelle distribuzioni in cui L4 esegue anche le operazioni di Azure IoT (abilitate per Arc con la propria identità gestita), è possibile invece assegnare i factory-code ruoli di arricchimento e i ruoli RBAC di Griglia di eventi a L4.
Convalidare il flusso di telemetria
Prima di convalidare il flusso end-to-end, verificare che ogni componente sia in esecuzione a livello corretto.
Passaggio 1: Verificare l'idoneità dei componenti
CoreDNS (L2, L3): Verificare che i pod CoreDNS siano in esecuzione e che funzioni la risoluzione DNS:
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): Verificare che i pod siano in esecuzione:
kubectl config use-context $L3_CLUSTER_NAME
kubectl get pods -l app=$ENVOY_POD_LABEL
Operazioni di Azure IoT MQTT Broker (L2, L3): Verificare che i listener siano attivi:
kubectl get service $K3S_SERVICE_NAME -n azure-iot-operations
Passaggio 2: Convalidare il percorso di connettività
Il flusso di telemetria end-to-end segue questo percorso:
- Telemetry ingestion (L2): i connettori OPC UA a L2 pubblicano i dati di telemetria nei flussi di dati di Operazioni di Azure IoT, che li inoltrano al broker MQTT.
- Da L2 a L3: MQTT Broker presso L2 pubblica messaggi in L3 usando MQTT.
- Da L3 a L4: MQTT Broker presso L3 pubblica messaggi upstream usando MQTT su WebSocket.
- Risoluzione DNS (L3): Flussi di dati e CoreDNS per Operazioni di Azure IoT in L3 risolvono i nomi dei servizi privati per consentire l'accesso a L4.
- Inoltro Proxy (da L3 a L4): Envoy Proxy su L3 inoltra il traffico MQTT a Envoy Proxy su L4.
- Egress (L4): Envoy Proxy su L4 invia il traffico all'Firewall di Azure Explicit Proxy sulla porta 8443 tramite ExpressRoute.
- Private routing: Il proxy instrada le richieste ai servizi Azure tramite endpoint privati.
- Integrazione Cloud: Servizi come i topic spaces di Event Grid, Archiviazione di Azure e Azure Key Vault sono accessibili in modo privato tramite collegamento privato di Azure. L'accesso alla rete pubblica è disabilitato per tutti i servizi Azure nella distribuzione.
Spazi degli argomenti di Griglia di eventi
I dati vengono pubblicati in Griglia di eventi tramite MQTT su WebSocket (/mqtt suffisso di percorso). Il flusso di dati Operazioni di Azure IoT di L3 esegue l'autenticazione usando l'identità gestita assegnata dal sistema (che ha i ruoli di EventGrid TopicSpaces Publisher e Subscriber) e invia il traffico tramite il proxy Envoy su L3, che inoltra al proxy Envoy su L4. Il traffico in uscita dal livello 4 viene instradato attraverso il proxy esplicito di Firewall di Azure (porta 8443), che quindi inoltra al private endpoint di Event Grid tramite ExpressRoute. Il livello 4 funge da pass-through puro e non esegue l'autenticazione.
I dati di telemetria vengono convalidati rispetto agli schemi definiti in gestione rete virtuale di Azure, applicati dai flussi di dati Operazioni di Azure IoT in esecuzione in L2 e L3.
Output di esempio
{
"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"
}
Verifica di controllo e post-distribuzione
Importante
In questa sezione vengono fornite le procedure di controllo consigliate. Chiedere al team di rete e alla sicurezza di esaminare questi passaggi prima di usarli nell'ambiente di produzione.
Dopo la distribuzione, verificare che l'isolamento di rete, la connettività privata e le assegnazioni RBAC siano configurate correttamente.
Passaggio 1: Verificare l'isolamento della rete tra i livelli
Verificare che non avvenga alcuna perdita di traffico tra livelli non adiacenti (ad esempio, L2 non deve raggiungere direttamente L4).
Da un host L2, tentare di raggiungere direttamente l'INDIRIZZO IP dell'host L4. La connessione deve scadere o essere rifiutata:
curl -v --connect-timeout 5 https://$L4_HOST_IP:8443Da un host L2 verificare che la connettività a L3 funzioni:
curl -v --connect-timeout 5 https://$L3_HOST_IP:$L3_PROXY_PORTEsaminare i log del firewall per verificare che il traffico tra livelli non sia imprevisto.
Passaggio 2: Confermare i percorsi di traffico tramite endpoint privati
Verificare che tutto il traffico associato a Azure instrada attraverso endpoint privati e non la rete Internet pubblica:
A partire da L4, risolvere i FQDN del servizio Azure e confermare che restituiscono indirizzi IP privati.
nslookup $EVENT_GRID_NAMESPACE.$LOCATION-1.ts.eventgrid.azure.net nslookup $STORAGE_ACCOUNT_NAME.blob.core.windows.net nslookup $KEY_VAULT_NAME.vault.azure.netOgni risultato deve restituire un indirizzo IP nell'intervallo di indirizzi privati (ad esempio,
10.254.x.x), non un indirizzo IP pubblico.Controllare il portale di Azure per ogni endpoint privato per verificare che lo stato della connessione sia Approved.
Nei log di Firewall di Azure verificare che il traffico in uscita da L4 venga instradato solo agli indirizzi IP dell'endpoint privato.
Passaggio 3: convalidare le assegnazioni di controllo degli accessi in base al ruolo
Verificare che siano presenti le assegnazioni di ruolo necessarie:
# 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
Verificare che l'identità gestita assegnata dal sistema Operazioni di Azure IoT sia elencata come assegnatario per ogni ruolo.
Passaggio 4: Verificare che il DNS venga risolto solo in IP privati
Da ogni livello in cui è stato distribuito CoreDNS, verificare che i nomi dei servizi Azure si risolvano in indirizzi IP privati.
# 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
Se una query restituisce un indirizzo IP pubblico, controllare le regole di inoltro di CoreDNS e il collegamento della zona DNS privata.
Limitazioni note
Per limitazioni comuni relative alla convalida della piattaforma, al supporto proxy e al Registry Schema, vedere Limitazioni note in Distribuzione di Operazioni di Azure IoT con connettività privata.
Le limitazioni seguenti sono specifiche dell'esercitazione sulla rete a più livelli:
- Livello 1: Il livello dispositivo L1 non è usato in questo flusso di distribuzione.
- Livello 4 Arc: Il livello 4 non è abilitato per Arc; a questo livello viene distribuito solo il proxy Envoy.
- Sovereign clouds: Questo scenario è stato convalidato solo in Azure cloud pubblico. Gli ambienti Sovereign Cloud, ad esempio Azure per enti pubblici, Azure gestiti da 21Vianet, usano endpoint differenti e nomi di zona DNS privato, pertanto non sono stati convalidati.
- Configurazioni fuori ambito: Scenari che coinvolgono le reti virtuali Azure con firewall esterni, proxy trasparenti o distribuzioni di reti virtuali solo cloud non sono state convalidate e non sono supportate.
Appendice
Informazioni di riferimento sulle risorse chiave 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>
Definizioni di ruolo personalizzate
ACX–Secrets Store Extension Owner: Concede le autorizzazioni per registrare e gestire il driver CSI dell'archivio segreti, configurare le classi del provider di segreti Azure Key Vault e gestire le identità gestite assegnate dall'utente.
{
"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-Collaboratori: Concede le autorizzazioni per gestire le assegnazioni di ruolo e le credenziali di identità federate per le identità gestite assegnate dall'utente all'interno del gruppo di risorse.
{
"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"
]
}
]
}
Annotazioni
Negli ambienti che usano Criteri di Azure automazione, queste definizioni manuali dei ruoli potrebbero non essere necessarie per i team OT. I criteri possono preassegnare i ruoli di Collaboratore o di Collaboratore ai dati di BLOB di archiviazione, secondo le esigenze.