KubeEdge 边缘 Ingress 高级部署指南

作者:Administrator 发布时间: 2025-11-25 阅读量:6 评论数:0

KubeEdge 边缘 Ingress 高级部署指南

—— 基于节点差异化配置与云边网络穿透方案

1. 方案背景与概述

在 KubeEdge 边缘计算场景中,标准的 Kubernetes Ingress 部署方式(DaemonSet + Service)面临两大挑战:

  1. 网络隔离:边缘节点通常位于私有网络或防火墙后,无法直接通过 ClusterIP 访问云端 API Server,导致 Ingress Controller 无法同步路由规则。
  2. 异构需求:不同的边缘节点往往连接不同的物理设备(如香港节点连接 Redis 缓存,日本节点连接 RTSP 摄像头),需要完全独立的 TCP/UDP 端口转发策略。

本指南采用 Deployment + HostNetwork + 独立 Kubeconfig 的架构,实现以下目标:

  • 云边穿透:通过挂载专用 Kubeconfig,确保边缘 Ingress 能稳定连接云端 Master。
  • 配置隔离hk-gatewayjp-gateway 拥有独立的 TCP/UDP 配置文件,互不干扰。
  • 统一接入:所有节点共享一套 HTTP/HTTPS Ingress 规则,实现统一的域名管理。

2. 架构设计

  • 部署模式Deployment 配合 NodeSelector。每个边缘节点运行一个独立的 Ingress Controller 实例。
  • 网络模式hostNetwork: true。Pod 直接监听边缘宿主机的物理网卡,无需 NAT,性能最优。
  • 配置管理
    • TCP/UDP:通过 --tcp-services-configmap 参数指向各自独立的 ConfigMap。
    • HTTP:通过标准的 Kubernetes Ingress 资源统一管理。

3. 基础环境准备

执行位置:云端 Master 节点

首先创建专用的命名空间和 RBAC 权限,这是 Ingress Controller 运行的基础。

创建文件 01-base-rbac.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: edge-ingress
---
# 创建服务账号
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-nginx
  namespace: edge-ingress
---
# 定义集群角色 (包含读取 Ingress, Services, Pods 等权限)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-nginx
rules:
  - apiGroups: ["", "networking.k8s.io"]
    resources: ["configmaps", "endpoints", "nodes", "pods", "secrets", "services", "ingresses", "ingresses/status"]
    verbs: ["get", "list", "watch", "update", "create", "patch"]
  - apiGroups: ["coordination.k8s.io"]
    resources: ["leases"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: ["discovery.k8s.io"]
    resources: ["endpointslices"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch", "update"]
---
# 关键修复:将权限绑定到 edge-ingress 命名空间的账号
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ingress-nginx-edge-fix
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx  
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: edge-ingress  

执行部署:

kubectl apply -f 01-base-rbac.yaml

4. 构建云边连接凭证 (Kubeconfig)

执行位置:云端 Master 节点

由于 KubeEdge 的网络特性,边缘 Pod 默认注入的 ServiceAccount Token 可能无法验证云端证书或路由不可达。我们将生成一个包含 Master 公网/局域网 IP 的长期有效 Kubeconfig,并将其封装为 Secret。

创建并运行脚本 generate_edge_config.sh

#!/bin/bash

# --- 配置区域 ---
NAMESPACE="edge-ingress"
SERVICE_ACCOUNT="ingress-nginx"
# 请确保边缘节点能 Ping 通此 IP (云端 Master IP)
SERVER_URL="https://192.168.6.234:6443" 
# ----------------

echo "1. 正在创建长期有效的 ServiceAccount Token..."
# Kubernetes 1.24+ 需要手动创建 Secret 才能获取长期 Token
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: ingress-nginx-token
  namespace: ${NAMESPACE}
  annotations:
    kubernetes.io/service-account.name: ${SERVICE_ACCOUNT}
type: kubernetes.io/service-account-token
EOF

# 等待 Secret 创建完成
sleep 2

echo "2. 正在提取 Token 和 CA 证书..."
TOKEN=$(kubectl -n ${NAMESPACE} get secret ingress-nginx-token -o jsonpath='{.data.token}' | base64 --decode)
CA_CRT=$(kubectl -n ${NAMESPACE} get secret ingress-nginx-token -o jsonpath='{.data.ca\.crt}')

echo "3. 正在生成 edge-ingress.kubeconfig 文件..."
cat <<EOF > edge-ingress.kubeconfig
apiVersion: v1
kind: Config
clusters:
- name: edge-cluster
  cluster:
    certificate-authority-data: ${CA_CRT}
    server: ${SERVER_URL}
contexts:
- name: edge-context
  context:
    cluster: edge-cluster
    namespace: ${NAMESPACE}
    user: edge-ingress-user
current-context: edge-context
users:
- name: edge-ingress-user
  user:
    token: ${TOKEN}
EOF

echo "4. 正在上传 Secret 到集群..."
# 清理旧 Secret (如果存在) 并创建新 Secret
kubectl delete secret ingress-kubeconfig-secret -n ${NAMESPACE} --ignore-not-found
kubectl create secret generic ingress-kubeconfig-secret -n ${NAMESPACE} --from-file=kubeconfig=edge-ingress.kubeconfig

echo "✅ 完成!Secret 'ingress-kubeconfig-secret' 已准备就绪。"

执行脚本:

chmod +x generate_edge_config.sh
./generate_edge_config.sh

5. 边缘节点隔离配置 (关键步骤)

执行位置:云端 Master 节点

为了防止云端业务 Pod 被错误调度到资源紧张的边缘节点,我们需要给所有边缘节点打上“污点(Taint)”。

假设:您的所有边缘节点都带有标签 node-role.kubernetes.io/edge (这是 KubeEdge 的默认行为,如果您的标签不同,请相应调整命令)。

执行以下命令,批量给边缘节点添加污点:


# 给所有带有 'node-role.kubernetes.io/edge' 标签的节点添加 NoSchedule 污点
# 污点键值对设为 kubeedge.io/dedicated=edge-workload
kubectl taint nodes -l node-role.kubernetes.io/edge kubeedge.io/dedicated=edge:NoSchedule

效果说明:执行后,任何没有配置对应容忍度(Toleration)的 Pod 将无法调度到边缘节点。这为边缘节点提供了必要的保护层。后续的 Ingress 部署 yaml 中已包含了必要的容忍度配置。

6. 部署香港网关 (HK-Gateway)

执行位置:云端 Master 节点

本配置专用于 hk-gateway 节点,定义其特有的端口映射。

  • 业务目标:暴露 Redis (TCP 9000) 和 Technitium DNS (UDP 53)。

创建文件 02-hk-gateway.yaml

# --- HK 节点专属 TCP 配置 ---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services-hk
  namespace: edge-ingress
data:
  # 语法: "宿主机端口": "Service命名空间/ServiceName:ServicePort"
  "9000": "default/redis-test:6379"

---
# --- HK 节点专属 UDP 配置 ---
apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services-hk
  namespace: edge-ingress
data:
  "53": "dns-service/technitium-dns-entry:5353"

---
# --- HK 节点 Ingress Controller ---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-hk
  namespace: edge-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ingress-nginx-hk
  template:
    metadata:
      labels:
        app: ingress-nginx-hk
    spec:
      hostNetwork: true             # 直接使用物理网卡
      dnsPolicy: ClusterFirstWithHostNet
      tolerations:
        - key: "kubeedge.io/dedicated"
          operator: "Equal"
          value: "edge"
          effect: "NoSchedule"
      nodeSelector:
        kubernetes.io/hostname: hk-gateway # <--- 锁定部署节点
      serviceAccountName: ingress-nginx
      
      # 挂载步骤4生成的 Kubeconfig
      volumes:
        - name: kubeconfig-volume
          secret:
            secretName: ingress-kubeconfig-secret

      containers:
        - name: controller
          image: registry.k8s.io/ingress-nginx/controller:v1.8.0
          args:
            - /nginx-ingress-controller
            # 关键:指定使用挂载的 kubeconfig 连接 API Server
            - --kubeconfig=/etc/kubernetes/ingress-kubeconfig/kubeconfig            
            - --election-id=ingress-hk     # 独立的选举ID
            - --controller-class=k8s.io/ingress-nginx
            - --ingress-class=nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            # 加载 HK 专属配置表
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services-hk
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services-hk
          
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          
          volumeMounts:
            - name: kubeconfig-volume
              mountPath: /etc/kubernetes/ingress-kubeconfig
              readOnly: true

应用配置:kubectl apply -f 02-hk-gateway.yaml


7. 部署日本网关 (JP-Gateway)

执行位置:云端 Master 节点

本配置专用于 jp-gateway 节点,配置与 HK 完全隔离。

  • 业务目标:暴露 RTSP 视频流 (TCP 554) 和 Technitium DNS (UDP 53)。

创建文件 03-jp-gateway.yaml

# --- JP 节点专属 TCP 配置 ---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services-jp
  namespace: edge-ingress
data:
  "554": "default/rtsp-service:554"

---
# --- JP 节点专属 UDP 配置 ---
apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services-jp
  namespace: edge-ingress
data:
  "53": "dns-service/technitium-dns-entry:5353"

---
# --- JP 节点 Ingress Controller ---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-jp
  namespace: edge-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ingress-nginx-jp
  template:
    metadata:
      labels:
        app: ingress-nginx-jp
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      tolerations:
        - key: "kubeedge.io/dedicated"
          operator: "Equal"
          value: "edge"
          effect: "NoSchedule"
      nodeSelector:
        kubernetes.io/hostname: jp-gateway # <--- 锁定部署节点
      serviceAccountName: ingress-nginx
      
      volumes:
        - name: kubeconfig-volume
          secret:
            secretName: ingress-kubeconfig-secret

      containers:
        - name: controller
          image: registry.k8s.io/ingress-nginx/controller:v1.8.0
          args:
            - /nginx-ingress-controller
            - --kubeconfig=/etc/kubernetes/ingress-kubeconfig/kubeconfig
            - --election-id=ingress-jp
            - --controller-class=k8s.io/ingress-nginx
            - --ingress-class=nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            # 加载 JP 专属配置表
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services-jp
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services-jp
          
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          
          volumeMounts:
            - name: kubeconfig-volume
              mountPath: /etc/kubernetes/ingress-kubeconfig
              readOnly: true

应用配置:kubectl apply -f 03-jp-gateway.yaml


8. 验证与运维指南

8.1 状态检查

在云端执行以下命令,确保两个 Pod 均已处于 Running 状态,且 IP 地址对应各自的边缘节点 IP。

kubectl get pods -n edge-ingress -o wide

8.2 日志排查

如果 Pod 启动失败或无法转发,请查看日志。成功连接的日志应包含 Backend successfully reloaded

# 查看 HK 节点日志
kubectl logs -f deployment/ingress-nginx-hk -n edge-ingress

# 查看 JP 节点日志
kubectl logs -f deployment/ingress-nginx-jp -n edge-ingress

8.3 修改配置

该架构支持热更新。如果需要修改端口转发规则,只需编辑对应的 ConfigMap:

# 例如:修改 HK 节点的 TCP 规则
kubectl edit configmap tcp-services-hk -n edge-ingress

保存退出后,Ingress Controller 会在数秒内自动检测变化并重载 Nginx 配置,无需重启 Pod。

8.4 统一 HTTP 接入

所有节点共享 Kubernetes 标准的 Ingress 资源。创建一个 Ingress 规则后,您可以通过 http://HK节点IPhttp://JP节点IP 访问同一个 Web 服务,实现高可用接入。

评论