在Cilium网络部署MetalLB

我在 Cilium Kubernetes Ingress HTTP配置案例 配置 ingress 输出 http服务时,遇到一个问题: 默认配置 LoadBalancer 类型服务,但是由于是裸机部署,并没有云厂商提供的负载均衡。所以Ingress一直没有分配到IP地址,也没有对应的 External-IP。

解决方法是部署 metallb 来提供对外服务IP地址

安装

  • 在集群安装MetalLB:

kubectl apply 安装 MantalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.4/config/manifests/metallb-native.yaml

输出显示:

kubectl apply 安装 MantalLB 输出显示
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/addresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
secret/webhook-server-cert created
service/webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created

备注

其他安装方法请参考 metallb Installation

配置

  • 创建 z-k8s-ip-pool.yaml

为负载均衡定义IPAddressPool CR
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: z-k8s-ip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.6.151-192.168.6.198
  • 创建IP池:

负载均衡创建IPAddressPool
kubectl create -f z-k8s-ip-pool.yaml

完成后检查 svcingress 会立即看到IP池中的IP被分配给了LoadBalancer EXTERNAL-IP:

检查SVC cilium-ingress-basic-ingress
kubectl get svc cilium-ingress-basic-ingress

输出显示IP池的第一个IP地址被分配给LoadBalancer的EXTERNAL-IP:

检查SVC cilium-ingress-basic-ingress 输出显示EXTERNAL-IP分配成功
NAME                           TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
cilium-ingress-basic-ingress   LoadBalancer   10.100.187.26   192.168.6.151   80:32598/TCP   25h

再检查 ingress 也看到ADDRESS分配了同样的IP地址:

检查ingress
kubectl get ingress basic-ingress

输出信息:

检查ingress可以看到分配了相同的IP
NAME            CLASS    HOSTS   ADDRESS         PORTS   AGE
basic-ingress   cilium   *       192.168.6.151   80      25h

但是此时,不管是ping还是telnet访问不了这个分配好的 IP 地址 192.168.6.151 ,原因是还没有声明服务IP地址,这个步骤有多种声明方式,比较简单的是 Layer 2 配置:

  • 配置 z-k8s-ip-pool_announce.yaml :

申明IP地址池的ARP公告
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: z-k8s-ip-pool
  namespace: metallb-system
spec:
  ipAddressPools:
  - z-k8s-ip-pool
  • 执行IP地址池ARP声明:

申明IP地址池的ARP公告
kubectl create -f z-k8s-ip-pool_announce.yaml

现在虽然 ping 192.168.6.151 没有响应,但是 telnet 192.168.6.151 80 端口可以打开了,证明负载均衡输出SVC成功

现在使用浏览器访问 http://192.168.6.151 就可以看到在 Cilium Kubernetes Ingress HTTP配置案例 搭建的案例WEB网站了,说明服务输出正确了

参考