PanMichael
作者PanMichael·2019-11-05 17:19
软件架构设计师·兴业数金

OpenShift使用MetalLB,打开了Service通向外界的大门

字数 3489阅读 4230评论 0赞 1

背景

在K8S/OpenShift中,如果要向集群外部暴露应用的服务,目前使用的方法有:NodePort、HostPort、Route、LoadBalancer、HostNetwork。

  • Route:为最常用的方法,但是一般只支持7层负载(默认),使用一个外部LB来负载多个Route实例,对外的访问的IP为该LB的IP。
  • NodePort:在私有集群中也常用来暴露服务,但是它必须使用30000以上的端口,数量有限,不便于管理,而且对于一些特殊的服务,如DNS,必须使用小端口号,那么使用NodePort则无法满足。
  • HostNetwork:对于集群中的一些特殊服务使用该方式,它将容器与宿主机的网络绑定,如OpenShift中的Router服务就是使用HostNetwork与Router节点绑定。它的缺点是pod必须与主机绑定,同时每个Node上只能运行一个Pod实例,因为端口无法被复用。
  • HostPort:与HostNetwork类似,将Pod指定的端口与Node对应的端口绑定。
  • LoadBalancer:一般只在公有云平台使用,可以使Service获得与主机同一平面的IP,方便对服务进行控制与对外输出。缺点是依赖于公有云平台。

从上可看出对于HTTP服务使用Route可以很方便地对外提供服务,而对于TCP/UDP服务比较好的方式是使用LoadBalancer(当然HTTP服务也方便使用该方式),但是它依赖于云平台,有没有一种方式能够帮助集群在非IaaS平台上使用LoadBalancer方式呢?答案是有的,那就是Google的项目MetalLB。

什么是MetalLB

MetalLB的官方地址:https://metallb.universe.tf/
MetalLB是使用标准路由协议的裸机Kubernetes/OpenShift集群的软负载均衡器,可以在物理机环境下实现对Service服务分配IP。

MetalLB支持两种申明模式:

1.Layer 2模式:ARP/NDP

Layer 2模式下,每个service会有集群中的一个node来负责。当服务客户端发起ARP解析的时候,对应的node会响应该ARP请求,之后,该service的流量都会指向该node(看上去该node上有多个地址)。

Layer 2模式并不是真正的负载均衡,因为流量都会先经过1个node后,再通过kube-proxy转给多个end points。如果该node故障,MetalLB会迁移 IP到另一个node,并重新发送免费ARP告知客户端迁移。现代操作系统基本都能正确处理免费ARP,因此failover不会产生太大问题。

Layer 2模式更为通用,不需要用户有额外的设备;但由于Layer 2模式使用ARP/ND,地址池分配需要跟客户端在同一子网,地址分配略为繁琐。同时Layer 2模式所有流量会进入到一个Node,该Node的带宽可能会成为一个网络瓶颈。

2.BGP模式。

BGP模式下,集群中所有node都会跟上联路由器建立BGP连接,并且会告知路由器应该如何转发service的流量。

BGP模式是真正的LoadBalancer。

MetalLB由两个组件组成:

  1. controller,负责IP地址的分配,以及service和endpoint的监听。
  2. speaker,负责保证service地址可达,例如Layer 2模式下,speaker会负责ARP请求应答。

部署MetalLB

Kubernetes

1.安装metalLB相关的应用

# kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.1/manifests/metallb.yaml

2.创建configmap配置

cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
 namespace: metallb-system
 name: config
data:
 config: |
   address-pools:
   - name: default
     protocol: layer2
     addresses:
     - 192.168.1.240-192.168.1.250
EOF

OpenShift

  1. 关闭OpenShift自带的LoadBalancer功能,这一步很重要,否则会跟
    删除/etc/origin/master/master-config.yaml中的externalIPNetworkCIDRs设置
networkConfig:
  externalIPNetworkCIDRs:
  - 0.0.0.0/0

2.下载MetalLB安装文件

# wget https://raw.githubusercontent.com/google/metallb/v0.8.1/manifests/metallb.yaml

3.删除将文件中DaemonSet资源中的配置spec.template.spec.securityContext.runAsUser
4.添加权限

# oc adm policy add-scc-to-user privileged -n metallb-system -z speaker

5.运行安装

# oc apply -f metallb.yaml

6.创建configmap配置

# cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.240-192.168.1.250
EOF

测试

1.对已有的一个应用创建新LoadBalancer类型的svc

[root@master1 ~]# oc expose dc/flask-app --name=metallb-app --type=LoadBalancer --port=5000

2.查看当前svc的状态

[root@master1 ~]# oc get svc
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP                         PORT(S)          AGE
flask-app   ClusterIP      172.30.193.89   <none>                              5000/TCP         35d
metallb-app    LoadBalancer   172.30.7.121    192.168.1.240,172.29.114.1          5000:32276/TCP   6m

其中service flask-app为之前创建的ClusterIP类型;service metallb-app为新建的LoadBalancer类型的服务,它带有一个由MetalLB控制器分配的一个IP 192.168.1.240(另外还有一个OpenShift分配的一个额外IP 172.29.114.1,该IP可忽略)。

3.使用openshift集群外部的机器访问该应用

[root@i-avler8qs ~]# curl http://192.168.1.240:5000
Hello world v2

总结

在没有使用了LoadBalancer(如MetalLB)前,OpenShift上的Service像是待在这里的宠物,外部访问它非常受限;使用了LoadBalancer后,Service主动向外面世界敞开了怀抱,每个Service都绑定有一个独立的IP,方便外部应用访问,同时也方便使用传统的防火墙方式进行控制访问。
LoadBalancer扩大了对OpenShift/Kubernetes集群使用的想象空间,而MetalLB无疑是性价比最高的方式。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

1

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广