Ack集群Pod独占EIP实践
引入一个实际生产环境案例,介绍在阿里云Ack集群中如何实现Pod独占公网EIP
背景
某线上应用部署在ack集群内,用于根据用户定义的http请求项配置,周期性检查http接口的请求响应状态,接口地址为内网或公网,当接口地址为公网时,频繁出现请求超时的报警错误。经过排查发现,在公网请求发生超时的时刻,集群vpc NAT带宽达到上限200Mbps,也就是25MB/s

分析:由于集群占用vpc,vpc内所有ip(node和pod的ip)都属于vpc内各子网地址,这些地址出公网的请求共用vpc绑定的公网NAT,在某时刻子网ip请求公网使用的EIP是随机的,无法控制,会产生和其他ip同时请求公网使用同一个EIP的情况,由此发生了带宽内拥挤,超限的情况,因此上述超时报警其实是客户端带宽不够产生的误报
解决方案
为了避免发生上述情况,解决办法是避免这些特定的pod请求公网时和其他ip发生公网带宽的争抢,走独立的公网出口,有以下两种方案:
- 方案一
将这些pod调度到特定的子网node,node的ip和pod的ip会使用特定的子网,这个特定的子网由于在特定的vSwitch虚拟交换机下,因此可以为这个子网单独指定路由条目,也就是将请求公网地址的请求的下一跳路由到特定的公网NAT,特定的公网NAT使用特定的EIP且不和其他子网共用
- 方案二
ack集群的网络使用的是阿里云Terway,在此前提下,阿里云提供了为Terway网络中的Pod挂载独立的公网EIP的解决方案,具体可以查看文档说明,简单来说就是阿里云提供了集群内的控制器,实现了通过k8s原生的声明式配置,调用EIP产品相关api动态为pod绑定EIP的功能
方案选取和实现
方案一,改动较大,需要将pod调度到特定的node上,且需要人工维护路由条目,维护性较差;
方案二,更为直接,在安装控制器插件后,通过给pod添加特定注解实现目的,主要分为两种方式:
- 一种是根据声明式配置动态随机购买EIP
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
labels:
app: example
spec:
replicas: 1
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
annotations:
k8s.aliyun.com/pod-with-eip: "true" # 自动创建并绑定EIP
k8s.aliyun.com/eip-bandwidth: "200" # EIP峰值带宽
k8s.aliyun.com/eip-internet-charge-type: "PayByTraffic" # EIP的计量方式
k8s.aliyun.com/eip-instance-charge-type: "PostPaid" # EIP的计费方式
k8s.aliyun.com/eip-name: "app-eip" # EIP名称
k8s.aliyun.com/eip-description: "app-eip" # EIP描述
- 一种是先购买EIP,pod注解中声明EIP的id
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
labels:
app: example
spec:
replicas: 1
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
annotations:
k8s.aliyun.com/pod-eip-instanceid: eip-2zeXXXXXx # EIP ID