前情回顾:
Kubernetes创建的容器Pod是以可伸缩集群方式承载业务的。由于Pod的可伸缩性,通过Pod的IP地址访问Pod所承载的业务并非一个可靠的方式,因此,Kubernetes引入了Service机制,用Service名称指向一个Pod集群。
Service有Nodeport,ClusterIP和Loadbalancer三种模式。在前期专题里面我们已经介绍了Nodeport和ClusterIP模式。今天我们介绍的是让容器向Internet提供服务的Loadbalancer模式。
让我们看一个使用Loadbalancer的例子:
如图,集群中运行了若干个apache httpd容器实例,它们统一对外呈现为一个service,名字叫my-service,对外(互联网)的IP地址为192.0.2.127.80。
显然,外界用户对192.0.2.127:80的访问是经过地址转换(NAT)到每个apache POD上的,如下图所示:
我们用yaml来配置这个service:
代码语言:javascript复制apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.0.2.127
那么,这个loadbalancer的NAT动作由谁来实际执行呢?
在Kubernetes的文档中,给出了阿里云、AWS、Azure等公有云上申请loadbalancer的方法,以及与OpenStack提供的LBaaS对接的方法。
以OpenStack提供的LBaaS为例:
我们在描述service的yaml中加入:
代码语言:javascript复制metadata:
name: my-service
annotations:
service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
Kubernetes会调用OpenStack的LBaaS实现前文提到的NAT(实际上是双向NAT)。当然,我们还需要在OpenStack中创建一个LBaaS。
问题来了,我们知道,无论是公有云提供商,还是OpenStack,资源发放的单位都并不是裸金属服务器(Bare-metal),而是虚拟机。
虚拟机运行容器平台的弊端是明显的。
在开篇《朝夕相伴触手可及的虚拟》中我们就提到,虚拟机的操作系统,实际上管理的是Hypervisor提供的虚拟化驱动,而并非是真实的硬件。这样一来,NVMe存储和RoCE网卡等昂贵的高级硬件根本无法发挥其优势,容器也无法通过CSI(容器存储接口:container storage interface,以后我们会介绍这个技术)挂载SAN存储的LUN卷。在运行关系型数据库的场景会严重降低性能,大规模数据库情况下几乎不可用。
因此,只有在物理服务器,也就是裸金属服务器上运行容器,才能充分发挥容器的优势,让使用这些先进硬件运行的机器学习等应用乘风破浪前行。
那么,在自行搭建裸金属服务器集群上运行kubernetes时,有没有办法使用LoadBalancer呢?
答案是肯定的。
对于轻量级Kubernetes集群,可以利用MetalLB等开源轻量级软件LB实现。MetalLB的部署也很简单,通过kubectl即可完成。
代码语言:javascript复制kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml
MetalLB有二层和三层模式,具体实现大家可以去这里看文档:
https://github.com/metallb/metallb
对于重量级Kubernetes集群,我们可以让硬件LB设备实现容器集群的负载均衡。
请看下回分解。