使用 CLB 为 Pod 分配公网地址映射
概述
房间类的游戏一般都要求每个每个房间都需要有独立的公网地址,TKE 集群默认只支持 EIP 方案,但 EIP 资源有限,有申请的数量限制和每日申请的次数限制(参考 EIP 配额限制),稍微上点规模,或频繁扩缩容更换EIP,可能很容易触达限制导致 EIP 分配失败;而如果保留 EIP,在 EIP 没被绑定前,又会收取额外的闲置费。
TKE Pod 绑定 EIP 参考 Pod 绑 EIP。
关于 EIP 与 CLB 映射两种方案的详细对比参考 TKE 游戏方案:房间类游戏网络接入。
除了 EIP 方案,您还可以使用 tke-extend-network-controller
插件的方案,本文将介绍如何使用 tke-extend-network-controller
插件来实现为每个 Pod 的指定端口都分配一个独立的公网地址映射(公网 IP:Port
到内网 Pod IP:Port
的映射)。
tke-extend-network-controller
的代码是开源的,源码托管在 GitHub: https://github.com/tkestack/tke-extend-network-controller
前提条件
安装 tke-extend-network-controller
前请确保满足以下前提条件:
- 确保腾讯云账号是带宽上移账号,参考 账户类型说明 进行判断或升级账号类型(如果账号创建的时间很早,有可能是传统账号)。
- 创建了 TKE 集群,且集群版本大于等于 1.26。
- 集群中安装了 cert-manager (webhook 依赖证书),参考 在 TKE 上安装 cert-manager。
- 需要一个腾讯云子账号的访问密钥(SecretID、SecretKey),参考子账号访问密钥管理,要求账号至少具有以下权限:
{
"version": "2.0",
"statement": [
{
"effect": "allow",
"action": [
"clb:DescribeLoadBalancerBackends",
"clb:DescribeLoadBalancerListeners",
"clb:DescribeLoadBalancers",
"clb:CreateLoadBalancer",
"clb:DescribeTargets",
"clb:DeleteLoadBalancer",
"clb:DeleteLoadBalancerListeners",
"clb:BatchDeregisterTargets",
"clb:BatchRegisterTargets",
"clb:DeregisterTargets",
"clb:CreateLoadBalancerListeners",
"clb:CreateListener",
"clb:RegisterTargets",
"clb:DeleteLoadBalancers",
"clb:DescribeLoadBalancersDetail",
"clb:DescribeQuota",
"clb:DescribeListeners"
],
"resource": [
"*"
]
}
]
}
安装 tke-extend-network-controller
在 TKE 应用市场 的网络
分类中找到 tke-extend-network-controller
,编辑 values.yaml
,根据自己需求进行配置,以下几个参数是必填的:
vpcID: "" # TKE 集群所在 VPC ID (vpc-xxx)
clusterID: "" # TKE 集群 ID (cls-xxx)
secretID: "" # 腾讯云子账号的 SecretID
secretKey: "" # 腾讯云子账号的 SecretKey
配置完成后点【完成】即可安装到集群。
如果您使用 GitOps 管理应用,不想通过 TKE 应用市场安装,也可以从 GitHub 下载 chart 然后通过 helm 安装。
确保 Pod 调度到原生节点或超级节点
要使用 CLB 为 Pod 分配公网地址映射的能力,需要保证承载游戏房间的 Pod 调度到原生节点或超级节点上,如果 Pod 在普通节点(CVM),将不会为该 Pod 分配 CLB 公网地址映射。
创建 DedicatedCLBService
为应用创建 DedicatedCLBService
:
selector
选中目标应用 Pod 的 labels。existedLbIds
传入用于为 Pod 分配公网映射的 CLB 实例 ID 列表,可动态追加。minPort
和maxPort
为 CLB 自动创建监听器的端口范围,每个端口只绑定一个 Pod。maxPod
用于限制最大 Pod/监听器 数量。ports
为 Pod 监听的端口列表,通常一个房间进程只监听一个端口。其中addressPodAnnotation
用于 CLB 绑定 Pod 后,自动将其 CLB 外部映射地址自动注入到指定的 pod annotation 中,可结合 Kubernetes 的 Downward API 将外部地址挂载进容器内,以便让应用能够感知到自身的公网地址。
apiVersion: networking.cloud.tencent.com/v1alpha1
kind: DedicatedCLBService
metadata:
namespace: demo # 游戏服 Pod 所在命名空间
name: gameserver
spec:
lbRegion: ap-chengdu # 可选,CLB 所在地域,默认为集群所在地域
minPort: 500 # 可选,在 CLB 自动创建 监听器,每个 Pod 占用一个端口,默认端口号范围在 500-50000
maxPort: 50000
maxPod: 50 # 可选,限制最大 Pod/监听器 数量。
selector:
app: gameserver
ports:
- protocol: TCP # 端口监听的协议(TCP/UDP)
targetPort: 9000 # 容器监听的端口 (游戏战斗服、会议等进程监听的端口)
addressPodAnnotation: networking.cloud.tencent.com/external-address # 可选,将外部地址自动注入到指定的 pod annotation 中
existedLbIds: # 复用已有的 CLB 实例,指定 CLB 实例 ID 的列表
- lb-xxx
lbAutoCreate:
enable: true # 当 CLB 不足时,自动创建 CLB
extensiveParameters: | # 购买 CLB 时的参数(JSON 字符串格式):按流量计费,超强型4实例规格,带宽上限 60 Gbps (完整参数列表参考 CreateLoadBalancer 接口 https://cloud.tencent.com/document/api/214/30692)
{
"InternetAccessible": {
"InternetChargeType": "TRAFFIC_POSTPAID_BY_HOUR",
"InternetMaxBandwidthOut": 61440
},
"SlaType": "clb.c4.xlarge"
}
将 CLB 映射的外部地址注入到 Pod 注解中
部署游戏服、会议等应用时,利用 Kubernetes 的 Downward API 能力将记录 Pod 外部地址的注解内容挂载到容器内:
spec:
containers:
- ...
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "address"
fieldRef:
fieldPath: metadata.annotations['networking.cloud.tencent.com/external-address']
容器内进程获取自身的 CLB 外部映射地址
进程启动时可轮询指定文件(本例中文件路径为 /etc/podinfo/address
),当文件内容为空说明此时 Pod 还未绑定到 CLB,当读取到内容时说明已经绑定成功,其内容为 Pod 的 CLB 外部映射地址,进程可拿到该地址做进一步处理,如游戏战斗服上报自身房间的外部地址给大厅服或匹配服。
文件内容的格式为 Host:Port
,其中 Host
是 CLB 的 VIP 或域名,所以格式又细分成以下两种形式:
IP:Port
: CLB 的 VIP 加对外的端口号,如1.1.1.1:567
,非域名化的 CLB 会使用该形式。Domain:Port
,CLB 的域名加对外的端口号,如lb-6q0yyqhb-p01vqztldre7is89.clb.cd-tencentclb.work:567
,域名化的 CLB 会使用该形式。
CLB 的域名化与非域名化
通常新创建的 CLB 一般是域名化的 CLB(参考此公告),即 CLB 没有固定的 VIP,它的外部地址就是一个域名,VIP 根据域名动态解析出来。
如何确定 CLB 是域名化还是非域名化呢?在 CLB 实例的详情页就可以看出来:
注意事项
CLB 有一些默认的限制,其中每个 CLB 的监听器数量限制为 50,即最多创建 50 个端口。这个限制只是个软性限制,如有需要,也可以通过 提工单 来调大。
配置 DedicatedCLBService
时,注意 minPort
和 maxPort
的范围,避免超出限制,也根据实际需要来选择合适的端口区间,比如单个 Pod 如果承载流量很大,端口范围可缩小点,限制绑定的 Pod 数量,避免单个 CLB 流量过大超出带宽上限;反之如果流量小,可扩大端口范围来绑定更多 Pod。