LTS

    Innovation Version

      KubeEdge Deployment Guide

      Description

      KubeEdge

      KubeEdge is an open source system dedicated to solving problems in edge scenarios. It extends the capabilities of containerized application orchestration and device management to edge devices. Based on Kubernetes, KubeEdge provides core infrastructure support for networks, application deployment, and metadata synchronization between the cloud and the edge. KubeEdge supports MQTT and allows for custom logic to enable communication for the resource-constrained devices at the edge. KubeEdge consists of components deployed on the cloud and edge nodes. The components are now open source.

      https://kubeedge.io/

      iSulad

      iSulad is a lightweight container runtime daemon designed for IoT and cloud infrastructure. It is lightweight, fast, and is not restricted by hardware specifications or architectures. It is suitable for wide application in various scenarios, such as cloud, IoT, and edge computing.

      https://gitee.com/openeuler/iSulad

      Preparations

      Component Versions

      ComponentVersion
      OSopenEuler 21.09
      Kubernetes1.20.2-4
      iSulad2.0.9-20210625.165022.git5a088d9c
      KubeEdgev1.8.0

      Node Planning Example

      NodeLocationComponents
      9.63.252.224CloudKubernetes (Master), iSulad, CloudCore
      9.63.252.227EdgeiSulad, EdgeCore

      Environment Configurations

      Configure the following settings on the cloud and edge nodes:

      # Disable the firewall.
      $ systemctl stop firewalld
      $ systemctl disable firewalld
      
      # Disable SELinux.
      $ setenforce 0
      
      # Configure the network, and enable the required forwarding mechanism.
      $ cat >> /etc/sysctl.d/k8s.conf <<EOF
      net.bridge.bridge-nf-call-ip6tables = 1
      net.bridge.bridge-nf-call-iptables = 1
      net.ipv4.ip_forward = 1
      vm.swappiness=0
      EOF
      
      # Make the rules take effect.
      $ modprobe br_netfilter
      $ sysctl -p /etc/sysctl.d/k8s.conf
      
      # Check whether the rules take effect.
      $ cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
      1
      $ cat /proc/sys/net/bridge/bridge-nf-call-iptables
      1
      
      # Disable the system swap.
      $ swapoff -a
      
      # Set the host names.
      # Cloudnode:
      $ hostnamectl set-hostname cloud.kubeedge
      # Edgenode:
      $ hostnamectl set-hostname edge.kubeedge
      
      # Example configurations for the hosts file. Set the values based on the actual deployment.
      $ cat >> /etc/hosts << EOF
      9.63.252.224 cloud.kubeedge
      9.63.252.227 edge.kubeedge
      EOF
      
      # Choose an accessible NTP server to synchronize the clock.
      $ ntpdate cn.pool.ntp.org
      
      # Install the cri-tools network tool.
      $ wget --no-check-certificate https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.20.0/crictl-v1.20.0-linux-amd64.tar.gz
      $ tar zxvf crictl-v1.20.0-linux-amd64.tar.gz -C /usr/local/bin
      
      # Install the CNI network plugins.
      $ wget --no-check-certificate https://github.com/containernetworking/plugins/releases/download/v0.9.0/cni-plugins-linux-amd64-v0.9.0.tgz
      $ mkdir -p /opt/cni/bin
      $ tar -zxvf cni-plugins-linux-amd64-v0.9.0.tgz -C /opt/cni/bin
      

      Configuring iSulad

      Configure the following settings on the cloud and edge nodes:

      # Configure iSulad (only the items to be modified are listed).
      $ cat /etc/isulad/daemon.json
      {
              "registry-mirrors": [
                      "docker.io"
              ],
              "insecure-registries": [
                      "k8s.gcr.io",
                      "quay.io",
                      "hub.oepkgs.net"
              ],
              "pod-sandbox-image": "k8s.gcr.io/pause:3.2",
              "network-plugin": "cni",
              "cni-bin-dir": "/opt/cni/bin",
              "cni-conf-dir": "/etc/cni/net.d",
      }
      
      # Configure the proxy if the node cannot directly access the Internet. Otherwise, skip this section.
      $ cat /usr/lib/systemd/system/isulad.service
      [Service]
      Type=notify
      Environment="HTTP_PROXY=http://..."
      Environment="HTTPS_PROXY=http://..."
      
      # Restart the iSulad and set it to start upon system startup.
      $ systemctl daemon-reload && systemctl restart isulad
      

      Deploying the Kubernetes Components

      Install and deploy the Kubernetes components on the cloud node only.

      # Install the Kubernetes tools.
      $ yum install kubernetes-master kubernetes-kubeadm kubernetes-client kubernetes-kubelet
      # Set kubelet to start upon system startup.
      $ systemctl enable kubelet --now
      
      # Note that the system proxy must be canceled before using the kubeadm init command.
      $ unset `env | grep -iE "tps?_proxy" | cut -d= -f1`
      $ env | grep proxy
      
      # Run the kubeadm init command.
      $ kubeadm init --kubernetes-version v1.20.2 --pod-network-cidr=10.244.0.0/16 --upload-certs --cri-socket=/var/run/isulad.sock
      # The default Kubernetes component image is gcr.k8s.io. You can add the --image-repository=xxx option to configure a custom image repository address (to test your own Kubernetes image).
      
      # Note that the network segment specified by pod-network-cidr cannot overlap the network segment of the host machine. Otherwise, the network is inaccessible.
      # You are advised to run the init command before configuring the network.
      Your Kubernetes control-plane has initialized successfully!
      
      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
      
      You should now deploy a pod network to the cluster.
      Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
        https://kubernetes.io/docs/concepts/cluster-administration/addons/
      
      Then you can join any number of worker nodes by running the following on each as root:
      ...
      
      # Run the commands as prompted.
      mkdir -p $HOME/.kube
      cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      chown $(id -u):$(id -g) $HOME/.kube/config
      # The commands make a copy of admin.conf, which is a kubectl configuration file initialized by the kubeadm command.
      # The file contains important configurations, such as the authentication information.
      
      # You can reset the configurations if an error occurs when running the init command.
      $ kubeadm reset
      
      # If "Unable to read config path "/etc/kubernetes/manifests"" is displayed, run the following command:
      $ mkdir -p /etc/kubernetes/manifests
      

      Configuring the Network

      Because the Calico network plugin cannot run on edge nodes, flannel is used instead. The issue has been submitted to the KubeEdge community.

      The cloud and edge nodes are in different network environments and require different affinity. Therefore, two flannel configuration files are required.

      # Download the flannel network plugin.
      $ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
      
      # Prepare for network configuration for the cloud node.
      $ cp kube-flannel.yml kube-flannel-cloud.yml
      
      # Modify the network configuration for the cloud node.
      $ patch kube-flannel-cloud.yml - <<EOF
      index c7edaef..f3846b9 100644
      --- a/kube-flannel.yml
      +++ b/kube-flannel.yml
      @@ -134,7 +134,7 @@ data:
       apiVersion: apps/v1
       kind: DaemonSet
       metadata:
      -  name: kube-flannel-ds
      +  name: kube-flannel-cloud-ds
         namespace: kube-system
         labels:
           tier: node
      @@ -158,6 +158,8 @@ spec:
                       operator: In
                       values:
                       - linux
      +              - key: node-role.kubernetes.io/agent
      +                operator: DoesNotExist
             hostNetwork: true
             priorityClassName: system-node-critical
             tolerations:
      EOF
      
      # Prepare for network configuration for the edge node.
      $ cp kube-flannel.yml kube-flannel-edge.yml
      
      # Modify the network configuration for the edge node.
      $ patch kube-flannel-edge.yml - <<EOF
      index c7edaef..66a5b5b 100644
      --- a/kube-flannel.yml
      +++ b/kube-flannel.yml
      @@ -134,7 +134,7 @@ data:
       apiVersion: apps/v1
       kind: DaemonSet
       metadata:
      -  name: kube-flannel-ds
      +  name: kube-flannel-edge-ds
         namespace: kube-system
         labels:
           tier: node
      @@ -158,6 +158,8 @@ spec:
                       operator: In
                       values:
                       - linux
      +              - key: node-role.kubernetes.io/agent
      +                operator: Exists
             hostNetwork: true
             priorityClassName: system-node-critical
             tolerations:
      @@ -186,6 +188,7 @@ spec:
               args:
               - --ip-masq
               - --kube-subnet-mgr
      +        - --kube-api-url=http://127.0.0.1:10550
               resources:
                 requests:
                   cpu: "100m"
      EOF
      
      # --kube-api-url is the listening IP address of EdgeCore on the edge node.
      
      # Configure the flannel network plugin.
      $ kubectl apply -f kube-flannel-cloud.yml
      $ kubectl apply -f kube-flannel-edge.yml
      
      # Check the node status.
      $ kubectl get node -A
      NAME             STATUS   ROLES                  AGE     VERSION
      cloud.kubeedge   Ready    control-plane,master   4h11m   v1.20.2
      

      Deploying the KubeEdge Cluster Using Keadm

      If you choose to deploy the cluster using Keadm, you need only to install the kubeedge-keadm RPM package on the cloud and edge nodes.

      $ yum install kubeedge-keadm
      

      Deploying CloudCore on the Cloud Node

      Initializing the Cluster

      # Set --advertise-address to the IP address of the cloud node.
      $ keadm init --advertise-address="9.63.252.224" --kubeedge-version=1.8.0
      Kubernetes version verification passed, KubeEdge installation will start...
      W0829 10:41:56.541877  420383 warnings.go:67] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
      W0829 10:41:57.253214  420383 warnings.go:67] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
      W0829 10:41:59.778672  420383 warnings.go:67] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
      W0829 10:42:00.488838  420383 warnings.go:67] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
      kubeedge-v1.8.0-linux-amd64.tar.gz checksum:
      checksum_kubeedge-v1.8.0-linux-amd64.tar.gz.txt content:
      [Run as service] start to download service file for cloudcore
      [Run as service] success to download service file for cloudcore
      kubeedge-v1.8.0-linux-amd64/
      kubeedge-v1.8.0-linux-amd64/edge/
      kubeedge-v1.8.0-linux-amd64/edge/edgecore
      kubeedge-v1.8.0-linux-amd64/cloud/
      kubeedge-v1.8.0-linux-amd64/cloud/csidriver/
      kubeedge-v1.8.0-linux-amd64/cloud/csidriver/csidriver
      kubeedge-v1.8.0-linux-amd64/cloud/admission/
      kubeedge-v1.8.0-linux-amd64/cloud/admission/admission
      kubeedge-v1.8.0-linux-amd64/cloud/cloudcore/
      kubeedge-v1.8.0-linux-amd64/cloud/cloudcore/cloudcore
      kubeedge-v1.8.0-linux-amd64/version
      
      KubeEdge cloudcore is running, For logs visit:  /var/log/kubeedge/cloudcore.log
      CloudCore started
      

      At this time, CloudCore is running but is not managed by systemd, and dynamicController (supporting the list watch function of EdgeCore) is not enabled. You need to modify the configuration.

      Modifying CloudCore Configurations

      # Modify the /etc/kubeedge/config/cloudcore.yaml file.
      # Enable dynamicController.
      $ cd /etc/kubeedge/config
      $ patch cloudcore.yaml - <<EOF
      index 28235a9..313375c 100644
      --- a/cloudcore.yaml
      +++ b/cloudcore.yaml
      @@ -1,7 +1,3 @@
       apiVersion: cloudcore.config.kubeedge.io/v1alpha1
       commonConfig:
         tunnelPort: 10350
      @@ -67,7 +63,7 @@ modules:
           load:
             updateDeviceStatusWorkers: 1
         dynamicController:
      -    enable: false
      +    enable: true	# Enable dynamicController to support the list watch function of EdgeCore.
         edgeController:
           buffer:
             configMapEvent: 1
      @@ -119,5 +115,3 @@ modules:
           restTimeout: 60
         syncController:
           enable: true
      EOF
      
      # Enable systemd to manage CloudCore.
      # Copy cloudcore.service to /usr/lib/systemd/system.
      $ cp /etc/kubeedge/cloudcore.service /usr/lib/systemd/system
      
      # Kill the current CloudCore process, then restart it.
      $ pkill cloudcore
      $ systemctl restart cloudcore
      
      # Check whether the CloudCore service is running.
      $ systemctl status cloudcore
      ● cloudcore.service
           Loaded: loaded (/usr/lib/systemd/system/cloudcore.service disabled; vendor preset: disabled)
           Active: active (running) since Sun 2021-08-29 10:50:14 CST; 4s ago
         Main PID: 424578 (cloudcore)
            Tasks: 36 (limit: 202272)
           Memory: 44.2M
              CPU: 112ms
           CGroup: /system.slice/cloudcore.service
                   └─424578 /usr/local/bin/cloudcore
      
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.845792  424578 upstream.go:121] start upstream controller
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.846586  424578 downstream.go:870] Start downstream devicecontroller
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.849475  424578 downstream.go:566] start downstream controller
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.946110  424578 server.go:243] Ca and CaKey don't exist in local directory, and will read from the secret
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.951806  424578 server.go:288] CloudCoreCert and key don't exist in local directory, and will read from the >
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.959661  424578 signcerts.go:100] Succeed to creating token
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.959716  424578 server.go:44] start unix domain socket server
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.959973  424578 uds.go:71] listening on: //var/lib/kubeedge/kubeedge.sock
      Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.966693  424578 server.go:64] Starting cloudhub websocket server
      Aug 29 10:50:17 cloud.kubeedge cloudcore[424578]: I0829 10:50:17.847150  424578 upstream.go:63] Start upstream devicecontroller
      

      CloudCore has been deployed on the cloud node. Then, deploy EdgeCore on the edge node.

      Managing the Edge Node

      Run the keadm join command on the edge node to manage it.

      Modifying iSulad Configurations

      File path: /etc/isulad/daemon.json

      {
          # Set pod-sandbox-image.
          "pod-sandbox-image": "kubeedge/pause:3.1",
          # The listening port `10350` of EdgeCore conflicts with the WebSocket port of iSulad. As a result, EdgeCore cannot be started. To resolve the conflict, change the value of `websocket-server-listening-port` in the iSulad configuration file (`/etc/isulad/daemon.json`) to `10351`.
          "websocket-server-listening-port": 10351,
      }
      

      After the configuration file is modified, run the systemctl restart isulad command to restart iSulad.

      Connecting EdgeCore to CloudCore

      # Obtain a token on the cloud node.
      $ keadm gettoken
      28c25d3b137593f5bbfb776cf5b19866ab9727cab9e97964dd503f87cd52cbde.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzAyOTE4MTV9.aGUyCi9gdysVtMu0DQzrD5TcV_DcXob647YeqcOxKDA
      
      # Run the keadm join command to connect EdgeCore to CloudCore.
      # --cloudcore-ipport is a mandatory parameter. 10000 is the default port of CloudCore.
      $ keadm join --cloudcore-ipport=9.63.252.224:10000 --kubeedge-version=1.8.0 --token=28c25d3b137593f5bbfb776cf5b19866ab9727cab9e97964dd503f87cd52cbde.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzAyOTE4MTV9.aGUyCi9gdysVtMu0DQzrD5TcV_DcXob647YeqcOxKDA
      Host has mosquit+ already installed and running. Hence skipping the installation steps !!!
      kubeedge-v1.8.0-linux-amd64.tar.gz checksum:
      checksum_kubeedge-v1.8.0-linux-amd64.tar.gz.txt content:
      [Run as service] start to download service file for edgecore
      [Run as service] success to download service file for edgecore
      kubeedge-v1.8.0-linux-amd64/
      kubeedge-v1.8.0-linux-amd64/edge/
      kubeedge-v1.8.0-linux-amd64/edge/edgecore
      kubeedge-v1.8.0-linux-amd64/cloud/
      kubeedge-v1.8.0-linux-amd64/cloud/csidriver/
      kubeedge-v1.8.0-linux-amd64/cloud/csidriver/csidriver
      kubeedge-v1.8.0-linux-amd64/cloud/admission/
      kubeedge-v1.8.0-linux-amd64/cloud/admission/admission
      kubeedge-v1.8.0-linux-amd64/cloud/cloudcore/
      kubeedge-v1.8.0-linux-amd64/cloud/cloudcore/cloudcore
      kubeedge-v1.8.0-linux-amd64/version
      
      KubeEdge edgecore is running, For logs visit: journalctl -u edgecore.service -b
      

      At this time, the deployment of EdgeCore is not complete because Docker is used in the default settings. You need to modify the configuration file to connect EdgeCore to iSulad.

      Modifying EdgeCore Configurations

      # Enable systemd to manage EdgeCore.
      # Copy edgecore.service to /usr/lib/systemd/system.
      $ cp /etc/kubeedge/edgecore.service /usr/lib/systemd/system
      
      # Modify the EdgeCore configurations.
      $ cd /etc/kubeedge/config
      $ patch edgecore.yaml - <<EOF
      index 165e24b..efbfd49 100644
      --- a/edgecore.yaml
      +++ b/edgecore.yaml
      @@ -32,7 +32,7 @@ modules:
             server: 9.63.252.224:10000
             writeDeadline: 15
      @@ -73,10 +73,10 @@ modules:
           podSandboxImage: kubeedge/pause:3.1
           registerNode: true
           registerNodeNamespace: default
      -    remoteImageEndpoint: unix:///var/run/dockershim.sock
      -    remoteRuntimeEndpoint: unix:///var/run/dockershim.sock
      +    remoteImageEndpoint: unix:///var/run/isulad.sock
      +    remoteRuntimeEndpoint: unix:///var/run/isulad.sock
           runtimeRequestTimeout: 2
      -    runtimeType: docker
      +    runtimeType: remote	# The runtime type of iSulad is remote.
           volumeStatsAggPeriod: 60000000000
         eventBus:
           enable: true
      @@ -97,7 +97,7 @@ modules:
           enable: true
           metaServer:
             debug: false
      -      enable: false
      +      enable: true		# Enable list watch我记得上文中间有空格的.
           podStatusSyncInterval: 60
           remoteQueryTimeout: 60
         serviceBus:
      EOF
      
      # Kill the current EdgeCore process.
      $ pkill edgecore
      
      # Restart EdgeCore.
      $ systemctl restart edgecore
      

      Checking Whether the Edge Node is Managed

      # Run the command on the cloud node. You can see that the edge node is added.
      $ kubectl get node -A
      NAME             STATUS   ROLES                  AGE     VERSION
      cloud.kubeedge   Ready    control-plane,master   19h     v1.20.2
      edge.kubeedge    Ready    agent,edge             5m16s   v1.19.3-kubeedge-v1.8.0
      

      The KubeEdge cluster has been deployed using the keadm command. Next, let's test the task delivery from the cloud to the edge.

      Deploying an Application

      Deploying Nginx

      # You can directly use the Nginx template provided by KubeEdge.
      $ kubectl apply -f https://github.com/kubeedge/kubeedge/raw/master/build/deployment.yaml
      deployment.apps/nginx-deployment created
      
      # Check whether Nginx is deployed on the edge node.
      $ kubectl get pod -A -owide | grep nginx
      default       nginx-deployment-77f96fbb65-fnp7n        1/1     Running   0          37s   10.244.2.4     edge.kubeedge    <none>           <none>
      
      # You can see that Nginx has been successfully deployed on the edge node.
      

      Testing the Function

      # Test whether the function is running properly.
      # Run the curl command on the edge node to access the IP address of Nginx, which is 10.244.2.4.
      $ curl 10.244.2.4:80
      <!DOCTYPE html>
      <html>
      <head>
      <title>Welcome to nginx!</title>
      <style>
          body {
              width: 35em;
              margin: 0 auto;
              font-family: Tahoma, Verdana, Arial, sans-serif;
          }
      </style>
      </head>
      <body>
      <h1>Welcome to nginx!</h1>
      <p>If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.</p>
      
      <p>For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br/>
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.</p>
      
      <p><em>Thank you for using nginx.</em></p>
      </body>
      </html>
      

      The deployment of KubeEdge and iSulad is complete.

      Deploying the KubeEdge Cluster Using Binary Files

      You can also deploy the KubeEdge cluster using binary files. Only two RPM packages are required: cloudcore (on the cloud node) and edgecore (on the edge node).

      The KubeEdge deployment using binary files is for testing only. Do not use this method in the production environment.

      Deploying CloudCore on the Cloud Node

      Log in to the cloud host.

      Installing the cloudcore RPM Package

      $ yum install kubeedge-cloudcore
      

      Creating CRDs

      $ kubectl apply -f /etc/kubeedge/crds/devices/
      $ kubectl apply -f /etc/kubeedge/crds/reliablesyncs/
      $ kubectl apply -f /etc/kubeedge/crds/router/
      

      Preparing the Configuration File

      $ cloudcore --defaultconfig > /etc/kubeedge/config/cloudcore.yaml
      

      Modify CloudCore configurations by referring to Deploying CloudCore Using Keadm.

      Running CloudCore

      $ pkill cloudcore
      $ systemctl start cloudcore
      

      Deploying EdgeCore on the Edge Node

      Log in to the edge host.

      Installing the edgecore RPM Package

      $ yum install kubeedge-edgecore
      

      Preparing the Configuration File

      $ edgecore --defaultconfig > /etc/kubeedge/config/edgecore.yaml
      

      Modify EdgeCore configurations by referring to Deploying EdgeCore Using Keadm.

      $ kubectl get secret -nkubeedge tokensecret -o=jsonpath='{.data.tokendata}' | base64 -d
      1c4ff11289a14c59f2cbdbab726d1857262d5bda778ddf0de34dd59d125d3f69.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzE0ODM3MzN9.JY77nMVDHIKD9ipo03Y0mSbxief9qOvJ4yMNx1yZpp0
      
      # Add the obtained token to the configuration file.
      sed -i -e "s|token: .*|token: ${token}|g" /etc/kubeedge/config/edgecore.yaml
      
      # The value of the token variable is obtained in the previous step.
      

      Running EdgeCore

      $ pkill edgecore
      $ systemctl start edgecore
      

      Appendix

      kube-flannel-cloud.yml

      # Application scenario: cloud node
      ---
      apiVersion: policy/v1beta1
      kind: PodSecurityPolicy
      metadata:
        name: psp.flannel.unprivileged
        annotations:
          seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
          seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
          apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
          apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
      spec:
        privileged: false
        volumes:
        - configMap
        - secret
        - emptyDir
        - hostPath
        allowedHostPaths:
        - pathPrefix: "/etc/cni/net.d"
        - pathPrefix: "/etc/kube-flannel"
        - pathPrefix: "/run/flannel"
        readOnlyRootFilesystem: false
        # Users and groups
        runAsUser:
          rule: RunAsAny
        supplementalGroups:
          rule: RunAsAny
        fsGroup:
          rule: RunAsAny
        # Privilege Escalation
        allowPrivilegeEscalation: false
        defaultAllowPrivilegeEscalation: false
        # Capabilities
        allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
        defaultAddCapabilities: []
        requiredDropCapabilities: []
        # Host namespaces
        hostPID: false
        hostIPC: false
        hostNetwork: true
        hostPorts:
        - min: 0
          max: 65535
        # SELinux
        seLinux:
          # SELinux is unused in CaaSP
          rule: 'RunAsAny'
      ---
      kind: ClusterRole
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: flannel
      rules:
      - apiGroups: ['extensions']
        resources: ['podsecuritypolicies']
        verbs: ['use']
        resourceNames: ['psp.flannel.unprivileged']
      - apiGroups:
        - ""
        resources:
        - pods
        verbs:
        - get
      - apiGroups:
        - ""
        resources:
        - nodes
        verbs:
        - list
        - watch
      - apiGroups:
        - ""
        resources:
        - nodes/status
        verbs:
        - patch
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: flannel
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: flannel
      subjects:
      - kind: ServiceAccount
        name: flannel
        namespace: kube-system
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: flannel
        namespace: kube-system
      ---
      kind: ConfigMap
      apiVersion: v1
      metadata:
        name: kube-flannel-cfg
        namespace: kube-system
        labels:
          tier: node
          app: flannel
      data:
        cni-conf.json: |
          {
            "name": "cbr0",
            "cniVersion": "0.3.1",
            "plugins": [
              {
                "type": "flannel",
                "delegate": {
                  "hairpinMode": true,
                  "isDefaultGateway": true
                }
              },
              {
                "type": "portmap",
                "capabilities": {
                  "portMappings": true
                }
              }
            ]
          }
        net-conf.json: |
          {
            "Network": "10.244.0.0/16",
            "Backend": {
              "Type": "vxlan"
            }
          }
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: kube-flannel-cloud-ds
        namespace: kube-system
        labels:
          tier: node
          app: flannel
      spec:
        selector:
          matchLabels:
            app: flannel
        template:
          metadata:
            labels:
              tier: node
              app: flannel
          spec:
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: kubernetes.io/os
                      operator: In
                      values:
                      - linux
                    - key: node-role.kubernetes.io/agent
                      operator: DoesNotExist
            hostNetwork: true
            priorityClassName: system-node-critical
            tolerations:
            - operator: Exists
              effect: NoSchedule
            serviceAccountName: flannel
            initContainers:
            - name: install-cni
              image: quay.io/coreos/flannel:v0.14.0
              command:
              - cp
              args:
              - -f
              - /etc/kube-flannel/cni-conf.json
              - /etc/cni/net.d/10-flannel.conflist
              volumeMounts:
              - name: cni
                mountPath: /etc/cni/net.d
              - name: flannel-cfg
                mountPath: /etc/kube-flannel/
            containers:
            - name: kube-flannel
              image: quay.io/coreos/flannel:v0.14.0
              command:
              - /opt/bin/flanneld
              args:
              - --ip-masq
              - --kube-subnet-mgr
              resources:
                requests:
                  cpu: "100m"
                  memory: "50Mi"
                limits:
                  cpu: "100m"
                  memory: "50Mi"
              securityContext:
                privileged: false
                capabilities:
                  add: ["NET_ADMIN", "NET_RAW"]
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: POD_NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              volumeMounts:
              - name: run
                mountPath: /run/flannel
              - name: flannel-cfg
                mountPath: /etc/kube-flannel/
            volumes:
            - name: run
              hostPath:
                path: /run/flannel
            - name: cni
              hostPath:
                path: /etc/cni/net.d
            - name: flannel-cfg
              configMap:
                name: kube-flannel-cfg
      

      kube-flannel-edge.yml

      # Application scenario: edge node
      ---
      apiVersion: policy/v1beta1
      kind: PodSecurityPolicy
      metadata:
        name: psp.flannel.unprivileged
        annotations:
          seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
          seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
          apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
          apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
      spec:
        privileged: false
        volumes:
        - configMap
        - secret
        - emptyDir
        - hostPath
        allowedHostPaths:
        - pathPrefix: "/etc/cni/net.d"
        - pathPrefix: "/etc/kube-flannel"
        - pathPrefix: "/run/flannel"
        readOnlyRootFilesystem: false
        # Users and groups
        runAsUser:
          rule: RunAsAny
        supplementalGroups:
          rule: RunAsAny
        fsGroup:
          rule: RunAsAny
        # Privilege Escalation
        allowPrivilegeEscalation: false
        defaultAllowPrivilegeEscalation: false
        # Capabilities
        allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
        defaultAddCapabilities: []
        requiredDropCapabilities: []
        # Host namespaces
        hostPID: false
        hostIPC: false
        hostNetwork: true
        hostPorts:
        - min: 0
          max: 65535
        # SELinux
        seLinux:
          # SELinux is unused in CaaSP
          rule: 'RunAsAny'
      ---
      kind: ClusterRole
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: flannel
      rules:
      - apiGroups: ['extensions']
        resources: ['podsecuritypolicies']
        verbs: ['use']
        resourceNames: ['psp.flannel.unprivileged']
      - apiGroups:
        - ""
        resources:
        - pods
        verbs:
        - get
      - apiGroups:
        - ""
        resources:
        - nodes
        verbs:
        - list
        - watch
      - apiGroups:
        - ""
        resources:
        - nodes/status
        verbs:
        - patch
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: flannel
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: flannel
      subjects:
      - kind: ServiceAccount
        name: flannel
        namespace: kube-system
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: flannel
        namespace: kube-system
      ---
      kind: ConfigMap
      apiVersion: v1
      metadata:
        name: kube-flannel-cfg
        namespace: kube-system
        labels:
          tier: node
          app: flannel
      data:
        cni-conf.json: |
          {
            "name": "cbr0",
            "cniVersion": "0.3.1",
            "plugins": [
              {
                "type": "flannel",
                "delegate": {
                  "hairpinMode": true,
                  "isDefaultGateway": true
                }
              },
              {
                "type": "portmap",
                "capabilities": {
                  "portMappings": true
                }
              }
            ]
          }
        net-conf.json: |
          {
            "Network": "10.244.0.0/16",
            "Backend": {
              "Type": "vxlan"
            }
          }
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: kube-flannel-edge-ds
        namespace: kube-system
        labels:
          tier: node
          app: flannel
      spec:
        selector:
          matchLabels:
            app: flannel
        template:
          metadata:
            labels:
              tier: node
              app: flannel
          spec:
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: kubernetes.io/os
                      operator: In
                      values:
                      - linux
                    - key: node-role.kubernetes.io/agent
                      operator: Exists
            hostNetwork: true
            priorityClassName: system-node-critical
            tolerations:
            - operator: Exists
              effect: NoSchedule
            serviceAccountName: flannel
            initContainers:
            - name: install-cni
              image: quay.io/coreos/flannel:v0.14.0
              command:
              - cp
              args:
              - -f
              - /etc/kube-flannel/cni-conf.json
              - /etc/cni/net.d/10-flannel.conflist
              volumeMounts:
              - name: cni
                mountPath: /etc/cni/net.d
              - name: flannel-cfg
                mountPath: /etc/kube-flannel/
            containers:
            - name: kube-flannel
              image: quay.io/coreos/flannel:v0.14.0
              command:
              - /opt/bin/flanneld
              args:
              - --ip-masq
              - --kube-subnet-mgr
              - --kube-api-url=http://127.0.0.1:10550
              resources:
                requests:
                  cpu: "100m"
                  memory: "50Mi"
                limits:
                  cpu: "100m"
                  memory: "50Mi"
              securityContext:
                privileged: false
                capabilities:
                  add: ["NET_ADMIN", "NET_RAW"]
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: POD_NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              volumeMounts:
              - name: run
                mountPath: /run/flannel
              - name: flannel-cfg
                mountPath: /etc/kube-flannel/
            volumes:
            - name: run
              hostPath:
                path: /run/flannel
            - name: cni
              hostPath:
                path: /etc/cni/net.d
            - name: flannel-cfg
              configMap:
                name: kube-flannel-cfg
      

      cloudcore.service

      # Application scenario: cloud node
      # File path: /usr/lib/systemd/system/cloudcore.service
      [Unit]
      Description=cloudcore.service
      
      [Service]
      Type=simple
      ExecStart=/usr/local/bin/cloudcore
      Restart=always
      RestartSec=10
      
      [Install]
      WantedBy=multi-user.target
      

      cloudcore.yaml

      # Application scenario: cloud node
      # File path: /etc/kubeedge/config/cloudcore.yaml
      apiVersion: cloudcore.config.kubeedge.io/v1alpha1
      commonConfig:
        tunnelPort: 10351
      kind: CloudCore
      kubeAPIConfig:
        burst: 200
        contentType: application/vnd.kubernetes.protobuf
        kubeConfig: /root/.kube/config
        master: ""
        qps: 100
      modules:
        cloudHub:
          advertiseAddress:
          - 9.63.252.224
          dnsNames:
          - ""
          edgeCertSigningDuration: 365
          enable: true
          https:
            address: 0.0.0.0
            enable: true
            port: 10002
          keepaliveInterval: 30
          nodeLimit: 1000
          quic:
            address: 0.0.0.0
            enable: false
            maxIncomingStreams: 10000
            port: 10001
          tlsCAFile: /etc/kubeedge/ca/rootCA.crt
          tlsCAKeyFile: /etc/kubeedge/ca/rootCA.key
          tlsCertFile: /etc/kubeedge/certs/server.crt
          tlsPrivateKeyFile: /etc/kubeedge/certs/server.key
          tokenRefreshDuration: 12
          unixsocket:
            address: unix:///var/lib/kubeedge/kubeedge.sock
            enable: true
          websocket:
            address: 0.0.0.0
            enable: true
            port: 10000
          writeTimeout: 30
        cloudStream:
          enable: false
          streamPort: 10003
          tlsStreamCAFile: /etc/kubeedge/ca/streamCA.crt
          tlsStreamCertFile: /etc/kubeedge/certs/stream.crt
          tlsStreamPrivateKeyFile: /etc/kubeedge/certs/stream.key
          tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
          tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
          tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
          tunnelPort: 10004
        deviceController:
          buffer:
            deviceEvent: 1
            deviceModelEvent: 1
            updateDeviceStatus: 1024
          context:
            receiveModule: devicecontroller
            responseModule: cloudhub
            sendModule: cloudhub
          enable: true
          load:
            updateDeviceStatusWorkers: 1
        dynamicController:
          enable: true
        edgeController:
          buffer:
            configMapEvent: 1
            deletePod: 1024
            endpointsEvent: 1
            podEvent: 1
            queryConfigMap: 1024
            queryEndpoints: 1024
            queryNode: 1024
            queryPersistentVolume: 1024
            queryPersistentVolumeClaim: 1024
            querySecret: 1024
            queryService: 1024
            queryVolumeAttachment: 1024
            ruleEndpointsEvent: 1
            rulesEvent: 1
            secretEvent: 1
            serviceAccountToken: 1024
            serviceEvent: 1
            updateNode: 1024
            updateNodeStatus: 1024
            updatePodStatus: 1024
          context:
            receiveModule: edgecontroller
            responseModule: cloudhub
            sendModule: cloudhub
            sendRouterModule: router
          enable: true
          load:
            ServiceAccountTokenWorkers: 4
            UpdateRuleStatusWorkers: 4
            deletePodWorkers: 4
            queryConfigMapWorkers: 4
            queryEndpointsWorkers: 4
            queryNodeWorkers: 4
            queryPersistentVolumeClaimWorkers: 4
            queryPersistentVolumeWorkers: 4
            querySecretWorkers: 4
            queryServiceWorkers: 4
            queryVolumeAttachmentWorkers: 4
            updateNodeStatusWorkers: 1
            updateNodeWorkers: 4
            updatePodStatusWorkers: 1
          nodeUpdateFrequency: 10
        router:
          address: 0.0.0.0
          enable: false
          port: 9443
          restTimeout: 60
        syncController:
          enable: true
      

      edgecore.service

      # Application scenario: edge node
      # File path: /etc/systemd/system/edgecore.service
      [Unit]
      Description=edgecore.service
      
      [Service]
      Type=simple
      ExecStart=/usr/local/bin/edgecore
      Restart=always
      RestartSec=10
      
      [Install]
      WantedBy=multi-user.target
      

      edgecore.yaml

      # Application scenario: edge node
      # File path: /etc/kubeedge/config/edgecore.yaml
      apiVersion: edgecore.config.kubeedge.io/v1alpha1
      database:
        aliasName: default
        dataSource: /var/lib/kubeedge/edgecore.db
        driverName: sqlite3
      kind: EdgeCore
      modules:
        dbTest:
          enable: false
        deviceTwin:
          enable: true
        edgeHub:
          enable: true
          heartbeat: 15
          httpServer: https://9.63.252.224:10002
          projectID: e632aba927ea4ac2b575ec1603d56f10
          quic:
            enable: false
            handshakeTimeout: 30
            readDeadline: 15
            server: 9.63.252.227:10001
            writeDeadline: 15
          rotateCertificates: true
          tlsCaFile: /etc/kubeedge/ca/rootCA.crt
          tlsCertFile: /etc/kubeedge/certs/server.crt
          tlsPrivateKeyFile: /etc/kubeedge/certs/server.key
          token: ""# Enter the token obtained from the cloud side.
          websocket:
            enable: true
            handshakeTimeout: 30
            readDeadline: 15
            server: 9.63.252.224:10000
            writeDeadline: 15
        edgeMesh:
          enable: false
          lbStrategy: RoundRobin
          listenInterface: docker0
          listenPort: 40001
          subNet: 9.251.0.0/16
        edgeStream:
          enable: false
          handshakeTimeout: 30
          readDeadline: 15
          server: 9.63.252.224:10004
          tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
          tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
          tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
          writeDeadline: 15
        edged:
          cgroupDriver: cgroupfs
          cgroupRoot: ""
          cgroupsPerQOS: true
          clusterDNS: ""
          clusterDomain: ""
          cniBinDir: /opt/cni/bin
          cniCacheDirs: /var/lib/cni/cache
          cniConfDir: /etc/cni/net.d
          concurrentConsumers: 5
          devicePluginEnabled: false
          dockerAddress: unix:///var/run/docker.sock
          edgedMemoryCapacity: 7852396000
          enable: true
          enableMetrics: true
          gpuPluginEnabled: false
          hostnameOverride: edge.kubeedge
          imageGCHighThreshold: 80
          imageGCLowThreshold: 40
          imagePullProgressDeadline: 60
          maximumDeadContainersPerPod: 1
          networkPluginMTU: 1500
          nodeIP: 9.63.252.227
          nodeStatusUpdateFrequency: 10
          podSandboxImage: kubeedge/pause:3.1
          registerNode: true
          registerNodeNamespace: default
          remoteImageEndpoint: unix:///var/run/isulad.sock
          remoteRuntimeEndpoint: unix:///var/run/isulad.sock
          runtimeRequestTimeout: 2
          runtimeType: remote
          volumeStatsAggPeriod: 60000000000
        eventBus:
          enable: true
          eventBusTLS:
            enable: false
            tlsMqttCAFile: /etc/kubeedge/ca/rootCA.crt
            tlsMqttCertFile: /etc/kubeedge/certs/server.crt
            tlsMqttPrivateKeyFile: /etc/kubeedge/certs/server.key
          mqttMode: 2
          mqttQOS: 0
          mqttRetain: false
          mqttServerExternal: tcp://127.0.0.1:1883
          mqttServerInternal: tcp://127.0.0.1:1884
          mqttSessionQueueSize: 100
        metaManager:
          contextSendGroup: hub
          contextSendModule: websocket
          enable: true
          metaServer:
            debug: false
            enable: true
          podStatusSyncInterval: 60
          remoteQueryTimeout: 60
        serviceBus:
          enable: false
      

      daemon.json

      # Application scenarios: cloud and edge nodes
      # File path: /etc/isulad/daemon.json
      {
          "group": "isula",
          "default-runtime": "lcr",
          "graph": "/var/lib/isulad",
          "state": "/var/run/isulad",
          "engine": "lcr",
          "log-level": "ERROR",
          "pidfile": "/var/run/isulad.pid",
          "log-opts": {
              "log-file-mode": "0600",
              "log-path": "/var/lib/isulad",
              "max-file": "1",
              "max-size": "30KB"
          },
          "log-driver": "stdout",
          "container-log": {
              "driver": "json-file"
          },
          "hook-spec": "/etc/default/isulad/hooks/default.json",
          "start-timeout": "2m",
          "storage-driver": "overlay2",
          "storage-opts": [
              "overlay2.override_kernel_check=true"
          ],
          "registry-mirrors": [
              "docker.io"
          ],
          "insecure-registries": [
              "k8s.gcr.io",
              "quay.io",
              "hub.oepkgs.net"
          ],
          "pod-sandbox-image": "k8s.gcr.io/pause:3.2",	# Set this parameter to kubeedge/pause:3.1 for edge nodes.
          "websocket-server-listening-port": 10351,
          "native.umask": "secure",
          "network-plugin": "cni",
          "cni-bin-dir": "/opt/cni/bin",
          "cni-conf-dir": "/etc/cni/net.d",
          "image-layer-check": false,
          "use-decrypted-key": true,
          "insecure-skip-verify-enforce": false
      }
      

      Bug Catching

      Buggy Content

      Bug Description

      Submit As Issue

      It's a little complicated....

      I'd like to ask someone.

      PR

      Just a small problem.

      I can fix it online!

      Bug Type
      Specifications and Common Mistakes

      ● Misspellings or punctuation mistakes;

      ● Incorrect links, empty cells, or wrong formats;

      ● Chinese characters in English context;

      ● Minor inconsistencies between the UI and descriptions;

      ● Low writing fluency that does not affect understanding;

      ● Incorrect version numbers, including software package names and version numbers on the UI.

      Usability

      ● Incorrect or missing key steps;

      ● Missing prerequisites or precautions;

      ● Ambiguous figures, tables, or texts;

      ● Unclear logic, such as missing classifications, items, and steps.

      Correctness

      ● Technical principles, function descriptions, or specifications inconsistent with those of the software;

      ● Incorrect schematic or architecture diagrams;

      ● Incorrect commands or command parameters;

      ● Incorrect code;

      ● Commands inconsistent with the functions;

      ● Wrong screenshots.

      Risk Warnings

      ● Lack of risk warnings for operations that may damage the system or important data.

      Content Compliance

      ● Contents that may violate applicable laws and regulations or geo-cultural context-sensitive words and expressions;

      ● Copyright infringement.

      How satisfied are you with this document

      Not satisfied at all
      Very satisfied
      Submit
      Click to create an issue. An issue template will be automatically generated based on your feedback.
      Bug Catching
      编组 3备份