什么是 ALB
- 全称 Application Load Balancer,是 AWS Elastic Load Balancing 中的一款产品
- Application Load Balancer 最适合 HTTP 和 HTTPS 流量的负载均衡
- 详细功能
什么是 EKS
- Amazon Elastic Kubernetes Service (Amazon EKS) 是一项托管服务,可用于在 上运行 AWS Kubernetes,而无需安装、操作和维护您自己的 Kubernetes 控制层面或节点
- 默认 k8s master 是在 aws 托管 VPC 内对用户不可见,只暴露了 API 接口,与用户所在 node VPC 需要通过 两个 ENI 接口进行通讯
如何结合
- 需要引入一个 aws-load-balancer-controller
- v2.0.0 版本开始 AWS ALB Ingress Controller 正式更名为 AWS LoadBalancer Controller 并 GA!(Our first GA release for AWS Load Balancer Controller ❤️ (aka. AWS ALB Ingress Controller v2))
- 再次证明了,AWS 生态的完善。此插件基本上就是官方放出来让社区自己来完善并不断迭代
- v2 版本开始,不单单只是一个 alb 的控制器了,添加了 nlb 的控制,至此可以同时支持 4 & 7 层
- controller 监听 k8s api server,其实是 watch ingress 的变化,当发现有变更,调用 aws api 触发 alb rule 变化,同时把一个 ingress 的 annotations 配置添加到 alb 中
- 依靠 ALB 本身就有的权重能力,配合 ingress annotations 配置多个 group + order(
alb.ingress.kubernetes.io/group.name
& alb.ingress.kubernetes.io/group.order
)来实现单 k8s 的蓝绿部署
- How it works
注意点
- Rules per load balancer (not counting default rules) :100
- CD 系统适配
- 无多 K8S 集群能力
- 其他(发掘中。。。)
想象力
- 其实这个东西就差最后一步即可实现多 K8S 集群的流量调度,本身 ALB 就有这个能力做这个事情,毕竟其实就是 Nginx
- 比如可以基于 ALB 的 TargetGroup 将不同的 K8S 的 Node 放入,接着依赖 ALB 的权重能力来实现多集群调度流量,这个需求其实还是存在的,单集群的 K8S 其实当有重大升级操作 Or 其他特殊原因的事情很容易一把全挂的情况发生
- 慢慢读代码,尝试添加此功能中。还是有蛮多细节需要注意的,比如需要注意 AWS API 限流,一次放多少规则过去,ALB 的 TargetGroup 会不会爆炸等问题
核心代码改动思考
- watch Ingress ---> Service ---> Pod ---> PodInfo
- 最后直接获取 PodInfo 信息后添加到 ALB targetgroup,可以考虑 targetgroupbinding 模块的逻辑中按照不同的 clusterName 来添加,这样其实就可以实现同时控制多个 k8s 集群
// buildPodInfo will construct PodInfo for given pod.
func buildPodInfo(pod *corev1.Pod) PodInfo {
podKey := NamespacedName(pod)
var podENIInfos []PodENIInfo
// we kept podENIInfo as nil if the eniInfo via annotation is malformed.
if eniInfo, err := buildPodENIInfos(pod); err == nil {
podENIInfos = eniInfo
}
var containerPorts []corev1.ContainerPort
for _, podContainer := range pod.Spec.Containers {
containerPorts = append(containerPorts, podContainer.Ports...)
}
return PodInfo{
Key: podKey,
UID: pod.UID,
ContainerPorts: containerPorts,
ReadinessGates: pod.Spec.ReadinessGates,
Conditions: pod.Status.Conditions,
PodIP: pod.Status.PodIP,
ENIInfos: podENIInfos,
}
}