我们在【Agones系列】Agones初体验 中部署GameServer对象,在ACK上创建了游戏服。本篇文章我们会介绍Agones的核心能力——GameServer的扩缩容。
Fleet
我们都知道在K8s中最基础的Pod对象之上有着多宗管理对象,例如Deployment、StatefulSet等。在Agones中,除了之前提到的GameServer对象以外,也有着类似的管理对象——Fleet。熟悉Deployment的同学对Fleet的理解是非常容易的。Fleet实际上管理的对象叫做GameServerSet,类似于ReplicaSet,Fleet-GameServerSet-GameServer 多级管理实现滚动升级的功能。同时我们也可以通过指定Fleet对象中的副本数来实现gs的扩容及缩容的功能。下面我们通过实验来看下Agones的扩缩容过程是怎样的。
首先在安装了Agones的K8s集群创建一个Fleet
apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
name: simple-game-server
spec:
replicas: 2
template:
spec:
ports:
- name: default
containerPort: 7654
template:
spec:
containers:
- name: simple-game-server
image: gcr.io/agones-images/simple-game-server:0.12
resources:
requests:
memory: "64Mi"
cpu: "20m"
limits:
memory: "64Mi"
cpu: "20m"
集群新增如下对象
kubectl get fleet
NAME SCHEDULING DESIRED CURRENT ALLOCATED READY AGE
simple-game-server Packed 2 2 0 2 17s
kubectl get gss
NAME SCHEDULING DESIRED CURRENT ALLOCATED READY AGE
simple-game-server-rhjtz Packed 2 2 0 2 20s
kubectl get gs
NAME STATE ADDRESS PORT NODE AGE
simple-game-server-rhjtz-gnhnx Ready xxx.xxx.xxx.xxx 7012 cn-xxx.xxx.xxx.xxx.xxx 21s
simple-game-server-rhjtz-zhxts Ready xxx.xxx.xxx.xxx 7909 cn-xxx.xxx.xxx.xxx.xxx 21s
kubectl get po
NAME READY STATUS RESTARTS AGE
simple-game-server-rhjtz-gnhnx 2/2 Running 0 24s
simple-game-server-rhjtz-zhxts 2/2 Running 0 24s
此时这两个gs都可以被访问
手动扩缩容
我们来试一下扩容
kubectl scale fleet simple-game-server --replicas=5
fleet.agones.dev/simple-game-server scaled
可以看到Fleet的事件,控制GameServerSet,将其副本数量从2扩展至5
kubectl describe fleet simple-game-server
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreatingGameServerSet 4m37s fleet-controller Created GameServerSet simple-game-server-rhjtz
Normal ScalingGameServerSet 2m4s fleet-controller Scaling active GameServerSet simple-game-server-rhjtz from 2 to 5
当前集群的对象状态
kubectl get fleet
NAME SCHEDULING DESIRED CURRENT ALLOCATED READY AGE
simple-game-server Packed 5 5 0 5 2m43s
kubectl get gss
NAME SCHEDULING DESIRED CURRENT ALLOCATED READY AGE
simple-game-server-rhjtz Packed 5 5 0 5 2m46s
kubectl get gs
NAME STATE ADDRESS PORT NODE AGE
simple-game-server-rhjtz-g72pq Ready xxx.xxx.xxx.xxx 7483 cn-xxx.xxx.xxx.xxx.xxx 14s
simple-game-server-rhjtz-gnhnx Ready xxx.xxx.xxx.xxx 7012 cn-xxx.xxx.xxx.xxx.xxx 2m47s
simple-game-server-rhjtz-jqpxt Ready xxx.xxx.xxx.xxx 7768 cn-xxx.xxx.xxx.xxx.xxx 14s
simple-game-server-rhjtz-pstgv Ready xxx.xxx.xxx.xxx 7486 cn-xxx.xxx.xxx.xxx.xxx 14s
simple-game-server-rhjtz-zhxts Ready xxx.xxx.xxx.xxx 7909 cn-xxx.xxx.xxx.xxx.xxx 2m47s
kubectl get po
NAME READY STATUS RESTARTS AGE
simple-game-server-rhjtz-g72pq 2/2 Running 0 16s
simple-game-server-rhjtz-gnhnx 2/2 Running 0 2m49s
simple-game-server-rhjtz-jqpxt 2/2 Running 0 16s
simple-game-server-rhjtz-pstgv 2/2 Running 0 16s
simple-game-server-rhjtz-zhxts 2/2 Running 0 2m49s
自动扩缩容
在K8s中有着HPA(水平自动扩缩)来自动调整Pod的数量,Agones通过FleetAutoscaler来实现自动调节gs数量的功能。下面是一个简单的FleetAutoscaler例子
apiVersion: "autoscaling.agones.dev/v1"
kind: FleetAutoscaler
metadata:
name: simple-game-server-autoscaler
spec:
fleetName: simple-game-server
policy:
type: Buffer
buffer:
bufferSize: 2
minReplicas: 0
maxReplicas: 10
这里通过fleetName指定自动扩缩绑定的Fleet对象。自动扩缩类型为buffer,buffer大小为2,最大的副本数指定为10。这里的buffer大小是相对于Allocated状态gs的个数。我们知道,正常创建的gs会处于Ready状态,Agones为适应open Match匹配机制设计了一种Allocated状态,代表分配使用,处于此状态的gs意味着游戏服可以被玩家连接进行游戏。buffer大小为2则表示gs的副本数量要比Allocated的gs数量多2。可以看出,buffer存在的意义是在玩家数量徒增时可以让fleet自动扩容,进而减少游戏服启动的时间。我们来配合gameserverallocation使用一下FleetAutoscaler。
首先创建一个gameserverallocation
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
required:
matchLabels:
agones.dev/fleet: simple-game-server
这里使用matchLabels匹配到对应的fleet
此时所有gs的状态如下所示,有一个gs的状态变为Allocated
kubectl get gs
NAME STATE ADDRESS PORT NODE AGE
simple-game-server-rhjtz-g72pq Ready xxx.xxx.xxx.xxx 7483 cn-xxx.xxx.xxx.xxx.xxx 145m
simple-game-server-rhjtz-gnhnx Ready xxx.xxx.xxx.xxx 7012 cn-xxx.xxx.xxx.xxx.xxx 147m
simple-game-server-rhjtz-jqpxt Ready xxx.xxx.xxx.xxx 7768 cn-xxx.xxx.xxx.xxx.xxx 145m
simple-game-server-rhjtz-pstgv Ready xxx.xxx.xxx.xxx 7486 cn-xxx.xxx.xxx.xxx.xxx 145m
simple-game-server-rhjtz-zhxts Allocated xxx.xxx.xxx.xxx 7909 cn-xxx.xxx.xxx.xxx.xxx 147m
我们现在进行缩容,调整gs数目为0
kubectl get gs
NAME STATE ADDRESS PORT NODE AGE
simple-game-server-rhjtz-zhxts Allocated xxx.xxx.xxx.xxx 7909 cn-xxx.xxx.xxx.xxx.xxx 147m
看到虽然副本数为0,但是依然Allocated状态的gs是不会被删除的,因为此时游戏可能在进行中。
我们创建FleetAutoscaler,配置buffer size为2时来看看gs的变化情况
kubectl apply -f fleetautoscaler.yaml
fleetautoscaler.autoscaling.agones.dev/simple-game-server-autoscaler created
kubectl get gs
NAME STATE ADDRESS PORT NODE AGE
simple-game-server-rhjtz-4dnrk Ready xxx.xxx.xxx.xxx 7734 cn-xxx.xxx.xxx.xxx.xxx 12s
simple-game-server-rhjtz-rsnnm Ready xxx.xxx.xxx.xxx 7067 cn-xxx.xxx.xxx.xxx.xxx 12s
simple-game-server-rhjtz-zhxts Allocated xxx.xxx.xxx.xxx 7909 cn-xxx.xxx.xxx.xxx.xxx 155m
自动扩容成3个gs,总数比Allocated数目多1
我们再手动分配一个gs,让其变为Allocated状态
kubectl create -f gameserverallocation.yaml
kubectl get gs
NAME STATE ADDRESS PORT NODE AGE
simple-game-server-rhjtz-4dnrk Allocated xxx.xxx.xxx.xxx 7734 cn-xxx.xxx.xxx.xxx.xxx 3m36s
simple-game-server-rhjtz-rsnnm Ready xxx.xxx.xxx.xxx 7067 cn-xxx.xxx.xxx.xxx.xxx 3m36s
simple-game-server-rhjtz-tgxwj Ready xxx.xxx.xxx.xxx 7030 cn-xxx.xxx.xxx.xxx.xxx 6s
simple-game-server-rhjtz-zhxts Allocated xxx.xxx.xxx.xxx 7909 cn-xxx.xxx.xxx.xxx.xxx 159m
可以看到总数gs已经扩为4了