このチュートリアルでは、OPC UA 資産を Azure IoT Operations クラスターに手動で追加します。 これらの資産は、Azure IoT Operations クラスターの MQTT ブローカーにメッセージを発行します。 通常、OT ユーザーは次の手順を実行します。
資産とは、物理デバイス、または、デバイス、マシン、システム、またはプロセスを表す論理エンティティです。 たとえば、物理資産には、ポンプ、モーター、タンク、生産ラインなどがあります。 定義する論理資産には、プロパティ、ストリーム データ ポイント、またはイベントを生成できます。
"OPC UA サーバー" は、資産と通信するソフトウェア アプリケーションです。 "OPC UA タグ" は、OPC UA サーバーが公開するデータ ポイントです。 OPC UA タグは、資産のステータス、パフォーマンス、品質、状態に関する、リアルタイムまたは履歴のデータを提供できます。
このチュートリアルでは、操作エクスペリエンス Web UI を使用して資産を作成します。 Azure CLI を使用し、これらのタスクの一部を完了することもできます。
前提条件
Kubernetes クラスターにデプロイされた、セキュリティで保護された設定が有効になっている Azure IoT Operations のインスタンス。 インスタンスを作成するには、次のいずれかを使用して Azure IoT Operations をデプロイします。
- 「クイック スタート: K3s を使用して GitHub Codespaces で Azure IoT Operations を実行する」では、このチュートリアルで使用できる Azure IoT Operations インスタンスを展開する簡単な手順が説明されています。 次に、セキュリティで保護された設定を有効にするには、「 Azure IoT Operations でセキュリティで保護された設定を有効にする」の手順に従います。
- 「デプロイの概要」では、Azure Kubernetes Service Edge Essentials を使用して Windows に、または K3s を使用して Ubuntu に Azure IoT Operations インスタンスを展開するための、詳細な手順について説明しています。 セキュリティで保護された設定の展開と最新バージョンのインストールについては、展開に関する記事の手順に従ってください。
Von Bedeutung
「クイック スタート: K3s を使用して GitHub Codespaces で Azure IoT Operations を実行する」の手順に従っている場合、作成するインスタンスでセキュリティで保護された設定を有効にすることはできません。
セキュリティで保護された設定を有効にすると、Azure IoT Operations インスタンスを含むリソース グループにも次のリソースが含まれます。
- Kubernetes クラスターに同期するシークレットを格納する Azure Key Vault インスタンス。
- Azure IoT Operations が Azure Key Vault インスタンスへのアクセスに使用するユーザー割り当てマネージド ID。
- データ フローなどの Azure IoT Operations コンポーネントが、Azure Event Hubs などのクラウド エンドポイントへの接続に使用できるユーザー割り当てマネージド ID。
- 資産とデバイスを格納するための Azure Device Registry 名前空間。
セキュリティで保護された設定を構成するときに、Key Vault Secrets Officer ロールを使用してシークレットを管理するためのアクセス許可をユーザー アカウントに付与することを確認します。
操作エクスペリエンス Web UI にサインインするには、Kubernetes - Azure Arc インスタンスを含むリソース グループに対する共同作成者以上のアクセス許可を持つ Microsoft Entra ID アカウントが必要です。 詳細については、「操作エクスペリエンス Web UI」を参照してください。
特に明記されていない限り、このチュートリアルのコンソール コマンドは Bash または PowerShell 環境で実行できます。
どのような問題が解決されますか?
OPC UA サーバーが公開するデータは複雑な構造になるので、理解が困難な場合があります。 Azure IoT Operations では、OPC UA 資産をタグ、イベント、プロパティとしてモデル化する方法が提供されます。 このモデル化により、データを理解することと、それを MQTT ブローカーやデータ フローなどのダウンストリーム プロセスで使用することがより簡単になります。
このチュートリアルでは、Azure Key Vault に格納されている資格情報を使用して、シミュレートされた OPC UA サーバーに対する認証を行う方法についても説明します。
OPC PLC シミュレーターを展開する
このチュートリアルでは、OPC PLC シミュレーターを使用してサンプル データを生成します。 OPC PLC シミュレーターをデプロイするには:
GitHub リポジトリから opc-plc-tutorial-deployment.yaml ファイルをダウンロードします。 コマンド ラインを使用してダウンロードするには、次のコマンドを実行します。
wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/refs/heads/main/samples/quickstarts/opc-plc-tutorial-deployment.yaml -O opc-plc-tutorial-deployment.yamlテキスト エディターでダウンロードした
opc-plc-tutorial-deployment.yamlファイルを開き、シミュレーターのパスワードを変更します。 パスワードは、--defaultpasswordパラメーターを使用して設定されます。 パスワードの値を書き留めます。後で必要になります。 次に、変更を保存します。OPC PLC シミュレーターをクラスターにデプロイするには、次のコマンドを実行します。
kubectl apply -f opc-plc-tutorial-deployment.yaml
次のスニペットは、ユーザーが適用した YAML ファイルを示します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: opc-plc-000000
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: opcplc-000000
template:
metadata:
labels:
app.kubernetes.io/component: opcplc-000000
spec:
containers:
- name: opc-plc
image: mcr.microsoft.com/iotedge/opc-plc:latest
args:
- "--plchostname=opcplc-000000"
- "--portnum=50000"
- "--certdnsnames=opcplc-000000"
- "--unsecuretransport"
- "--slownodes=5"
- "--slowrate=10"
- "--fastnodes=10"
- "--fasttypelowerbound=212"
- "--fasttypeupperbound=273"
- "--fasttyperandomization=True"
- "--veryfastrate=1000"
- "--guidnodes=1"
- "--appcertstoretype=FlatDirectory"
- "--dontrejectunknownrevocationstatus"
- "--disableanonymousauth"
- "--defaultuser=contosouser"
- "--defaultpassword=contosouserpassword"
ports:
- containerPort: 50000
volumeMounts:
- name: opc-plc-default-application-cert
mountPath: /app/pki/own
- name: opc-plc-trust-list
mountPath: /app/pki/trusted
volumes:
- name: opc-plc-default-application-cert
secret:
secretName: opc-plc-default-application-cert
- name: opc-plc-trust-list
secret:
secretName: opc-plc-trust-list
serviceAccountName: opcplc-000000-service-account
---
apiVersion: v1
kind: Service
metadata:
name: opcplc-000000
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
type: ClusterIP
selector:
app.kubernetes.io/component: opcplc-000000
ports:
- port: 50000
protocol: TCP
targetPort: 50000
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: opc-plc-self-signed-issuer
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: opc-plc-default-application-cert
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
secretName: opc-plc-default-application-cert
duration: 2160h # 90d
renewBefore: 360h # 15d
issuerRef:
name: opc-plc-self-signed-issuer
kind: Issuer
commonName: OpcPlc
dnsNames:
- opcplc-000000
- opcplc-000000.azure-iot-operations.svc.cluster.local
- opcplc-000000.azure-iot-operations
uris:
- urn:OpcPlc:opcplc-000000
usages:
- digital signature
- key encipherment
- data encipherment
- server auth
- client auth
privateKey:
algorithm: RSA
size: 2048
encodeUsagesInRequest: true
isCA: false
---
apiVersion: v1
kind: Secret
metadata:
name: opc-plc-trust-list
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
data: {}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: opcplc-000000-service-account
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: opc-plc-000000-secret-access-role
namespace: azure-iot-operations
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: opc-plc-000000-secret-access-rolebinding
namespace: azure-iot-operations
subjects:
- kind: ServiceAccount
name: opcplc-000000-service-account
namespace: azure-iot-operations
roleRef:
kind: Role
name: opc-plc-000000-secret-access-role
apiGroup: rbac.authorization.k8s.io
相互信頼の確立
OPC PLC シミュレーターが OPC UA のコネクタにデータを送信するには、それらの間で相互信頼を確立する必要があります。 このチュートリアルでは、OPC PLC シミュレーターと OPC UA 用コネクタで自己署名証明書を使用して、OPC UA 用コネクタとの相互信頼を確立します。
- シミュレーターのアプリケーション インスタンス証明書は、
opc-plc-default-application-certKubernetes シークレットに格納されます。 - OPC UA のアプリケーション インスタンス証明書のコネクタは、
aio-opc-opcuabroker-default-application-certKubernetes シークレットに格納されます。
Von Bedeutung
運用環境では、エンタープライズ グレードのアプリケーション インスタンス証明書を使用して相互信頼を確立します。 詳細については、「 エンタープライズ グレードのアプリケーション インスタンス証明書を構成する」を参照してください。
シミュレーターの信頼リストにコネクタの証明書を追加する
各 OPC UA サーバーには、信頼リストを管理するための独自のメカニズムがあります。 コネクタの証明書をシミュレーターの信頼リストに追加するには、次のコマンドを実行します。
cert=$(kubectl -n azure-iot-operations get secret aio-opc-opcuabroker-default-application-cert -o jsonpath='{.data.tls\.crt}' | base64 -d)
data=$(kubectl create secret generic temp --from-literal=opcuabroker.crt="$cert" --dry-run=client -o jsonpath='{.data}')
kubectl patch secret opc-plc-trust-list -n azure-iot-operations -p "{\"data\": $data}"
$cert = kubectl -n azure-iot-operations get secret aio-opc-opcuabroker-default-application-cert -o jsonpath='{.data.tls\.crt}' | %{ [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_)) }
$data = kubectl create secret generic temp --from-literal=opcuabroker.crt="$cert" --dry-run=client -o jsonpath='{.data}'
kubectl patch secret opc-plc-trust-list -n azure-iot-operations -p "{""data"": $data}"
シミュレーターの証明書をコネクタの信頼リストに追加する
OPC UA サーバーの種類ごとに、アプリケーション インスタンス証明書を管理するための独自のメカニズムがあります。 シミュレーターの証明書を opcplc-000000.crt という名前のファイルにダウンロードするには、次のコマンドを実行します。
kubectl -n azure-iot-operations get secret opc-plc-default-application-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > opcplc-000000.crt
kubectl -n azure-iot-operations get secret opc-plc-default-application-cert -o jsonpath='{.data.tls\.crt}' | %{ [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_)) } > opcplc-000000.crt
シミュレーターの証明書をコネクタの信頼リストに追加するには:
操作エクスペリエンス Web UI に移動し、Microsoft Entra ID 資格情報でサインインします。
サイトを選択します。 新しいデプロイを使用している場合には、サイトがまだ存在しません。 前に作成したクラスターは、[未割り当てインスタンスの表示] を選択することで確認できます。 操作エクスペリエンスにおいて、インスタンスは Azure IoT Operations を展開したクラスターを表します。
Azure IoT Operations をデプロイしたインスタンスを選択します。
ヒント
インスタンスが表示されない場合、そのユーザーは適切な Microsoft Entra ID テナントにいない可能性があります。 操作エクスペリエンスの右上のメニューからテナントを変更できます。
[デバイス] を選び、[証明書とシークレットの管理] を選びます。
[証明書とシークレット] ページで、[新しい証明書の追加] を選びます。
[証明書のアップロード] を選び、証明書ストアとして [OPC UA 信頼リスト] を選び、前にダウンロードした
opcplc-000000.crtファイルを選びます。 次に、[ アップロード] を選択します。を選択してを適用します。
シミュレーターのアプリケーション インスタンス証明書が OPC UA の信頼リストのコネクタに追加されました。
デバイスを追加する
このステップでは、操作エクスペリエンスを使用して、OPC PLC シミュレーターに接続できるデバイスを追加します。 デバイスを追加するには次のようにします。
[ デバイス ] を選択し、[ 新規作成] を選択します。
デバイス名として「
opc-ua-connector」と入力し、[Microsoft.OpcUa] タイルで [新規] を選びます。次の Microsoft.OpcUa 受信エンドポイント情報を入力します。
フィールド 値 エンドポイント名 opc-ua-connector-0OPC UA サーバー URL opc.tcp://opcplc-000000:50000ユーザー認証モード Username password
このチュートリアルでは、操作エクスペリエンス Web UI から Azure Key Vault インスタンスに新しいシークレットを追加します。 シークレットは、Kubernetes クラスターに自動的に同期されます。
ユーザー名参照を追加するには、[ 参照の追加]、[ 新規作成] の順に選択します。
シークレット名として
plcusernameを入力し、シークレット値としてcontosouserします。 次に、[適用] を選択します。パスワード参照を追加するには、[ 参照の追加]、[ 新規作成] の順に選択します。
シークレット名として
plcpassword、シークレット値として opc-plc-deployment.yaml ファイルに追加したパスワードを入力します。 次に、[適用] を選択します。[デバイスの詳細] ページで、[次へ] を選択して [追加情報] ページに移動します。
[カスタム プロパティの追加] ページでは、必要に応じてデバイスのカスタム プロパティを更新または追加できます。 完了したら、[次へ] を選びます。
[要約] ページでデバイス定義を保存するには、[作成] を選びます。
この構成は、opc-ua-connector というエンドポイントを使用して、opc-ua-connector-0 という新しいデバイスをクラスターに展開します。 Azure portal でデバイスを表示することも、kubectl を使用して Kubernetes クラスター内のデバイスを表示することもできます。
kubectl get device -n azure-iot-operations
リソース グループ内の Azure Key Vault インスタンスで、 plcusername シークレットと plcpassword シークレットを確認できます。 シークレットは Kubernetes クラスターに同期され、 kubectl get secret -n azure-iot-operations コマンドを使用して表示できます。 [同期されたシークレットの管理] ページの操作エクスペリエンスで シークレットを 確認することもできます。
資産を管理する
操作エクスペリエンスでインスタンスを選択すると、[資産] ページに使用可能な資産の一覧が表示されます。 資産がまだない場合、この一覧は空です。
アセットを作成する
資産を作成するには、[資産の作成] を選択 します。 次に、以下の資産情報を入力します。
| フィールド | 値 |
|---|---|
| 受信エンドポイント | opc-ua-connector-0 |
| アセット名 | thermostat |
| 説明 | A simulated thermostat asset |
既存のカスタム プロパティを削除し、次のカスタム プロパティを追加します。 後のチュートリアルで扱う Power BI テンプレートでそのクエリを実行するので、正確なプロパティ名を使うよう注意してください。
| プロパティ名 | プロパティの詳細 |
|---|---|
| バッチ | 102 |
| 顧客 | Contoso |
| 機器 | ボイラー |
| isSpare | ほんとう |
| 位置 | シアトル |
[ 次へ ] を選択して [ データセット] ページに移動します。
データセットを作成する
データセットを作成するには、[データセットの作成] を選択 します。 次の表に示すデータセットの詳細を入力します。
| フィールド | 値 |
|---|---|
| データセット名 | thermostat |
| 行き先 | MQTT |
| トピック | azure-iot-operations/data/thermostat |
[ 作成] を選択し、次 にデータセットを保存し、[ データ ポイント ] ページに移動します。
ヒント
[既定の 設定の管理 ] を選択すると、各データ ポイントの既定のサンプリング間隔とキュー サイズを変更できます。
OPC UA データ ポイントを作成する
[データ ポイント] ページに OPC UA データ ポイント を追加します。 データ ポイントを追加するには、[データ ポイントの 追加] を選択します。 次の表に示すデータ ポイントの詳細を入力します。
| データ ソース | データ ポイント名 |
|---|---|
| ns=3;s=SpikeData | 温度 |
ここでのデータ ソース値は、特定の OPC UA シミュレーター ノードです。 ノードは、指定された範囲内でランダムな値を生成し、断続的なスパイクも発生します。
保存 を選択します。
[ 次へ ] を選択して [イベント グループ ] ページに移動し、[ 次へ ] を選択して [管理グループ ] ページに移動し、[ 次へ ] を選択して [確認 ] ページに移動します。
レビュー
資産とタグの詳細を確認し、必要な調整を行ったら、[作成] を選択します。
この構成では、thermostat という名前の新しい資産をクラスターに展開します。
kubectlを使用して、クラスター内の資産をローカルに表示することもできます。
kubectl get assets.namespace -n azure-iot-operations
Azure portal でリソースを表示する
Azure portal で作成したデバイスと資産を表示するには、Azure デバイス レジストリに移動します。
ポータルを使用すると、資産の詳細を表示できます。 さらに詳細を表示するには、[JSON ビュー] を選択します。
データが流れていることを検証する
mosquitto_sub ツールを使用して、データが MQTT ブローカーに流れているかを検証します。 この例では、Kubernetes クラスターで mosquitto_sub ツールを実行します。
次のコマンドを実行して、クラスターの MQTT ブローカーを操作するのに役立つ mosquitto_pub と mosquitto_sub ツールを含むポッドを展開します。
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml次のスニペットは、ユーザーが適用した YAML ファイルを示します。
# Important: do not use in production environments # Create a service account apiVersion: v1 kind: ServiceAccount metadata: name: mqtt-client namespace: azure-iot-operations --- # Creates a pod with mosquitto-clients and mqttui utilities in your cluster apiVersion: v1 kind: Pod metadata: name: mqtt-client # The namespace must match the IoT MQ BrokerListener's namespace # Otherwise use the long hostname: aio-broker.azure-iot-operations.svc.cluster.local namespace: azure-iot-operations spec: # Use the "mqtt-client" service account which comes with default deployment # Otherwise create it with `kubectl create serviceaccount mqtt-client -n azure-iot-operations` serviceAccountName: mqtt-client containers: # Install mosquitto and mqttui utilities on Alpine linux - image: alpine name: mqtt-client command: ["sh", "-c"] args: ["apk add mosquitto-clients mqttui && sleep infinity"] resources: limits: cpu: 500m memory: 200Mi requests: cpu: 100m memory: 100Mi volumeMounts: - name: broker-sat mountPath: /var/run/secrets/tokens - name: trust-bundle mountPath: /var/run/certs volumes: - name: broker-sat projected: sources: - serviceAccountToken: path: broker-sat audience: aio-internal # Must match audience in BrokerAuthentication expirationSeconds: 86400 - name: trust-bundle configMap: name: azure-iot-operations-aio-ca-trust-bundle # Default root CA cert注意
この構成は安全ではありません。 運用環境では、この構成を使わないでください。
mqtt-client ポッドが実行されているときに、次のコマンドを実行して、作成したポッド内にシェル環境を作成します。
kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- shmqtt-client ポッドの Bash シェルで次のコマンドを実行し、mosquitto_sub ツールを使用して MQTT ブローカーに接続し、ワイルドカードを使用して
data/#トピックをサブスクライブします。mosquitto_sub --host aio-broker --port 18883 --topic "azure-iot-operations/data/#" -v --debug --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)このコマンドは、
data/#キーを押して停止するまで実行され続け、 トピックにメッセージが到着するたびに表示します。 シェル環境を終了するには、「exit」と入力します。
追加したサーモスタット 資産がデータを発行していることを確認するには、 azure-iot-operations/data/thermostat トピックのメッセージを表示します。
Client $server-generated/0000aaaa-11bb-cccc-dd22-eeeeee333333 received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (92 bytes))
azure-iot-operations/data/thermostat {"temperature":{"SourceTimestamp":"2025-02-14T11:27:44.5030912Z","Value":48.17536741017152}}
Client $server-generated/0000aaaa-11bb-cccc-dd22-eeeeee333333 received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (90 bytes))
azure-iot-operations/data/thermostat {"temperature":{"SourceTimestamp":"2025-02-14T11:27:45.50333Z","Value":98.22872507286887}}
Client $server-generated/0000aaaa-11bb-cccc-dd22-eeeeee333333 received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (92 bytes))
azure-iot-operations/data/thermostat {"temperature":{"SourceTimestamp":"2025-02-14T11:27:46.503381Z","Value":12.533323356430426}}
データが流れていない場合は、aio-opc-opc.tcp-1 ポッドを再起動します。
次のコマンドを実行して、
aio-opc-opc.tcp-1ポッドの名前を確認します。kubectl get pods -n azure-iot-operationsポッドの名前は
aio-opc-opc.tcp-1-849dd78866-vhmz6のようになります。次の例のようなコマンドを実行して、
aio-opc-opc.tcp-1ポッドを再起動します。 前の手順のaio-opc-opc.tcp-1ポッドの名前を使用します。kubectl delete pod aio-opc-opc.tcp-1-849dd78866-vhmz6 -n azure-iot-operations
前のチュートリアルで追加したサンプル タグによって、次の例のようなメッセージが資産から生成されます。
{
"temperature":{
"Value":24.86898871648548,
"SourceTimestamp":"2025-04-25T14:50:07.195274Z"
}
}
問題を解決した方法について
このチュートリアルでは、デバイスを追加し、資産とタグを定義しました。 この資産とタグは、OPC UA サーバーからのデータをモデル化して、MQTT ブローカーやその他のダウンストリーム プロセスでデータを容易に使用できるようにします。
AZURE Key Vault に格納されている資格情報を使用して、OPC UA サーバーに対する認証を行いました。 この方法は、資産定義の資格情報をハードコーディングするよりも安全です。
次のチュートリアルでは、定義した thermostat 資産を使用します。
リソースをクリーンアップする
次のチュートリアルに進む場合は、すべてのリソースを保持してください。
Azure IoT Operations のデプロイは削除して、クラスターは保持したい場合は、az iot ops delete コマンドを使用します。
az iot ops delete --cluster $CLUSTER_NAME --resource-group $RESOURCE_GROUP
このクイックスタート用に作成したすべてのリソースを削除する場合は、Azure IoT Operations を展開した Kubernetes クラスターを削除した後、そのクラスターを含んでいた Azure リソース グループを削除します。
これらのクイックスタートで Codespaces を使った場合は、GitHub から Codespace を削除します。