zoukankan      html  css  js  c++  java
  • 在kubernetes集群中使用虚拟节点创建1万Pod-支持在线教育业务

    使用虚拟节点提升k8s集群容量和弹性

    image

    在kubernetes集群中添加虚拟节点的方式已被非常多的客户普遍使用,基于虚拟节点可以极大提升集群的Pod容量和弹性,灵活动态的按需创建ECI Pod,免去集群容量规划的麻烦。目前虚拟节点已广泛应用在如下场景。

    • 在线业务的波峰波谷弹性需求:如在线教育、电商等行业有着明显的波峰波谷计算特征,使用虚拟节点可以显著减少固定资源池的维护,降低计算成本。
    • 提升集群Pod容量:当传统的flannel网络模式集群因vpc路由表条目或者vswitch网络规划限制导致集群无法添加更多节点时,使用虚拟节点可以规避上述问题,简单而快速的提升集群Pod容量。
    • 数据计算:使用虚拟节点承载Spark、Presto等计算场景,有效降低计算成本。
    • CI/CD和其他Job类型任务

    下面我们介绍如何使用虚拟节点快速创建1万个pod,这些eci pod按需计费,不会占用固定节点资源池的容量。

    相比较而言,AWS EKS在一个集群中最多只能创建1000个 Fargate Pod。基于虚拟节点的方式可以轻松创建过万个ECI Pod。

    创建多个虚拟节点

    请先参考ACK产品文档部署虚拟节点:https://help.aliyun.com/document_detail/118970.html

    因为使用多个虚拟虚拟节点往往用于部署大量ECI Pod,我们建议谨慎确认vpc/vswitch/安全组的配置,确保有足够的vswitch ip资源(虚拟节点支持配置多个vswitch解决ip容量问题),使用企业级安全组可以突破普通安全组的2000个实例限制。

    通常而言,如果单个k8s集群内eci pod数量小于3000,我们推荐部署单个虚拟节点。如果希望在虚拟节点上部署更多的pod,我们建议在k8s集群中部署多个虚拟节点来对其进行水平扩展,多个虚拟节点的部署形态可以缓解单个虚拟节点的压力,支撑更大的eci pod容量。这样3个虚拟节点可以支撑9000个eci pod,10个虚拟节点可以支撑到30000个eci pod。

    image

    为了更简单的进行虚拟节点水平扩展,我们使用statefulset的方式部署vk controller,每个vk controller管理一个vk节点,statefulset的默认Pod副本数量是1。当需要更多的虚拟节点时,只需要修改statefulset的replicas即可。

    # kubectl -n kube-system scale statefulset virtual-node-eci --replicas=4
    statefulset.apps/virtual-node-eci scaled
    
    # kubectl get no
    NAME                            STATUS     ROLES    AGE     VERSION
    cn-hangzhou.192.168.1.1         Ready      <none>   63d     v1.12.6-aliyun.1
    cn-hangzhou.192.168.1.2         Ready      <none>   63d     v1.12.6-aliyun.1
    virtual-node-eci-0              Ready      agent     1m     v1.11.2-aliyun-1.0.207
    virtual-node-eci-1              Ready      agent     1m     v1.11.2-aliyun-1.0.207
    virtual-node-eci-2              Ready      agent     1m     v1.11.2-aliyun-1.0.207
    virtual-node-eci-3              Ready      agent     1m     v1.11.2-aliyun-1.0.207
    
    # kubectl -n kube-system get statefulset virtual-node-eci
    NAME              READY   AGE
    virtual-node-eci  4/4     1m
    
    # kubectl -n kube-system get pod|grep virtual-node-eci
    virtual-node-eci-0                                               1/1     Running   0           1m
    virtual-node-eci-1                                               1/1     Running   0           1m
    virtual-node-eci-2                                               1/1     Running   0           1m
    virtual-node-eci-3                                               1/1     Running   0           1m

    当我们在vk namespace中创建多个nginx pod时(将vk ns加上指定label,强制让ns中的pod调度到虚拟节点上),可以发现pod被调度到了多个vk节点上。

    # kubectl create ns vk
    # kubectl label namespace vk virtual-node-affinity-injection=enabled
    
    # kubectl -n vk run nginx --image nginx:alpine --replicas=10
    deployment.extensions/nginx scaled
    
    # kubectl -n vk get pod -o wide
    NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE                NOMINATED NODE   READINESS GATES
    nginx-546c47b569-blp88   1/1     Running   0          69s   192.168.1.26   virtual-node-eci-1  <none>           <none>
    nginx-546c47b569-c4qbw   1/1     Running   0          69s   192.168.1.76   virtual-node-eci-0  <none>           <none>
    nginx-546c47b569-dfr2v   1/1     Running   0          69s   192.168.1.27   virtual-node-eci-2  <none>           <none>
    nginx-546c47b569-jfzxl   1/1     Running   0          69s   192.168.1.68   virtual-node-eci-1  <none>           <none>
    nginx-546c47b569-mpmsv   1/1     Running   0          69s   192.168.1.66   virtual-node-eci-1  <none>           <none>
    nginx-546c47b569-p4qlz   1/1     Running   0          69s   192.168.1.67   virtual-node-eci-3  <none>           <none>
    nginx-546c47b569-x4vrn   1/1     Running   0          69s   192.168.1.65   virtual-node-eci-2  <none>           <none>
    nginx-546c47b569-xmxx9   1/1     Running   0          69s   192.168.1.30   virtual-node-eci-0  <none>           <none>
    nginx-546c47b569-xznd8   1/1     Running   0          69s   192.168.1.77   virtual-node-eci-3  <none>           <none>
    nginx-546c47b569-zk9zc   1/1     Running   0          69s   192.168.1.75   virtual-node-eci-2  <none>           <none>

    运行1万个ECI Pod

    在上述步骤中我们已经创建了4个虚拟节点,能够支撑12000个ECI Pod,我们只需要将workload指定调度到虚拟节点即可。这里我们需要关注kube-proxy的可扩展性。

    1. 虚拟节点创建的ECI Pod默认支持访问集群中的ClusterIP Service,这样每个ECI Pod都需要watch apiserver保持一个连接以监听svc/endpoints变化。当大量pod同时Running时,apiserver和slb将维持Pod数量的并发连接,所以需要确保slb规格能否支撑期望的并发连接数。
    2. 如果ECI Pod无需访问ClusterIP Service,则可以将virtual-node-eci statefulset的ECI_KUBE_PROXY环境变量值设置为"false",这样就不会有大量slb并发连接的存在,也会减少apiserver的压力。
    3. 我么也可以选择将ECI Pod访问的ClusterIP Service暴露成内网slb类型,然后通过privatezone的方式让ECI Pod不必基于kube-proxy也能否访问到集群中的Service服务。

    缩减vk虚拟节点数量

    因为vk上的eci pod是按需创建,当没有eci pod时vk虚拟节点不会占用实际的资源,所以一般情况下我们不需要减少vk节点数。但用户如果确实希望减少vk节点数时,我们建议按照如下步骤操作。

    假设当前集群中有4个虚拟节点,分别为virtual-node-eci-0/.../virtual-node-eci-3。我们希望缩减到1个虚拟节点,那么我们需要删除virtual-node-eci-1/../virtual-node-eci-3这3个节点。

    • 先优雅下线vk节点,驱逐上面的pod到其他节点上,同时也禁止更多pod调度到待删除的vk节点上。
    # kubectl drain virtual-node-eci-1 virtual-node-eci-2 virtual-node-eci-3
    
    # kubectl get no
    NAME                      STATUS                     ROLES    AGE    VERSION
    cn-hangzhou.192.168.1.1   Ready                      <none>   66d    v1.12.6-aliyun.1
    cn-hangzhou.192.168.1.2   Ready                      <none>   66d    v1.12.6-aliyun.1
    virtual-node-eci-0        Ready                      agent    3d6h   v1.11.2-aliyun-1.0.207
    virtual-node-eci-1        Ready,SchedulingDisabled   agent    3d6h   v1.11.2-aliyun-1.0.207
    virtual-node-eci-2        Ready,SchedulingDisabled   agent    3d6h   v1.11.2-aliyun-1.0.207
    virtual-node-eci-3        Ready,SchedulingDisabled   agent    66m    v1.11.2-aliyun-1.0.207

    之所以需要先优雅下线vk节点的原因是vk节点上的eci pod是被vk controller管理,如果vk节点上还存在eci pod时删除vk controller,那样将导致eci pod被残留,vk controller也无法继续管理那些pod。

    • 待vk节点下线后,修改virtual-node-eci statefulset的副本数量,使其缩减到我们期望的vk节点数量。
    # kubectl -n kube-system scale statefulset virtual-node-eci --replicas=1
    statefulset.apps/virtual-node-eci scaled
    
    # kubectl -n kube-system get pod|grep virtual-node-eci
    virtual-node-eci-0                                                1/1     Running   0          3d6h

    等待一段时间,我们会发现那些vk节点变成NotReady状态。

    # kubectl get no
    NAME                      STATUS                        ROLES    AGE    VERSION
    cn-hangzhou.192.168.1.1   Ready                         <none>   66d    v1.12.6-aliyun.1
    cn-hangzhou.192.168.1.2   Ready                         <none>   66d    v1.12.6-aliyun.1
    virtual-node-eci-0        Ready                         agent    3d6h   v1.11.2-aliyun-1.0.207
    virtual-node-eci-1        NotReady,SchedulingDisabled   agent    3d6h   v1.11.2-aliyun-1.0.207
    virtual-node-eci-2        NotReady,SchedulingDisabled   agent    3d6h   v1.11.2-aliyun-1.0.207
    virtual-node-eci-3        NotReady,SchedulingDisabled   agent    70m    v1.11.2-aliyun-1.0.207
    • 手动删除NotReady状态的虚拟节点
    # kubelet delete no virtual-node-eci-1 virtual-node-eci-2 virtual-node-eci-3
    node "virtual-node-eci-1" deleted
    node "virtual-node-eci-2" deleted
    node "virtual-node-eci-3" deleted
    # kubectl get no
    NAME                      STATUS     ROLES    AGE    VERSION
    cn-hangzhou.192.168.1.1   Ready      <none>   66d    v1.12.6-aliyun.1
    cn-hangzhou.192.168.1.2   Ready      <none>   66d    v1.12.6-aliyun.1
    virtual-node-eci-0        Ready      agent    3d6h   v1.11.2-aliyun-1.0.207

    查看更多:https://yqh.aliyun.com/detail/6738?utm_content=g_1000106525

    上云就看云栖号:更多云资讯,上云案例,最佳实践,产品入门,访问:https://yqh.aliyun.com/

  • 相关阅读:
    mongodb
    python中读取文件的read、readline、readlines方法区别
    uva 129 Krypton Factor
    hdu 4734
    hdu 5182 PM2.5
    hdu 5179 beautiful number
    hdu 5178 pairs
    hdu 5176 The Experience of Love
    hdu 5175 Misaki's Kiss again
    hdu 5174 Ferries Wheel
  • 原文地址:https://www.cnblogs.com/yunqishequ/p/12420187.html
Copyright © 2011-2022 走看看