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。
图片来源:https://zhuanlan.zhihu.com/p/103717169
BGP模式
跟L2模式的区别就是能够通过BGP协议正确分布流量了,不再需要一个Leader节点。
这种模式需要路由器支持接收MetalLB的BGP广播,从而把请求分布到正确的节点上。
缺点就是需要上层路由器支持BGP。而且因为BGP单Session的限制,如果Calico也是使用的BGP模式,就会有冲突从而导致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:
- name: default
protocol: layer2
addresses:- 192.168.122.100-192.168.122.200
EOF
- 192.168.122.100-192.168.122.200
创建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:
- name: nginx
image: harbor.cluster.local/library/nginx:latest
ports:- name: http
containerPort: 80
- name: http
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
type: LoadBalancer
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
- NAT配置
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