介绍

KubeEdge 原版的云端组件,在边缘节点加入后,需要手动配置 iptables 等选项,才能正常使用 kubectl logs/metrics/exec,使用步骤较繁琐。

为了 KubeEdge 和 KubeSphere 能更好地集成, KubeSphere 边缘计算团队开发了 EdgeWatcher/IPTables-Operator 等组件,实现了边缘节点加入后自动配置 iptables 以支持边缘节点的 kubectl logs 日志、kubectl top 实时监控和 kubectl exec 工作负载命令行。

同时 KubeSphere 边缘计算团队对边缘节点安装程序 keadm 进行了定制,增加了更多命令行选项,实现单条命令加入集群。

云端 CloudCore 安装

云端配置如下:
软件版本:KubeSphere v3.0.0
云端节点:192.168.10.7 192.168.10.8 192.168.10.9
云端公网IP: 222.222.222.222 (示例,cloudcore会针对这个IP签发证书)

(1) 下载 helm 安装包并解压

wget https://kubeedge.pek3b.qingstor.com/helm/v1.5.0/kubeedge.tar
tar xvf kubeedge.tar

(2) 修改 Values.yaml 配置,设置公网IP和端口,节点内网 NodePort 地址和端口,不冲突情况下,端口使用默认值,只需要修改两个IP地址即可。各 deployment 的 nodeselector 和 toleration 依据集群节点酌情设置。iptablesAgent 需要设置为可以调度到 master 节点。所有 cloudcore 相关工作负载均不要调度到边缘节点。

# 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" #选择一个节点内网地址

(3) 创建 kubeedge namespace,并安装 kubeedge

kubectl create ns kubeedge
#在 kubeedge 的 helm 包文件夹的同级目录下执行
helm install kubeedge kubeedge --version 0.1.0 --namespace kubeedge

(4) 读取连接 token

kubectl get secret -nkubeedge tokensecret -o=jsonpath='{.data.tokendata}' | base64 -d

(5) 在云控制台,设置公网端口映射和防火墙

内网 IP内网端口外网端口
192.168.10.73100010000
192.168.10.73100110001
192.168.10.73100210002
192.168.10.73100310003
192.168.10.73100410004

防火墙允许 10000 - 10004 端口

(6) 更新 metrics-server 以适配 KubeEdge v1.5.0

helm delete -n kube-system metrics-server
kubectl apply -f https://kubeedge.pek3b.qingstor.com/metrics-server.yaml

边缘节点加入集群

边缘节点配置需求:安装 docker 19.3.0 以上版本

(1) 下载定制的 Keadm

#下载对应平台的keadm
arch=$(uname -m) && curl -O https://kubeedge.pek3b.qingstor.com/bin/v1.5.0/$arch/edgecore && chmod +x edgecore

(2) 加入集群
节点名称为 edgenode-1,虚拟 IP 为 192.168.100.1,该虚拟 IP 为 kubectl logs/metrics/exec 使用,选择不与云端节点和边缘节点自身 IP 地址段冲突的 IP 地址段即可。token 使用云端第 (4) 步读取到的。

./keadm join --kubeedge-version=1.5.0 --cloudcore-ipport=222.222.222.222:10000 --certport 10012 --quicport 10001 --tunnelport 10004 --edgenode-name edgenode-1 --edgenode-ip 192.168.100.1 --token <f2a2d523970930dd7f2652aa6bdfce2a41655da1a9d6eb5a3fdc2b31f4e48692.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDYyNzA4MTd9.47yokq3G70np0sQYORjOHtYISZoNLoomVAys1JBrSOA>

备注:当前版本可能第一次运行在校验下载包时会失败,忽略直接再次运行命令即可

节点加入后,等待约1到2分钟,云端的 edge-watcher 和 iptables-operator 组件会自动检测到边缘节点的加入,并配置好 iptables 项,可以使用 kubectl logs/top/exec 来操作边缘节点的实时日志、监控和命令行。

(3) 加入集群后,为边缘节点设置 taint

kubectl taint nodes edgenode-1 node.kubeedge.io=edge:NoSchedule

边缘节点退出集群

如需将边缘节点退出云端集群

./keadm reset
apt remove mosquitto
rm -rf /var/lib/kubeedge /var/lib/edged /etc/kubeedge/ca /etc/kubeedge/certs

备注:如果删除不掉tmpfs挂载文件夹,可以重启节点或者umount之后再删除。

云端 CloudCore 卸载

在云端执行

kubectl delete iptables -n kubeedge iptables
helm delete kubeedge -n kubeedge
kubectl delete -f kubeedge/crds
kubectl delete ns kubeedge

如果卸载时误操作先删除了 iptables-operator-controller-manager 导致 finalizer 无法执行卡住删除 crd 流程,执行下面命令

kubectl patch crd/iptables.kubeedge.kubesphere.io -p '{"metadata":{"finalizers":[]}}' --type=merge

    Ma-Dan 边缘节点加入集群后,可以提供几张边缘节点在 「KubeSphere 节点管理」页面的截图么?比如在 KubeSphere 界面查看边缘节点的监控指标或日志?现在看起来跟 KubeSphere 产品的关联比较少

    UI 上看边缘节点的监控指标得等 KubeSphere v3.1 , 按上面步骤配置后可以用kubectl top nodes/pods 看

      11 天 后

      Ma-Dan 您好!非常感谢您编写的《KubeSphere 集成 KubeEdge 快速上手指南》,为我们以后集成KubeEdge提供了很好的参考!但是我这边之前已经按照原始的方式部署好了KubeSphere和KubeEdge环境,在KubeSphere界面也能正常显示出边缘节点,但是无法正常显示边缘节点的资源使用情况,而且在查看边缘节点容器日志的时候会显示错误
      “Internal Server Error
      Get https://10.168.1.165:10350/containerLogs/wenchi/suanfaceshi-6877797bc4-mthhq/suanfaceshi?tailLines=1000&timestamps=true: dial tcp 10.168.1.165:10350: connect: connection refused”。
      看到您文中第一句写道:“KubeEdge 原版的云端组件,在边缘节点加入后,需要手动配置 iptables 等选项”,这个操作我这边没有做过,也没看到有相关的参考文档,可以请教一下您大概需要怎么操作吗?谢谢您!

        csuffyy 首先要保证 10.168.1.165 这个IP本身不和云端其它节点冲突。手动操作就是在ks-apiserver和metrics-server所在的节点(node-ip)上,增加如下两项IPTables。这两个组件也要以Hostnetwork运行。
        iptables -t nat -A OUTPUT -d 10.168.1.165 -p tcp –dport 10350 -j DNAT –to-destination node-ip:31003
        iptables -t nat -A OUTPUT -d 10.168.1.165 -p tcp –dport 10250 -j DNAT –to-destination node-ip:31003
        这样log和metrics才能访问到cloudcore并转发到边缘端。
        还是建议使用iptables-operator+edge-watcher方式,它是自动完成了这个手动操作。

          Ma-Dan 谢谢您的热心回复!看来手动操作确实很麻烦,我按照您上面的指导操作,结果还是没有成功,最后重置了系统,并使用您本文中介绍的方式进行了安装。有区别的一点是,我因为是在局域网环境下,没有公网地址,所以使用的内外网IP地址及端口都是一样的(我使用的端口号是31000-31004),然后边端接入的指令也做了一点小的改动,原文给出的边端接入指令中 –certport 10012 ,我这里改成了 –certport 3102 ,总体来说,现在可以正常查看边端容器的日志了,但是有发现一些小的问题,具体如下:

          1、边缘节点的资源使用实时监测中的CPU和内存使用情况不能正常显示:

          2、边缘节点初始的几个容器组运行异常:

          比如,node-exporter容器的日志:
          standard_init_linux.go:211: exec user process caused “exec format error”

          以上情况不知道是不是因为边缘端的系统架构是Arm64引起的,晚点我再使用X86架构的边端测试一下。

          再次谢谢 Ma-Dan

            csuffyy 第一个问题,请先看下kube-system下的metrics-server是否正常运行,需要v0.4.1版本,并且以hostnetwork方式工作。第二个问题,是边缘节点角色没有设置taint造成的,即使是x64节点以边缘角色加入后,也会这样,只是不会报exec format error错误,但是实际负载也不能正常运行,因为这些daemonset主要是在云端工作的。请按照边缘节点加入后的第三步为节点设置taint(kubectl taint nodes edgenode-1 node.kubeedge.io=edge:NoSchedule),然后这些错误的容器组目前先手动删除,只要不产生新的就可以。

              Ma-Dan metrics-server 是正常运行的,版本也是 v0.4.1

              Ma-Dan 请按照边缘节点加入后的第三步为节点设置taint(kubectl taint nodes edgenode-1 node.kubeedge.io=edge:NoSchedule)

              这个步骤也是做了的,结果如下:

                Ma-Dan 另外还发现了一个新的问题,我创建了一个工作负载和对应的服务,如果调度到master节点(10.168.1.128),则服务 http://10.168.1.128:30428 能正常访问,但是如果调度到edgenode节点(10.168.1.155),则服务 http://10.168.1.155:30428 无法访问。不知道是什么原因引起的,还请您多多指教,谢谢!

                工作负载:

                服务:

                  csuffyy metrics-server是正常工作了,需要更新ks-console。请将kubesphere-system下的deployment ks-console的镜像修改为 kubespheredev/ks-console:latest ,应该就能正确显示了。
                  kubectl edit deployments.apps -n kubesphere-system ks-console

                    csuffyy 检查了一下,应该是ks-apiserver尚未更新,请问您可以自己编译kubesphere的ks-apiserver么?使用这个PR的修改 kubesphere/kubesphere#3173 编译出ks-apiserver镜像,再更新 kubesphere 下 ks-apiserver deployment,就可以读取显示边缘节点的监控值了。

                      Ma-Dan 还从来没做过这个操作呢,看起来比较陌生,不过我先尽力尝试一下吧,谢谢您!

                        csuffyy 这部分功能将会集成到v3.1中,那时就不用这样操作了,目前还在开发测试过程中,所以有时会有这样的过程。感谢您的耐心试用,使用中的问题和建议欢迎随时跟我们沟通!

                          11 天 后