1. 说明

项目地址:MetalLB

为了系统的扩展性和稳定性,我们需要将服务暴露到单独的 IP 上,避免使用 Kubernetes 集群IP。

MetalLB 需要以下镜像:

1
2
quay.io/metallb/controller:v0.13.5
quay.io/metallb/speaker:v0.13.5

本文仅介绍了使用 L2 模式,BGP 模式请查看官网。

2. 环境准备

如果您在 IPVS 模式下使用 kube-proxy,从 Kubernetes v1.14.2 开始,您必须启用严格的 ARP 模式。

执行如下命令完成配置:

1
2
3
4
5
6
7
8
9
# 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

3. 导入资源

由于 MetalLB 的配置过于庞大,不便于在此展示,可将文件 conf/metallb-native.yaml 推送到控制节点,再使用 kubectl apply -f metallb-native.yaml 导入资源。

或者你可以使用以下命令在线导入资源:

1
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.5/config/manifests/metallb-native.yaml

导入完成后使用以下命令查看结果:

1
kubectl get pods -n metallb-system -o wide

如果一切无误,则会在所有节点上启动 speaker

4. 配置 LoadBalancer 地址

部署完成后,需要指定 LoadBalancer 可分配的地址。

由于是小型化部署,所以 L2 模式已经够用,当然,如果你是自建机房,想使用 BGP 的方案的话可自行查阅文档。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: primary-pool
  namespace: metallb-system
spec:
  addresses:
    # 根据实际需求自行配置
    - '10.0.0.5-10.0.0.9' (1)
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2-net
  namespace: metallb-system
spec:
  ipAddressPools:
    - primary-pool
其中:
1 用于指定 LoadBalancer 可用的地址。

5. 验证部署结果

执行以下步骤,验证部署结果。

5.1. 导入测试配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-test
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

5.2. 验证测试结果

执行以下命令,验证测试结果

1
2
3
4
5
kubectl get service,pods
# 查看LD 的 IP
kubectl get service -o jsonpath='{.items[*].status.loadBalancer.ingress[*].ip}'
ADDRESS=$(kubectl get service -o jsonpath='{.items[*].status.loadBalancer.ingress[*].ip}')
curl http://$ADDRESS/

如果一切无误,将看到 Pod 启动完成且 Service 有 EXTERNAL-IP ,浏览器可正常访问此地址。

6. 扩展