操作场景
原生 LoadBalancer 模式 Service 可自动创建负载均衡 CLB,并通过集群的 NodePort 转发至集群内,再通过 iptable 或 ipvs 进行二次转发。该模式下的 Service 能满足大部分使用场景 ,但在以下场景中更推荐使用直连 Pod 模式 Service:
有获取来源 IP 需求时(非直连模式必须另外开启 Local 转发)。
要求具备更高转发性能时(非直连模式下 CLB 和 Service 本身存在两层 CLB,性能有一定损失)。
需使用完整的健康检查和会话保持到 Pod 层级时(非直连模式下 CLB 和 Service 本身存在两层 CLB,健康检查及会话保持功能较难配置)。
说明
若您的集群是 Serverless 集群,则默认为直连 Pod 模式,您无需任何操作。
当前 GlobalRouter 和 VPC-CNI 容器网络模式均支持直连 Pod 模式,您可以在 集群列表 中单击集群 ID 进入集群详情页面,在集群的"基本信息"页面中查看当前集群使用的网络插件。 容器网络模式为 VPC-CNI
使用限制
集群 Kubernetes 版本需要高于 1.12。
集群网络模式必须开启 VPC-CNI 弹性网卡模式。
直连模式 Service 使用的工作负载需使用 VPC-CNI 弹性网卡模式。
默认 CLB 的后端数量限制是200个,如果您绑定的工作负载的副本数超过200时,可通过 提交工单 提升负载均衡 CLB 的配额。 满足 CLB 本身绑定弹性网卡的功能限制,详情请参见 绑定弹性网卡。 开启直连 Pod 模式的工作负载更新时,将会根据 CLB 的健康检查状态进行滚动更新,会对更新速度造成一定影响。
不支持 HostNetwork 类型的工作负载。
操作步骤
2. 参考 控制台创建 Service 步骤,进入新建 Service 页面,根据实际需求设置 Service 参数。
其中,部分关键参数信息需进行如下设置,如下图所示: 服务访问方式:选择为公网 LB 访问或内网 LB 访问。
网络模式:勾选采用负载均衡直连 Pod 模式。
Workload 绑定:选择引用 Workload。
3. 单击创建服务,完成创建。
直连 Pod 模式 Service 的 YAML 配置与普通 Service YAML 配置相同,示例中的 annotation 即代表是否开启直连 Pod 模式。
kind: Service
apiVersion: v1
metadata:
annotations:
service.cloud.tencent.com/direct-access: "true"
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: LoadBalancer
annotation 扩展
service.cloud.tencent.com/tke-service-config: [tke-service-configName]
注意事项
如何保证滚动更新时的可用性保证
Kubernetes 官方提供的一个特性 ReadinessGate,主要是用来控制 Pod 的状态,集群版本需高于1.12。默认情况下,Pod 有以下 Condition:PodScheduled、Initialized、ContainersReady,当这几个状态都 Ready 的时候,Pod Ready 的 Condition 就通过了。但是在云原生场景下,Pod 的状态可能需要参考其他状态。ReadinessGate 提供了这样一个机制,允许为 Pod 的状态判断添加一个栅栏,由第三方来进行判断与控制。这样 Pod 的状态就和第三方关联起来了。
直连模式滚动更新的变化
当用户开始为应用做滚动更新的时候,Kubernetes 会根据更新策略进行滚动更新。但其判断一批 Pod 启动的标识仅包括 Pod 自身的状态,并不会考虑该 Pod 在负载均衡上是否配置健康检查且通过。如在接入层组件高负载时,不能及时对此类 Pod 进行及时调度,则滚动更新成功的 Pod 可能并没有正在对外提供服务,从而导致服务的中断。
为了关联滚动更新和负载均衡的后端状态,TKE 接入层组件引入了 Kubernetes 1.12中引入的新特性 ReadinessGate。TKE 接入层组件仅在确认后端绑定成功并且健康检查通过时,通过配置 ReadinessGate 的状态来使 Pod 达到 Ready 的状态,从而推动整个工作负载的滚动更新。
在集群中使用 ReadinessGate
Kubernetes 集群提供了服务注册的机制,只需要将您的服务以 MutatingWebhookConfigurations 资源的形式注册至集群即可。集群会在 Pod 创建的时候按照配置的回调路径进行通知,此时可对 Pod 进行创建前的操作,即给 Pod 加上 ReadinessGate。需注意此回调过程必须是 HTTPS,即需要在 MutatingWebhookConfigurations 中配置签发请求的 CA,并在服务端配置该 CA 签发的证书。
ReadinessGate 机制的灾难恢复
用户集群中的服务注册或证书有可能被用户删除,虽然这些系统组件资源不应该被用户修改或破坏。在用户对集群的探索或是误操作下,这类问题会不可避免的出现。因此接入层组件在启动时会检查以上资源的完整性,在完整性受到破坏时会重建以上资源,加强系统的鲁棒性。详情可参见 Kubernetes Pods ReadinessGate 特性。 容器网络模式为 GlobalRouter
使用限制
单个工作负载仅能运行在一种网络模式下,您可选择弹性网卡直连或 GlobalRoute 直连。
仅支持带宽上移账号。
默认 CLB 的后端数量限制是 200 个,如果您绑定的工作负载的副本数超过 200 时,可通过 提交工单 提升负载均衡 CLB 的配额。 使用 CLB 直连 Pod,需注意网络链路受云服务器的安全组限制,确认安全组配置是否放开对应的协议和端口,需要开启 CVM 上工作负载对应的端口。
步骤1:开启直连配置
对于 GlobalRouter 集群,需先在集群维度开启直连能力,再为具体的 Service 开启直连模式。
在 kube-system/tke-service-controller-config ConfigMap 中新增 GlobalRouteDirectAccess: "true" 以开启 GlobalRoute 直连能力。
1. 登录容器服务控制台,在左侧导航栏中选择集群。
2. 在集群列表中,单击目标集群 ID,进入集群详情页。
3. 在配置管理 > ConfigMap 页面,命名空间选择 kube-system,搜索并找到 tke-service-controller-config,单击更新配置。
4. 在更新配置页面,选择手动增加,变量名填写为 GlobalRouteDirectAccess,变量值填写为 true(注意没有引号)。
5. 单击更新 ConfigMap。
1. 在集群列表中,单击目标集群 ID,进入集群详情页。
2. 在配置管理 > ConfigMap 页面,单击 tke-service-controller-config 右侧的编辑 YAML。或通过命令行执行以下命令进入 YAML 编辑模式:
kubectl edit configmap tke-service-controller-config -n kube-system
3. 在 data 字段下新增一行 GlobalRouteDirectAccess: "true"(注意缩进2个空格),保存即可:
data:
GlobalRouteDirectAccess: "true"
注意:
如果集群中不存在 tke-service-controller-config ConfigMap,可通过以下命令创建:
kubectl create configmap tke-service-controller-config \\
-n kube-system \\
--from-literal=GlobalRouteDirectAccess=true
步骤2:Service 或 Ingress 中开启直连模式
2.1 Service 开启直连模式
在 Service 的 metadata.annotations 中添加以下注解,即可开启直连 Pod 模式。删除该注解或将其值设为 "false" 则关闭直连模式。
kind: Service
apiVersion: v1
metadata:
annotations:
service.cloud.tencent.com/direct-access: "true"
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: LoadBalancer
您也可以对已有 Service 使用以下命令直接添加注解:
kubectl annotate service <service-name> -n <namespace> \\
service.cloud.tencent.com/direct-access=true
2.2 Ingress 开启直连模式
对于 Ingress,需使用 ingress.cloud.tencent.com/direct-access: "true" 注解来开启直连模式:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
ingress.cloud.tencent.com/direct-access: "true"
kubernetes.io/ingress.class: qcloud
name: my-ingress
namespace: default
spec:
rules:
- http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
annotation 扩展
service.cloud.tencent.com/tke-service-config: [tke-service-configName]