kubeedge 组件
Edged:一个运行在 edge 节点的 agent 程序,管理边缘的容器化应用程序
EdgeHub:边缘的通信接口模块。这是一个 Web 套接字客户端,负责边缘计算与云服务的交互。包括同步云端资源到边缘端,以及报告边缘端 host 和 device 状态到云端
CloudHub:云端通讯接口模块。一个 Web 套接字服务器,负责监视云端的更改、缓存以及向 EdgeHub 发送消息
EdgeController:管理边缘节点。它是一个扩展的 Kubernetes 控制器,管理边缘节点和 pod 元数据,以便数据可以面向特定的边缘节点
EventBus:使用 MQTT 处理内部边缘通信。MQTT 客户端与 MQTT 服务器(mosquitto)交互,为其他组件提供发布和订阅功能
DeviceTwin:处理设备元数据的设备软件镜像。该模块有助于处理设备状态并将其同步到云上。它还为应用程序提供查询接口,它连接到一个轻量级数据库(SQLite)
MetaManager:管理边缘节点上的元数据。这是 Edged 和 Edgehub 之间的消息处理器。负责在轻量级数据库(SQLite)中存储 / 检索元数据
kubeEdge 包括 cloud 和 edge 部分,在 kubernetes 构建,在 cloud 与 edge 端提供核心的基础支持,比如网络,应用,部署以及元数据的同步等。
安装kubeEdge 需要安装 kubernetes 集群,cloud 与 edge 部分
cloud side: docker, kubernetes cluster and cloudcore.
edge side:docker, mqtt and edgecore.
Prerequisites
Install docker on cloud and edge side (you can also run other runtime, such as containerd) Install kubeadm/kubectl on cloud side Creating kubernetes cluster with kubeadm on cloud side Go The minimum required go version is 1.12. You can install this version by using this website. Install mosquitto on every edge side
golang版本
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# go version go version go1.14.6 linux/arm64
1. 安装 cloud side
git clone https://github.com/kubeedge/kubeedge.git $GOPATH/src/github.com/kubeedge/kubeedge cd $GOPATH/src/github.com/kubeedge/kubeedge
生成秘钥
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# build/tools/certgen.sh genCertAndKey edge Generating RSA private key, 4096 bit long modulus (2 primes) ......................................................................................................++++ ......................................++++ e is 65537 (0x010001) Can't load /root/.rnd into RNG 281473257408128:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd Generating RSA private key, 2048 bit long modulus (2 primes) ..........................................+++++ ......................................................................+++++ e is 65537 (0x010001) Can't load /root/.rnd into RNG 281473864328832:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd Signature ok subject=C = CN, ST = Zhejiang, L = Hangzhou, O = KubeEdge, CN = kubeedge.io Getting CA Private Key
缺少/root/.rnd
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# ls /root/.rnd ls: cannot access '/root/.rnd': No such file or directory root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# cd /root root@ubuntu:~# openssl rand -writerand .rnd root@ubuntu:~# ls /root/.rnd /root/.rnd root@ubuntu:~# cd - /opt/gopath/src/github.com/kubeedge/kubeedge
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# build/tools/certgen.sh genCertAndKey edge Generating RSA private key, 2048 bit long modulus (2 primes) ...............................+++++ ..............................................+++++ e is 65537 (0x010001) Signature ok subject=C = CN, ST = Zhejiang, L = Hangzhou, O = KubeEdge, CN = kubeedge.io Getting CA Private Key root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# ls /etc/kubeedge/ca rootCA.crt rootCA.key rootCA.srl root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# ls /etc/kubeedge/ ca certs root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# ls /etc/kubeedge/certs/ edge.crt edge.csr edge.key root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge#
/etc/kubeedge/ca
和 /etc/kubeedge/certs
生成,可以拷贝至 edge 服务端
certgen.sh stream (可选)
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# build/tools/certgen.sh stream You must set CLOUDCOREIPS Env,The environment variable is set to specify the IP addresses of all cloudcore If there are more than one IP need to be separated with space. root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# export CLOUDCOREIPS="192.168.56.105" root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# build/tools/certgen.sh stream Generating RSA private key, 2048 bit long modulus (2 primes) ...............+++++ ...+++++ e is 65537 (0x010001) Certificate Request: Data: Version: 1 (0x0) Subject: C = CN, ST = Zhejiang, L = Hangzhou, O = KubeEdge Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit)
…………………………
…………………………
root@ubuntu:~/cmd# tree /etc/kubeedge/ /etc/kubeedge/ ├── ca │ ├── rootCA.crt │ ├── rootCA.key │ ├── rootCA.srl │ └── streamCA.crt ├── certs │ ├── edge.crt │ ├── edge.csr │ ├── edge.key │ ├── stream.crt │ ├── stream.csr │ └── stream.key └── config └── cloudcore.yaml 3 directories, 11 files
编译kubeadm
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# make all WHAT=keadm hack/verify-golang.sh go detail version: go version go1.14.6 linux/arm64 go version: 1.14.6 KUBEEDGE_OUTPUT_SUBPATH=_output/local hack/make-rules/build.sh keadm building github.com/kubeedge/kubeedge/keadm/cmd/keadm + go build -o /opt/gopath/src/github.com/kubeedge/kubeedge/_output/local/bin/keadm -gcflags= -ldflags '-s -w -buildid= -X github.com/kubeedge/kubeedge/pkg/version.buildDate=2021-04-09T03:50:56Z -X github.com/kubeedge/kubeedge/pkg/version.gitCommit=853c367496baaccb966cb5d09c3fcd7f00ab2816 -X github.com/kubeedge/kubeedge/pkg/version.gitTreeState=clean -X github.com/kubeedge/kubeedge/pkg/version.gitVersion=v1.6.0-beta.0.168+853c367496baac -X github.com/kubeedge/kubeedge/pkg/version.gitMajor=1 -X github.com/kubeedge/kubeedge/pkg/version.gitMinor=6+' github.com/kubeedge/kubeedge/keadm/cmd/keadm + set +x root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# find ./ -name keadm ./_output/local/bin/keadm ./tests/e2e/keadm ./keadm ./keadm/cmd/keadm
go build -o /opt/gopath/src/github.com/kubeedge/kubeedge/_output/local/bin/keadm
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# ~/cmd/keadm version version: version.Info{Major:"1", Minor:"6+", GitVersion:"v1.6.0-beta.0.168+853c367496baac", GitCommit:"853c367496baaccb966cb5d09c3fcd7f00ab2816", GitTreeState:"clean", BuildDate:"2021-04-09T03:50:56Z", GoVersion:"go1.14.6", Compiler:"gc", Platform:"linux/arm64"} root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# ~/cmd/keadm gettoken ca087da069379101e94210dc8437712540efa7d5d298d7dfea90df52552cf162.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MTgwMjQ2MjZ9.VxYI8ATgvp4yLc317AEArVsqdCEQRBRC1oa3ZOrxH-E root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge#
编译 cloudcore
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# make all WHAT=cloudcore hack/verify-golang.sh go detail version: go version go1.14.6 linux/arm64 go version: 1.14.6 KUBEEDGE_OUTPUT_SUBPATH=_output/local hack/make-rules/build.sh cloudcore building github.com/kubeedge/kubeedge/cloud/cmd/cloudcore + go build -o /opt/gopath/src/github.com/kubeedge/kubeedge/_output/local/bin/cloudcore -gcflags= -ldflags '-s -w -buildid= -X github.com/kubeedge/kubeedge/pkg/version.buildDate=2021-04-07T08:42:40Z -X github.com/kubeedge/kubeedge/pkg/version.gitCommit=853c367496baaccb966cb5d09c3fcd7f00ab2816 -X github.com/kubeedge/kubeedge/pkg/version.gitTreeState=clean -X github.com/kubeedge/kubeedge/pkg/version.gitVersion=v1.6.0-beta.0.168+853c367496baac -X github.com/kubeedge/kubeedge/pkg/version.gitMajor=1 -X github.com/kubeedge/kubeedge/pkg/version.gitMinor=6+' github.com/kubeedge/kubeedge/cloud/cmd/cloudcore + set +x root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# find ./ -name cloudcore ./pkg/apis/componentconfig/cloudcore ./_output/local/bin/cloudcore ./cloud/cmd/cloudcore root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge#
创建设备模块和设备CRD
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# cd build/crds/devices root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# ls devices_v1alpha1_devicemodel.yaml devices_v1alpha1_device.yaml devices_v1alpha2_devicemodel.yaml devices_v1alpha2_device.yaml root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl create -f devices_v1alpha1_devicemodel.yaml customresourcedefinition.apiextensions.k8s.io/devicemodels.devices.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl create -f devices_v1alpha1_device.yaml customresourcedefinition.apiextensions.k8s.io/devices.devices.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices#
cloudcore 可执行文件和配置文件
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# file ./_output/local/bin/cloudcore ./_output/local/bin/cloudcore: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.7.0, BuildID[sha1]=46b0f3e80a14f05f4fbfc7cb47c24259b193617b, stripped root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge#
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# mkdir -p ~/cmd/conf
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# cp ../_output/local/bin/cloudcore ~/cmd
cp: cannot stat '../_output/local/bin/cloudcore': No such file or directory
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# cp _output/local/bin/cloudcore ~/cmd
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# cd ~/cmd/conf
root@ubuntu:~/cmd/conf# ls
kube-apiserve端口
root@ubuntu:~# netstat -pan | grep -i listen | grep kube-apiserve tcp6 0 0 :::6443 :::* LISTEN 12424/kube-apiserve
[root@bogon ~]# curl https://10.11.96.82:6443 curl: (60) Peer's Certificate issuer is not recognized. More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option. [root@bogon ~]# curl https://10.10.16.82:6443 --insecure { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"", "reason": "Forbidden", "details": { }, "code": 403 }[root@bogon ~]#
/etc/kubernetes/manifests/kube-apiserver.yaml
可以将cloudcore或edgecore二进制文件移动到任何地方,但需要在与二进制文件相同的目录中创建conf目录。 如果cloud和edge是同一台机器请注意和edgecore分开目录
.kube/config
In the cloudcore.yaml, modify the below settings.
-
Either
kubeAPIConfig.kubeConfig
orkubeAPIConfig.master
: This would be the path to your kubeconfig file. It might be either/root/.kube/config
or
/home/<your_username>/.kube/config
depending on where you have setup your kubernetes by performing the below step:
To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
By default, cloudcore use https connection to Kubernetes apiserver. If
master
andkubeConfig
are both set,master
will override any value in kubeconfig.
root@ubuntu:~/cmd# ls cloudcore conf root@ubuntu:~/cmd# ./cloudcore F0408 10:42:04.947826 27713 server.go:51] [ config: Required value: config file /etc/kubeedge/config/cloudcore.yaml not exist. For the configuration file format, please refer to --minconfig and --defaultconfig command ] goroutine 1 [running]: k8s.io/klog/v2.stacks(0x40001a6001, 0x4000354000, 0xe0, 0x134) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:996 +0xac k8s.io/klog/v2.(*loggingT).output(0x26d34c0, 0x4000000003, 0x0, 0x0, 0x40003ff810, 0x25e7148, 0x9, 0x33, 0x40001f5b00) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:945 +0x17c k8s.io/klog/v2.(*loggingT).printDepth(0x26d34c0, 0x3, 0x0, 0x0, 0x1, 0x40001f5cb8, 0x1, 0x1) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:718 +0x118 k8s.io/klog/v2.(*loggingT).print(...) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:703 k8s.io/klog/v2.Fatal(...) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:1436 github.com/kubeedge/kubeedge/cloud/cmd/cloudcore/app.NewCloudCoreCommand.func1(0x4000030dc0, 0x26ff7e8, 0x0, 0x0) /opt/gopath/src/github.com/kubeedge/kubeedge/cloud/cmd/cloudcore/app/server.go:51 +0x438 github.com/spf13/cobra.(*Command).execute(0x4000030dc0, 0x4000198190, 0x0, 0x0, 0x4000030dc0, 0x4000198190) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/github.com/spf13/cobra/command.go:846 +0x1c4 github.com/spf13/cobra.(*Command).ExecuteC(0x4000030dc0, 0x43f07c, 0x400018e058, 0x0) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/github.com/spf13/cobra/command.go:950 +0x260 github.com/spf13/cobra.(*Command).Execute(...) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/github.com/spf13/cobra/command.go:887 main.main() /opt/gopath/src/github.com/kubeedge/kubeedge/cloud/cmd/cloudcore/cloudcore.go:16 +0x54 goroutine 19 [chan receive]: k8s.io/klog/v2.(*loggingT).flushDaemon(0x26d34c0) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:1131 +0x70 created by k8s.io/klog/v2.init.0 /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/v2/klog.go:416 +0x118 goroutine 85 [select]: github.com/kubeedge/kubeedge/cloud/pkg/router/rule.handleResult(0x40004cc9c0, 0x400018e1e0) /opt/gopath/src/github.com/kubeedge/kubeedge/cloud/pkg/router/rule/statushandler.go:49 +0x13c created by github.com/kubeedge/kubeedge/cloud/pkg/router/rule.init.1 /opt/gopath/src/github.com/kubeedge/kubeedge/cloud/pkg/router/rule/statushandler.go:27 +0x54 goroutine 86 [select]: k8s.io/apimachinery/pkg/util/wait.BackoffUntil(0x1840a80, 0x1a201a0, 0x400051c300, 0x1, 0x400018e0c0) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:167 +0xec k8s.io/apimachinery/pkg/util/wait.JitterUntil(0x1840a80, 0x12a05f200, 0x0, 0x1, 0x400018e0c0) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 +0x88 k8s.io/apimachinery/pkg/util/wait.Until(...) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:90 k8s.io/apimachinery/pkg/util/wait.Forever(0x1840a80, 0x12a05f200) /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:81 +0x50 created by k8s.io/component-base/logs.InitLogs /opt/gopath/src/github.com/kubeedge/kubeedge/vendor/k8s.io/component-base/logs/logs.go:58 +0x8
参考
root@ubuntu:~/cmd# mkdir -p /etc/kubeedge/config/
root@ubuntu:~/cmd# ./cloudcore --defaultconfig > /etc/kubeedge/config/cloudcore.yaml
root@ubuntu:~/cmd# ./cloudcore --version KubeEdge v1.6.0-beta.0.168+853c367496baac root@ubuntu:~/cmd#
1.6 需要如下
root@ubuntu:~/cmd# cd /opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# ls devices_v1alpha1_devicemodel.yaml devices_v1alpha1_device.yaml devices_v1alpha2_devicemodel.yaml devices_v1alpha2_device.yaml root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl create -f devices_v1alpha2_devicemodel.yaml Error from server (AlreadyExists): error when creating "devices_v1alpha2_devicemodel.yaml": customresourcedefinitions.apiextensions.k8s.io "devicemodels.devices.kubeedge.io" already exists
devices_v1alpha1_devicemodel.yaml devices_v1alpha1_device.yaml devices_v1alpha2_devicemodel.yaml devices_v1alpha2_device.yaml root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl delete -f .com/kubeedge/kubeedge/build/crds/devices# ls error: the path ".com/kubeedge/kubeedge/build/crds/devices#" does not exist root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl delete -f devices_v1alpha1_devicemodel.yaml customresourcedefinition.apiextensions.k8s.io "devicemodels.devices.kubeedge.io" deleted root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl delete -f devices_v1alpha1_device.yaml customresourcedefinition.apiextensions.k8s.io "devices.devices.kubeedge.io" deleted root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl create -f devices_v1alpha2_devicemodel.yaml customresourcedefinition.apiextensions.k8s.io/devicemodels.devices.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# ls devices_v1alpha1_devicemodel.yaml devices_v1alpha1_device.yaml devices_v1alpha2_devicemodel.yaml devices_v1alpha2_device.yaml root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices# kubectl create -f devices_v1alpha2_device.yaml customresourcedefinition.apiextensions.k8s.io/devices.devices.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/devices#
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs# ls cluster_objectsync_v1alpha1.yaml objectsync_v1alpha1.yaml root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs# kubectl create -f cluster_objectsync_v1alpha1.yaml customresourcedefinition.apiextensions.k8s.io/clusterobjectsyncs.reliablesyncs.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs# kubectl create -f objectsync_v1alpha1.yaml customresourcedefinition.apiextensions.k8s.io/objectsyncs.reliablesyncs.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs# cd ../router/ root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/router# ls router_v1_ruleEndpoint.yaml router_v1_rule.yaml root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/router# kubectl create -f router_v1_ruleEndpoint.yaml customresourcedefinition.apiextensions.k8s.io/ruleendpoints.rules.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/router# kubectl create -f router_v1_rule.yaml customresourcedefinition.apiextensions.k8s.io/rules.rules.kubeedge.io created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge/build/crds/router#
cloudCore:
pkill cloudcore nohup cloudcore > cloudcore.log 2>&1 &
./cloudcore --config cloudcore.yaml
root@ubuntu:~/cmd# nohup cloudcore > cloudcore.log 2>&1 & [1] 36041 root@ubuntu:~/cmd# ls cloudcore cloudcore.log conf [1]+ Exit 127 nohup cloudcore > cloudcore.log 2>&1 root@ubuntu:~/cmd# ps -elf | grep cloudcore 0 S root 36049 24962 0 80 0 - 1096 pipe_w 11:10 pts/0 00:00:00 grep cloudcore root@ubuntu:~/cmd#
创建node
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# kubectl apply -f ./build/node.json node/edge-node created root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# kubectl get nodes NAME STATUS ROLES AGE VERSION edge-node Unknown edge 36s ubuntu Ready master 178d v1.18.1 root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge#
root@ubuntu:~/cmd# cat cloudcore.log nohup: ignoring input nohup: failed to run command 'cloudcore': No such file or directory root@ubuntu:~/cmd# nohup ./cloudcore > cloudcore.log 2>&1 & [1] 36676 root@ubuntu:~/cmd# ps -elf | grep cloudcore 0 S root 36712 24962 0 80 0 - 1096 pipe_w 11:12 pts/0 00:00:00 grep cloudcore [1]+ Exit 255 nohup ./cloudcore > cloudcore.log 2>&1 root@ubuntu:~/cmd#
E0507 15:14:32.101516 57266 server.go:324] failed to sign a certificate, error: failed to parse ECPrivateKey, err: x509: failed to parse EC private key: asn1: structure error: tags don't match (16 vs {class:1 tag:24 length:103 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} ecPrivateKey @2 F0507 15:14:32.101554 57266 cloudhub.go:73] failed to parse ECPrivateKey, err: x509: failed to parse EC private key: asn1: structure error: tags don't match (16 vs {class:1 tag:24 length:103 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} ecPrivateKey @2
// Check whether the CloudCore certificates exist in the local directory if hubconfig.Config.Key == nil && hubconfig.Config.Cert == nil { klog.Infof("CloudCoreCert and key don't exist in local directory, and will read from the secret") // Check whether the CloudCore certificates exist in the secret secretHasCert := CheckCertExistsFromSecret() if !secretHasCert { klog.Info("CloudCoreCert and key don't exist in the secret, and will be signed by CA") certDER, keyDER, err := SignCerts() if err != nil { klog.Errorf("failed to sign a certificate, error: %v", err) return err } err = CreateCloudCoreSecret(certDER, keyDER) if err != nil { klog.Errorf("failed to save CloudCore cert and key to secret, error: %v", err) return err } UpdateConfig(nil, nil, certDER, keyDER) } else { s, err := GetSecret(CloudCoreSecretName, NamespaceSystem) if err != nil { klog.Errorf("failed to get CloudCore secret, error: %v", err) return err } certDER := s.Data[CloudCoreCertName] keyDER := s.Data[CloudCoreKeyDataName] UpdateConfig(nil, nil, certDER, keyDER) } } e
root@ubuntu:/etc/kubeedge/certs# ls edge.crt edge.csr edge.key stream.crt stream.csr stream.key
private key root@ubuntu:/etc/kubeedge/certs# openssl genrsa -out server.key 1024 Generating RSA private key, 1024 bit long modulus (2 primes) ....+++++ .+++++ e is 65537 (0x010001)
public key root@ubuntu:/etc/kubeedge/certs# openssl rsa -in server.key -pubout -out server.crt writing RSA key root@ubuntu:/etc/kubeedge/certs# cd - /root/cmd root@ubuntu:~/cmd# ls /etc/kubeedge/certs/ edge.crt edge.csr edge.key server.crt server.key stream.crt stream.csr stream.key root@ubuntu:~/cmd#
nohup: ignoring input I0408 14:49:55.702998 32710 server.go:64] Version: v1.6.0-beta.0.168+853c367496baac I0408 14:49:55.706916 32710 config.go:45] Succeed in loading CA certificate from local directory I0408 14:49:55.707004 32710 config.go:52] Succeed in loading CA key from local directory I0408 14:49:55.707055 32710 config.go:66] Succeed in loading certificate from local directory I0408 14:49:55.707098 32710 config.go:72] Succeed in loading private key from local directory I0408 14:49:55.707137 32710 module.go:34] Module cloudhub registered successfully I0408 14:49:55.729873 32710 module.go:34] Module edgecontroller registered successfully I0408 14:49:55.729986 32710 module.go:34] Module devicecontroller registered successfully I0408 14:49:55.730027 32710 module.go:34] Module synccontroller registered successfully W0408 14:49:55.730183 32710 module.go:37] Module cloudStream is disabled, do not register W0408 14:49:55.730230 32710 module.go:37] Module router is disabled, do not register W0408 14:49:55.730246 32710 module.go:37] Module dynamiccontroller is disabled, do not register I0408 14:49:55.730341 32710 core.go:24] Starting module devicecontroller I0408 14:49:55.730383 32710 core.go:24] Starting module synccontroller I0408 14:49:55.730676 32710 core.go:24] Starting module cloudhub I0408 14:49:55.730518 32710 downstream.go:870] Start downstream devicecontroller I0408 14:49:55.730825 32710 core.go:24] Starting module edgecontroller I0408 14:49:55.731610 32710 upstream.go:111] start upstream controller I0408 14:49:55.733378 32710 downstream.go:566] start downstream controller I0408 14:49:55.853325 32710 signcerts.go:98] Succeed to creating token I0408 14:49:55.853470 32710 server.go:44] start unix domain socket server F0408 14:49:55.853732 32710 server.go:52] asn1: structure error: tags don't match (2 vs {class:0 tag:6 length:9 isCompound:false}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} @2 goroutine 487 [running]:
root@ubuntu:/etc/kubeedge/certs# openssl genrsa -out server.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) ...............+++++ ................................+++++ e is 65537 (0x010001) root@ubuntu:/etc/kubeedge/certs# openssl req -new -key server.key -subj -/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io -out server.crt name is expected to be in the format /type0=value0/type1=value1/type2=... where characters may be escaped by \. This name is not in that format: '-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io' problems making Certificate Request root@ubuntu:/etc/kubeedge/certs# subject="-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io" root@ubuntu:/etc/kubeedge/certs# openssl req -new -key server.key -subj ${subject} -out server.crt name is expected to be in the format /type0=value0/type1=value1/type2=... where characters may be escaped by \. This name is not in that format: '-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io' problems making Certificate Request root@ubuntu:/etc/kubeedge/certs# subject="/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io" root@ubuntu:/etc/kubeedge/certs# openssl req -new -key server.key -subj ${subject} -out server.crt root@ubuntu:/etc/kubeedge/certs# cd - /root/cmd
还是没成功
build/tools/certgen.sh stream 替换
root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# export CLOUDCOREIPS="192.168.56.105" root@ubuntu:/opt/gopath/src/github.com/kubeedge/kubeedge# build/tools/certgen.sh stream
root@ubuntu:~/cmd# vi /etc/kubeedge/config/cloudcore.yaml # With --minconfig , you can easily used this configurations as reference. # It's useful to users who are new to KubeEdge, and you can modify/create your own configs accordingly. # This configuration is suitable for beginners. apiVersion: cloudcore.config.kubeedge.io/v1alpha1 kind: CloudCore kubeAPIConfig: kubeConfig: /root/.kube/config master: "" leaderelection: LeaderElect: false LeaseDuration: 0s RenewDeadline: 0s ResourceLock: "" ResourceName: "" ResourceNamespace: "" RetryPeriod: 0s modules: cloudHub: advertiseAddress: - 10.10.16.82 https: address: 0.0.0.0 enable: true port: 10002 nodeLimit: 1000 tlsCAFile: /etc/kubeedge/ca/rootCA.crt tlsCAKeyFile: /etc/kubeedge/ca/rootCA.key tlsCertFile: /etc/kubeedge/certs/stream.crt tlsPrivateKeyFile: /etc/kubeedge/certs/stream.key unixsocket: address: unix:///var/lib/kubeedge/kubeedge.sock enable: true websocket: address: 0.0.0.0 enable: true port: 10000 router: address: 0.0.0.0 port: 9443 restTimeout: 60
cloudcore.yaml配置文件
root@ubuntu:~# vi /etc/kubeedge/config/cloudcore.yaml # With --minconfig , you can easily used this configurations as reference. # It's useful to users who are new to KubeEdge, and you can modify/create your own configs accordingly. # This configuration is suitable for beginners. apiVersion: cloudcore.config.kubeedge.io/v1alpha1 kind: CloudCore kubeAPIConfig: kubeConfig: /root/.kube/config master: "" leaderelection: LeaderElect: false LeaseDuration: 0s RenewDeadline: 0s ResourceLock: "" ResourceName: "" ResourceNamespace: "" RetryPeriod: 0s modules: cloudHub: advertiseAddress: - 10.10.16.82 https: address: 0.0.0.0 enable: true port: 10002 nodeLimit: 1000 tlsCAFile: /etc/kubeedge/ca/rootCA.crt tlsCAKeyFile: /etc/kubeedge/ca/rootCA.key tlsCertFile: /etc/kubeedge/certs/server.crt tlsPrivateKeyFile: /etc/kubeedge/certs/server.key unixsocket: address: unix:///var/lib/kubeedge/kubeedge.sock enable: true websocket: address: 0.0.0.0 enable: true port: 10000 router: address: 0.0.0.0 port: 9443 restTimeout: 60
注意根据你的环境修改以下两处地方。
1)kubeConfig的值
2)master的值
3)advertiseAddress的值,修改为master节点的IP
tlsCertFile 和 tlsPrivateKeyFile
tlsCertFile: /etc/kubeedge/certs/server.crt 和 tlsPrivateKeyFile: /etc/kubeedge/certs/server.key 由cloudcore根据kubeConfig生成
root@ubuntu:~/cmd# ./cloudcore I0408 16:28:46.089053 8684 server.go:64] Version: v1.6.0-beta.0.168+853c367496baac I0408 16:28:46.093027 8684 config.go:45] Succeed in loading CA certificate from local directory I0408 16:28:46.093097 8684 config.go:52] Succeed in loading CA key from local directory I0408 16:28:46.093149 8684 module.go:34] Module cloudhub registered successfully I0408 16:28:46.115176 8684 module.go:34] Module edgecontroller registered successfully I0408 16:28:46.115246 8684 module.go:34] Module devicecontroller registered successfully I0408 16:28:46.115279 8684 module.go:34] Module synccontroller registered successfully W0408 16:28:46.115371 8684 module.go:37] Module cloudStream is disabled, do not register W0408 16:28:46.115387 8684 module.go:37] Module router is disabled, do not register W0408 16:28:46.115400 8684 module.go:37] Module dynamiccontroller is disabled, do not register I0408 16:28:46.115462 8684 core.go:24] Starting module edgecontroller I0408 16:28:46.115548 8684 upstream.go:111] start upstream controller I0408 16:28:46.115736 8684 core.go:24] Starting module devicecontroller I0408 16:28:46.115846 8684 core.go:24] Starting module synccontroller I0408 16:28:46.115886 8684 core.go:24] Starting module cloudhub I0408 16:28:46.115884 8684 downstream.go:870] Start downstream devicecontroller I0408 16:28:46.118415 8684 downstream.go:566] start downstream controller I0408 16:28:46.228033 8684 server.go:311] CloudCoreCert and key don't exist in local directory, and will read from the secret ---可以忽略 I0408 16:28:46.243042 8684 signcerts.go:98] Succeed to creating token I0408 16:28:46.243171 8684 server.go:44] start unix domain socket server I0408 16:28:46.243560 8684 uds.go:71] listening on: //var/lib/kubeedge/kubeedge.sock I0408 16:28:46.243736 8684 server.go:64] Starting cloudhub websocket server I0408 16:28:48.116172 8684 upstream.go:63] Start upstream devicecontroller
# Default values for kubeedge. # This is a YAML-formatted file. # Declare variables to be passed into your templates. appVersion: "0.1.0" cloudCore: repository: "kubespheredev/cloudcore" tag: "v1.5.0" pullPolicy: "IfNotPresent" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/edge operator: DoesNotExist tolerations: [] cloudhubPort: "10000" #cloudhub https协议外网端口 cloudhubQuicPort: "10001" #cloudhub Quic协议外网端口 cloudhubHttpsPort: "10002" #cloudhub边缘节点首次连接凭token获取证书外网端口 cloudstreamPort: "10003" #cloudstream外网端口(用于k8s-apiserver,metrics server连接) tunnelPort: "10004" #tunnel外网端口(用于边缘节点建立log/exec/metrics等需要的edgestream连接) cloudHub: advertiseAddress: - 222.222.222.222 #外网IP nodeLimit: "100" #最大边缘节点个数 websocket: enable: true quic: enable: false maxIncomingStreams: "10000" https: enable: true cloudStream: enable: true service: cloudhubNodePort: "30000" #cloudhub https协议NodePort端口 cloudhubQuicNodePort: "30001" #cloudhub Quic协议NodePort端口 cloudhubHttpsNodePort: "30002" #cloudhub边缘节点首次连接凭token获取证书NodePort端口 cloudstreamNodePort: "30003" #cloudstreamNodePort端口 tunnelNodePort: "30004" #tunnelNodePort端口 edgeWatcher: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/edge operator: DoesNotExist tolerations: [] controllerManager: repository: "kubespheredev/edge-watcher" tag: "v0.1.0" pullPolicy: "IfNotPresent" kubeRBACProxy: repository: "kubesphere/kube-rbac-proxy" tag: "v0.5.0" pullPolicy: "IfNotPresent" edgeWatcherAgent: repository: "kubespheredev/edge-watcher-agent" tag: "v0.1.0" pullPolicy: "IfNotPresent" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/edge operator: DoesNotExist tolerations: - effect: NoSchedule key: node-role.kubernetes.io/master - key: CriticalAddonsOnly operator: Exists edgeNode: labels: - name: "node-role.kubernetes.io/edge" value: "" iptablesRules: source: metricsPort: "10250" logPort: "10350" destination: address: "192.168.10.7" #选择一个节点内网地址
root@cloud:~/cmd# openssl x509 -in /etc/kubeedge/certs/edge.crt -text -noout Certificate:
cloudcore 端口映射
export CLOUDCOREIPS="192.168.2.201" iptables -t nat -A OUTPUT -p tcp --dport 10350 -j DNAT --to $CLOUDCOREIPS:10003
kubeedge configmap
[root@cloud crds]# cat instance.yaml apiVersion: devices.kubeedge.io/v1alpha2 kind: Device metadata: name: temperature-simulate labels: description: 'temperature' manufacturer: 'test' spec: deviceModelRef: name: temperature-model-simulate nodeSelector: nodeSelectorTerms: - matchExpressions: - key: 'name' operator: In values: - pcl001-desktop status: twins: - propertyName: temperature-status desired: metadata: type: string value: '' [root@cloud crds]# cat model.yaml apiVersion: devices.kubeedge.io/v1alpha2 kind: DeviceModel metadata: name: temperature-model-simulate namespace: default spec: properties: - name: temperature-status description: Temperature collected from the edge device type: string: accessMode: ReadOnly defaultValue: '' [root@cloud crds]#
[root@cloud ~]# cd temperature_yaml/ [root@cloud temperature_yaml]# ls crds deployment.yaml [root@cloud temperature_yaml]# cd crds/ [root@cloud crds]# ls instance.yaml model.yaml [root@cloud crds]# kubectl get cm No resources found in default namespace. [root@cloud crds]# kubectl create -f model.yaml devicemodel.devices.kubeedge.io/temperature-model-simulate created [root@cloud crds]# kubectl create -f instance.yaml device.devices.kubeedge.io/temperature-simulate created [root@cloud crds]# kubectl get cm NAME DATA AGE device-profile-config-pcl001-desktop 1 3s [root@cloud crds]# kubectl describe cm device-profile-config-pcl001-desktop Name: device-profile-config-pcl001-desktop Namespace: default Labels: <none> Annotations: <none> Data ==== deviceProfile.json: ---- {"deviceInstances":[{"id":"temperature-simulate","name":"temperature-simulate","model":"temperature-model-simulate","twins":[{"propertyName":"temperature-status","desired":{"value":"","metadata":{"type":"string"}},"reported":{"value":""}}]}],"deviceModels":[{"name":"temperature-model-simulate","properties":[{"name":"temperature-status","dataType":"string","description":"Temperature collected from the edge device","accessMode":"ReadOnly","defaultValue":""}]}],"protocols":[{"protocolConfig":null,"protocolCommonConfig":null}]} Events: <none> [root@cloud crds]#
traffic-light
[root@cloud traffic-light]# ls crd deploy.yaml Dockerfile driver.go go.mod go.sum main.go Makefile message.go README.md vendor [root@cloud traffic-light]# cd crd/ [root@cloud crd]# ls instance.yaml model.yaml [root@cloud crd]# cat instance.yaml apiVersion: devices.kubeedge.io/v1alpha2 kind: Device metadata: name: traffic-light-instance-01 # namespace: traffic labels: description: Light model: traffic-light spec: deviceModelRef: name: traffic-light nodeSelector: nodeSelectorTerms: - matchExpressions: - key: '' operator: In values: - raspberrypi # give your edge node name status: twins: - desired: metadata: type: string value: "OFF" propertyName: red reported: metadata: timestamp: "1576146376369" type: string value: "OFF" - desired: metadata: type: string value: "ON" propertyName: yellow reported: metadata: timestamp: "1576146376370" type: string value: "OFF" - desired: metadata: type: string value: "OFF" propertyName: green reported: metadata: timestamp: "1576146376369" type: string value: "OFF" [root@cloud crd]# cat model.yaml apiVersion: devices.kubeedge.io/v1alpha2 kind: DeviceModel metadata: name: traffic-light # namespace: traffic spec: properties: - name: red description: Indicates whether the led light is ON/OFF type: string: accessMode: ReadWrite defaultValue: 'OFF' - name: yellow description: Indicates whether the yellow light is ON/OFF type: string: accessMode: ReadWrite defaultValue: 'OFF' - name: green description: Indicates whether the green light is ON/OFF type: string: accessMode: ReadWrite defaultValue: 'OFF' - name: red-pin-number description: Indicates red led pin munber type: int: accessMode: ReadOnly defaultValue: 25 - name: green-pin-number description: Indicates green led pin munber type: int: accessMode: ReadOnly defaultValue: 23 - name: yellow-pin-number description: Indicates rellow led pin munber type: int: accessMode: ReadOnly defaultValue: 24 [root@cloud crd]# kubectl create -f model.yaml devicemodel.devices.kubeedge.io/traffic-light created [root@cloud crd]# kubectl create -f instance.yaml device.devices.kubeedge.io/traffic-light-instance-01 created [root@cloud crd]# kubectl get cm NAME DATA AGE device-profile-config-pcl001-desktop 1 12m device-profile-config-raspberrypi 1 3s [root@cloud crd]# kubectl describe cm device-profile-config-raspberrypi Name: device-profile-config-raspberrypi Namespace: default Labels: <none> Annotations: <none> Data ==== deviceProfile.json: ---- {"deviceInstances":[{"id":"traffic-light-instance-01","name":"traffic-light-instance-01","model":"traffic-light","twins":[{"propertyName":"red","desired":{"value":"OFF","metadata":{"type":"string"}},"reported":{"value":"OFF","metadata":{"timestamp":"1576146376369","type":"string"}}},{"propertyName":"yellow","desired":{"value":"ON","metadata":{"type":"string"}},"reported":{"value":"OFF","metadata":{"timestamp":"1576146376370","type":"string"}}},{"propertyName":"green","desired":{"value":"OFF","metadata":{"type":"string"}},"reported":{"value":"OFF","metadata":{"timestamp":"1576146376369","type":"string"}}}]}],"deviceModels":[{"name":"traffic-light","properties":[{"name":"red","dataType":"string","description":"Indicates whether the led light is ON/OFF","accessMode":"ReadWrite","defaultValue":"OFF"},{"name":"yellow","dataType":"string","description":"Indicates whether the yellow light is ON/OFF","accessMode":"ReadWrite","defaultValue":"OFF"},{"name":"green","dataType":"string","description":"Indicates whether the green light is ON/OFF","accessMode":"ReadWrite","defaultValue":"OFF"},{"name":"red-pin-number","dataType":"int","description":"Indicates red led pin munber","accessMode":"ReadOnly","defaultValue":25,"minimum":0,"maximum":0},{"name":"green-pin-number","dataType":"int","description":"Indicates green led pin munber","accessMode":"ReadOnly","defaultValue":23,"minimum":0,"maximum":0},{"name":"yellow-pin-number","dataType":"int","description":"Indicates rellow led pin munber","accessMode":"ReadOnly","defaultValue":24,"minimum":0,"maximum":0}]}],"protocols":[{"protocolConfig":null,"protocolCommonConfig":null}]} Events: <none> [root@cloud crd]#
[root@cloud traffic-light]# cat deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: traffic-light # namespace: traffic spec: replicas: 1 selector: matchLabels: app: traffic-light template: metadata: labels: app: traffic-light spec: nodeName: raspberrypi hostNetwork: true containers: - name: light image: kubeedge/traffic-light:arm32-v1 #image: kubeedge/traffic-light-test:arm32-v1 command: ["/traffic/light"] args: ["--device=traffic-light-instance-01"] imagePullPolicy: IfNotPresent securityContext: privileged: true volumeMounts: - name: config-volume mountPath: /opt/kubeedge/ volumes: - name: config-volume configMap: name: device-profile-config-raspberrypi restartPolicy: Always
更新:"red","desired":{"value":"ON"
[root@cloud crd]# kubectl get device NAME AGE temperature-simulate 15m traffic-light-instance-01 3m42s [root@cloud crd]# kubectl edit device traffic-light-instance-01
led-raspberrypi
[root@cloud led-raspberrypi]# ls
configuration crds deployment.yaml Dockerfile go.mod go.sum images light_driver light_mapper.go Makefile README.md vendor
[root@cloud led-raspberrypi]#
在边缘节点机器上,执行docker ps
查看容器。再进入容器查看json文件:
# docker 4bc0f93a0174 / # cat /opt/kubeedge/deviceProfile.json {"deviceInstances":[{"id":"led-light-instance-01","name":"led-light-instance-01","model":"led-light"}],"deviceModels":[{"name":"led-light","properties":[{"name":"power-status","dataType":"string","description":"Indicates whether the led light is ON/OFF","accessMode":"ReadWrite","defaultValue":"OFF"},{"name":"gpio-pin-number","dataType":"int","description":"Indicates whether the GPIO pin to which LED is connected","accessMode":"ReadOnly","defaultValue":18}]}],"protocols":[{"protocol_config":null}]}
docker logs -f 4bc0f93a0174 I0318 03:54:21.558189 1 light_mapper.go:242] Watching on the device twin values for device: led-light-instance-01 I0318 03:54:22.559353 1 light_mapper.go:272] Actual values are in sync with Expected value I0318 03:54:22.559374 1 light_mapper.go:242] Watching on the device twin values for device: led-light-instance-01 I0318 03:54:23.560669 1 light_mapper.go:272] Actual values are in sync with Expected value I0318 03:54:23.560695 1 light_mapper.go:242] Watching on the device twin values for device: led-light-instance-01 I0318 03:54:24.561883 1 light_mapper.go:248] Expected Value : ON I0318 03:54:24.561909 1 light_mapper.go:252] Actual Value: OFF I0318 03:54:24.561913 1 light_mapper.go:254] Equating the actual value to expected value I0318 03:54:24.561918 1 light_mapper.go:257] Turning ON the light I0318 03:54:24.561922 1 light_driver.go:11] TurnON pin: 18 I0318 03:54:24.562033 1 light_mapper.go:242] Watching on the device twin values for device: led-light-instance-01 I0318 03:54:25.563141 1 light_mapper.go:248] Expected Value : ON I0318 03:54:25.563164 1 light_mapper.go:252] Actual Value: OFF I0318 03:54:25.563168 1 light_mapper.go:254] Equating the actual value to expected value I0318 03:54:25.563172 1 light_mapper.go:257] Turning ON the light I0318 03:54:25.563195 1 light_driver.go:11] TurnON pin: 18 I0318 03:54:25.563281 1 light_mapper.go:242] Watching on the device twin values for device: led-light-instance-01
//equateTwinValue is responsible for equating the actual state of the device to the expected state that has been set func equateTwinValue(updateMessage DeviceTwinUpdate) { glog.Info("Watching on the device twin values for device: ", configFile.DeviceName) wg.Add(1) go subscribe() getTwin(updateMessage) wg.Wait() if deviceTwinResult.Twin[powerStatus].Expected != nil && ((deviceTwinResult.Twin[powerStatus].Actual == nil) && deviceTwinResult.Twin[powerStatus].Expected != nil || (*deviceTwinResult.Twin[powerStatus].Expected.Value != *deviceTwinResult.Twin[powerStatus].Actual.Value)) { glog.Info("Expected Value : ", *deviceTwinResult.Twin[powerStatus].Expected.Value) if deviceTwinResult.Twin[powerStatus].Actual == nil { glog.Info("Actual Value: ", deviceTwinResult.Twin[powerStatus].Actual) } else { glog.Info("Actual Value: ", *deviceTwinResult.Twin[powerStatus].Actual.Value) } glog.Info("Equating the actual value to expected value") switch strings.ToUpper(*deviceTwinResult.Twin[powerStatus].Expected.Value) { case "ON": glog.Info("Turning ON the light") //Turn On the light by supplying power on the pin specified lightdriver.TurnON(int64(pinNumber)) //读写gpio口 case "OFF": glog.Info("Turning OFF the light") //Turn Off the light by cutting off power on the pin specified lightdriver.TurnOff(int64(pinNumber)) //读写gpio口 default: panic("OOPS!!!!! Attempt to perform invalid operation " + *deviceTwinResult.Twin[powerStatus].Expected.Value + " on LED light") } updateMessage = createActualUpdateMessage(*deviceTwinResult.Twin[powerStatus].Expected.Value) changeTwinValue(updateMessage) } else { glog.Info("Actual values are in sync with Expected value") } } func main() { changeDeviceState("online") updateMessage := createActualUpdateMessage("unknown") for { equateTwinValue(updateMessage) } }
configuration/config.go
//ConfigFilePath contains the location of the configuration file var ConfigFilePath = "configuration/config.yaml" //ConfigMapPath contains the location of the configuration file var ConfigMapPath = "/opt/kubeedge/deviceProfile.json"
//ReadFromConfigMap is used to load the information from the configmaps that are provided from the cloud func (deviceProfile *DeviceProfile) ReadFromConfigMap() error { jsonFile, err := ioutil.ReadFile(CONFIG_MAP_PATH) if err != nil { return err } err = json.Unmarshal(jsonFile, deviceProfile) if err != nil { return err } return nil }
light_mapper.go
func LoadConfigMap() error { var ok bool readConfigMap := configuration.DeviceProfile{} err := readConfigMap.ReadFromConfigMap() if err != nil { return errors.New("Error while reading from config map " + err.Error()) } for _, device := range readConfigMap.DeviceInstances { if strings.ToUpper(device.Model) == modelName && strings.ToUpper(device.Name) == strings.ToUpper(configFile.DeviceName) { deviceID = device.ID } } for _, deviceModel := range readConfigMap.DeviceModels { if strings.ToUpper(deviceModel.Name) == modelName { for _, property := range deviceModel.Properties { if strings.ToUpper(property.Name) == pinNumberConfig { if pinNumber, ok = property.DefaultValue.(float64); ok == false { return errors.New(" Error in reading pin number from config map") } } } } } return nil }
downstream + configmap
// Constants for protocol, datatype, configmap, deviceProfile const ( OPCUA = "opcua" Modbus = "modbus" Bluetooth = "bluetooth" CustomizedProtocol = "customized-protocol" DataTypeInt = "int" DataTypeString = "string" DataTypeDouble = "double" DataTypeFloat = "float" DataTypeBoolean = "boolean" DataTypeBytes = "bytes" ConfigMapKind = "ConfigMap" ConfigMapVersion = "v1" DeviceProfileConfigPrefix = "device-profile-config-" DeviceProfileJSON = "deviceProfile.json" )
// updateConfigMap updates the protocol, twins and data in the deviceProfile in configmap func (dc *DownstreamController) updateConfigMap(device *v1alpha2.Device) { if len(device.Spec.NodeSelector.NodeSelectorTerms) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions) != 0 && len(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values) != 0 { configMap, ok := dc.configMapManager.ConfigMap.Load(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0]) if !ok { klog.Error("Failed to load configmap") return } nodeConfigMap, ok := configMap.(*v1.ConfigMap) if !ok { klog.Error("Failed to assert to configmap") return } dp, ok := nodeConfigMap.Data[DeviceProfileJSON] if !ok || dp == "{}" { // This case should never be hit as we delete empty configmaps klog.Error("Failed to get deviceProfile from configmap data or deviceProfile is empty") return } deviceProfile := &types.DeviceProfile{} if err := json.Unmarshal([]byte(dp), deviceProfile); err != nil { klog.Errorf("Failed to unmarshal due to error: %v", err) return } var oldProtocol string for _, devInst := range deviceProfile.DeviceInstances { if device.Name == devInst.Name { oldProtocol = devInst.Protocol break } } // delete the old protocol for i, ptcl := range deviceProfile.Protocols { if ptcl.Name == oldProtocol { deviceProfile.Protocols = append(deviceProfile.Protocols[:i], deviceProfile.Protocols[i+1:]...) break } } // add new protocol deviceProtocol := &types.Protocol{} if device.Spec.Protocol.OpcUA != nil { deviceProtocol = buildDeviceProtocol(OPCUA, device.Name, device.Spec.Protocol.OpcUA) } else if device.Spec.Protocol.Modbus != nil { deviceProtocol = buildDeviceProtocol(Modbus, device.Name, device.Spec.Protocol.Modbus) } else if device.Spec.Protocol.Bluetooth != nil { deviceProtocol = buildDeviceProtocol(Bluetooth, device.Name, device.Spec.Protocol.Bluetooth) } else if device.Spec.Protocol.CustomizedProtocol != nil { deviceProtocol = buildDeviceProtocol(CustomizedProtocol, device.Name, device.Spec.Protocol.CustomizedProtocol) } else { klog.Warning("Unsupported device protocol") } // add protocol common deviceProtocol.ProtocolCommonConfig = device.Spec.Protocol.Common // update the propertyVisitors, twins, data and protocol in deviceInstance for _, devInst := range deviceProfile.DeviceInstances { if device.Name == devInst.Name { // update property visitors addPropertyVisitorsToDeviceInstance(device, devInst) // update twins devInst.Twins = device.Status.Twins // update data and data topic if len(device.Spec.Data.DataProperties) > 0 || len(device.Spec.Data.DataTopic) > 0 { devInst.Data = &v1alpha2.DeviceData{ DataProperties: device.Spec.Data.DataProperties, DataTopic: device.Spec.Data.DataTopic, } } // update protocol devInst.Protocol = deviceProtocol.Name break } } deviceProfile.Protocols = append(deviceProfile.Protocols, deviceProtocol) bytes, err := json.Marshal(deviceProfile) if err != nil { klog.Errorf("Failed to marshal deviceprofile: %v, error: %v", deviceProfile, err) return } nodeConfigMap.Data[DeviceProfileJSON] = string(bytes) // store new config map dc.configMapManager.ConfigMap.Store(device.Spec.NodeSelector.NodeSelectorTerms[0].MatchExpressions[0].Values[0], nodeConfigMap) if _, err := dc.kubeClient.CoreV1().ConfigMaps(device.Namespace).Update(context.Background(), nodeConfigMap, metav1.UpdateOptions{}); err != nil { klog.Errorf("Failed to update config map %v in namespace %v, error: %v", nodeConfigMap, device.Namespace, err) return } } }
Reset KubeEdge Master and Worker nodes
Master
keadm reset
will stop cloudcore
and delete KubeEdge related resources from Kubernetes master like kubeedge
namespace. It doesn't uninstall/remove any of the pre-requisites.
It provides a flag for users to specify kubeconfig path, the default path is /root/.kube/config
.
Example:
# keadm reset --kube-config=$HOME/.kube/config
SUBJECTALTNAME
SUBJECTALTNAME="subjectAltName = IP.1:127.0.0.1,IP.2:10.10.16.82"
kubectl get secret -nkubeedge NAME TYPE DATA AGE casecret Opaque 2 90m cloudcoresecret Opaque 2 90m default-token-kp5mr kubernetes.io/service-account-token 3 3d3h tokensecret Opaque 1 3d3h
root@ubuntu:~# kubectl get secret -nkubeedge NAME TYPE DATA AGE casecret Opaque 2 91m cloudcoresecret Opaque 2 91m default-token-kp5mr kubernetes.io/service-account-token 3 3d3h tokensecret Opaque 1 3d3h root@ubuntu:~# kubectl delete secret casecret -nkubeedge secret "casecret" deleted root@ubuntu:~# kubectl delete secret cloudcoresecret -nkubeedge secret "cloudcoresecret" deleted root@ubuntu:~# kubectl delete secret default-token-kp5mr -nkubeedge secret "default-token-kp5mr" deleted root@ubuntu:~# kubectl delete secret tokensecret -nkubeedge secret "tokensecret" deleted root@ubuntu:~# kubectl get secret -nkubeedge NAME TYPE DATA AGE default-token-h9t59 kubernetes.io/service-account-token 3 16s root@ubuntu:~# kubectl get secret -nkubeedge NAME TYPE DATA AGE casecret Opaque 2 73s cloudcoresecret Opaque 2 73s default-token-h9t59 kubernetes.io/service-account-token 3 101s tokensecret Opaque
KubeEdge v1.5 安装(在线版)
KubeSphere
https://kubesphere.com.cn/forum/d/3258-kubesphere-kubeedge
整体结构和应用
https://zhuanlan.zhihu.com/p/342626632
KUBEEDGE源码分析系列(五):DEVICETWIN模块详解
http://www.sel.zju.edu.cn/blog/2021/01/25/kubeedge%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%B3%BB%E5%88%97%E4%BA%94devicetwin%E6%A8%A1%E5%9D%97%E8%AF%A6%E8%A7%A3/
在树莓派上安装kubeedge
https://gobea.cn/blog/detail/yrGp8358.html
https://github.com/alibaba/openyurt
https://www.bookstack.cn/read/kubeedge/177016
https://blog.renkeju.com/2020/05/11/kubeedge/
https://www.bookstack.cn/read/kubeedge-1.4.0-en/24cedf71e82006f4.md
证书
https://kubeedge.io/en/docs/setup/keadm/
https://kubeedge.io/en/docs/setup/local/
https://kubeedge.io/en/docs/setup/config/