在基于ECS自建的Kubernetes集群中集成VNode以接入ECI服务

在阿里云ECS上自建了Kubernetes集群并需要接入ECI服务时,您需要在集群中部署虚拟节点(VNode)。本文介绍在同一VPC下,ECS上自建的Kubernetes集群如何快速接入VNode,以便使用ECI。

背景信息

ECI支持无缝集成Kubernetes,可以为Kubernetes提供一种层次化的解决方案:即ECI负责底层Pod容器资源的调度和管理工作,Kubernetes在ECI之上作为PaaS层来管理业务负载。如果您在阿里云ECS上自建了Kubernetes集群,可以通过部署虚拟节点(VNode)的方式来使用ECI。更多信息,请参见自建Kubernetes集群对接ECI

前提条件

  • 已在ECS上通过kubeadm自建了Kubernetes集群,且集群的版本属于1.13~1.30版本。

  • 集群中已部署Flannel、Calico或Cilium网络插件。

安装VNodectl

为了能够方便地接入和管理VNode,ECI提供了VNodectl命令行工具。建议您将VNodectl安装在Kubernetes集群的master节点上。

  1. 连接集群。

  2. 下载安装包。

    wget https://eci-docs.oss-cn-beijing.aliyuncs.com/vnode/vnodectl_0.0.4-beta_linux_amd64.tar.gz -O vnodectl.tar.gz 
  3. 解压安装包。

    tar xvf vnodectl.tar.gz 
  4. 复制vnodectl到指定目录。

    cp vnodectl /usr/local/bin/vnode

配置~/.vnode/config文件

  1. 修改~/.vnode/config文件内容。

    vim ~/.vnode/config

    请根据实际修改~/.vnode/config文件内容,以下为示例:

    重要
    • kubeconfig需具有cluster-admin权限。如果您想要使用更小权限的kubeconfig,请参见配置集群

    • 请确保使用的kubeconfig文件中的apiserver地址能被Vnode访问。

    kind: vnode
    contexts:
        - name: default                                          # context名称
          region-id: cn-hangzhou                                 # 地域ID
          access-key-id: LTAI5tJbBkHcHBUmuP7C****                # AccessKey ID
          access-key-secret: 5PlpKJT6sgLcD4f9y5pACNDbEg****      # AccessKey Secret,
          vswitch-id: vsw-7xv2yk45qp5etidgf****                  # VNode所属交换机ID
          security-group-id: sg-7xv5tcch4kjdr65t****             # VNode所属安全组ID
          kubeconfig: /path/to/kubeconfig                        # 集群kubeconfig文件
    current-context: default
  2. 使VNode运行加载context下的配置。

    vnode config set-context <context-name>

创建Vnode

  1. 创建一个VNode。

    vnode create

    返回示例如下,其中VirtualNodeId的值即为生成的VNode的ID。

    {"RequestId":"AB772F9D-2FEF-5BFD-AAFB-DA3444851F29","VirtualNodeId":"vnd-7xvetkyase7gb62u****"}
  2. 查看节点信息。

    kubectl get node

    返回示例如下,可以看到集群中已接入VNode。

    NAME                                    STATUS     ROLES                  AGE    VERSION
    cn-hangzhou.vnd-7xvetkyase7gb62u****    Ready      agent                  174m   v1.20.6
    vnode-test001                           Ready      control-plane,master   23h    v1.20.6
    vnode-test002                           Ready      <none>                 22h    v1.20.6

配置反亲和性策略

由于VNode不是真实节点,因此无法运行DaemonSet。创建VNode后,您需要修改kube-proxy的DaemonSet,配置nodeAffinity来禁止DaemonSet调度到VNode。

  1. 修改DaemonSet配置。

    kubectl -n kube-system edit ds kube-proxy
  2. 配置nodeAffinity。

    在spec>template>spec下添加以下YAML:

    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: type
              operator: NotIn
              values:
              - virtual-kubelet

后续操作

创建VNode后,您可以通过以下方式将Pod调度到VNode上,以使用ECI来运行Pod。

  • 手动调度

    通过配置nodeSelector和tolerations、指定nodeName的方式,可以手动将Pod调度到VNode。具体操作,请参见将Pod调度到VNode

  • 自动调度

    部署eci-profile组件后,可以自定义配置Selector,将满足条件的Pod自动调度到VNode。具体操作,请参见使用eci-profile调度Pod到VNode

打通Pod网络

调度到VNode上的ECI Pod将占用所属VPC下交换机的一个弹性网卡资源,默认具备一个内网IP地址。

默认情况下,ECI Pod无法访问自建集群Overlay网络(Flannel、Calico或Cilium)中的Pod,但自建集群Overlay网络中的Pod是可以访问ECI Pod的。如果ECI Pod需要访问自建集群Overlay网络中的Pod,需要在所属VPC的路由表中增加路由条目,使得从ECI Pod出去的数据包可以通过该路由条目,正确路由到自建集群对应的ECS节点上。

配置示例如下:

  • 示例场景

    假设集群中有2个Pod,1个运行在VNode上(test1 ),1个运行在ECS节点上(test2)。默认情况下,test2可以访问test1,但test1无法访问test2。

    NAME      READY     RESTARTS    AGE    IP                NODE                                   NOMINATED NODE   READINESS NODE
    test1     1/1       0           58s    192.168.0.245     cn-hangzhou.vnd-7xvetkyase7gb62u****   <none>           <none>
    test2     1/1       0           35s    10.88.1.4         vnode-test002                          <none>           <none>
  • 操作步骤

    1. 登录专有网络管理控制台

    2. 在左侧导航栏,单击路由表

    3. 切换地域,找到Pod所属VPC对应的路由表,单击路由表ID。

    4. 路由条目列表页签下,单击自定义路由条目页签。

    5. 单击添加路由条目

    6. 在弹出的对话框中,配置路由条目,然后单击确定

      以示例场景为例:

      • 目标网段:输入ECS节点所在的交换机网段。例如10.88.1.0/24。

      • 下一跳类型:选择ECS实例

      • ECS实例:选择ECS节点。

  • 结果验证

    通过kubectl exec命令进入test-pod-1的容器内执行ping命令,如果可以Ping通test2的IP,则表示已经打通Pod网络,test1可以访问test2。

相关文档