通过虚拟节点将Pod调度到ECI上运行

当您需要在短时间内快速创建大量Pod时,ECS节点扩容速度可能无法满足要求,而预留额外的ECS节点又会产生资源浪费。借助ACK虚拟节点(Virtual Node)可以将Pod快速地调度到弹性容器实例ECI上运行,且无需购买和管理ECS节点。本文主要介绍如何在注册集群中将Pod调度到ECI上运行。

工作原理

阿里云弹性容器实例ECI(Elastic Container Instance)是面向容器设计的无服务器弹性计算服务,提供了免运维、强隔离、能快速启动的容器运行环境。使用ECI时,您无需购买和管理底层ECS服务器,可以更加关注容器应用而非底层基础设施的维护工作。您可按需创建ECI,仅为容器配置的资源付费(按量按秒计费)。

通常,您的ACK集群会有至少一组ECS节点池,创建Pod时,背后是将Pod调度到ECS节点上运行,这种架构能很好地应对流量稳定的业务。如果您的业务有不易提前预测的瞬时波峰,尽管ACK支持弹性伸缩,但ECS节点池扩容时,ECS实例的创建和启动本身会有一定的额外耗时。借助虚拟节点Virtual Node,您可以直接将Pod调度到ECI上运行,省去节点创建时间,避免产生闲置节点资源,降低成本。

image

前提条件

步骤一:为ack-virtual-node组件配置RAM权限

通过onectl配置

  1. 在本地安装配置onectl。具体操作,请参见通过onectl管理注册集群

  2. 执行以下命令,为ack-virtual-node组件配置RAM权限。

    onectl ram-user grant --addon ack-virtual-node

    预期输出:

    Ram policy ack-one-registered-cluster-policy-ack-virtual-node granted to ram user ack-one-user-ce313528c3 successfully.

通过控制台配置

在注册集群安装组件之前,您需要在接入集群中设置AccessKey用来访问云服务的权限。设置AccessKey之前,您需要创建RAM用户并为其添加访问相关云资源的权限。

  1. 创建RAM用户。具体操作,请参见创建RAM用户

  2. 可选:创建自定义权限策略。具体操作,请参见创建自定义权限策略。

    展开查看自定义策略模板

    {
        "Version": "1",
        "Statement": [
            {
                "Action": [
                    "eci:CreateContainerGroup",
                    "eci:DeleteContainerGroup",
                    "eci:DescribeContainerGroups",
                    "eci:DescribeContainerGroupStatus",
                    "eci:DescribeContainerGroupEvents",
                    "eci:DescribeContainerLog",
                    "eci:UpdateContainerGroup",
                    "eci:UpdateContainerGroupByTemplate",
                    "eci:CreateContainerGroupFromTemplate",
                    "eci:RestartContainerGroup",
                    "eci:ExportContainerGroupTemplate",
                    "eci:DescribeContainerGroupMetric",
                    "eci:DescribeMultiContainerGroupMetric",
                    "eci:ExecContainerCommand",
                    "eci:CreateImageCache",
                    "eci:DescribeImageCaches",
                    "eci:DeleteImageCache",
                    "vpc:DescribeVSwitches"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            }
        ]
    }
  3. 为RAM用户添加权限。具体操作,请参见为RAM用户授权

    可选择自定义权限策略或AliyunECIFullAccess策略为RAM用户授权。

  4. 为RAM用户创建AccessKey。具体操作,请参见获取AccessKey

  5. 使用AccessKey在注册集群中创建名为alibaba-addon-secret的Secret资源。

    安装ack-virtual-node组件时将自动引用此AccessKey访问对应的云服务资源。

    kubectl -n kube-system create secret generic alibaba-addon-secret --from-literal='access-key-id=<your access key id>' --from-literal='access-key-secret=<your access key secret>'
    说明

    <your access key id><your access key secret>为上一步获取的AccessKey信息。

步骤二:安装ack-virtual-node组件

通过onectl安装

执行以下命令,安装ack-virtual-node组件。

onectl addon install ack-virtual-node

预期输出:

Addon ack-virtual-node, version **** installed.

通过控制台安装

  1. 登录容器服务管理控制台,在左侧导航栏选择集群

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择运维管理 > 组件管理

  3. 单击其他页签,在ack-virtual-node组件区域单击安装

    提示对话框中单击确定。这时会以集群默认虚拟交换机和安全组作为ack-virtual-node的初始ECI配置参数。具体操作,请参见相关操作

步骤三:将Pod调度到ECI上运行

为集群部署了ack-virtual-node组件后,您可以借助虚拟节点将Pod调度到ECI上。本小节介绍了在注册集群中将Pod调度到ECI上的两种常见方式。调度前需要确保Virtual node的状态为Ready。

  1. 执行以下命令,查看Virtual node状态。

    kubectl  get no |grep virtual-kubelet

    预期输出:

    virtual-kubelet-cn-hangzhou-b   Ready    agent                  18d   v1.20.11-aliyun.1

    从预期输出可知,当前Virtual node状态为Ready。

  2. 通过以下三种方式可将Pod调度到ECI上运行。

    方式一:配置Pod标签(集群版本需大于1.16)

    将Pod添加标签alibabacloud.com/eci=true,Pod将以ECI方式运行,其节点是虚拟节点,示例如下:

    1. 执行以下命令给Pod添加标签。

    2. kubectl run nginx --image nginx -l alibabacloud.com/eci=true
    3. 执行以下命令查看Pod。

    4. kubectl get pod -o wide|grep virtual-kubelet
    5. 预期输出:

    6. nginx-7fc9f746b6-r4xgx     0/1     ContainerCreating   0          20s   192.168.XX.XX   virtual-kubelet        <none>           <none>

    方式二:配置命名空间标签

    将Pod所在的命名空间添加标签alibabacloud.com/eci=true,Pod将以ECI方式运行,其节点是虚拟节点,示例如下:

    1. 执行以下命令创建虚拟节点。

    2. kubectl create ns vk
    3. 执行以下命令将Pod所在的命名空间添加标签。

    4. kubectl label namespace vk alibabacloud.com/eci=true
    5. 执行以下命令将命名空间中的Pod调度到虚拟节点上。

    6. kubectl -n vk run nginx --image nginx
    7. 执行以下命令查看Pod。

    8. kubectl -n vk get pod -o wide|grep virtual-kubelet
    9. 预期输出:

    10. nginx-6f489b847d-vgj4d      1/1     Running             0          1m   192.168.XX.XX   virtual-kubelet        <none>           <none>

    方式三:指定节点名称

    指定Pod调度到虚拟节点,添加 nodeName: virtual-kubelet-cn-shanghai-k,Pod将以ECI方式运行,其节点是虚拟节点,示例如下:

    1. 使用以下内容,创建nginx-deployment.yaml。

    2. apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
      kind: Deployment
      metadata:
        name: nginx-deployment-basic
        labels:
          app: nginx
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            nodeName: virtual-kubelet-cn-shanghai-k             # 指定vk的nodeName
            containers:
            - name: nginx
              image: nginx:1.7.9 # replace it with your exactly <image_name:tags>
              ports:
              - containerPort: 80
              resources:
                limits:
                  cpu: "500m"
    3. 执行以下命令,创建应用。

    4. kubectl apply -f nginx-deployment.yaml
    5. 执行以下命令查看Pod。

    6. kubectl  get pod -o wide|grep virtual-kubelet
    7. 预期输出:

    8. nginx-6f489b847d-XXX      1/1     Running             0          1m   192.168.XX.XX   virtual-kubelet        <none>           <none>
      nginx-6f489b847d-XXX      1/1     Running             0          1m   192.168.XX.XX   virtual-kubelet        <none>           <none>

相关操作

修改ECI交换机配置

您可以修改ECI Pod所在的虚拟交换机。建议配置多个虚拟交换机支持多可用区,当单个可用区库存不足时,Controller会选择另外一个可用区创建ECI Pod。

通过如下命令修改ECI交换机相关信息:

kubectl edit configmap eci-profile -n kube-system

配置示例如下:

data:
  enableClusterIp: "true"
  enableHybridMode: "false"
  enablePrivateZone: "false"
  securityGroupId: sg-2zeeyaaxlkq9sppl****
  selectors: ""
  vSwitchIds: vsw-2ze23nqzig8inprou****,vsw-2ze94pjtfuj9vaymf****     # ECI Pod所属交换机。可配置多个,用半角逗号间隔。
  vpcId: vpc-2zeghwzptn5zii0w7****

更多关于eci-profile配置的详细信息,请参见配置eci-profile

删除虚拟节点

  1. 在注册集群中卸载ack-virtual-node组件。

    通过onectl卸载

    执行以下命令,卸载组件。

    onectl addon uninstall ack-virtual-node

    预期输出:

    Addon ack-virtual-node uninstalled.

    通过控制台卸载

    组件管理页面卸载ack-virtual-node组件即可。

  2. 通过命令kubectl delete node <node name>删除相关虚拟节点。

    说明

    卸载ack-virtual-node组件后,集群中已创建的ECI Pod并不会被删除。