全部产品

线下Kubernetes集群使用ECI

如果您在自建机房或者其他线下环境部署了Kubernetes集群,您需要在集群中部署虚拟节点(Virtual Kubelet)来使用ECI。本文为您介绍线下自建的集群如何对接ECI,包括将自建集群接入阿里云注册集群并部署虚拟节点,或者在自建集群中直接部署Virtual Kubelet。

前提条件

已开通阿里云账号。具体操作,请参见阿里云账号注册流程

背景信息

基于Kubernetes社区的Virtual Kubelet技术,ECI通过虚拟节点与Kubernetes实现无缝对接,使得Kubernetes集群可以轻松获得极大的弹性能力,而不必受限于集群的节点计算容量。如果您的Kubernetes集群是线下自建的,可以通过以下两种方式来使用ECI:

说明

推荐您使用方式一,该方式便于您及时升级Virtual Kubelet的版本(即ack-virtual-node的版本),以使用相关的新功能。

使用限制

在该混合云场景下,部分功能无法支持或有条件支持,不支持的功能如下:

  • Annotations更新

  • Labels更新

  • Spec.ActiveDeadlineSeconds更新

  • ConfigMap、Secret更新

  • kubectl logs-f命令(支持logs查询,不支持follow模式)

  • kubectl attach命令

  • kubectl port-forward命令

  • 部分DownwardAPI参数无法引用(如:status.hostIP)

  • ClusterIP

    需要通过阿里云高速通道或者智能接入网关SAG打通网络,更多信息,请参见高速通道或者智能接入网关SAG

准备工作

操作前,您需要准备好以下信息:

参数

描述

获取方式

ECI_ACCESS_KEY、ECI_SECRET_KEY

AccessKey ID和对应的AccessKey Secret。虚拟节点操作ECI的凭证。

请参见获取AccessKey

ALIYUN_CLUSTERID

集群ID,集群的唯一标识。

如果采用接入注册集群的方式,集群ID将由系统自动生成;如果采用部署Virtual Kubelet的方式,您需要自定义集群ID。

ECI_REGION

地域ID。ECI实例将部署在该地域下。

您可以通过弹性容器实例控制台或者调用DescribeRegions获取ECI支持的地域信息。

ECI_VPC

专有网络VPC ID。ECI实例将部署在该VPC下。

您可以在专有网络控制台专有网络页面创建并查看VPC。

ECI_VSWITCH

虚拟交换机ID。ECI实例将部署在该交换机下。

您可以在专有网络控制台交换机页面创建并查看交换机,根据已选的VPC来选择对应的交换机。

ECI_SECURITY_GROUP

安全组ID。ECI实例将部署在该安全组下。

您可以在ECS管理控制台安全组页面创建并查看安全组,根据已选的VPC来选择对应的安全组。

接入注册集群并部署虚拟节点

您可以将自建集群通过接入注册集群的方式接入到阿里云容器服务管理平台,然后部署虚拟节点,以便使用ECI。相关操作步骤如下:

  1. 登录容器服务管理控制台

  2. 在左侧导航栏单击集群

  3. 创建注册集群。

    1. 集群列表页面,单击创建集群

    2. 选择注册集群页签,完成集群相关配置,然后单击创建集群

      需要注意的配置项如下表所示。更多信息,请参见创建注册集群

      参数

      描述

      地域、专有网络、虚拟交换机

      根据准备信息,选择所需的地域、专有网络和虚拟交换机。

      API Server访问

      默认为API Server创建一个内网SLB实例,您可以根据需要选择SLB实例规格。

      绑定EIP

      设置是否创建并绑定EIP,可用于建立集群链接。

      安全组

      自动创建一个安全组,用于划分安全域,统一控制网络流量。

      日志服务

      设置是否启用阿里云日志服务,可用于快速采集容器日志。

      集群删除保护

      设置是否启用集群删除保护,可防止通过控制台或API误释放集群。

  4. 将自建集群接入到注册集群中。

    1. 集群列表页面,找到新创建的集群,单击集群名称。

    2. 集群信息页面,单击连接信息页签。

    3. 在自建集群中创建ConfigMap。

      根据网络情况,选择公网页签或者私网页签,复制内容到yaml配置文件中(假设为agent.yaml),然后在自建集群中执行kubectl apply -f agent.yaml命令创建ConfigMap。

    4. 在自建集群中执行以下命令查看接入情况。

      kubectl -n kube-system get pod |grep ack-cluster-agent

      预期返回:

      ack-cluster-agent-5f7d568f6-6fc4k              1/1     Running   0          9s
      ack-cluster-agent-5f7d568f6-tf6fp              1/1     Running   0          9s
  5. 部署虚拟节点。

    1. 在左侧导航栏,选择市场>应用目录

    2. 阿里云应用页签下,找到ack-virtual-node应用,然后单击该应用。

    3. 配置参数,并选择之前创建的注册集群进行安装。

      参数页签下,填入准备好的交换机ID、安全组ID,以及AccessKey ID和AccessKey Secret。

      说明

      如果第4步是通过公网接入注册集群,则镜像参数repository的值需要去掉vpc字样,例如:registry.cn-hangzhou.aliyuncs.com/acs/virtual-nodes-eci。

      更多信息,请参见将Virtual Node接入注册集群

更多关于接入注册集群并部署虚拟节点的信息,请参见自建Kubernetes集群如何使用弹性容器实例ECI

直接部署Virtual Kubelet

您可以在自建的集群内直接部署Virtual Kubelet来使用ECI。部署前,您需要先获取最新的VK版本。更多信息,请参见Virtual Kubelet版本记录

部署Virtual Kubelet的操作步骤如下:

  1. 为Virtual Kubelet创建一个服务账号并绑定至集群角色中,用于正常创建Pod资源。

    1. 执行以下命令,创建一个名为vk-admin的服务账号。

      kubectl create serviceaccount vk-admin -n kube-system
    2. 执行以下命令,将vk-admin账号绑定至cluster-admin集群角色中。

      kubectl create clusterrolebinding vk-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:vk-admin
  2. 准备部署Virtual Kubelet的yaml配置文件vk.yaml。

    yaml配置文件的内容示例如下,您需要根据之前准备的信息,替换yaml文件中对应的参数值。

    注意

    Virtual Kubelet版本必须为v2.0.0.121-eff0e01c0-aliyun及以后版本。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: virtual-node-controller
      name: virtual-node-controller
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: virtual-node-controller
      template:
        metadata:
          labels:
            app: virtual-node-controller
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: type
                    operator: NotIn
                    values:
                    - virtual-kubelet
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - virtual-node-controller
                  topologyKey: kubernetes.io/hostname
                weight: 100
          containers:
          - name: virtual-node-controller
            # 部署Virtual Kubelet所需的镜像及版本
            image: registry.cn-beijing.aliyuncs.com/acs/virtual-nodes-eci:v2.0.0.121-eff0e01c0-aliyun
            imagePullPolicy: Always
            args:
            - --provider
            - alibabacloud
            - --nodename
            - $(VN_INSTANCE)
            env:
            - name: VN_INSTANCE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.name
            - name: KUBELET_PORT
              value: "10250"
            - name: VKUBELET_POD_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.podIP
            - name: VKUBELET_TAINT_KEY
              value: "virtual-kubelet.io/provider"
            - name: VKUBELET_TAINT_VALUE
              value: "alibabacloud"
            - name: VKUBELET_TAINT_EFFECT
              value: "NoSchedule"
            - name: ECI_QUOTA_CPU
              value: "1000000"
            - name: ECI_QUOTA_MEMORY
              value: 6400Ti
            - name: ECI_QUOTA_POD
              value: "3000"
            - name: ECI_KUBE_PROXY
              value: "true"
            # ECI创建的地域
            - name: ECI_REGION
              value: <region-id>
            # ECI创建使用的Access Key
            - name: ECI_ACCESS_KEY
              value: <access-key>
            # ECI创建使用的Secret Key
            - name: ECI_SECRET_KEY
              value: <secret-kty>
            # ECI创建使用的VPC ID
            - name: ECI_VPC
              value: <vpc-id>
            # ECI创建使用的虚拟交换机ID
            - name: ECI_VSWITCH
              value: <vsw-id>
            # ECI创建使用的安全组ID
            - name: ECI_SECURITY_GROUP
              value: <security-group-id>
            # ECI创建自定义的集群ID
            - name: ALIYUN_CLUSTERID
              value: <cluster-id>
            - name: ALIYUN_PRIVATE_ZONE
              value: "false"
            # ECI创建时,混合云场景开关配置
            - name: ECI_HYBRID_MODE
              value: "true"
           #开启Webhook
            - name: WEBHOOK
              value: "true"
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          serviceAccount: vk-admin
          serviceAccountName: vk-admin
  3. 部署Virtual Kubelet。

    kubectl apply -f vk.yaml
  4. 查看部署情况。

    kubectl get deploy/virtual-node-controller -n kube-system

    部署完成的返回示例如下。

    NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
    virtual-node-controller            1/1         1                      1                  161m
  5. 查看部署Virtual Kubelet后的节点信息。

    kubectl get nodes

    部署Virtual Kubelet后生成的虚拟节点名称为virtual-kubelet。如果能查询到virtual-kubelet节点,且状态为Ready,则表示部署成功。返回示例如下:

    NAME                STATUS   ROLES    AGE   VERSION
    master-1            Ready    <none>   19d   v1.18.8-aliyun.1
    master-2           Ready    <none>   19d   v1.18.8-aliyun.1
    virtual-kubelet    Ready    agent     18d   v1.18.8-aliyun.1
说明

如果您需要使用新功能,可能需要升级Virtual Kubele。您可以通过kubectl edit deployment -n kube-system virtual-node-controller命令编辑对应的资源,修改image tag到需要升级的版本。

调度Pod到虚拟节点

当集群中存在虚拟节点时,您可以将Pod调度到虚拟节点,以使用ECI来运行Pod。需要注意的相关配置如下:

  • 创建容器负载到虚拟节点时,由于虚拟节点有特殊的Taints,Pod需要配置nodeSelector和tolerations后才能指定调度到虚拟节点上。示例如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx
      nodeSelector:
        type: virtual-kubelet
      tolerations:
      - key: virtual-kubelet.io/provider
        operator: Exists
  • 由于ECI对接Kubernetes集群使用的是Virtual Kubelet,即虚拟节点,没有真实的计算节点存在,因此不支持部署DaemonSet。在创建DaemonSet时,您需要配置反亲和调度策略,防止DaemonSet调度到虚拟节点上。您需要在待部署的DaemonSet的spec.template.spec.affinity字段中添加如下配置:

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