乐趣区

关于go:如何用Shifu来接入一个私有驱动的物联网设备

在上一篇《如何写一个树莓派的驱动来管制 GPIO LED》中咱们分享了驱动的编写办法。尽管实现了管制,然而驱动只能在本地执行,不具备任何的可扩展性。尤其是当设施数量多了当前管控难度将急剧减少。

这始终是一个物联网开发者的难题。那么有什么方法能够大批量,模块化的接入相似驱动的设施呢?

欢送来到边无际的这一系列的第二篇分享—— 如何用 Shifu Framework 来接入一个公有驱动物联网设施。

简介

本文是一个应用 Shifu 接入树莓派 Python 驱动的指南,其中蕴含 Shifu Framework, Docker, Linux, Kubernetes 的基本操作,任何开发者都能够浏览本文来学习 Shifu Framework 的开发方法。
文中的 Shifu Framework 架构如下:
北向通过”deviceshifu-http-http”向上凋谢 HTTP API 接口,南向通过”rpio-gpio-driver”来和理论设施交互。

指标

  1. 在树莓派上装置 k3s 集群并装置 Shifu Framework
  2. 打包树莓派 LED 驱动到一个容器镜像
  3. 在 Shifu 中部署树莓派 LED 的数字孪生
  4. 实现对树莓派 LED 的近程自动化管控

本次分享中用到的设施有

  1. 树莓派(本文中用到的为 Raspberry Pi 3B+),运行着 64 位的 Raspberry Pi OS
  2. 上篇文章连贯的电路

须要的基本知识:

· 根本的 Python
· Linux 命令行基本操作(创立一个文件,装置利用,SSH,运行一个程序)
· Docker/containerd 基本操作
· K8s/K3s 基本操作

步骤

第一步:装置 K3s

首先咱们要在树莓派中运行一个 Kubernetes 集群,这里并不限度用户应用的版本,然而为了节俭资源本文中应用的是 k3s

本文参考的是装置教程
https://rancher.com/docs/k3s/…

具体步骤本文将不波及。在今后的分享中将会带着大家进行具体的装置解说,纵情期待。

装置结束后,执行“kubectl version”查看以后 kubernetes 版本:

利用“kubectl get nodes”查看以后集群的状态,显示”Ready”即示意集群能够应用:

至此,k3s 装置完结。

第二步:装置 Shifu

首先将 Shifu 我的项目克隆到本地,我的项目地址为: https://github.com/Edgenesis/…

执行命令为:git clone https://github.com/Edgenesis/…

上面通过“kubectl apply -f shifu/k8s/crd/install/shifu_install.yml”即可一键将 Shifu 部署到 k3s 集群中:

再次执行“kubectl get pods -A”,即可看到 Shifu Framework 的控制器被部署到集群中:

咱们也能够通过“edgedevices”这个 CRD 来治理设施资源(以后没有设施):

至此,Shifu 装置结束。

第三步:打包驱动

咱们须要利用 Shifu 提供的一个小工具来实现能够近程操纵本地驱动,具体的教程请看:

https://github.com/Edgenesis/…

这个小工具实现了将用户 / 程序发送来的 HTTP 申请转换到本地命令行来执行。

教程外面提供了一个驱动示例,门路为

https://github.com/Edgenesis/…

内容如下:

能够看到实例 Dockerfile 分两局部,首先是用“golang”这个镜像来编译 Shifu 提供的“http_to_ssh_stub.go”来实现 HTTP 到 SSH 命令行的转换。接着是利用一个空的“alpine”镜像,配置 SSH 来供演示。

接下来让咱们来正式操作。

思考到树莓派的性能局限,本次编译将从电脑端执行,将编译好的镜像推送到 Docker Hub 来供近程调用即可。

首先,咱们建设一个新的文件夹,这里用的是“dev”,而后将上一篇文章中应用到的树莓派 LED 驱动保留到该目录:

-- led_driver.py

驱动内容不变

从 Shifu 我的项目的“driver_util/examples/simple-alpine/”目录下将“Dockerfile.sample”复制到“dev”目录下:

dev/
├── Dockerfile.sample
└── led_driver.py

更改以下字段将第二部的镜像从“alpine”改为“python:alpine”,装置“RPi.GPIO”的 Python 库

最初将 Python 驱动拷贝到运行容器中,新的 Dockerfile 如下,改变的中央已用红字标记进去

FROM golang:1.17.1 as builder
WORKDIR /
 ENV GOPROXY=https://goproxy.cn,direct
ENV GO111MODULE=on
ENV GOPRIVATE=github.com/Edgenesis
 COPY driver_util driver_util
 WORKDIR /driver_util
RUN go mod download
 # Build the Go app
RUN CGO_ENABLED=0 GOOS=$(go env GOOS) GOARCH=$(go env GOARCH) gobuild -a -o /output/http2ssh-stub http_to_ssh_stub.go
 FROM python:alpine
 RUN apk add --no-cache --update openrc openssh \
    && mkdir -p /run/openrc \
    && touch /run/openrc/softlevel \
    && sed -ie "s/#PubkeyAuthentication/PubkeyAuthentication/g"/etc/ssh/sshd_config \
    && sed -ie "s/#PasswordAuthenticationyes/PasswordAuthentication no/g" /etc/ssh/sshd_config \
    && sed -ie "s/AllowTcpForwardingno/AllowTcpForwarding yes/g" /etc/ssh/sshd_config \
    && echo"PubkeyAcceptedKeyTypes=+ssh-rsa" >>  /etc/ssh/sshd_config\
    && ssh-keygen -A \
    && passwd -d root \
    && mkdir ~/.ssh \
    && while ! [-e/etc/ssh/ssh_host_rsa_key.pub]; do sleep 1; done \
    && cp /etc/ssh/ssh_host_rsa_key.pub~/.ssh/authorized_keys
 RUN apk add --no-cache -Uu --virtual .build-dependencies libffi-devopenssl-dev build-base musl \
    && pip3 install --no-cache --upgrade RPi.GPIO\
    && apk del --purge .build-dependencies \
    && apk add --no-cache --purge curlca-certificates musl \
    && rm -rf /var/cache/apk/* /tmp/*
 WORKDIR /root/
 COPY --from=builder /output/http2ssh-stub http2ssh-stub
COPY --from=builder/driver_util/examples/simple-alpine/docker-entrypoint.sh docker-entrypoint.sh
COPY dev/led_driver.py led_driver.py
RUN chmod +x docker-entrypoint.sh
 # Command to run the executable
ENTRYPOINT ["./docker-entrypoint.sh"]

接下来咱们来打包封装 Docker 镜像,因为树莓派的 CPU 是 ARM64 的处理器,本文中编译应用的电脑为 x86,所以咱们须要应用 Docker 的 buildx 性能来进行镜像构建,无关 buildx 的教程本文就不再叙述,需要的话能够移步:

https://docs.docker.com/build…

利用“docker buildx build –platform=linux/arm64 -f dev/Dockerfile.sample . -t edgehub/rpi-gpio-driver:v0.0.1 –push”来构建镜像并推送到 docker hub 中。

至此,镜像打包局部实现。

前期咱们将提供一键打包模块,让这一步简略到填写一个配置文件 + 一行命令即可,纵情期待😊

第四步:部署设施孪生到树莓派中

有了镜像当前,咱们能够将数字孪生部署到集群中,上面咱们来筹备部署所须要的文件。

首先是一个 Kuberenetes Deployment YAML 文件,用来运行 deviceShifu 和驱动的 Pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: edgedevice-rpi-gpio-deployment
  name: edgedevice-rpi-gpio-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: edgedevice-rpi-gpio-deployment
  template:
    metadata:
      labels:
        app: edgedevice-rpi-gpio-deployment
    spec:
      containers:
      - image: edgehub/deviceshifu-http-http:v0.0.1
        name: deviceshifu-http
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: edgedevice-config
          mountPath: "/etc/edgedevice/config"
          readOnly: true
        env:
        - name: EDGEDEVICE_NAME
          value: "edgedevice-rpi-gpio"
        - name: EDGEDEVICE_NAMESPACE
          value: "devices"
      - image: edgehub/rpi-gpio-driver:v0.0.1
        name: driver
        volumeMounts:
        - mountPath: /dev/gpiomem
          name: gpiomem
        securityContext:
          privileged: true
        ports:
        - containerPort: 11112
        env:
        - name: EDGEDEVICE_DRIVER_SSH_KEY_PATH
          value: "/etc/ssh/ssh_host_rsa_key"
        - name: EDGEDEVICE_DRIVER_HTTP_PORT
          value: "11112"
        - name: EDGEDEVICE_DRIVER_EXEC_TIMEOUT_SECOND
          value: "5"
        - name: EDGEDEVICE_DRIVER_SSH_USER
          value: "root"
      volumes:
      - name: edgedevice-config
        configMap:
          name: rpi-gpio-configmap-0.0.1
      - name: gpiomem
        hostPath:
          path: /dev/gpiomem
      serviceAccountName: edgedevice-sa

请留神在 Deployment 文件中咱们为了在容器中应用树莓派的 GPIO,须要在容器的“securityContext”中退出“privileged: true”再通过 volume 的模式将树莓派的“/dev/gpiomem”挂载到容器中。

一个 Kubernetes Service YAML 文件,用来将 deviceShifu 的申请从域名代理到真正的 Pod:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: edgedevice-rpi-gpio-deployment
  name: edgedevice-rpi-gpio
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: edgedevice-rpi-gpio-deployment
  type: LoadBalancer

一个 Kubernetes ConfigMap YAML 文件,用来配置 deviceShifu:

apiVersion: v1
kind: ConfigMap
metadata:
  name: rpi-gpio-configmap-0.0.1
  namespace: default
data:
  driverProperties: |
    driverSku: RaspberryPiB+
    driverImage: edgenesis/rpi-gpio-python:v0.0.1
    driverExecution: "python led_driver.py"
  instructions: |
    pin:
    operate:
    help:
# Telemetries are configurable health checks of the EdgeDevice
# Developer/user can configure certain instructions to be usedas health check
# of the device. In this example, the device_health telemetry ismapped to
# "get_status" instruction, executed every 1000 ms
  telemetries: |
    device_health:
      properties:
        instruction: help
        initialDelayMs: 1000
        intervalMs: 1000

在 ConfigMap 中咱们须要配置驱动的执行门路,因为在生成镜像时咱们将 Python 文件间接放到了默认门路下,在这里填写“python led_driver.py”即可。如果驱动是一个二进制文件的话这里间接填写二进制的目录即可。

一个 Shifu EdgeDevice YAML 文件,用来生成设施孪生:

apiVersion: shifu.edgenesis.io/v1alpha1
kind: EdgeDevice
metadata:
  name: edgedevice-rpi-gpio
  namespace: devices
spec:
  sku: "RaspberryPi 3B+"
  connection: Ethernet
  address: 0.0.0.0:11112
  protocol: HTTPCommandline

将这四个文件放到树莓派中,目录内容如下:

led-deploy/
├──deviceshifu-rpi-gpio-configmap.yaml
├──deviceshifu-rpi-gpio-deployment.yaml
├──deviceshifu-rpi-gpio-service.yaml
└──edgedevice-rpi-gpio-edgedevice.yaml

利用“kubectl apply -f<dir>”即可将 deviceShifu 部署到 k3s 集群中:

接着通过“kubectl get pods”来查看运行状态:

通过“kubectl get edgedevices -n devices”来查看集群中的所有设施孪生:

再通过 describe,即可查看数字孪生的详细信息:

Note:在这里你能够留神到代表设施状态的字段”Edgedevicephase”是”Failed”的状态,这是一个目前已知的 bug,咱们将会尽快修复!

接下来咱们就能够和设施互动了,在这里咱们部署一个 nginx 容器来代表理论场景中的利用

部署命令为:“kubectl run nginx –image=nginx”

接着执行“kubectl exec -it nginx — bash”进入 nginx 的命令行:

最初,利用 curl 来给设施发送命令,驱动承受的命令格局为:
`python led_driver --pin <x> --operate <on/off>

利用 Shifu 来发送命令的话将由 HTTP 转换到命令行,申请地址写法为:


最初一步:运行成果

程序通过间接给设施的域名发送 HTTP 申请,即可操控 LED 灯泡的亮 / 灭

至此,将树莓派驱动接入 Shifu 的教程编写结束

** 总结 **

在此篇文章中,咱们实现了将一个用于操控树莓派 GPIO 的 Python 本地驱动接入 Shifu Framework,实现能够用 HTTP 来近程间接操控。能够看到,对于公有,甚至于二进制文件 Shifu 也能够轻松接入。Shifu Framework 的延展性能够让物联网开发者领有有限的可能。十分感谢您看到了这里,咱们期待您的反馈,如果感觉文章写得不错或者有任何倡议请毫不犹豫地留言。
退出移动版