kubeedge安装并接入摄像头操作说明

kubeedge安装并接入摄像头操作说明

一、说明

组件 版本 下载地址 说明
k8s 1.22.0 github 安装步骤可参考我之前的帖子
kubeedge 1.22.0 github 截至发帖最新
摄像头 淘宝(非广告,选类似的) 支持RTSP、ONVIF协议,使用有线

且准备至少2台server(服务器或虚拟机)。

二、安装

1、安装keadm

在已安装的k8s集群中操作,首先获取压缩包:

复制代码
https://github.com/kubeedge/kubeedge/releases/download/v1.22.0/keadm-v1.22.0-linux-amd64.tar.gz

安装keadm:

复制代码
tar -zxvf keadm-v1.22.0-linux-amd64.tar.gz
cp keadm /usr/bin/

2、安装cloudcore

执行:

复制代码
#配置docker代理,方便拉取相关镜像
keadm init --advertise-address=192.168.135.134 --kubeedge-version=v1.22.0  --kube-config=/root/.kube/config

查看cloudcore安装情况:

复制代码
root@ubuntu:/usr/local/src/github.com/kubeedge/kubeedge# kubectl get all -n kubeedge
NAME                               READY   STATUS    RESTARTS   AGE
pod/cloud-iptables-manager-9p9lf   1/1     Running   0          87s
pod/cloudcore-55fcd4f859-f2brv     1/1     Running   0          87s

NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                                             AGE
service/cloudcore   ClusterIP   10.96.3.145   <none>        10000/TCP,10001/UDP,10002/TCP,10003/TCP,10004/TCP   87s

NAME                                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/cloud-iptables-manager   1         1         1       1            1           <none>          87s
daemonset.apps/edge-eclipse-mosquitto   0         0         0       0            0           <none>          87s

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cloudcore   1/1     1            1           87s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/cloudcore-55fcd4f859   1         1         1       87s

3、安装edgecore

准备一台服务器作为edge节点(还未纳管进k8s集群),且该节点需要安装containerd(docker不兼容)。

1)修改主机名

节点名称需要和cloudcore端不同,否则无法加入k8s集群。以edge-1为例:

复制代码
hostnamectl set-hostname edge-1
vim /etc/hosts

对/etc/hosts的内容进行修改:将127.0.1.1改为新的不在集群内重复的名称。

复制代码
127.0.0.1       localhost
127.0.1.1       edge-1

修改完后重启该节点:

复制代码
reboot -h now
2)安装containerd
(1)更新系统并安装依赖
复制代码
sudo apt update && sudo apt upgrade -y
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
​(2)添加Docker官方GPG密钥和仓库源*
复制代码
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
​(3)安装containerd*
复制代码
sudo apt update
sudo apt install -y containerd.io
(4)启动服务并设置开机自启
复制代码
sudo systemctl enable --now containerd
sudo systemctl status containerd  # 检查状态(应为active)
​(5)验证安装​
复制代码
sudo ctr version  # 显示Client和Server版本即成功
3)安装CNI

安装完containerd后,需要安装对应的cni插件。

(1)containerd中添加cni插件配置

sudo vi /etc/containerd/config.toml

复制代码
# disabled_plugins = ["cri"]
[plugins."io.containerd.grpc.v1.cri".cni]
  bin_dir = "/opt/cni/bin"   # CNI插件二进制文件路径
  conf_dir = "/etc/cni/net.d" # CNI配置文件路径
(2)安装CNI插件

安装cni插件:

复制代码
mkdir -p /opt/cni/bin 
wget https://github.com/containernetworking/plugins/releases/download/v1.7.1/cni-plugins-linux-amd64-v1.7.1.tgz
sudo tar -C /opt/cni/bin -xzf cni-plugins-linux-amd64-v1.7.1.tgz

配置cni:

/etc/cni/net.d/10-mynet.conflist的内容如下:

复制代码
{
  "cniVersion": "1.0.0",
  "name": "mynet",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "cni0",
      "isGateway": true,
      "ipMasq": true,
      "ipam": {
        "type": "host-local",
        "ranges": [
          [{"subnet": "10.88.0.0/16"}]
        ],
        "routes": [{"dst": "0.0.0.0/0"}]
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    }
  ]
}

重启containerd:

复制代码
sudo systemctl restart containerd
sudo systemctl status containerd # 确认服务状态正常
4)、安装edgecore

配置containerd的代理,下载镜像:

复制代码
ctr images pull docker.io/kubeedge/installation-package:v1.22.0

在cloudcore节点中获取token:

复制代码
root@ubuntu:/usr/local/src/github.com/kubeedge/kubeedge# keadm gettoken
e1c7098d412bf8df63e4f3f3bb44415147dda285164ef6cac2e19fc3aa73c71a.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjI3NjE5NTZ9.dVqpfvh6_vWhgZoQXft1D8hmki4prBv-AIGXwT2tX_A

在edgecore节点执行:

复制代码
keadm join --cloudcore-ipport=192.168.20.50:10000 --token=27a37ef16159f7d3be8fae95d588b79b3adaaf92727b72659eb89758c66ffda2.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTAyMTYwNzd9.JBj8LLYWXwbbvHKffJBpPd5CyxqapRQYDIXtFZErgYE --kubeedge-version=v1.17.0
5)、适配容器环境

修改端侧端口监听地址:

由于相关容器跑在容器环境中,故需要修改监听地址为该edgecore节点的地址:

复制代码
vim /etc/kubeedge/config/edgecore.yaml

将127.0.0.1改为:

复制代码
...
tailoredKubeletConfig:
  address: 192.168.135.135
...

在/etc/hosts中加入域名:

复制代码
192.168.135.135 localhost

重启edgecore:

复制代码
systemctl restart edgecore.service
#查看edgecore是否异常
systemctl status edgecore.service

注意:当前情况下,calico的pod出现问题也没有影响。若需要解决calico的问题请安装edgemesh组件。

5)、卸载kubeedge

若之前步骤操作有问题,或者需要重新安装,则需要执行以下步骤:

复制代码
keadm deprecated reset

sudo rm -rf /etc/kubeedge/
sudo rm -rf /var/lib/kubeedge/

三、接入摄像头

1、确认摄像头信息

需要到摄像头官网下载对应操作app,来获取摄像头ip,以及对摄像头进行配置。

该部分摄像头的说明书中有介绍。

2、部署 ONVIF Mapper

1)搭建编译环境

kubeedge没有提供已编译好的镜像(估计是每个厂商的onvif协议理解和处理的不一样)。故需要自行编译。本人本地虚拟机(Ubuntu20.04)编译没成功。故找到官方提供的编译镜像。(估计Ubuntu18.0.4能成)。

下载编译镜像:

复制代码
docker pull kubeedge/build-tools:1.22.9-ke1

搭建编译环境:

复制代码
#启动容器
docker run -it kubeedge/build-tools:1.22.9-ke1 bash
#找个目录下载onvif的代码
git clone git@github.com:kubeedge/mappers-go
#更新环境
apt-get update && 
apt-get install -y upx-ucl gcc-aarch64-linux-gnu libc6-dev-arm64-cross gcc-arm-linux-gnueabi libc6-dev-armel-cross libva-dev libva-drm2 libx11-dev libvdpau-dev libxext-dev libsdl1.2-dev libxcb1-dev libxau-dev libxdmcp-dev yasm 
apt install pkg-config
apt install curl
curl -sLO https://ffmpeg.org/releases/ffmpeg-4.1.6.tar.bz2 && 
tar -jx --strip-components=1 -f ffmpeg-4.1.6.tar.bz2 &&  
./configure &&  make && 
sudo make install
2)编译onvif-mapper二进制
复制代码
#编译onvif代码
cd /usr/local/src/mappers-go/mappers/onvif/cmd
#后续调试会遇到解析onvif协议的问题,需要修改对应的代码。
#主要有两点:1、解析摄像头返回的RTSP协议地方。2、获取RTSPurl的地方。
go build -o onvif .
3)制作onvif-mapper镜像

编译好后,将二进制拷贝出来(根据/usr/local/src/mappers-go/mappers/onvif/中DockeFile的说明放入bin目录下)。

复制代码
docker cp 容器号:/usr/local/src/mappers-go/mappers/onvif/cmd/onvif /usr/local/src/mappers-go/mappers/onvif/cmd/bin/

然后拉取制作DockerFile要求的镜像:

复制代码
docker pull ubuntu:18.04
docker run -it --rm ubuntu:18.04 bash
#在该镜像中安装如下依赖:
apt install libva2 libva-drm2 libva-x11-2 libvdpau1 libvdpau-dev
#再次提交镜像
docker commit 容器号 ubuntu:18.05

修改DockerFile文件,将ubuntu:18.04改为ubuntu:18.05

然后制作镜像:

复制代码
docker build -t onvif-mapper:v1.7-linux-amd64 .
4)在端侧导入
复制代码
docker save onvif-mapper:v1.7-linux-amd64>onvif-mapper.tar.gz
scp onvif-mapper.tar.gz root@端侧ip:/目录
ctr -n k8s.io images import onvif-mapper.tar.gz
5)启动摄像头接入pod

修改配置文件

复制代码
cd /usr/local/src/github.com/kubeedge/mappers-go/mappers/onvif/

中部署文件deployment.yaml,本人重命名为:5-onvif-mapper-deployment.yaml,并修改内容为:

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: onvif-mapper
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: onvif-mapper
  template:
    metadata:
      labels:
        app: onvif-mapper
    spec:
      # 使用节点选择器,确保 Pod 被调度到有摄像头的边缘节点
      nodeSelector:
        kubernetes.io/hostname: edge-1
      containers:
      - name: onvif-mapper
        image: docker.io/library/onvif-mapper:v1.7-linux-amd64
        volumeMounts:
        - mountPath: /etc/secret
          name: camera-secret
        - name: device-profile-volume
          mountPath: /opt/kubeedge/
          readOnly: true
        - name: frames-volume
          mountPath: /home/btg/frames
        - name: videos-volume
          mountPath: /home/btg/videos
      volumes:
      - name: camera-secret
        secret:
          secretName: onvif-camera-secret
      - name: device-profile-volume
        configMap:
          name: device-profile-config-01
          items:
          - key: deviceProfile.json
            path: deviceProfile.json
      - name: frames-volume
        hostPath:
          path: /home/btg/frames
          type: DirectoryOrCreate
      - name: videos-volume
        hostPath:
          path: /home/btg/videos
          type: DirectoryOrCreate

其对应的cm文件为:4-onvif-cm.yaml

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: device-profile-config-01
  namespace: default
data:
  deviceProfile.json: |-
    {
        "deviceInstances": [
            {
                "id": "my-onvif-camera",
                "name": "my-onvif-camera",
                "protocol": "customized-protocol-camera01",
                "model": "onvif-camera-model",
                "twins": [
                    {
                        "propertyName": "SaveFrame",
                        "desired": {
                            "value": "true",
                            "metadata": {
                                "type": "boolean"
                            }
                        },
                        "reported": {
                            "value": "true",
                            "metadata": {
                                "type": "boolean"
                            }
                        }
                    },
                    {
                        "propertyName": "SaveVideo",
                        "desired": {
                            "value": "true",
                            "metadata": {
                                "type": "boolean"
                            }
                        },
                        "reported": {
                            "value": "true",
                            "metadata": {
                                "type": "boolean"
                            }
                        }
                    },
                    {
                        "propertyName": "reboot",
                        "desired": {
                            "value": "false",
                            "metadata": {
                                "timestamp": "1550049403598",
                                "type": "boolean"
                            }
                        },
                        "reported": {
                            "value": "false",
                            "metadata": {
                                "timestamp": "1550049403598",
                                "type": "boolean"
                            }
                        }
                    }
                ],
                "propertyVisitors": [
                    {
                        "name": "reboot",
                        "propertyName": "reboot",
                        "modelName": "onvif-camera-model",
                        "collectCycle": 2000000000,
                        "protocol": "customized-protocol-camera01",
                        "visitorConfig": {
                            "protocolName": "onvif",
                            "configData": {
                                "method": "SystemReboot"
                            }
                        }
                    },
                    {
                        "name": "SaveFrame",
                        "propertyName": "SaveFrame",
                        "modelName": "onvif-camera-model",
                        "collectCycle": 10000000000,
                        "protocol": "customized-protocol-camera01",
                        "visitorConfig": {
                            "protocolName": "onvif",
                            "configData": {
                                "method": "SaveFrame",
                                "outputDir": "/home/btg/frames",
                                "format": "jpg",
                                "frameCount": 10,
                                "frameInterval": 20000000000
                            }
                        }
                    },
                    {
                        "name": "SaveVideo",
                        "propertyName": "SaveVideo",
                        "modelName": "onvif-camera-model",
                        "collectCycle": 30000000000,
                        "protocol": "customized-protocol-camera01",
                        "visitorConfig": {
                            "protocolName": "onvif",
                            "configData": {
                                "method": "SaveVideo",
                                "outputDir": "/home/btg/videos",
                                "format": "avi",
                                "frameCount": 2
                            }
                        }
                    }
                ]
            }
        ],
        "deviceModels": [
            {
                "name": "onvif-camera-model",
                "properties": [
                    {
                        "name": "reboot",
                        "dataType": "boolean",
                        "description": "Reboot the camera",
                        "accessMode": "ReadWrite",
                        "defaultValue": false
                    },
                    {
                        "name": "SaveFrame",
                        "dataType": "boolean",
                        "description": "Save video frames",
                        "accessMode": "ReadWrite",
                        "defaultValue": true
                    },
                    {
                        "name": "SaveVideo",
                        "dataType": "boolean",
                        "description": "Save video stream",
                        "accessMode": "ReadWrite",
                        "defaultValue": true
                    }
                ]
            }
        ],
        "protocols": [
            {
                "name": "customized-protocol-camera01",
                "protocol": "customized-protocol",
                "protocolConfig": {
                    "protocolName": "onvif",
                    "configData": {
                        "url": "192.168.1.188:80",
                        "userName": "admin",
                        "password": "/etc/secret/password"
                    }
                },
                "protocolCommonConfig": null
            }
        ]
    }

注意:容器现在还不支持mp4加解码。故需要配置为avi。

此外还需要将摄像头的密码也进行配置,放入1-onvif-secret.yaml文件

复制代码
# onvif-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: onvif-camera-secret
  namespace: default
type: Opaque
data:
  password: MTIzNDU2Cg==

其中password使用base64编码获得。

复制代码
echo 123456 |base64

启动相关pod:

复制代码
kubectl apply -f 1-onvif-secret.yaml
kubectl apply -f 4-onvif-cm.yaml
kubectl apply -f 5-onvif-mapper-deployment.yaml

此时从k8s中看到的相关pod如下:

复制代码
default            onvif-mapper-5f666d8769-2md8c              1/1     Running
kubeedge           cloud-iptables-manager-dx55x               1/1     Running
kubeedge           cloudcore-55fcd4f859-pffmv                 1/1     Running
kubeedge           edge-eclipse-mosquitto-bdnz5               1/1     Running
6)验证结果

此时到边缘节点中查看相应的目录:

复制代码
ll /home/btg/frames/
ll /home/btg/videos/

注意:/home/btg/videos中保存的是视频帧,每秒数量在摄像头界面进行配置。

四、附录

1、查看日志

edgecore日志:

复制代码
journalctl -u edgecore -n 50 -f

2、测试rtsp是否通

复制代码
# 使用ffmpeg测试RTSP流,具体rul写法参见摄像头的说明书
ffmpeg -i "rtsp://admin:123456@192.168.1.188:554/cho01.264" -t 10 -f null -

# 使用vlc测试
vlc "rtsp://admin:123456@192.168.1.188:554"

3、控制摄像头运动

复制代码
http://192.168.1.188:80/digest/frmPTZControl
post方式,发送的body为:
摄像头向左转动:
{"Type":1,"Dev":1,"Ch":1,"Data":{"Cmd":23,"IsStop":0,"Speed":5}}
摄像头向右转动:
{"Type":1,"Dev":1,"Ch":1,"Data":{"Cmd":24,"IsStop":1,"Speed":5}}
摄像头向上转动:
{"Type":1,"Dev":1,"Ch":1,"Data":{"Cmd":21,"IsStop":1,"Speed":5}}
摄像头向下转动:
{"Type":1,"Dev":1,"Ch":1,"Data":{"Cmd":22,"IsStop":1,"Speed":5}}

返回的body为:
{"Result":0,"Data":{"StatusCode":"Operation Ok"}}


curl -X POST \
  http://192.168.1.188:80/digest/frmPTZControl \
  -H "Content-Type: application/json" \
  --digest -u admin:123456 \
  -d '{"Type":1,"Dev":1,"Ch":1,"Data":{"Cmd":24,"IsStop":0,"Speed":5}}'
相关推荐
serendipity_hky2 小时前
【微服务 - easy视频 | day02】全局过滤器+局部过滤器+全局拦截器
spring cloud·微服务·云原生·架构
运维 小白4 小时前
k8s 部署MySQL主从集群(一主两从)1.0
mysql·容器·kubernetes
ζั͡山 ั͡有扶苏 ั͡✾5 小时前
完善EKF可观测性体系:基于ElastAlert2构建k8s智能钉钉日志告警系统
容器·kubernetes·钉钉·kibana·filebeat·日志监控
陈陈CHENCHEN5 小时前
【Kubernetes】K8s 集群 Ingress 入口规则
kubernetes
一枚正在学习的小白5 小时前
k8s的包管理工具(5)--读取文件内容
云原生·容器·kubernetes
阿里云云原生7 小时前
AI 原生应用开发实战营·京沪双城回顾 & PPT 下载
云原生
muyesouu9 小时前
kubernetes 安装配置 需要有两个地方配置国内镜像地址
云原生·容器·kubernetes
阿里云云原生9 小时前
从 Transform 到 Transformer,用 EventBridge 与百炼构建实时智能的 ETL 数据管道
云原生
easy_coder11 小时前
MinIO:云原生时代的分布式对象存储从入门到精通
分布式·云原生