跳到主要内容

使用 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 前请确保满足以下前提条件:

  1. 确保腾讯云账号是带宽上移账号,参考 账户类型说明 进行判断或升级账号类型(如果账号创建的时间很早,有可能是传统账号)。
  2. 创建了 TKE 集群,且集群版本大于等于 1.26。
  3. 集群中安装了 cert-manager (webhook 依赖证书),参考 在 TKE 上安装 cert-manager
  4. 需要一个腾讯云子账号的访问密钥(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:

  1. selector 选中目标应用 Pod 的 labels。
  2. existedLbIds 传入用于为 Pod 分配公网映射的 CLB 实例 ID 列表,可动态追加。
  3. minPortmaxPort 为 CLB 自动创建监听器的端口范围,每个端口只绑定一个 Pod。
  4. maxPod 用于限制最大 Pod/监听器 数量。
  5. ports 为 Pod 监听的端口列表,通常一个房间进程只监听一个端口。其中 addressPodAnnotation 用于 CLB 绑定 Pod 后,自动将其 CLB 外部映射地址自动注入到指定的 pod annotation 中,可结合 Kubernetes 的 Downward API 将外部地址挂载进容器内,以便让应用能够感知到自身的公网地址。
dedicated-clb-service.yaml
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 或域名,所以格式又细分成以下两种形式:

  1. IP:Port: CLB 的 VIP 加对外的端口号,如 1.1.1.1:567,非域名化的 CLB 会使用该形式。
  2. 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 时,注意 minPortmaxPort 的范围,避免超出限制,也根据实际需要来选择合适的端口区间,比如单个 Pod 如果承载流量很大,端口范围可缩小点,限制绑定的 Pod 数量,避免单个 CLB 流量过大超出带宽上限;反之如果流量小,可扩大端口范围来绑定更多 Pod。