边缘计算到端侧AI框架的演化(四) EasyFaas的网络部署架构方案

146 阅读5分钟

EasyFaaS网络架构部署方案

EasyFaaS使用基于Linux bridge的容器网络架构。每个funclet组件负责管理容器网络,通过创建bridge网桥和veth pair来实现容器间的网络通信 network.go:25-41 。

网络组件配置

1. 网络管理器初始化

funclet在启动时会初始化网络管理器并创建bridge网桥 funclet.go:115-119 。

2. Bridge网桥配置

网络管理器通过InitNetwork方法创建bridge,并配置IP网段 network.go:47-68 。

3. 容器网络设置

每个容器启动时,系统会为其分配IP地址并设置网络 init.go:100-104 。

单机裸金属部署方案

1. 环境准备

基于快速开始文档,需要准备Linux环境(内核4.0+)和Docker:

2. All-in-One部署方式

EasyFaaS提供了all-in-one部署方式,特别适合单机部署。这种方式将controller、funclet和stubs组件打包在一个镜像中

3. 编译构建

首先编译所有模块:

# 编译全部模块  
make  
  
# 打包all-in-one镜像  
scripts/build-image.sh -m=one -i=easyfaas -t=dev

4. 裸金属部署配置

创建部署脚本 deploy-bare-metal.sh:

#!/bin/bash  
  
# 设置数据目录  
export faasPath=/opt/easyfaas/faas  
mkdir -p ${faasPath}/{runtime,runner,data,funcData,invoker/run}  
  
# 启动runner-runtime准备运行时环境  
docker run -td \  
  -e WITHRUNNER=1 \  
  -e WITHNODEJS10=1 \  
  -e WITHNODEJS12=1 \  
  -e WITHPYTHON3=1 \  
  --name runner-runtime \  
  -v ${faasPath}/runtime:/var/faas/runtime \  
  -v ${faasPath}/runner:/var/faas/runner \  
  registry.baidubce.com/easyfaas-public/runner-runtime:demo1.0  
  
# 等待runtime准备完成  
echo "等待runtime准备完成..."  
sleep 30  
  
# 启动all-in-one服务  
docker run -td \  
  --privileged \  
  --name easyfaas \  
  -p 8080:8080 \  
  -p 8002:8002 \  
  -v ${faasPath}/runner:/var/faas/runner \  
  -v ${faasPath}/runtime:/var/faas/runtime \  
  -v ${faasPath}/data:/var/faas/runner-data \  
  -v ${faasPath}/funcData:/var/faas/funcData \  
  -v ${faasPath}/invoker/run:/var/run/faas \  
  easyfaas:dev  
  
echo "EasyFaaS部署完成!"  
echo "Controller端口: 8080"  
echo "Registry端口: 8002"

5. 网络配置优化

对于裸金属部署,需要优化网络配置以避免冲突。基于代码中的网络配置:

创建自定义网络配置:

// pkg/funclet/network/bare_metal_options.go  
package network  
  
import "os"  
  
func GetBareMetalNetworkOptions() *NetworkOption {  
    return &NetworkOption{  
        BridgeName: "easyfaas-br0",  
        BridgeIP:   "192.168.100.1/24", // 避免与常见网段冲突  
        MTU:        1500,  
    }  
}  
  
func IsBareMetalEnvironment() bool {  
    return os.Getenv("EASYFAAS_DEPLOY_MODE") == "bare-metal"  
}

6. 服务启动脚本

创建系统服务配置 /etc/systemd/system/easyfaas.service:

[Unit]  
Description=EasyFaaS Function Computing Service  
After=docker.service  
Requires=docker.service  
  
[Service]  
Type=forking  
Environment=EASYFAAS_DEPLOY_MODE=bare-metal  
ExecStart=/opt/easyfaas/deploy-bare-metal.sh  
ExecStop=/usr/bin/docker stop easyfaas runner-runtime  
ExecStopPost=/usr/bin/docker rm easyfaas runner-runtime  
Restart=always  
RestartSec=10  
  
[Install]  
WantedBy=multi-user.target

7. 功能验证

部署完成后,可以通过以下方式验证:

# 检查服务状态  
docker ps  
  
# 测试controller接口  
curl http://localhost:8080/health  
  
# 测试registry接口    
curl http://localhost:8002/v1/functions

Docker Bridge容器网络部署

基于代码中的docker-compose配置 docker-compose.yaml:21-40 ,以下是三台服务器的配置示例:

服务器1 (Controller节点)

version: '2.0'  
services:  
  easyfaas-controller:  
    image: easyfaas/controller:latest  
    network_mode: host  
    command:  
    - ./controller  
    - --port=8080  
    - --repository-endpoint=http://192.168.1.100:8081  
    volumes:  
    - /var/run/faas:/var/run/faas

服务器2 (Funclet节点1)

version: '2.0'  
services:  
  easyfaas-funclet:  
    image: easyfaas/mini-funclet:latest  
    network_mode: bridge  
    privileged: true  
    command:  
    - ./funclet  
    - --container-num=20  
    - --bridge-name=easyfaas0  
    - --bridge-cidr=172.18.0.0/16  
    volumes:  
    - /var/run/faas:/var/run/faas

服务器3 (Funclet节点2)

version: '2.0'  
services:  
  easyfaas-funclet:  
    image: easyfaas/mini-funclet:latest  
    network_mode: bridge  
    privileged: true  
    command:  
    - ./funclet  
    - --container-num=20  
    - --bridge-name=easyfaas0  
    - --bridge-cidr=172.19.0.0/16  
    volumes:  
    - /var/run/faas:/var/run/faas

网络隔离配置

系统通过iptables规则实现容器间网络隔离 iptables_linux.go:28-45 ,并支持NAT出站流量 iptables_linux.go:48-71 。

k8s部署方案

1. Kubernetes资源定义文件

ConfigMap配置管理

# configmap.yaml  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: easyfaas-config  
  namespace: easyfaas-system  
data:  
  controller.yaml: |  
    port: "8080"  
    repository-endpoint: "http://easyfaas-registry:8002"  
    repository-version: "v1"  
    repository-auth-type: "noauth"  
    maxprocs: "10"  
    http-enhanced: "true"  
  funclet.yaml: |  
    reserved-memory: "100M"  
    reserved-cpu: "0.3"  
    runner-memory: "128M"  
    container-num: "20"  
    bridge-name: "easyfaas0"  
    bridge-ip: "10.244.0.1/16"

Controller部署配置

# controller-deployment.yaml  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: easyfaas-controller  
  namespace: easyfaas-system  
spec:  
  replicas: 1  
  selector:  
    matchLabels:  
      app: easyfaas-controller  
  template:  
    metadata:  
      labels:  
        app: easyfaas-controller  
    spec:  
      serviceAccountName: easyfaas-controller  
      containers:  
      - name: controller  
        image: easyfaas/controller:latest  
        ports:  
        - containerPort: 8080  
        env:  
        - name: CONTROLLER_CONFIG_PATH  
          value: "/etc/easyfaas/controller.yaml"  
        volumeMounts:  
        - name: config  
          mountPath: /etc/easyfaas  
        - name: faas-run  
          mountPath: /var/run/faas  
        command:  
        - ./controller  
        - --config=/etc/easyfaas/controller.yaml  
        - --logtostderr=true  
        - -v=2  
      volumes:  
      - name: config  
        configMap:  
          name: easyfaas-config  
      - name: faas-run  
        emptyDir: {}

Funclet DaemonSet配置

# funclet-daemonset.yaml  
apiVersion: apps/v1  
kind: DaemonSet  
metadata:  
  name: easyfaas-funclet  
  namespace: easyfaas-system  
spec:  
  selector:  
    matchLabels:  
      app: easyfaas-funclet  
  template:  
    metadata:  
      labels:  
        app: easyfaas-funclet  
    spec:  
      serviceAccountName: easyfaas-funclet  
      hostNetwork: false  
      hostPID: false  
      containers:  
      - name: funclet  
        image: easyfaas/mini-funclet:latest  
        securityContext:  
          privileged: true  
          capabilities:  
            add:  
            - NET_ADMIN  
            - SYS_ADMIN  
        env:  
        - name: MY_POD_NAME  
          valueFrom:  
            fieldRef:  
              fieldPath: metadata.name  
        - name: MY_NODE_NAME  
          valueFrom:  
            fieldRef:  
              fieldPath: spec.nodeName  
        - name: KUBERNETES_MODE  
          value: "true"  
        volumeMounts:  
        - name: config  
          mountPath: /etc/easyfaas  
        - name: faas-run  
          mountPath: /var/run/faas  
        - name: faas-runtime  
          mountPath: /var/faas/runtime  
        - name: faas-runner  
          mountPath: /var/faas/runner  
        - name: faas-data  
          mountPath: /var/faas/runner-data  
        command:  
        - ./funclet  
        - --config=/etc/easyfaas/funclet.yaml  
        - --logtostderr=true  
        - -v=10  
      volumes:  
      - name: config  
        configMap:  
          name: easyfaas-config  
      - name: faas-run  
        hostPath:  
          path: /var/run/faas  
          type: DirectoryOrCreate  
      - name: faas-runtime  
        hostPath:  
          path: /var/faas/runtime  
          type: DirectoryOrCreate  
      - name: faas-runner  
        hostPath:  
          path: /var/faas/runner  
          type: DirectoryOrCreate  
      - name: faas-data  
        hostPath:  
          path: /var/faas/runner-data  
          type: DirectoryOrCreate

2. 服务发现机制

Service资源定义

# services.yaml  
apiVersion: v1  
kind: Service  
metadata:  
  name: easyfaas-controller  
  namespace: easyfaas-system  
spec:  
  selector:  
    app: easyfaas-controller  
  ports:  
  - port: 8080  
    targetPort: 8080  
    name: http  
  type: ClusterIP  
---  
apiVersion: v1  
kind: Service  
metadata:  
  name: easyfaas-registry  
  namespace: easyfaas-system  
spec:  
  selector:  
    app: easyfaas-registry  
  ports:  
  - port: 8002  
    targetPort: 8002  
    name: http  
  type: ClusterIP

3. 网络策略适配

修改网络管理器以支持Kubernetes

基于现有的网络管理器接口 network.go:25-29 ,我们需要创建一个Kubernetes适配的网络管理器:

// pkg/funclet/network/k8s_network.go  
package network  
  
import (  
    "fmt"  
    "os"  
)  
  
type KubernetesNetworkManager struct {  
    *ContainerNetwork  
    kubernetesMode bool  
}  
  
func NewKubernetesNetworkManager() NetworkManagerInterface {  
    return &KubernetesNetworkManager{  
        ContainerNetwork: &ContainerNetwork{},  
        kubernetesMode:   isKubernetesEnvironment(),  
    }  
}  
  
func isKubernetesEnvironment() bool {  
    return os.Getenv("KUBERNETES_MODE") == "true" ||   
           os.Getenv("KUBERNETES_SERVICE_HOST") != ""  
}  
  
func (k *KubernetesNetworkManager) InitNetwork(opt *NetworkOption) error {  
    if k.kubernetesMode {  
        // 在Kubernetes环境中,跳过自定义bridge创建  
        // 使用Pod网络  
        return nil  
    }  
    // 回退到原有的bridge网络  
    return k.ContainerNetwork.InitNetwork(opt)  
}  
  
func (k *KubernetesNetworkManager) SetContainerNet(containerPid int) error {  
    if k.kubernetesMode {  
        // 在Kubernetes环境中,容器网络由CNI管理  
        return nil  
    }  
    return k.ContainerNetwork.SetContainerNet(containerPid)  
}

修改Funclet初始化逻辑

需要修改 funclet.go:97 中的网络管理器创建:

// 在InitFunclet函数中  
var networkManager network.NetworkManagerInterface  
if os.Getenv("KUBERNETES_MODE") == "true" {  
    networkManager = network.NewKubernetesNetworkManager()  
} else {  
    networkManager = network.NewNetworkManager()  
}  
  
f = &Funclet{  
    // ... 其他字段  
    NetworkManager: networkManager,  
    // ... 其他字段  
}

4. 权限和安全配置

RBAC权限配置

# rbac.yaml  
apiVersion: v1  
kind: ServiceAccount  
metadata:  
  name: easyfaas-controller  
  namespace: easyfaas-system  
---  
apiVersion: v1  
kind: ServiceAccount  
metadata:  
  name: easyfaas-funclet  
  namespace: easyfaas-system  
---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRole  
metadata:  
  name: easyfaas-controller  
rules:  
- apiGroups: [""]  
  resources: ["pods", "services", "endpoints"]  
  verbs: ["get", "list", "watch"]  
- apiGroups: ["apps"]  
  resources: ["deployments", "daemonsets"]  
  verbs: ["get", "list", "watch"]  
---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRole  
metadata:  
  name: easyfaas-funclet  
rules:  
- apiGroups: [""]  
  resources: ["nodes", "pods"]  
  verbs: ["get", "list", "watch"]  
- apiGroups: [""]  
  resources: ["pods/exec"]  
  verbs: ["create"]  
---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
  name: easyfaas-controller  
roleRef:  
  apiGroup: rbac.authorization.k8s.io  
  kind: ClusterRole  
  name: easyfaas-controller  
subjects:  
- kind: ServiceAccount  
  name: easyfaas-controller  
  namespace: easyfaas-system  
---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
  name: easyfaas-funclet  
roleRef:  
  apiGroup: rbac.authorization.k8s.io  
  kind: ClusterRole  
  name: easyfaas-funclet  
subjects:  
- kind: ServiceAccount  
  name: easyfaas-funclet  
  namespace: easyfaas-system

网络策略

# network-policy.yaml  
apiVersion: networking.k8s.io/v1  
kind: NetworkPolicy  
metadata:  
  name: easyfaas-network-policy  
  namespace: easyfaas-system  
spec:  
  podSelector:  
    matchLabels:  
      app: easyfaas-funclet  
  policyTypes:  
  - Ingress  
  - Egress  
  ingress:  
  - from:  
    - podSelector:  
        matchLabels:  
          app: easyfaas-controller  
  egress:  
  - to:  
    - podSelector:  
        matchLabels:  
          app: easyfaas-registry  
  - to: []  
    ports:  
    - protocol: TCP  
      port: 53  
    - protocol: UDP  
      port: 53

完整部署脚本

# namespace.yaml  
apiVersion: v1  
kind: Namespace  
metadata:  
  name: easyfaas-system
#!/bin/bash  
# deploy.sh  
kubectl apply -f namespace.yaml  
kubectl apply -f rbac.yaml  
kubectl apply -f configmap.yaml  
kubectl apply -f services.yaml  
kubectl apply -f controller-deployment.yaml  
kubectl apply -f funclet-daemonset.yaml  
kubectl apply -f network-policy.yaml