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/