Skip to content

边缘计算云原生实践

边缘计算将计算能力从云端延伸到网络边缘,实现数据就近处理和低延迟响应。本文深入探讨K3s、KubeEdge等边缘计算平台的架构、部署和最佳实践。

🌐 边缘计算架构

边缘-云协同架构

yaml
edge_cloud_architecture:
  cloud_datacenter:
    role: "集中管理和大数据处理"
    responsibilities:
      - "统一控制平面"
      - "应用编排和调度"
      - "模型训练和优化"
      - "长期数据存储和分析"
      - "全局策略管理"
    
    typical_workloads:
      - "大数据批处理"
      - "机器学习训练"
      - "跨区域数据聚合"
      - "全局业务逻辑"
    
    technologies:
      - "Kubernetes集群"
      - "大数据平台"
      - "AI/ML平台"
      - "数据仓库"
  
  edge_nodes:
    role: "就近处理和快速响应"
    responsibilities:
      - "实时数据处理"
      - "本地推理执行"
      - "离线自治运行"
      - "数据预处理和过滤"
      - "设备管理和控制"
    
    typical_workloads:
      - "实时视频分析"
      - "IoT数据处理"
      - "边缘AI推理"
      - "本地缓存服务"
    
    technologies:
      - "K3s/KubeEdge"
      - "边缘AI框架"
      - "时序数据库"
      - "本地存储"
  
  end_devices:
    role: "数据采集和简单处理"
    responsibilities:
      - "传感器数据采集"
      - "设备状态监控"
      - "简单数据过滤"
      - "协议转换"
    
    typical_devices:
      - "IoT传感器"
      - "工业PLC"
      - "智能摄像头"
      - "边缘网关"
    
    technologies:
      - "MQTT协议"
      - "Modbus协议"
      - "边缘代理"
      - "设备SDK"
yaml
communication_patterns:
  cloud_to_edge:
    description: "云到边缘的下行通信"
    use_cases:
      application_deployment:
        - "应用更新推送"
        - "配置下发"
        - "模型分发"
      
      device_management:
        - "设备配置"
        - "固件升级"
        - "策略更新"
    
    protocols:
      - "MQTT over TLS"
      - "gRPC"
      - "WebSocket"
      - "HTTP/2"
  
  edge_to_cloud:
    description: "边缘到云的上行通信"
    use_cases:
      data_reporting:
        - "指标上报"
        - "日志收集"
        - "事件通知"
      
      data_synchronization:
        - "离线数据同步"
        - "增量更新"
        - "状态上报"
    
    optimization:
      - "数据压缩"
      - "批量上传"
      - "智能过滤"
      - "断点续传"
  
  edge_to_edge:
    description: "边缘节点间通信"
    use_cases:
      - "本地服务发现"
      - "数据共享"
      - "协同计算"
      - "故障转移"
    
    technologies:
      - "mDNS"
      - "边缘服务网格"
      - "本地消息队列"

🚀 K3s轻量级Kubernetes

K3s架构和部署

yaml
k3s_features:
  lightweight:
    binary_size: "< 100MB"
    memory_footprint: "~512MB"
    benefits:
      - "快速部署"
      - "低资源占用"
      - "边缘设备友好"
      - "IoT场景适用"
  
  simplified_components:
    differences_from_k8s:
      removed:
        - "Cloud Provider"
        - "Storage Plugins(使用local-path)"
        - "Legacy特性"
      
      replaced:
        etcd: "SQLite(默认)或Embedded etcd"
        docker: "containerd内置"
        flannel: "默认CNI"
      
      added:
        - "Helm Controller"
        - "Traefik Ingress"
        - "ServiceLB"
        - "Local Storage Provider"
  
  production_ready:
    certifications:
      - "CNCF认证Kubernetes"
      - "100% Kubernetes API兼容"
      - "通过Conformance测试"
    
    enterprise_features:
      - "高可用部署"
      - "自动备份"
      - "SELinux支持"
      - "Secret加密"
yaml
k3s_deployment:
  single_server:
    installation: |
      # 单节点安装
      curl -sfL https://get.k3s.io | sh -
      
      # 验证安装
      k3s kubectl get nodes
      
      # 获取kubeconfig
      sudo cat /etc/rancher/k3s/k3s.yaml
    
    configuration: |
      # K3s配置文件 /etc/rancher/k3s/config.yaml
      write-kubeconfig-mode: "0644"
      tls-san:
        - "k3s.example.com"
        - "192.168.1.100"
      
      # 禁用默认组件
      disable:
        - traefik
        - servicelb
      
      # 数据目录
      data-dir: "/var/lib/rancher/k3s"
      
      # Node标签
      node-label:
        - "node-type=edge"
        - "location=factory-a"
  
  high_availability:
    embedded_etcd: |
      # HA集群部署(Embedded etcd)
      # 第一个server节点
      curl -sfL https://get.k3s.io | sh -s - server \
        --cluster-init \
        --tls-san=k3s-cluster.example.com
      
      # 获取token
      sudo cat /var/lib/rancher/k3s/server/node-token
      
      # 添加其他server节点
      curl -sfL https://get.k3s.io | sh -s - server \
        --server https://k3s-server1:6443 \
        --token ${NODE_TOKEN}
    
    external_datastore: |
      # 使用外部数据库(PostgreSQL/MySQL)
      curl -sfL https://get.k3s.io | sh -s - server \
        --datastore-endpoint="postgres://username:password@hostname:5432/k3s"
    
    load_balancer: |
      # 负载均衡器配置(HAProxy示例)
      global
          maxconn 50000
      
      defaults
          mode tcp
          timeout connect 10s
          timeout client 30s
          timeout server 30s
      
      frontend k3s-api
          bind *:6443
          default_backend k3s-servers
      
      backend k3s-servers
          balance roundrobin
          server k3s-1 192.168.1.11:6443 check
          server k3s-2 192.168.1.12:6443 check
          server k3s-3 192.168.1.13:6443 check
  
  agent_nodes:
    join_cluster: |
      # Worker节点加入集群
      curl -sfL https://get.k3s.io | K3S_URL=https://k3s-server:6443 \
        K3S_TOKEN=${NODE_TOKEN} sh -
    
    node_labels: |
      # 添加节点标签和污点
      curl -sfL https://get.k3s.io | K3S_URL=https://k3s-server:6443 \
        K3S_TOKEN=${NODE_TOKEN} \
        sh -s - agent \
        --node-label location=edge-site-a \
        --node-label hardware=raspberry-pi \
        --node-taint edge=true:NoSchedule

K3s边缘应用部署

yaml
edge_workloads:
  video_analytics:
    deployment: |
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: video-analytics
        namespace: edge-apps
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: video-analytics
        template:
          metadata:
            labels:
              app: video-analytics
          spec:
            nodeSelector:
              location: edge-site-a
              hardware: gpu-enabled
            
            containers:
            - name: analytics
              image: video-analytics:v1.0
              resources:
                requests:
                  memory: "512Mi"
                  cpu: "500m"
                limits:
                  memory: "2Gi"
                  cpu: "2"
                  nvidia.com/gpu: 1
              
              env:
              - name: RTSP_URL
                value: "rtsp://camera.local/stream"
              - name: MODEL_PATH
                value: "/models/yolov5s.pt"
              
              volumeMounts:
              - name: models
                mountPath: /models
              - name: output
                mountPath: /output
            
            volumes:
            - name: models
              persistentVolumeClaim:
                claimName: model-storage
            - name: output
              hostPath:
                path: /var/lib/analytics
                type: DirectoryOrCreate
  
  iot_gateway:
    deployment: |
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: mqtt-config
      data:
        mosquitto.conf: |
          listener 1883
          allow_anonymous false
          password_file /mosquitto/config/passwd
          
          listener 8883
          cafile /mosquitto/config/ca.crt
          certfile /mosquitto/config/server.crt
          keyfile /mosquitto/config/server.key
          
          persistence true
          persistence_location /mosquitto/data/
      
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: mqtt-broker
      spec:
        replicas: 1
        template:
          spec:
            nodeSelector:
              node-type: edge
            
            containers:
            - name: mosquitto
              image: eclipse-mosquitto:2
              ports:
              - containerPort: 1883
                name: mqtt
              - containerPort: 8883
                name: mqtts
              
              volumeMounts:
              - name: config
                mountPath: /mosquitto/config
              - name: data
                mountPath: /mosquitto/data
            
            volumes:
            - name: config
              configMap:
                name: mqtt-config
            - name: data
              persistentVolumeClaim:
                claimName: mqtt-data
  
  edge_caching:
    deployment: |
      # 边缘缓存服务
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: edge-cache
      spec:
        selector:
          matchLabels:
            app: edge-cache
        template:
          metadata:
            labels:
              app: edge-cache
          spec:
            nodeSelector:
              node-type: edge
            
            hostNetwork: true
            
            containers:
            - name: nginx
              image: nginx:alpine
              ports:
              - containerPort: 80
                hostPort: 80
              
              volumeMounts:
              - name: cache
                mountPath: /var/cache/nginx
              - name: config
                mountPath: /etc/nginx/nginx.conf
                subPath: nginx.conf
            
            volumes:
            - name: cache
              hostPath:
                path: /var/cache/edge-nginx
                type: DirectoryOrCreate
            - name: config
              configMap:
                name: nginx-cache-config
yaml
edge_autonomy:
  offline_capability:
    local_registry: |
      # 本地镜像仓库
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: local-registry
      spec:
        replicas: 1
        template:
          spec:
            containers:
            - name: registry
              image: registry:2
              ports:
              - containerPort: 5000
              
              env:
              - name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
                value: /var/lib/registry
              
              volumeMounts:
              - name: registry-data
                mountPath: /var/lib/registry
            
            volumes:
            - name: registry-data
              persistentVolumeClaim:
                claimName: registry-storage
      
      ---
      # 镜像同步Job
      apiVersion: batch/v1
      kind: CronJob
      metadata:
        name: image-sync
      spec:
        schedule: "0 2 * * *"
        jobTemplate:
          spec:
            template:
              spec:
                containers:
                - name: sync
                  image: skopeo:latest
                  command:
                  - /bin/bash
                  - -c
                  - |
                    # 同步关键镜像到本地仓库
                    for image in $(cat /config/images.txt); do
                      skopeo copy \
                        docker://$image \
                        docker://local-registry:5000/$image
                    done
                
                volumeMounts:
                - name: config
                  mountPath: /config
                
                volumes:
                - name: config
                  configMap:
                    name: sync-images-list
                
                restartPolicy: OnFailure
    
    local_dns: |
      # CoreDNS本地DNS配置
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: coredns-custom
        namespace: kube-system
      data:
        edge.server: |
          edge.local:53 {
              errors
              cache 30
              forward . 192.168.1.1
              reload
          }
          
          # 本地服务解析
          local.cluster:53 {
              file /etc/coredns/local.hosts
              reload
          }
        
        local.hosts: |
          local-registry.local.cluster.  IN A  192.168.1.100
          mqtt-broker.local.cluster.     IN A  192.168.1.101
    
    data_persistence: |
      # 本地数据持久化
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: timescaledb
      spec:
        serviceName: timescaledb
        replicas: 1
        template:
          spec:
            containers:
            - name: timescaledb
              image: timescale/timescaledb:latest-pg14
              env:
              - name: POSTGRES_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: postgres-secret
                    key: password
              
              volumeMounts:
              - name: data
                mountPath: /var/lib/postgresql/data
        
        volumeClaimTemplates:
        - metadata:
            name: data
          spec:
            accessModes: ["ReadWriteOnce"]
            storageClassName: local-path
            resources:
              requests:
                storage: 50Gi

🔗 KubeEdge边缘计算平台

KubeEdge架构

yaml
kubeedge_architecture:
  cloud_components:
    cloudcore:
      description: "云端核心组件"
      modules:
        cloudhub:
          - "WebSocket服务器"
          - "边缘节点连接管理"
          - "消息路由"
        
        edgecontroller:
          - "边缘节点管理"
          - "应用下发"
          - "状态同步"
        
        devicecontroller:
          - "设备模型管理"
          - "设备数据同步"
          - "设备twin维护"
  
  edge_components:
    edgecore:
      description: "边缘端核心组件"
      modules:
        edgehub:
          - "云端通信客户端"
          - "消息路由"
          - "离线缓存"
        
        edged:
          - "轻量级Kubelet"
          - "Pod生命周期管理"
          - "本地资源管理"
        
        eventbus:
          - "MQTT事件总线"
          - "设备数据路由"
          - "模块间通信"
        
        servicebus:
          - "HTTP服务总线"
          - "REST API代理"
          - "服务发现"
        
        devicetwin:
          - "设备状态管理"
          - "设备shadow维护"
          - "设备数据同步"
        
        metamanager:
          - "元数据管理"
          - "本地存储(SQLite)"
          - "持久化保证"
yaml
kubeedge_deployment:
  cloudcore_installation: |
    # 云端安装
    # 1. 准备Kubernetes集群
    # 2. 安装CloudCore
    
    # 使用Helm安装
    helm repo add kubeedge https://raw.githubusercontent.com/kubeedge/kubeedge/master/build/helm
    
    helm install cloudcore kubeedge/cloudcore \
      --set cloudCore.modules.cloudHub.advertiseAddress="{cloud-server-ip}" \
      --set cloudCore.modules.cloudHub.nodeLimit=1000 \
      --namespace kubeedge \
      --create-namespace
    
    # 生成边缘节点Token
    kubectl get secret -n kubeedge tokensecret -o jsonpath='{.data.tokendata}' | base64 -d
  
  edgecore_installation: |
    # 边缘端安装
    # 下载EdgeCore
    wget https://github.com/kubeedge/kubeedge/releases/download/v1.15.0/keadm-v1.15.0-linux-amd64.tar.gz
    tar -zxvf keadm-v1.15.0-linux-amd64.tar.gz
    
    # 安装EdgeCore
    sudo ./keadm join \
      --cloudcore-ipport=${CLOUDCORE_IP}:10000 \
      --token=${EDGE_NODE_TOKEN} \
      --edgenode-name=edge-node-1 \
      --cgroupdriver=systemd \
      --remote-runtime-endpoint=unix:///var/run/containerd/containerd.sock
  
  edge_configuration: |
    # 边缘节点配置 /etc/kubeedge/config/edgecore.yaml
    apiVersion: edgecore.config.kubeedge.io/v1alpha2
    kind: EdgeCore
    modules:
      edgehub:
        enable: true
        heartbeat: 15
        tlsCaFile: /etc/kubeedge/ca/rootCA.crt
        tlsCertFile: /etc/kubeedge/certs/edge.crt
        tlsPrivateKeyFile: /etc/kubeedge/certs/edge.key
        httpServer: https://${CLOUDCORE_IP}:10002
        websocket:
          enable: true
          server: ${CLOUDCORE_IP}:10000
      
      edged:
        enable: true
        cgroupDriver: systemd
        clusterDNS: "169.254.96.16"
        clusterDomain: cluster.local
        devicePluginEnabled: true
        gpuPluginEnabled: false
        imageGCHighThreshold: 80
        imageGCLowThreshold: 40
        maximumDeadContainersPerPod: 1
      
      eventBus:
        enable: true
        mqttMode: 2  # 2: internal mqtt broker
        mqttServerInternal: tcp://127.0.0.1:1883
        mqttServerExternal: tcp://0.0.0.0:1883
      
      metaManager:
        enable: true
        metaServer:
          enable: true
          server: 127.0.0.1:10550

设备管理

yaml
device_management:
  device_model: |
    # 设备模型定义
    apiVersion: devices.kubeedge.io/v1alpha2
    kind: DeviceModel
    metadata:
      name: temperature-sensor
      namespace: default
    spec:
      properties:
      - name: temperature
        description: Temperature in celsius
        type:
          int:
            accessMode: ReadOnly
            maximum: 100
            minimum: -50
            unit: celsius
      
      - name: humidity
        description: Humidity percentage
        type:
          int:
            accessMode: ReadOnly
            maximum: 100
            minimum: 0
            unit: percentage
      
      - name: status
        description: Device status
        type:
          string:
            accessMode: ReadWrite
            defaultValue: active
  
  device_instance: |
    # 设备实例
    apiVersion: devices.kubeedge.io/v1alpha2
    kind: Device
    metadata:
      name: sensor-01
      namespace: default
      labels:
        location: factory-a
        type: temperature-sensor
    spec:
      deviceModelRef:
        name: temperature-sensor
      
      nodeSelector:
        nodeSelectorTerms:
        - matchExpressions:
          - key: node-role.kubernetes.io/edge
            operator: Exists
      
      protocol:
        modbus:
          slaveID: 1
        common:
          collectCycle: 10000  # ms
          reportCycle: 30000   # ms
      
      propertyVisitors:
      - propertyName: temperature
        modbus:
          register: holding
          offset: 0
          limit: 1
          scale: 0.1
      
      - propertyName: humidity
        modbus:
          register: holding
          offset: 1
          limit: 1
          scale: 1
  
  mapper_deployment: |
    # Modbus Mapper部署
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: modbus-mapper
    spec:
      replicas: 1
      template:
        spec:
          nodeSelector:
            node-role.kubernetes.io/edge: ""
          
          hostNetwork: true
          
          containers:
          - name: mapper
            image: kubeedge/modbus-mapper:v1.0
            env:
            - name: MQTT_SERVER
              value: "tcp://127.0.0.1:1883"
            
            securityContext:
              privileged: true
yaml
edge_autonomy_kubeedge:
  edge_rule: |
    # 边缘规则引擎
    apiVersion: rules.kubeedge.io/v1
    kind: Rule
    metadata:
      name: temperature-alert
      namespace: default
    spec:
      source: "temperature-sensor"
      sourceResource:
        path: "/temperature"
      
      target: "alert-service"
      targetResource:
        path: "/alerts"
      
      condition: "temperature > 80"
  
  edge_stream: |
    # Sedna边缘AI推理
    apiVersion: sedna.io/v1alpha1
    kind: IncrementalLearningJob
    metadata:
      name: helmet-detection
    spec:
      dataset:
        name: "helmet-dataset"
        trainProb: 0.8
      
      trainSpec:
        template:
          spec:
            nodeName: cloud-node
            containers:
            - image: helmet-detection-train:v1
              name: train
      
      evalSpec:
        template:
          spec:
            nodeName: cloud-node
            containers:
            - image: helmet-detection-eval:v1
              name: eval
      
      deploySpec:
        template:
          spec:
            nodeName: edge-node-1
            containers:
            - image: helmet-detection-infer:v1
              name: infer

📋 边缘计算面试重点

架构设计类

  1. 边缘计算与云计算的本质区别?

    • 计算位置和延迟
    • 数据处理模式
    • 网络带宽要求
    • 运维管理方式
  2. 如何设计边缘-云协同架构?

    • 工作负载划分原则
    • 数据同步策略
    • 离线自治能力
    • 故障容错机制
  3. 边缘计算的主要应用场景?

    • 工业IoT
    • 智慧城市
    • 车联网
    • AR/VR

K3s实践类

  1. K3s与K8s的主要差异?

    • 组件简化
    • 资源占用
    • 部署方式
    • 适用场景
  2. 如何部署K3s高可用集群?

    • Embedded etcd vs外部数据库
    • 负载均衡配置
    • 节点故障恢复
    • 备份策略
  3. K3s边缘节点管理最佳实践?

    • 节点标签和污点
    • 网络断连处理
    • 本地镜像管理
    • 资源限制策略

KubeEdge应用类

  1. KubeEdge的架构组件?

    • CloudCore功能
    • EdgeCore模块
    • 通信机制
    • 设备管理
  2. 如何实现设备到云端的数据流转?

    • 设备模型定义
    • Mapper开发
    • 数据路由规则
    • 云端数据处理
  3. 边缘自治能力如何实现?

    • 本地数据缓存
    • 离线决策
    • 规则引擎
    • 状态同步

技术选型类

  1. K3s vs KubeEdge的选择?

    • 功能对比
    • 设备管理能力
    • 部署复杂度
    • 适用场景
  2. 边缘AI推理的部署策略?

    • 模型压缩优化
    • 硬件加速方案
    • 模型更新机制
    • 性能监控
  3. 边缘安全的关键考虑?

    • 设备认证
    • 通信加密
    • 数据隐私保护
    • 安全更新机制

🔗 相关内容


边缘计算是云原生技术向边缘延伸的重要趋势,通过K3s、KubeEdge等平台可以实现云边协同的应用架构。掌握边缘计算的核心概念和实践技能,对于构建现代IoT和实时处理系统至关重要。

正在精进