使用 Akri 发现 OPC UA 服务器
Akri 是一个 Kubernetes 资源接口,可用于在 Kubernetes 群集中轻松公开异类叶设备 (,例如 IP 相机和 USB 设备) 资源。 Akri 会持续检测有权访问这些设备的节点,以基于它们计划工作负荷。 Akri 是一个为边缘制作的 CNCF 沙盒项目,用于处理叶设备的动态外观和消失。 它目前支持 OPC UA、ONVIF 和 udev 协议,但你也可以实现模板提供的自定义协议处理程序。 在此处阅读有关 Akri 的详细信息。
本文介绍如何在 Azure 中部署示例 OPC PLC 服务器容器,并通过在 AKS Edge Essentials 群集上部署 Akri 来发现它们。 OPC UA 是用于工业自动化的通信协议。 它是一种客户端/服务器技术,附带安全和通信框架。 如果在演示中的任何时间点,想要深入了解 OPC UA 或阐明术语,请参阅 联机 OPC UA 规范。
此演示可帮助你开始使用 Akri 来发现 OPC UA 服务器,并通过包含 OPC UA 客户端的中转站使用这些服务器。 具体而言,为此方案创建了名为 OPC UA 监视 的 Akri 配置。 此配置演示如何使用 Akri 检测特定 OPC UA 变量的异常值。 为此,中转站中的 OPC UA 客户端订阅该变量,并通过 gRPC 提供其值供异常情况检测 Web 应用程序使用。 可以使用此配置监视晴雨表、CO 检测器等。 但是,对于此示例,OPC UA 变量表示 PLC (可编程逻辑控制器) 恒温器温度的值。 超出 70-80 度范围的任何值都是异常。 此外,如果要使用证书实现安全性,请跳到末尾的 部分。
先决条件
- AKS Edge Essentials 群集启动并运行。
- 要向其部署 OPC PLC 服务器的 Azure 订阅和资源组。
- Akri 仅适用于 Linux:在本练习中使用 Linux 节点。
创建 OPC UA 服务器
现在,创建一些要发现的 OPC UA PLC 服务器。 部署 OPC PLC 服务器容器,而不是从头开始。 可在此处阅读有关 容器及其参数的详细信息。 此演示使用提供的模板将 OPC PLC 服务器容器实例部署到 Azure。
转到 Azure IoT Edge OPC PLC 示例的自述文件,然后选择“部署到 Azure”。
选择 “编辑模板” 并导航到第 172 行。 将整行替换为以下代码,以添加部署所需 OPC PLC 服务器所需的标志:
"[concat('./opcplc --pn=50000 --sph --fn=1 --fr=1 --ft=uint --ftl=65 --ftu=85 --ftr=True --aa --sph --ftl=65 --ftu=85 --ftr=True --ut', ' --ph=', variables('aciPlc'), add(copyIndex(), 1), '.', resourceGroup().location, '.azurecontainer.io')]"
可以在 自述文件中阅读有关参数的详细信息。
保存模板,并填写项目和实例详细信息。 对于
Number of Simulations
,请指定2
以运行两个 OPC PLC 服务器。选择“ 查看并创建”,然后选择 “创建 ”以在 Azure 上部署服务器。
现已成功创建两个 OPC UA PLC 服务器,每个服务器都有一个快速 PLC 节点,这将以 1 的速率生成下限 = 65、上限 = 85 的无符号整数。
运行 Akri
通过检查容器实例是否已在Azure 门户启动,确保 OPC UA 服务器正在运行。
为了使 Akri 能够正确发现服务器,请在安装 Akri 时指定正确的发现 URL。
发现 URL 显示为
opc.tcp://<FQDN>:50000/
。 若要获取 OPC PLC 服务器的 FQDN,请导航到 Azure 中的部署,你将看到 FQDN。 将 FQDN 复制并粘贴到每台服务器的发现 URL 中。添加 Akri helm 图表(如果尚未添加):
helm repo add akri-helm-charts https://project-akri.github.io/akri/
如果之前已添加 Akri helm 图表,请更新最新版本的存储库:
helm repo update
使用 Helm 安装 Akri。 安装 Akri 时,通过设置 helm 值
opcua.discovery.enabled=true
来指定要部署 OPC UA 发现处理程序。在此方案中,指定
Identifier
希望代理监视的 NodeID 的 和NamespaceIndex
。 在本例中,这是之前创建的 temperature 变量,其 的 为Identifier
FastUInt1
和NamespaceIndex
2
。请确保将 替换为
opcua.configuration.discoveryDetails.discoveryUrls
在上一步中获取的 URL:helm install akri akri-helm-charts/akri ` --set opcua.discovery.enabled=true ` --set opcua.configuration.enabled=true ` --set opcua.configuration.name=akri-opcua-monitoring ` --set opcua.configuration.brokerPod.image.repository="ghcr.io/project-akri/akri/opcua-monitoring-broker" ` --set opcua.configuration.brokerPod.image.tag="latest-dev" ` --set opcua.configuration.brokerProperties.IDENTIFIER='FastUInt1' ` --set opcua.configuration.brokerProperties.NAMESPACE_INDEX='2' ` --set opcua.configuration.discoveryDetails.discoveryUrls[0]="opc.tcp://<FQDN of 1st container instance>:50000/" ` --set opcua.configuration.discoveryDetails.discoveryUrls[1]="opc.tcp://<FQDN of 2nd container instance>:50000/" `
注意
FastUInt1
是 OPC PLC 服务器提供的 快速更改节点 的标识符。安装 Akri 后,Akri 代理会发现这两个服务器,并为每个服务器创建一个实例。 监视两个中转站 Pod 的启动,每个服务器各一个:
kubectl get pods -o wide --watch
还可以确保 Akri 的监视 Pod 已成功连接到 OPC UA 服务器:
kubectl logs <name of OPC UA monitoring pod>
检查 Akri 的更多元素:
- 运行
kubectl get crd
,应会看到列出的 CRD。 - 运行
kubectl get akric
,应会看到akri-opcua-monitoring
。 - 如果发现 OPC PLC 服务器并启动 Pod,则可以通过运行
kubectl get akrii
来查看实例,并且可以通过运行kubectl get akrii akri-opcua-monitoring-<ID> -o yaml
来进一步检查。
- 运行
将异常情况检测 Web 应用程序部署为代理的最终使用者
为此端到端演示创建了一个异常情况检测 Web 应用程序示例。 它具有一个 gRPC 存根,用于调用代理的 gRPC 服务,获取最新的温度值。 然后,它使用局部离群因子策略确定此值是否是数据集的离群值。 数据集只是一个 CSV 文件,其数字在 70-80 之间重复多次;因此,任何明显超出此范围的值都将被视为离群值。 Web 应用程序用作日志,显示发送这些值的所有温度值和 OPC UA 服务器的地址。 它以红色显示异常值。 由于在 OPC UA 服务器中设置函数的方式, DoSimulation
异常值始终为 120。
部署异常情况检测应用,并为应用watch Pod 启动:
kubectl apply -f https://raw.githubusercontent.com/project-akri/akri/main/deployment/samples/akri-anomaly-detection-app.yaml
kubectl get pods -o wide --watch
运行 Pod 后,获取应用的节点 IP 和服务端口号:
Get-AKSEdgeNodeAddr
kubectl get svc
导航到
http://<NODE IP>:<SERVICE PORT NUM>/
。 站点加载需要几秒钟的时间,此时应会看到温度值的日志,该日志每隔几秒更新一次。 请注意这些值如何来自两个不同的发现 URL,特别是两个 OPC UA 服务器中的每一个。
可选:OPC UA 服务器和代理的证书
这是一个可选过程,可用于试用具有证书的 Akri 以增强安全性。 按照以下步骤部署具有安全性的 OPC PLC 服务器,并创建可用于对服务器和代理进行身份验证的 Kubernetes 机密。
创建具有安全性的 OPC UA 服务器
转到 Azure IoT Edge OPC PLC 示例的自述文件,然后选择“部署到 Azure”。
选择 “编辑模板” 并导航到第 172 行。 将整行替换为以下代码,以添加部署所需 OPC PLC 服务器所需的标志:
"[concat('./opcplc --pn=50000 --sph --fn=1 --fr=1 --ft=uint --ftl=65 --ftu=85 --ftr=True --aa --sph --ftl=65 --ftu=85 --ftr=True', ' --ph=', variables('aciPlc'), add(copyIndex(), 1), '.', resourceGroup().location, '.azurecontainer.io')]"
在
resources
节下,在第三properties
(行 167) 节中添加以下代码, (与image
、command
、ports
等 ) 相同的级别:"volumeMounts": [ { "name": "filesharevolume", "mountPath": "/app/pki" } ],
然后,将以下代码添加到第二个“properties” (行 163) 部分, (与
containers
) 相同的级别:"volumes": [ { "name": "filesharevolume", "azureFile": { "shareName": "acishare", "storageAccountName": "<storageAccName>", "storageAccountKey": "<storageAccKey>" } } ]
保存模板,并填写项目和实例详细信息。 对于
Number of Simulations
,请指定2
以运行两个 OPC PLC 服务器。选择“ 查看”和“创建”,然后选择“ 创建 ”以在 Azure 上部署服务器。
现已成功创建两个 OPC UA PLC 服务器,每个服务器都有一个快速 PLC 节点,这将以 1 的速率生成下限 = 65、上限 = 85 的无符号整数。
创建 X.509 v3 证书
为中转站创建三个符合 OPC UA 的 X.509v3 证书 (一个,) 每个服务器创建一个证书,确保证书包含 必要的组件,例如应用程序 URI。
证书要求:
- 它们都应由通用证书颁发机构 (CA) 签名,并且所有证书的签名算法应为
SHA256
。 - 密钥大小还必须大于或等于
2048
位。 - 服务器证书和 AkriBroker 证书的 DNS 应包含创建的 OPC UA 服务器容器实例的 FQDN, (转到 运行 Akri 的步骤 3 了解如何获取 FQDN) 。
- OPC UA 服务器证书应在证书生成术语中 (命名
OpcPlc
,CN=OpcPlc
) 并且 Akri 代理证书应 (CN=AkriBroker
命名AkriBroker
,) (CA 名称) 没有要求。
有许多工具可用于为 OPC UA 生成适当的证书,例如 OPC Foundation 的证书生成器或 OpenSSL。 OPC Foundation 的证书生成器是一个更方便的选项,而 OpenSSL 提供了更多的自定义空间。
如果选择使用 OPC Foundation 的证书生成器,请按照以下步骤生成:
安装 Perl。
下载 .zip 文件或克隆 OPC Foundation 的证书生成器存储库 (杂项工具) 。
从 Visual Studio 开发人员命令提示符运行
build_certificate-generator.bat
, (建议) Visual Studio 2022。从 Visual Studio 2022 生成
Opc.Ua.CertificateGenerator
解决方案。检查是否已
Opc.Ua.CertificateGenerator.exe
在 目录中build/Debug/Opc.Ua.CertificateGenerator
成功生成。使用以下示例命令创建证书。 有关更多选项 ,请参阅杂项工具 :
- Self-Signed CA:
.\Opc.Ua.CertificateGenerator.exe -cmd issue -sp . -sn CN=<CA name e.g. MyCA> -ca true -pw <password>
- OPC UA 服务器证书:
.\Opc.Ua.CertificateGenerator.exe -cmd issue -sp . -an OpcPlc -ikf '.\private\MyCA [hash].pfx' -ikp <password>-dn <DNS separated by commas>
- Akri 代理证书:
.\Opc.Ua.CertificateGenerator.exe -cmd issue -sp . -an AkriBroker -ikf '.\private\MyCA [hash].pfx' -ikp <password>-dn <DNS separated by commas>
.crl
仅当从生成器创建 CA 时,才使用 OpenSSL (为 CA 创建文件() 缺少.crl
该文件)。
如果选择使用 OpenSSL,请参阅以下引用列表:
创建 opcua-broker-credentials Kubernetes 机密
OPC UA 客户端证书作为装载为卷的 Kubernetes 机密传递给 OPC UA 监视代理。
创建 Kubernetes 机密,使用预期密钥名称投影每个证书/crl/私钥 (client_certificate
、 client_key
、 ca_certificate
和 ca_crl
) 。 指定文件路径,使其指向在上一部分中创建的凭据:
kubectl create secret generic opcua-broker-credentials `
--from-file=client_certificate=/path/to/AkriBroker/own/certs/AkriBroker\ \[<hash>\].der `
--from-file=client_key=/path/to/AkriBroker/own/private/AkriBroker\ \[<hash>\].pfx `
--from-file=ca_certificate=/path/to/ca/certs/SomeCA\ \[<hash>\].der `
--from-file=ca_crl=/path/to/ca/crl/SomeCA\ \[<hash>\].crl
证书将装载到 /etc/opcua-certs/client-pki 处mountPath
的卷credentials
,如 OPC UA 配置 helm 模板中所示。 此路径是中转站期望查找证书的位置。
将证书文件夹装载到 ACI
按照这些说明 创建 Azure 文件共享。
创建 Azure 文件共享和证书后,按所述将 CA 和 OPC UA 服务器证书上传到文件共享。
├── own
│ ├── certs
│ │ └── OpcPlc [hash].der
│ └── private
│ └── OpcPlc [hash].pfx
└── trusted
├── certs
│ └── CA.der
└── crl
└── CA.crl
注意
由于我们在模板中添加了一个安全标志,这会导致在文件共享中生成任意证书。 可以删除文件共享中的任何未识别证书, (文件夹路径应与上图) 完全相同。
执行这些步骤以确保安全性后,在容器实例上单击“ 重启 ”以更新它并使用装载的证书运行。
运行 Akri 并部署 Web 应用
按照上一部分操作,运行 Akri 并发现服务器,但现在在命令末尾添加一行 --set opcua.configuration.mountCertificates='true'
。 请确保将 替换为opcua.configuration.discoveryDetails.discoveryUrls
从Azure 门户找到的 URL:
helm install akri akri-helm-charts/akri `
--set opcua.discovery.enabled=true `
--set opcua.configuration.enabled=true `
--set opcua.configuration.name=akri-opcua-monitoring `
--set opcua.configuration.brokerPod.image.repository="ghcr.io/project-akri/akri/opcua-monitoring-broker" `
--set opcua.configuration.brokerPod.image.tag="latest-dev" `
--set opcua.configuration.brokerProperties.IDENTIFIER='FastUInt1' `
--set opcua.configuration.brokerProperties.NAMESPACE_INDEX='2' `
--set opcua.configuration.discoveryDetails.discoveryUrls[0]="opc.tcp://<FQDN of 1st container instance>:50000/" `
--set opcua.configuration.discoveryDetails.discoveryUrls[1]="opc.tcp://<FQDN of 2nd container instance>:50000/" `
--set opcua.configuration.mountCertificates='true'
在此处,可以按照将异常情况检测 Web 应用程序部署为代理的最终使用者部分,在网页上查看 OPC PLC 值。
清理
删除异常情况检测应用程序:
kubectl delete -f https://raw.githubusercontent.com/project-akri/akri/main/deployment/samples/akri-anomaly-detection-app.yaml
从群集中卸载 Akri。
helm delete akri
导航到容器实例删除 OPC UA 服务器部署,然后在Azure 门户中选择“删除”。