0%

私有化Kubernetes实现Load Balancer

介绍

众所周知,k8s的Load Balancer需要依赖公有云提供的Load Balancer,如果我们需要在私有环境使用,则需要安装额外的组件,这里我选用的是MetalLB

注意: 文中此演示了基础功能,更多高级用法请大家参考官网文档。

组件安装

  1. 检查兼容性

    官网文档地址:https://metallb.universe.tf/installation/network-addons/

    网络插件 兼容性
    Calico 部分支持(已知问题
    Canal 支持
    Cilium 支持
    Flannel 支持
    Kube-router 部分支持(已知问题
    Romana 支持(额外的集成指南
    Weave Net 部分支持(已知问题
  2. 安装

    我使用的是Flannel,没有兼容性问题可以直接使用。安装非常简单,运行官方提供的脚本即可。

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

    稍等片刻后,使用kubectl get pods -n metallb-system列出所有POD,当都READY了就表示已经安装好了。

    注意: 实际POD数量是:master节点数量 + worker节点数量 + 1

    1
    2
    3
    4
    5
    6
    7
    8
    NAME                          READY   STATUS    RESTARTS   AGE
    controller-65895b47d4-flmfm 1/1 Running 0 163m
    speaker-5qz4v 1/1 Running 0 163m
    speaker-6rl9r 1/1 Running 0 163m
    speaker-hhllr 1/1 Running 0 163m
    speaker-ht4ns 1/1 Running 0 163m
    speaker-spzt6 1/1 Running 0 163m
    speaker-wjk84 1/1 Running 0 163m
  3. 配置

    MetalLB有两种模式,分别为Layer 2BGP后者需要路由器支持,所以我选择了前者。最终我还是选择了BGP模式,自由度更高。

    创建ConfigMap文件 metallb-config.yaml

    • Layer 2(两选一)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      apiVersion: v1
      kind: ConfigMap
      metadata:
      namespace: metallb-system
      name: config
      data:
      config: |
      address-pools:
      - name: default
      protocol: layer2
      addresses:
      - 192.168.2.150-192.168.2.199 # IP段需要与k8s管理网段一致
    • BGP(两选一)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      apiVersion: v1
      kind: ConfigMap
      metadata:
      namespace: metallb-system
      name: config
      data:
      config: |
      peers:
      - peer-address: 192.168.2.1 # 路由器地址
      peer-asn: 65000 # 路由器AS
      my-asn: 65009 # 工作AS
      address-pools:
      - name: default
      protocol: bgp
      addresses:
      - 192.168.3.0/24 #分配的IP网段

应用配置文件

1
kubectl apply -f metallb-config.yaml

组件测试

首先我们创建一个用于测试的服务 test.yaml

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
32
33
34
35
36
37
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
# 指定IP,如果指定的IP不在范围内或被占用则用分配失败
# 不指定则会随机分配
loadBalancerIP: 192.168.2.188
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer

当服务创建后,运行kubectl get svc查看分配到IP

1
2
3
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26h
nginx LoadBalancer 10.96.213.132 192.168.2.188 80:30823/TCP 22s

用浏览器打开http://192.168.2.188/验证,不出意外的话就会返回我们熟悉的Welcome to nginx!。到此我们就可以愉快的使用Load Balancer了。

注意: 如果在k8s节点机器上访问速度会很慢,大概需要1分钟左右,不知道是不是组件的BUG。这确实是一个bug,详情请看《Bare Metal K8S 63 Second Service Routing Delay - when accessing service via ClusterIP, or ExternalIP》,解决方案如下:

在文件夹 /usr/lib/systemd/system/ 新建 systemd-flannel-disable-tx-checksum.service 并写入

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=Disable TX checksum offload on flannel.1
After=sys-devices-virtual-net-flannel.1.device

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -K flannel.1 tx-checksum-ip-generic off

[Install]
WantedBy=sys-devices-virtual-net-flannel.1.device

然后设置为开机启动即可

1
2
systemctl enable systemd-flannel-disable-tx-checksum
systemctl start systemd-flannel-disable-tx-checksum