其他分享
首页 > 其他分享> > K8S v1.18.x 部署-Kubeadm方式-7:部署Addon-MetalLB

K8S v1.18.x 部署-Kubeadm方式-7:部署Addon-MetalLB

作者:互联网

MetalLB
MetalLB , 通过K8S原生的方式提供LB类型的Service支持,开箱即用。

MetalLB在Kubernetes内运行,监控服务对象的变化,一旦察觉有新的LoadBalancer服务运行,并且没有可申请的负载均衡器之后,就会完成两部分的工作:

用户需要在配置中提供一个地址池,MetalLB将会在其中选取地址分配给该服务。

根据不同配置,MetalLB会以二层(ARP/NDP)或者BGP的方式进行地址的广播。

Calico: 部分支持
Canel: 支持
Flannel: 支持
Kube-router: 部分支持
Romana: 支持
Weave Net: 部分支持

工作模式
Layer2模式
MetalLB在这种模式下,只需要一段跟K8S管理网相同网段的地址即可。

MetalLB会从K8S节点中选一个Leader节点,在这个节点上面响应LB地址段的ARP请求,从而使上层路由把发往LB的流量都发到Leader节点。

缺点也很明显,所有对LB的请求都会发往Leader节点。如果当前Service下面的Pod分布在不同节点,那么这个流量还会从Leader发往相应的节点。

不过用在实验环境里这个模式不需要路由器支持BGP。

K8S v1.18.x 部署-Kubeadm方式-7:部署Addon-MetalLB

图片来源:https://zhuanlan.zhihu.com/p/103717169

BGP模式
跟L2模式的区别就是能够通过BGP协议正确分布流量了,不再需要一个Leader节点。

这种模式需要路由器支持接收MetalLB的BGP广播,从而把请求分布到正确的节点上。

缺点就是需要上层路由器支持BGP。而且因为BGP单Session的限制,如果Calico也是使用的BGP模式,就会有冲突从而导致MetalLB无法正常工作。

K8S v1.18.x 部署-Kubeadm方式-7:部署Addon-MetalLB

图片来源:https://zhuanlan.zhihu.com/p/103717169

部署MetalLB
如果kube-proxy启用了IPVS,需要设置strictARP: true。


[root@K8S-PROD-M1 ~]# kubectl edit configmap -n kube-system kube-proxy
...
    ipvs:
      excludeCIDRs: null
      minSyncPeriod: 5s
      scheduler: wrr
      strictARP: true  #将false设置成true
      syncPeriod: 5s
      tcpFinTimeout: 0s
      tcpTimeout: 0s
      udpTimeout: 0s
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: ipvs
...

或者使用下面的方法:

# see what changes would be made, returns nonzero returncode if different
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system

# actually apply the changes, returns nonzero returncode on errors only
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

部署MetalLB

[root@K8S-PROD-M1 ~]# docker pull metallb/controller:v0.9.3
[root@K8S-PROD-M1 ~]# docker tag metallb/controller:v0.9.3 harbor.cluster.local/library/metallb/controller:v0.9.3
[root@K8S-PROD-M1 ~]# docker push harbor.cluster.local/library/metallb/controller:v0.9.3


* 获取部署文件

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml


然后修改metal.yaml中Deployment的镜像地址为私有镜像地址。

* 执行部署

On first install only

[root@K8S-PROD-M1 metallb]# kubectl apply -f metallb-namespace.yaml
[root@K8S-PROD-M1 metallb]# kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
[root@K8S-PROD-M1 metallb]# kubectl apply -f metallb.yaml


**配置MetalLB**
创建一个Configmap文件,为MetalLB设置网址范围以及协议相关的选择和配置,这里以一个简单的二层配置为例:LB地址段是192.168.122.100-192.168.122.200,跟K8S节点的管理网是同一个/24地址段。

[root@K8S-PROD-M1 metallb]# cat > config.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:


创建ConfigMap:

[root@K8S-PROD-M1 metallb]# kubectl apply -f config.yaml
该ConfigMap一旦创建,IP地址池信息将被缓存至MetalLB Controller, 如果修改了IP地址池,则需要重新创建MetalLB Controller Pod。

**配置更新过程**

[root@K8S-PROD-M1 metallb]# kubectl -n metallb-system logs -f pod/controller-6c578774c8-7xnjb
...
{"caller":"main.go:63","event":"endUpdate","msg":"end of service update","service":"kubernetes-dashboard/kubernetes-dashboard","ts":"2020-09-24T03:21:19.959638677Z"}
{"caller":"main.go:126","event":"stateSynced","msg":"controller synced, can allocate IPs now","ts":"2020-09-24T03:21:19.95968369Z"}
...


**测试MetalLB**
**创建SVC**

piVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:


apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:

deploy-lbsvc-demo.yaml


[root@K8S-PROD-M1 metallb]# kubectl apply -f deploy-lbsvc-demo.yaml

查看SVC

[root@K8S-PROD-M1 metallb]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>            443/TCP        23d
nginx        LoadBalancer   10.106.22.150   192.168.122.100   80:31852/TCP   2m30s
svc-demo-1   ClusterIP      10.98.47.47     <none>            80/TCP         5m10s
svc-demo-2   ClusterIP      10.109.97.203   <none>            8080/TCP       47h

查看日志


[root@K8S-PROD-M1 metallb]# kubectl -n metallb-system logs -f pod/controller-6c578774c8-7xnjb
...
{"caller":"main.go:49","event":"startUpdate","msg":"start of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.415605635Z"}
{"caller":"service.go:114","event":"ipAllocated","ip":"192.168.122.100","msg":"IP address assigned by controller","service":"default/nginx","ts":"2020-09-24T06:24:46.41577988Z"}
{"caller":"main.go:96","event":"serviceUpdated","msg":"updated service object","service":"default/nginx","ts":"2020-09-24T06:24:46.53081167Z"}
{"caller":"main.go:98","event":"endUpdate","msg":"end of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.530878232Z"}
{"caller":"main.go:49","event":"startUpdate","msg":"start of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.530912503Z"}
{"caller":"main.go:75","event":"noChange","msg":"service converged, no change","service":"default/nginx","ts":"2020-09-24T06:24:46.531027842Z"}
{"caller":"main.go:76","event":"endUpdate","msg":"end of service update","service":"default/nginx","ts":"2020-09-24T06:24:46.531200567Z"}
...

访问SVC

iptables -t nat -A PREROUTING -m tcp -p tcp -d 192.168.191.32 --dport 31852 -j DNAT --to-destination 192.168.122.100:80


* 访问Web UI

浏览器中访问:http://192.168.191.32:31852即可访问nginx首页,或者:

[root@server ~]# curl http://192.168.122.100/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
......



**高级功能**
**多个Service共用一个IP**
创建Service的时候加上一个annotation:metallb.universe.tf/allow-shared-ip: <some_key>,那么使用相同Key的Service会共用同一个IP。

然共享IP的前提是这些Service都使用不同的Port。

标签:MetalLB,metallb,service,v1.18,部署,kubectl,K8S,root
来源: https://blog.51cto.com/15127525/2658808