背景

目前,很多边缘计算容器开源我的项目在应用上均存在一个默认的前提:用户须要提前准备一个规范的或者特定工具搭建的 Kubernetes 集群,而后再通过特定工具或者其余形式在集群中部署相应组件来体验边缘能力。这无疑进步了用户体验边缘能力的门槛,而且应用上有泛滥的限度,让用户很难上手。 简略整顿,大略会有如下问题:

门槛太高

  • 用户须要提前准备一个 Kubernetes 集群,对于很多用户来说门槛太高,搭建的流程比较复杂,容易失败,把很多想应用边缘能力的人群拒之门外;

限制性太大

  • 往往要求特定工具搭建的特定版本的 Kubernetes 集群,通用性太差,用户在想在理论生产环境上应用限制性太大;

增加边缘节点比拟麻烦

  • 增加边缘节点须要依附搭建 Kubernetes 集群自身的工具增加 Kubernetes 原生的节点再进行转化,对第三方工具依赖性较强,并且操作流程比拟麻烦,容易出错;

自动化能力较差

  • 无论 Kubernetes 集群的搭建,还是增加边缘节点都很难在生产环境自动化起来,相干流程还须要本人的团队进行二次开发,集成难度较大;

为了升高用户体验边缘能力的门槛,云原生社区的同学打算开发一个能够一键部署边缘 Kubernetes 集群的办法,让用户能够更容易、更简略的体验边缘 Kubernetes 集群。

架构设计

针对上述问题,为了升高用户应用边缘 Kubernetes 集群的门槛,让边缘 Kubernetes 集群具备生产能力,咱们设计了一键就能够部署进去一个边缘 Kubernetes 集群的计划,齐全屏蔽装置细节,让用户能够零门槛的体验边缘能力。

初衷

  • 让用户很简略、无门槛的应用边缘 Kubernetes 集群,并能在生产环境真正把边缘能力用起来;

指标

一键化应用

  • 可能一键搭建起一个边缘 Kubernetes 集群;
  • 可能一键很简略、很灵便的增加边缘节点;

两种装置创景

  • 反对在线装置;
  • 反对离线装置,让私有化环境也能很简略;

可生产应用

  • 不要封装太多,能够让想应用边缘 Kubernetes 集群的团队能在外部零碎进行简略的集成,就生产可用;

零学习老本

  • 尽可能的和 kubeadm 的应用形式保持一致,让用户无额定的学习老本,会用 kubeadm 就会用 edgeadm;

准则

  • 不批改 kubeadm 源码

    • 尽量援用和复用 kubeadm 的源码,尽量不批改 kubeadm 的源码,防止前面降级的隐患;
    • 基于 kubeadm 但又高于 kubeadm,不用被 kubeadm 的设计所局限,只有能让用户应用起来更简略就能够被容许;
  • 容许用户抉择是否部署边缘能力组件;
  • 容许用户自定义边缘能力组件的配置;

设计与实现

咱们钻研了 kubeadm 的源码,发现能够借用 kubeadm 创立原生 Kubernetes集群、join 节点、workflow 思维来一键部署边缘 Kubernetes 集群,并且能够分步去执行装置步骤。这正是咱们想要的简略、灵便、低学习老本的部署计划。于是咱们站在伟人的肩膀上,利用 Kubedam 的思维,复用 kubeadm 的源码,设计出了如下的解决方案。

其中 kubeadm init cluster/join node局部齐全复用了 kubadm 的源码,所有逻辑和 kubeadm 完全相同。

这个计划有如下几个长处:

齐全兼容 kubeadm

咱们只是站在 kubeadm 的肩膀上,在 kubeadm init/join 之前设置了一些边缘集群须要的配置参数,将初始化 Master 或 Node 节点自动化,装置了容器运行时。在 kubeadm init/join 实现之后,装置了 CNI 网络插件和部署了相应的边缘能力组件。

咱们以 Go Mod 形式援用了 kubeadm 源码,整个过程中并未对 kubeadm 的源码批改过一行,齐全的原生,为前面降级更高版本的 kubeadm 做好了筹备。

一键化,用起来简略、灵便、自动化

edgeadm init 集群和 join 节点齐全保留了 kubeadm init/join 原有的参数和流程,只是主动了初始化节点和装置容器运行时,能够用edgeadm --enable-edge=fasle参数来一键化装置原生 Kubernetes 集群, 也能够用edgeadm --enable-edge=true参数一键化来装置边缘 Kubernetes 集群。

能够 Join 任何只有可能拜访到 Kube-apiserver 位于任何地位的节点, 也能够 join master。join master 也连续了 kubeadm 的的形式,搭建高可用的节点能够在须要的时候,间接用 join master 去扩容 Master 节点,实现高可用。

无学习老本,和 kubeadm 的应用完全相同

因为kubeadm init cluster/join node局部齐全复用了 kubadm 的源码,所有逻辑和 kubeadm 完全相同,齐全保留了 kubeadm 的应用习惯和所有 flag 参数,用法和 kubeadm 应用齐全一样,没有任何新的学习老本,用户能够按 kubeadm 的参数或者应用 kubeadm.config 去自定义边缘 Kubernetes 集群。

边缘节点平安加强

借助 Kubernetes Node鉴权机制,咱们默认开启了NodeRestriction准入插件,确保每个节点身份都惟一,只具备最小权限集,即便某个边缘节点被攻破也无奈操作其余边缘节点。

Kubelet 咱们也默认开启了Kubelet配置证书轮换机制,在 Kubelet 证书行将过期时, 将主动生成新的秘钥,并从 Kubernetes API 申请新的证书。 一旦新的证书可用,它将被用于与 Kubernetes API 间的连贯认证。

用 edgeadm 装置边缘 Kubernetes 集群

以下流程社区曾经录制了具体教程视频,可联合文档进行装置:

视频资源链接:用edgeadm一键装置边缘Kubernetes 集群和原生Kubernetes 集群

装置条件

  • 遵循 kubeadm 的最低要求 ,Master && Node 最低2C2G,磁盘空间不小于1G;
  • 目前反对 amd64、arm64 两个体系;

    其余体系可自行编译 edgeadm 和制作相应体系安装包,可参考 5. 自定义Kubernetes动态安装包
  • 反对的 Kubernetes 版本:大于等于v1.18,提供的安装包仅提供 Kubernetes v1.18.2 版本;

    其余 Kubernetes 版本可参考 5. 自定义 Kubernetes 动态安装包,自行制作。

下载 edgeadm 动态安装包

下载 edgeadm 动态安装包,并拷贝到所有 Master 和 Node 节点。

留神批改"arch=amd64"参数,目前反对[amd64, amd64], 下载本人机器对应的体系结构,其余参数不变

arch=amd64 version=v0.3.0-beta.0 && rm -rf edgeadm-linux-* && wget https://superedge-1253687700.cos.ap-guangzhou.myqcloud.com/$version/$arch/edgeadm-linux-$arch-$version.tgz && tar -xzvf edgeadm-linux-* && cd edgeadm-linux-$arch-$version && ./edgeadm

安装包大概200M,对于安装包的详细信息可查看 5. 自定义Kubernetes动态安装包

如果下载安装包比较慢,可间接查看相应SuperEdge相应版本, 下载edgeadm-linux-amd64/arm64-*.0.tgz,并解压也是一样的。

一键装置边缘独立 Kubernetes 集群性能从 SuperEdge-v0.3.0-beta.0开始反对,留神下载 v0.3.0-beta.0 及当前版本。

装置边缘 Kubernetes Master 节点

./edgeadm init --kubernetes-version=1.18.2 --image-repository superedge.tencentcloudcr.com/superedge --service-cidr=10.96.0.0/12 --pod-network-cidr=192.168.0.0/16 --install-pkg-path ./kube-linux-*.tar.gz --apiserver-cert-extra-sans=<Master节点外网IP> --apiserver-advertise-address=<Master节点内网IP> --enable-edge=true -v=6

其中:

  • --enable-edge=true: 是否部署边缘能力组件,默认 true
--enable-edge=false 示意装置原生 Kubernetes 集群,和 kubeadm 搭建的集群齐全一样;
  • --install-pkg-path: Kubernetes 动态安装包的地址
--install-pkg-path的值能够为机器上的门路,也能够为网络地址(比方:http://xxx/xxx/kube-linux-arm... 能免密wget到就能够),留神用和机器体系匹配的Kubernetes动态安装包;
  • --apiserver-cert-extra-sans: kube-apiserver的证书扩大地址

    • 举荐签订Master节点外网IP或者域名,只有签订的Master节点的IP或者域名能被边缘节点拜访到就能够,当然内网IP也被容许,前提是边缘节点能够通过此IP拜访 Kube-apiserver。自定义域名的话可自行在所有 Matser和Node节点配置 hosts;
    • 签订外网IP和域名,是因为边缘节点个别和 Master 节点不在同一局域网,须要通过外网来退出和拜访Master;
  • --image-repository:镜像仓库地址
要是 superedge.tencentcloudcr.com/superedge 比较慢,可换成其余减速镜像仓库,只有能 Pull 下来 kube-apiserver,kube-controller-manager,kube-scheduler,kube-proxy,etcd, pause……镜像就能够。

其余参数和 kubeadm 含意完全相同,可按 kubeadm 的要求进行配置。

也可用 kubeadm.config 配置 kubeadm 的原参数,通过edgeadm init --config kubeadm.config --install-pkg-path ./kube-linux-*.tar.gz 来创立边缘 Kubernetes 集群。

要是执行过程中没有问题,集群胜利初始化,会输入如下内容:

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:edgeadm join xxx.xxx.xxx.xxx:xxx --token xxxx \    --discovery-token-ca-cert-hash sha256:xxxxxxxxxx    --install-pkg-path <Path of edgeadm kube-* install package>

执行过程中如果呈现问题会间接返回相应的错误信息,并中断集群的初始化,可应用./edgeadm reset命令回滚集群的初始化操作。

设置Master kube-config 文件

要使非 root 用户能够运行 kubectl,请运行以下命令,它们也是 edgeadm init 输入的一部分:

mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config

或者,如果你是 root 用户,则能够运行:

export KUBECONFIG=/etc/kubernetes/admin.conf

留神保留./edgeadm init输入的./edgeadm join命令,前面增加Node节点时会用到。

其中token的有效期和kubeadm一样24h,过期之后能够用./edgeadm token create创立新的token。

--discovery-token-ca-cert-hash 的值生成也同 kubeadm,可在 Master 节点执行上面命令生成。

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

Join 边缘节点

在边缘节点上执行 <2>.下载edgeadm动态安装包,或者通过其余形式把 edgeadm 动态安装包上传到边缘节点,而后执行如下命令:

./edgeadm join <Master节点外网IP/Master节点内网IP/域名>:Port --token xxxx \     --discovery-token-ca-cert-hash sha256:xxxxxxxxxx      --install-pkg-path <edgeadm Kube-*动态安装包地址/FTP门路> --enable-edge=true

其中:

  • <Master 节点外网 IP/Master 节点内网IP/域名>:Port 是节点拜访 Kube-apiserver 服务的地址
能够把edgeadm init退出节点提醒的 Kube-apiserver 服务的地址视状况换成Master节点外网IP/Master节点内网IP/域名,次要取决于想让节点通过外网还是内网拜访 Kube-apiserver 服务。
  • --enable-edge=true: 退出的节点是否作为边缘节点(是否部署边缘能力组件),默认 true
--enable-edge=false 示意 join 原生 Kubernetes 集群节点,和 kubeadm join 的节点齐全一样;

如果执行过程中没有问题,新的 Node 胜利退出集群,会输入如下内容:

This node has joined the cluster:* Certificate signing request was sent to apiserver and a response was received.* The Kubelet was informed of the new secure connection details.Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

执行过程中如果呈现问题会间接返回相应的错误信息,并中断节点的增加,可应用./edgeadm reset命令回滚退出节点的操作,从新 join。

提醒:如果边缘节点 join 胜利后都会给边缘节点打一个label: superedge.io/edge-node=enable,不便后续利用用 nodeSelector 抉择利用调度到边缘节点;

原生 Kubernetes 节点和 kubeadm 的 join 一样,不会做任何操作。

用 edgeadm 装置边缘高可用 Kubernetes 集群

装置前提

  • 筹备一个Master VIP,做为可用负载平衡对立入口;
  • 3台满足 kubeadm 的最低要求 的机器作为Master节点;
  • 3台满足 kubeadm 的最低要求 的机器做worker节点;

装置 Haproxy

在 Master 上装置 Haproxy 作为集群总入口

留神:替换配置文件中的 < Master VIP >

# yum install -y haproxy# cat << EOF >/etc/haproxy/haproxy.cfgglobal    log         127.0.0.1 local2    chroot      /var/lib/haproxy    pidfile     /var/run/haproxy.pid    maxconn     4000    user        haproxy    group       haproxy    daemon    stats socket /var/lib/haproxy/statsdefaults    mode                    http    log                     global    option                  httplog    option                  dontlognull    option http-server-close    option forwardfor       except 127.0.0.0/8    option                  redispatch    retries                 3    timeout http-request    10s    timeout queue           1m    timeout connect         10s    timeout client          1m    timeout server          1m    timeout http-keep-alive 10s    timeout check           10s    maxconn                 3000frontend  main *:5000    acl url_static       path_beg       -i /static /images /javascript /stylesheets    acl url_static       path_end       -i .jpg .gif .png .css .js    use_backend static          if url_static    default_backend             appfrontend kubernetes-apiserver    mode                 tcp    bind                 *:16443    option               tcplog    default_backend      kubernetes-apiserverbackend kubernetes-apiserver    mode        tcp    balance     roundrobin    server  master-0  <Master VIP>:6443 check # 这里替换 Master VIP 为用户本人的 VIPbackend static    balance     roundrobin    server      static 127.0.0.1:4331 checkbackend app    balance     roundrobin    server  app1 127.0.0.1:5001 check    server  app2 127.0.0.1:5002 check    server  app3 127.0.0.1:5003 check    server  app4 127.0.0.1:5004 checkEOF

装置 Keepalived

在所有 Master 装置 Keepalived,执行同样操作:
留神:

  • 替换配置文件中的 < Master VIP >
  • 上面的 keepalived.conf 配置文件中 < Master 本机外网 IP > 和 < 其余 Master 外网 IP > 在不同 Master 的配置须要调换地位,不要填错。
  ## 装置keepalived  yum install -y keepalived  cat << EOF >/etc/keepalived/keepalived.conf   ! Configuration File for keepalived  global_defs {     smtp_connect_timeout 30     router_id LVS_DEVEL_EDGE_1  }  vrrp_script checkhaproxy{  script "/etc/keepalived/do_sth.sh"  interval 5  }  vrrp_instance VI_1 {      state BACKUP      interface eth0      nopreempt      virtual_router_id 51      priority 100      advert_int 1      authentication {          auth_type PASS          auth_pass aaa      }      virtual_ipaddress {          <master VIP> # 这里替换 Master VIP 为用户本人的 VIP      }      unicast_src_ip <Master 本机外网 IP>      unicast_peer {        <其余 Master 外网 IP>        <其余 Master 外网 IP>      }  notify_master "/etc/keepalived/notify_action.sh master"  notify_backup "/etc/keepalived/notify_action.sh BACKUP"  notify_fault "/etc/keepalived/notify_action.sh FAULT"  notify_stop "/etc/keepalived/notify_action.sh STOP"  garp_master_delay 1  garp_master_refresh 5     track_interface {       eth0     }     track_script {       checkhaproxy      }  }  EOF

装置高可用边缘 Kubernetes Master

在其中一台 Master 中执行集群初始化操作

./edgeadm init --control-plane-endpoint <Master VIP> --upload-certs --kubernetes-version=1.18.2 --image-repository superedge.tencentcloudcr.com/superedge --service-cidr=10.96.0.0/12 --pod-network-cidr=192.168.0.0/16 --apiserver-cert-extra-sans=<Master节点外网IP/Master节点内网IP/域名/> --install-pkg-path <edegadm Kube-*动态安装包地址> -v=6
参数含意同 3. 用 edgeadm 装置边缘 Kubernetes 集群,其余和 kubeadm 统一,这里不在解释;

要是执行过程中没有问题,集群胜利初始化,会输入如下内容:

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/  You can now join any number of the control-plane node running the following command on each as root:  edgeadm join xxx.xxx.xxx.xxx:xxx --token xxxx \    --discovery-token-ca-cert-hash sha256:xxxxxxxxxx \    --control-plane --certificate-key xxxxxxxxxx    --install-pkg-path <Path of edgeadm kube-* install package>    Please note that the certificate-key gives access to cluster sensitive data, keep it secret!As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use"edgeadm init phase upload-certs --upload-certs" to reload certs afterward.Then you can join any number of worker nodes by running the following on each as root:edgeadm join xxx.xxx.xxx.xxx:xxxx --token xxxx \    --discovery-token-ca-cert-hash sha256:xxxxxxxxxx      --install-pkg-path <Path of edgeadm kube-* install package>

执行过程中如果呈现问题会间接返回相应的错误信息,并中断集群的初始化,应用./edgeadm reset命令回滚集群的初始化操作。

要使非 root 用户能够运行 kubectl,请运行以下命令,它们也是 edgeadm init 输入的一部分:

mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config

或者,如果你是 root 用户,则能够运行:

export KUBECONFIG=/etc/kubernetes/admin.conf

留神保留./edgeadm init输入的./edgeadm join命令,前面增加Master节点和边缘节点须要用到。

Join Master 节点

在另一台 Master 执行./edgeadm join命令

./edgeadm join xxx.xxx.xxx.xxx:xxx --token xxxx    \    --discovery-token-ca-cert-hash sha256:xxxxxxxxxx \    --control-plane --certificate-key xxxxxxxxxx     \    --install-pkg-path <edgeadm Kube-*动态安装包地址 

要是执行过程中没有问题,新的 Master 胜利退出集群,会输入如下内容:

This node has joined the cluster and a new control plane instance was created:* Certificate signing request was sent to apiserver and approval was received.* The Kubelet was informed of the new secure connection details.* Control plane (master) label and taint were applied to the new node.* The Kubernetes control plane instances scaled up.* A new etcd member was added to the local/stacked etcd cluster.To start administering your cluster from this node, 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        Run 'kubectl get nodes' to see this node join the cluster.

执行过程中如果呈现问题会间接返回相应的错误信息,并中断节点的增加,应用./edgeadm reset命令回滚集群的初始化操作。

Join node 边缘节点

./edgeadm join xxx.xxx.xxx.xxx:xxxx --token xxxx \    --discovery-token-ca-cert-hash sha256:xxxxxxxxxx     --install-pkg-path <edgeadm Kube-*动态安装包地址/FTP门路>

要是执行过程中没有问题,新的 node 胜利退出集群,会输入如下内容:

This node has joined the cluster:* Certificate signing request was sent to apiserver and a response was received.* The Kubelet was informed of the new secure connection details.Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

执行过程中如果呈现问题会间接返回相应的错误信息,并中断节点的增加,应用./edgeadm reset命令回滚集群的初始化操作。

自定义 Kubernetes 动态安装包

Kubernetes 动态安装包的目录构造如下:

kube-linux-arm64-v1.18.2.tar.gz ## kube-v1.18.2 arm64的Kubernetes动态安装包├── bin                         ## 二进制目录│   ├── conntrack               ## 连贯跟踪的二进制文件│   ├── kubectl                 ## kube-v1.18.2的kubectl│   ├── kubelet                 ## kube-v1.18.2的kubelet│   └── lite-apiserver          ## 相应版本的lite-apiserver,可编译SuperEdge的lite-apiserver生成├── cni                         ## cin的配置│   └── cni-plugins-linux-v0.8.3.tar.gz ## v0.8.3的CNI插件二进制压缩包└── container                   ## 容器运行时目录    └── docker-19.03-linux-arm64.tar.gz ## docker 19.03 arm64体系的装置脚本和安装包

自定义其余 Kubernetes 版本

自定义其余 Kubernetes 版本须要做的有两件事:

  • 替换二进制目录中的 kubectl 和 kubelet 文件,版本须要大于等于 Kubernetes v1.18.0;
  • 确保 init 应用的镜像仓库中有相应 Kubernetes 版本的根底镜像;

自定义其余体系 Kubernetes 动态安装包

自定义 Kubernetes 动态安装包其余体系须要做三件事:

  • 将 Kubernetes 动态安装包的所有二进制换成指标体系,包含 cni 和 container 相应安装包中的二进制;
  • 确保 init 应用的镜像仓库中有相应体系的 Kubernetes 版本的根底镜像,举荐应用多体系镜像;
  • 充沛测试,确保没有什么兼容问题。要有相干问题,也能够在 SuperEdge 社区提 Issues 一块来修复。
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!