【OpenKruiseGame】云原生游戏OpenKruiseGame网络选型
一、简介
在非网关场景下,游戏开发者需要考虑如何暴露游戏服的外部IP端口供玩家连接访问。玩家通过不同的端口接入到不同的服务器中。在不同场景下往往需要不同的网络产品。
GameServerSet为会其管理下的每一个Pod都添加一个独有的label,当在GameServerSet中配置了network字段时,OpenKruiseGame会为此GameServerSet管理下的每一个Pod都创建一个k8s service,这样每一个Pod都会有一个对外暴露的入口,可以使不同的玩家连入不同的游戏服务器。

OpenKruiseGame(OKG)集成了不同的网络插件,用户可以通过GameServerSet设置游戏服的网络参数,并在生成的GameServer中查看网络状态信息。本文档介绍以下几个模型:
- CCE-NodePort
- CCE-HostPort
- HwCloud-CCE-ELB
- CCE-EIP
1.1 选型建议
不同的网络模型都有其适用场景
- CCE-NodePort:适用于对稳定性要求不高的情况下,外部可以通过节点上的公网IP和端口连接到游戏服。
- CCE-HostPort:适用于游戏服数量不多的情况,HostPort一个节点上只能存在一个游戏服,外部可以通过节点上的公网IP和游戏服对外暴露的端口连接到游戏服。
- HwCloud-CCE-ELB:适用于大多数情况,有较多数量游戏服且对稳定性要求较高。华为云ELB可以接通多个游戏服后端,外部可以通过ELB绑定的公网IP和游戏服对外暴露的端口连接到游戏服。
- CCE-EIP:适用于对游戏服网络要求很高的场景,每个游戏服都绑定了一个公网IP,外部直接通过公网IP和游戏服的运行端口连接到游戏服。
二、准备
2.1 准备CCE集群环境
步骤一:准备CCE集群

步骤二:配置kubeconfig
步骤三: 安装helm
wget https://get.helm.sh/helm-v3.18.5-linux-amd64.tar.gz
tar -zxf ./helm-v3.18.5-linux-amd64.tar.gz
cp -a ./linux-amd64/helm /usr/local/bin/helm
2.2 安装OpenKruiseGame
使用helm在集群中安装OpenKruiseGame
# 添加helm源
helm repo add openkruise https://openkruise.github.io/charts/
# 安装OpenKruise
helm install kruise openkruise/kruise --version 1.8.0 --set manager.image.repository=openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/kruise-manager --set featureGates="PodProbeMarkerGate=true"
# 安装OpenKruiseGame
helm install kruise-game openkruise/kruise-game --version 1.0.0 --set image.repository=registry-cn-hangzhou.ack.aliyuncs.com/acs/kruise-game-manager
2.3 更新OpenKruiseGame Manager使用的镜像
要对接到CCE ELB,需要OpenKruiseGame Manager组件的镜像更新最新版本。
此最新版本需要使用开源代码编译制作镜像,并更新组件使用的镜像。
步骤一:制作最新版本镜像
wget https://github.com/openkruise/kruise-game/archive/refs/heads/master.zip
unzip ./master.zip
cd ./kruise-game-master
# 国内网络可以配置golang代理提升网络连接
vim ./Dockerfile
# 在 go mod download的前一行添加
RUN go env -w GOPROXY=https://goproxy.cn,direct
# 修改后保存退出vim
# 制作镜像并推送到镜像仓库
# 以推送到华为云SWR为例
docker build ./ -t kruise-game-manager:master
# username和password以实际的镜像仓库凭证为准
docker login -u {username} -p {password} swr.cn-north-4.myhuaweicloud.com
# 组织名称以自己实际的SWR组织名称为准
docker tag kruise-game-manager:master swr.cn-north-4.myhuaweicloud.com/{组织名称}/kruise-game-manager:master
docker push swr.cn-north-4.myhuaweicloud.com/{组织名称}/kruise-game-manager:master

步骤二:升级OpenKruiseGame
helm repo add openkruise https://openkruise.github.io/charts/ --force-update
helm upgrade kruise-game openkruise/kruise-game --version 1.0.0 --set image.repository=swr.cn-north-4.myhuaweicloud.com/{组织名称}/kruise-game-manager --set image.tag=master
三、网络模型使用
3.1 使用CCE NodePort网络模型
使用OpenKruiseGame在CCE集群中使用NodePort网络模型
适用于华为CCE Standard集群,华为CCE Turbo集群
开始部署gamerserverset,使用NodePort网络模型
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: minecraft-test
namespace: default
spec:
replicas: 3
updateStrategy:
rollingUpdate:
podUpdatePolicy: InPlaceIfPossible
network:
networkType: Kubernetes-NodePort # 使用Kubernetes NodePort网络模型
networkConf:
- name: PortProtocols # 提供服务的容器名以及对应暴露的端口和协议,可以配置多个值
value: "520/UDP"
- name: Fixed
value: "true"
gameServerTemplate:
spec:
containers:
- image: swr.cn-north-4.myhuaweicloud.com/cpaas/minecraft-demo:1.12.2
name: minecraft
spec.network.networkConf字段可用的参数:
- PortProtocols
含义:Pod实际暴露的端口及协议,支持填写多个端口/协议。
格式:port1/protocol1,port2/protocol2,…(协议需大写)
默认值:N/A
是否支持变更:是 - Fixed
含义:是否固定访问IP/端口。如果值为true,即使Pod删除重建,网络内外映射关系也不会改变
格式:true/false
默认值:false
是否支持变更:是 - AllowNotReadyContainers
含义:在容器原地升级时允许部分容器不断流,可填写多个
格式:{containerName_0},{containerName_1},… 例:sidecar
默认值:N/A
是否支持变更:在原地升级过程中不可变更
使用yaml部署GameServerSet后查看GameServer资源

可以看到GameServerSet启动了3个Pod,同时GameServer也启动了3个服务。
从GameServer查看游戏服务的网络配置

对应的,集群中创建了3个NodePort类型的service,各个service对外暴露了不同的端口。

3.2 使用CCE HostPort网络模型
适用于华为CCE Standard集群
使用OpenKruiseGame在CCE集群中使用HostPort网络模型
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: minecraft-test
namespace: default
spec:
replicas: 3
updateStrategy:
rollingUpdate:
podUpdatePolicy: InPlaceIfPossible
network:
networkType: Kubernetes-HostPort # 使用Kubernetes HostPort网络模型
networkConf:
- name: ContainerPorts # 提供服务的容器名以及对应暴露的端口和协议,可以配置多个值
value: "minecraft:520/TCP"
gameServerTemplate:
spec:
containers:
- image: swr.cn-north-4.myhuaweicloud.com/cpaas/minecraft-demo:1.12.2
name: minecraft
spec.network.networkConf字段可用的参数:
- ContainerPorts
含义:
提供服务的容器名以及对应暴露的端口和协议,可以配置多个值。
格式:containerName:port1/protocol1,port2/protocol2,…(协议需大写)
默认值:N/A
是否支持变更:不支持,在创建时即永久生效,随Pod生命周期结束而结束
使用yaml部署gFameserverset后查看GameServer资源

可以看到GameServerSet启动了3个Pod,同时GameServer也启动了3个服务。
从GameServer查看游戏服务的网络配置

对应的,在节点上也创建了对应的HostPort转发规则

3.3 对接华为云CCE LoadBalancer Service
使用OpenKruiseGame在Kubernetes集群中使用Hwcloud-CCE-ELB网络模型
适用于华为CCE Standard集群,华为CCE Turbo集群*
使用OpenKruiseGame在CCE集群中对接ELB
修改kruise-game-manager配置文件,开启CCE开关
kubectl edit configmap kruise-game-manager-config -n kruise-game-system
# 将配置文件中[hwcloud]部分的配置修改为如下
[hwcloud]
enable = true
[hwcloud.elb]
max_port = 700
min_port = 500
block_ports = []
[hwcloud.cce.elb]
max_port = 65535
min_port = 32768
block_ports = []
# 修改后保存并退出编辑

配置参数说明:
enable:网络模型插件启动开关,true为开启,false为关闭
max_port:服务对外暴露的端口最大值
min_port:服务对外暴露的端口最小值
block_ports:禁止对外暴露的服务端口,实际生产中有一些需要保留的端口或者高危端口,使用此配置禁用部分端口
修改配置后重新部署kruise-game-controller-manager
kubectl rollout restart deployment kruise-game-controller-manager -n kruise-game-system
开始部署gamerserverset,将服务对接到华为云ELB
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: minecraft-test
namespace: default
spec:
replicas: 3
updateStrategy:
rollingUpdate:
podUpdatePolicy: InPlaceIfPossible
network:
networkType: HwCloud-CCE-ELB # 使用华为CCE-ELB网络模型
networkConf:
- name: PortProtocols # 后端pod实际使用的端口和网络协议,可以配置多个值
value: "520/TCP"
- name: Fixed # 是否要固定对外暴露的端口
value: "true"
- name: kubernetes.io/elb.class # ELB实例的类型,与华为云CCE LoadBalancer使用的annotation相同
value: performance
- name: kubernetes.io/elb.id # ELB实例的ID,与华为云CCE LoadBalancer使用的annotation相同,其值以华为云ELB的实际ID为准
value: 2f0f...e1d78
gameServerTemplate:
spec:
containers:
- image: swr.cn-north-4.myhuaweicloud.com/cpaas/minecraft-demo:1.12.2
name: minecraft
spec.network.networkConf字段可用的参数:
- PortProtocols
含义:Pod实际暴露的端口及协议,支持填写多个端口/协议。
格式:port1/protocol1,port2/protocol2,…(协议需大写)
默认值:N/A
是否支持变更:是 - Fixed
含义:是否固定访问IP/端口。如果值为true,即使Pod删除重建,网络内外映射关系也不会改变
格式:true/false
默认值:false
是否支持变更:是 - AllowNotReadyContainers
含义:在容器原地升级时允许部分容器不断流,可填写多个
格式:{containerName_0},{containerName_1},… 例:sidecar
默认值:N/A
是否支持变更:在原地升级过程中不可变更 - ExternalTrafficPolicyType
含义:Service LoadBalancer是否只转发给本地实例。直接影响创建出的的service的spec.externalTrafficPolicy字段。
格式:Local/Cluster
默认值:Cluster
是否支持变更:否 - 其他与华为云CCE集群相关的参数,参考华为云官方文档
使用注解(Annotations)配置负载均衡的高级功能
https://support.huaweicloud.com/usermanual-cce/cce_10_0385.html
使用yaml部署GameServerSet后查看GameServer资源。

可以看到GameServerSet启动了3个Pod,同时GameServer也启动了3个服务。
从GameServer查看游戏服务的网络配置。

对应的,集群中创建了3个LoadBalancer类型的service,各个service对外暴露了不同的端口。

3.4 游戏服使用固定公网IP
在对游戏服有强网络需求的场景下,需要通过公网IP直连到游戏服。本例介绍如何在创建游戏服时自动创建并绑定公网IP到游戏服上,并固定公网IP,即使游戏服重建公网IP也不会变化。
删除Pod后,在配置的固定EIP过期时间内,如果有同名的Pod创建,EIP依旧可用。只有在EIP过期时间内没有同名Pod创建时会删除EIP。
适用于华为CCE Turbo集群
部署GamerServerSet,并将游戏绑定华为云弹性公网IP(EIP)。
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: minecraft-test
namespace: default
spec:
replicas: 3
updateStrategy:
rollingUpdate:
podUpdatePolicy: InPlaceIfPossible
gameServerTemplate:
metadata:
annotations:
yangtse.io/pod-with-eip: 'true' # EIP跟随Pod创建
yangtse.io/eip-bandwidth-size: '5' # EIP带宽
yangtse.io/eip-network-type: 5_bgp # EIP类型
yangtse.io/eip-charge-mode: bandwidth # EIP计费模式
yangtse.io/static-eip: 'true' # Pod固定EIP
yangtse.io/static-eip-expire-duration: 5m # 固定EIP过期回收的时间间隔
spec:
containers:
- image: swr.cn-north-4.myhuaweicloud.com/cpaas/minecraft-demo:1.12.2
name: minecraft
固定EIP的annotation配置:
- static-eip: 是否开启Pod固定EIP,默认值"false"。需要设为"true"以固定EIP。
- static-eip-expire-duration: 删除固定EIP的Pod后,对应的固定EIP过期回收的时间间隔,默认值"5m"。
- pod-with-eip: 是否需要跟随Pod创建EIP并绑定到该Pod,默认值"false"。需要设为"true"以开启自动创建EIP。
- eip-bandwidth-size: 带宽大小,单位为Mbit/s,默认值5。
- eip-network-type: 公网IP类型,默认值"5_bgp"。具体类型以各区域配置为准,详情请参见华为云弹性公网IP控制台的购买页面。
- eip-charge-mode: 公网IP计费方式。"bandwidth"表示按带宽计费,"traffic"表示按流量计费。

可以通过Pod的annotation查绑定的Pod EIP。可以看到Pod分别绑定了不同的EIP。
kubectl get pod minecraft-static-ip-0 -o jsonpath='{.metadata.annotations.yangtse\.io/allocated-ipv4-eip}{"\n"}'
kubectl get pod minecraft-static-ip-1 -o jsonpath='{.metadata.annotations.yangtse\.io/allocated-ipv4-eip}{"\n"}'
kubectl get pod minecraft-static-ip-2 -o jsonpath='{.metadata.annotations.yangtse\.io/allocated-ipv4-eip}{"\n"}'

手动删除pod使其重建,再查看绑定的EIP。

新pod创建好之后再次查看pod 绑定的EIP。

可以看到各个Pod绑定的EIP都没有变,证明EIP已经固定。
- 点赞
- 收藏
- 关注作者
评论(0)