容器和Serverless的多样结合
随着容器和Serverless概念的普及,阿里云容器服务团队和弹性计算团队合作推出了多个Serverless容器产品和解决方案,包括Serverless Kubernetes、弹性容器实例ECI、virtual-nodes addon功能。这些不同的产品为用户提供了丰富的无服务器容器应用场景支持。
Serverless Kubernetes
阿里云容器服务的Serverless Kubernetes已经公测一段时间,用户无需管理服务器,同时能够正常使用kubernetes各种API操作,包括创建pod、service、ingress、job等。无服务器的最大价值不仅是免去了服务器运维的负担,更为应用提供了强大的弹性扩容能力,弹性不再受限于集群的节点规模,而且应用仅按资源使用量付费。
Kubernetes Virtual Nodes
为了进一步优化容器服务的使用体验和提供更多场景的丰富支持,我们推出了virtual-nodes功能,为用户的kubernetes集群提供极致的弹性扩容的能力。
如上图所示,virtual-nodes为经典kubernetes集群添加了虚拟节点,集群中真实worker节点和虚拟节点同时存在,通过虚拟节点动态创建ECI容器实例。ECI的pod与真实节点上的pod互联互通,都运行在同一个用户vpc网络中。
通过virtual-nodes,用户无需创建的新的集群,在原有的kubernetes集群中就可以获得“无限”的弹性能力,用户无需创建出很多真实worker节点就可以享受到“无限”的计算容量。virtual-nodes可应用在大数据计算、基因计算、视频渲染、混合云等典型计算场景,对于在线应用的短时间扩容同样适用。
通过virtual-nodes,我们给基于有限节点的kubernetes集群赋予了"无限"扩容的能力
我们如何使用virtual-nodes呢?让我们先了解下背后的实现原理。
弹性容器实例ECI和Virutal Kubelet
弹性容器实例ECI
弹性容器实例是阿里云弹性计算团队最新推出的一款敏捷安全的Serverless容器运行时服务。弹性容器实例具备如下特点:
- 无需管理基础设施即可运行容器
- 灵活按需使用,按秒计费
- 借助安全沙箱技术确保应用安全
更多信息请参考产品页:https://www.aliyun.com/product/eci
与Serverless Kubernetes容器服务不同的是,ECI不提供原生的kubernetes API,比如无法使用kubectl操作pod/service/ingress/job资源。但通过virtual kubelet创新性的把kubernetes和ECI连接在了一起,实现了通过kubernetes API动态创建ECI实例。
Virtual Kubelet
Virtual Kubelet最初是微软Azure发起的开源项目,目标是让公有云的弹性容器实例类产品能与kubernetes更好的集成,实现kubernetes的serverless能力。在实现上VK提供了一种机制可以与多家不同的provider集成,目前已支持Azure的ACI、AWS的fargate、华为的CCI。VK也被应用在IoT Edge场景。近期我们也提交了ECI的provider并已被合并:https://github.com/virtual-kubelet/virtual-kubelet/tree/master/providers/alicloud
Virutal Kubelet向kubernetes APIServer注册了一个虚拟节点,持续监听pod变化事件,并动态创建ECI实例。
Virutal Kubelet通过虚拟节点的方式创新性的连接了Kubernetes与ECI,Virutal Kubelet和ECI是virtual nodes的技术基础设施。
下面将介绍如何在阿里云容器服务中部署virtual nodes。
在阿里云托管kubernetes集群中部署virtual nodes
1. 开通ECI
ECI目前正在公测,需要填写邀测申请开通服务:https://page.aliyun.com/form/act171611821/index.htm
2. 创建托管Kubernetes集群
进入容器服务控制台创建托管Kubernetes集群
https://cs.console.aliyun.com/#/k8s/cluster/create/managed
集群创建成功后,可以在集群管理或节点页面查看vswitchid、securitygroup信息。
3. 使用kubectl一键部署virtual nodes
请替换alicloud-virtual-kubelet.yaml文件中的ECI_VSWITCH、ECI_SECURITY_GROUP、ECI_ACCESS_KEY、ECI_SECRET_KEY环境变量
# cat alicloud-virtual-nodes-eci.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: alicloud-virtual-nodes-eci
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: alicloud-virtual-nodes-eci
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: alicloud-virtual-nodes-eci
namespace: kube-system
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: alicloud-virtual-nodes-eci
namespace: kube-system
labels:
app: alicloud-virtual-nodes-eci
spec:
replicas: 1
selector:
matchLabels:
app: alicloud-virtual-nodes-eci
template:
metadata:
labels:
app: alicloud-virtual-nodes-eci
spec:
serviceAccount: alicloud-virtual-nodes-eci
containers:
- name: alicloud-virtual-kubelet
image: registry.cn-hangzhou.aliyuncs.com/acs/virtual-nodes-eci:v1.0.0.1-aliyun
imagePullPolicy: Always
args: ["--provider", "alibabacloud"]
env:
- name: KUBELET_PORT
value: "10250"
- name: VKUBELET_POD_IP
valueFrom:
fieldRef:
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_REGION
value: "cn-hangzhou"
- name: ECI_VSWITCH
value: "xxx"
- name: ECI_SECURITY_GROUP
value: "xxx"
- name: ECI_ACCESS_KEY
value: "xxx"
- name: ECI_SECRET_KEY
value: "xxx"
执行yaml文件,然后查看pod和节点状态,可以发现,集群中已经添加了一个新的virtual node虚拟节点
# kubectl apply -f ./alicloud-virtual-nodes-eci.yaml
serviceaccount "alicloud-virtual-nodes-eci" created
clusterrolebinding "alicloud-virtual-nodes-eci" created
deployment "alicloud-virtual-nodes-eci" created
# kubectl -n kube-system get pod|grep virtual-nodes
alicloud-virtual-nodes-eci-54b748489c-gkcmn 1/1 Running 0 53s
# kubectl get node
NAME STATUS ROLES AGE VERSION
cn-hangzhou.i-bp19cyop0b1skne04djt Ready <none> 10m v1.11.2
cn-hangzhou.i-bp19cyop0b1skne04dju Ready <none> 10m v1.11.2
cn-hangzhou.i-bp19cyop0b1skne04djv Ready <none> 10m v1.11.2
virtual-kubelet Ready agent 55s v1.11.2
通过控制台,同样可以看到virtual-kubelet虚拟节点的存在。
4. 部署Pod到虚拟节点上
虚拟节点已经存在,我们需要为即将运行的pod设置nodeSelector和tolerations,让pod调度到virtual-kubelet虚拟节点上。
# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
nodeSelector:
kubernetes.io/role: agent
beta.kubernetes.io/os: linux
type: virtual-kubelet
tolerations:
- key: virtual-kubelet.io/provider
operator: Exists
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 1m
我们可以看到,nginx pod被调度到虚拟节点中,没有运行在集群中任何一个worker节点之上。通过这种virtual nodes的方式,实现了容器应用的无服务器化部署和弹性扩容,用户无需再为集群的节点规格选择和容量规划而烦劳。
总结
通过上面的步骤,我们可以快速部署virtual node,但上述配置过程还是略显繁琐,用户需要配置AK和集群的vswitch/安全组信息,未来我们将会在阿里云容器服务控制台支持一键部署virtual-nodes插件,让用户免于虚拟节点配置的过程,轻松让k8s集群拥有强大的弹性扩容能力。请持续关注阿里云容器服务最新产品动态。
参考链接:
申请ECI使用:https://page.aliyun.com/form/act171611821/index.htm
ECI控制台:https://www.aliyun.com/product/eci
Virtual Kubelet Provier for ECI: https://github.com/virtual-kubelet/virtual-kubelet/tree/master/providers/alicloud
创建托管Kubernetes集群:https://cs.console.aliyun.com/#/k8s/cluster/create/managed
创建Serverless Kubernetes集群:https://cs.console.aliyun.com/#/k8s/cluster/create/serverless
Serverless Kubernetes示例:https://github.com/AliyunContainerService/serverless-k8s-examples