- 云原生
- 容器编排
- 边缘计算
【免费下载链接】k0s
k0s - The Zero Friction Kubernetes
k0s 默认不内置负载均衡器,要为 Kubernetes Service 提供LoadBalancer类型支持,MetalLB 是纯软件、无云厂商依赖的典型方案。本指南将基于 k0s 官方示例文档,完整演示如何通过 k0s 内置 Helm 扩展安装 MetalLB、配置 L2 模式的 IP 地址池,并部署一个带负载均衡器的示例应用完成端到端验证;同时结合仓库源码说明 strictARP 与 kube-proxy 模式的底层关系,帮助你在一台或多台裸金属节点上快速获得可用的外部访问入口。
关于负载均衡器(Load Balancer)
负载均衡器用于将应用暴露到外部网络:它提供一个单一 IP 地址,把进入的请求路由到你的应用后端。要让 Kubernetes 集群能够成功创建type: LoadBalancer的 Service,集群里必须先有可用的负载均衡器实现,否则 Service 的EXTERNAL-IP会一直停留在<pending>状态。
在 k0s 中,负载均衡器有两种典型实现方式:
- 云厂商提供的负载均衡器:作为集群外的外部服务提供(通常会产生额外费用)。k0s 以providerless模式构建 Kubernetes 组件,Kubernetes 的云控制器需要作为独立的集群插件安装,详见 docs/cloud-providers.md。
- 集群内部的纯软件方案:MetalLB:不依赖任何云厂商,是裸金属(bare-metal)部署场景下最常用的选择。
MetalLB 的工作原理
MetalLB 实现了 Kubernetes 的LoadBalancerService:当集群中请求一个LoadBalancer类型的 Service 时,MetalLB 会从配置好的地址范围内分配一个 IP,并让网络"知道"这个 IP 存在于集群中(L2 模式下通过 ARP 应答实现)。这样做的好处是彻底绕开了对云厂商的依赖,因此 MetalLB 特别适合裸金属部署。
前置条件:与 k0s 默认 CNI 的兼容性
MetalLB 对底层网络环境有一定要求(可参考 MetalLB 官方文档中的 Requirements 章节)。k0s 默认使用Kube-Router作为 CNI 插件,它与 MetalLB 兼容,前提是你不要使用 MetalLB 的 BGP 模式(即使用默认的 L2 模式)。
这一点可以从 k0s 源码中得到印证:pkg/apis/k0s/v1beta1/network.go 中的DefaultNetwork()将Provider默认值设为"kuberouter"(同时默认PodCIDR: 10.244.0.0/16、ServiceCIDR: 10.96.0.0/12);而 pkg/apis/k0s/v1beta1/network.go 的校验逻辑表明provider字段只支持kuberouter、calico、custom三个取值。
前置条件:kube-proxy 的 strictARP
如果你没有使用 Kube-Router,而是使用 kube-proxy 的IPVS 模式,就必须在 kube-proxy 中启用strict ARP 模式(这也是 MetalLB 官方准备工作中要求的步骤),否则 MetalLB 的 ARP 应答可能被 kube-proxy 的 IPVS 转发规则干扰。
k0s 中通过ClusterConfig的spec.network.kubeProxy段配置:
apiVersion: k0s.k0sproject.io/v1beta1 kind: ClusterConfig metadata: name: k0s spec: network: kubeProxy: mode: ipvs ipvs: strictARP: true从源码看,该配置的完整链路是:spec.network.kubeProxy.ipvs.strictARP对应 pkg/apis/k0s/v1beta1/kubeproxy.go 中KubeProxyIPVSConfiguration.StrictARP字段;k0s 控制器随后在 pkg/component/controller/kubeproxy.go 中把它写入生成的 kube-proxyConfigMap(StrictARP: kubeProxy.IPVS.StrictARP),最终透传给 kube-proxy 进程。
这里补充两个与 kube-proxy 模式相关的源码事实:
- 默认模式是iptables:pkg/apis/k0s/v1beta1/kubeproxy.go 的
DefaultKubeProxy()返回Mode: ModeIptables,且 校验逻辑 仅接受iptables、ipvs、userspace、nftables四种取值。因此在默认 iptables 模式下无需配置 strictARP,直接用 MetalLB 的 L2 模式即可。 - 如果你启用了 IPVS 模式,务必一并设置
ipvs.strictARP: true。
前置条件:节点间的端口 7946
节点之间必须放行7946 端口(TCP 与 UDP),MetalLB 的 L2 模式需要节点间通信来协调 IP 的所有权与故障转移。此外,安装 MetalLB 前要确认节点上 7946 端口没有被其他软件占用——例如 docker daemon 默认也会监听 7946,冲突会导致 MetalLB 无法正常工作。
安装 MetalLB
方式一:使用 k0s Helm 扩展(本指南推荐)
k0s 内置了对 Helm Chart 的管理能力,可以通过 k0s 配置文件(spec.extensions.helm)声明式地安装 Chart,k0s 会自动将其转换为 Helm 发布。下面是安装 MetalLB 的完整配置:
apiVersion: k0s.k0sproject.io/v1beta1 kind: ClusterConfig metadata: name: k0s spec: extensions: helm: repositories: - name: metallb url: https://metallb.github.io/metallb charts: - name: metallb chartname: metallb/metallb version: "0.15.3" namespace: metallb-system把这段内容并入你的k0s.yaml,然后重启 k0s 控制器(或按常规方式重新应用配置),MetalLB 就会自动部署到metallb-system命名空间。该机制对应的数据结构可在 pkg/apis/k0s/v1beta1/extensions.go 中看到:HelmExtensions包含concurrencyLevel、repositories、charts三部分。
关于spec.extensions.helm各字段的说明(详见 docs/helm-charts.md):
repositories 字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
name | 必填 | 仓库名称 |
url | 必填 | 仓库 URL |
insecure | true | 是否跳过 TLS 证书校验 |
caFile | - | 校验 HTTPS 服务端时使用的 CA 证书文件 |
certFile | - | mTLS 客户端证书文件 |
keyFile | - | mTLS 客户端密钥文件 |
username | - | Basic HTTP 认证用户名 |
password | - | Basic HTTP 认证密码 |
charts 字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
name | - | Helm release 名称 |
chartname | - | 形如仓库名/chart名的 Chart 引用,或 tgz 文件路径 |
version | - | 要安装的 Chart 版本 |
timeout | - | 等待 release 安装完成的超时时间 |
values | - | 以 YAML 字符串形式提供的自定义 values |
namespace | - | 安装 Chart 的目标命名空间 |
forceUpgrade | true | 设为false时禁用升级时的--force标志 |
order | 0 | 清单应用顺序,值相同时按字母序 |
k0s 处理这些 Chart 时默认使用--create-namespace、--atomic、--wait、--wait-for-jobs等 Helm 选项,upgrade场景还会追加--force(可参考 docs/helm-charts.md 中的说明)。需要注意:k0s 只支持提供合法index.yaml的经典 Helm 仓库。
另外,k0s 也支持以helm.k0sproject.io/v1beta1的Chart自定义资源方式部署 Chart(推荐用于 GitOps 场景),配置方式可参见 docs/helm-charts.md。
方式二:其他安装途径
MetalLB 官方还提供了 manifests 直装等其他安装方法,可参考 MetalLB 官方安装文档(本文不再展开)。
创建 MetalLB 配置:IP 地址池与 L2 通告
安装完成后,还需要告诉 MetalLB 可以分配哪些 IP。创建一个 ConfigMap(实际上是 CRD 资源),其中包含负载均衡器的 IP 地址范围。有两点约束:
- IP 池必须是 MetalLB 专用的:不能复用 Kubernetes 节点 IP,也不能使用被其他服务控制的 IP;
- 可以使用私网地址:例如
192.168.1.180-192.168.1.199,但若需要从外部网络访问,你还得自行处理从外部网络到该私网网段的路由。本文示例不涉及外部访问,因此直接使用私网池。
创建如下 YAML 文件(例如命名为metallb-l2-pool.yaml),然后执行kubectl apply -f metallb-l2-pool.yaml:
--- apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - <ip-address-range-start>-<ip-address-range-stop> # 或使用 CIDR 写法: # - <ip-address>/<cidr> --- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: example namespace: metallb-system要点说明:
IPAddressPool定义可分配的地址范围,支持区间写法(起始IP-结束IP)与CIDR 写法(IP/前缀)两种格式;L2Advertisement声明使用L2 模式对外通告该池,这也正是与 k0s 默认 Kube-Router CNI 兼容、且无需配置 BGP 的模式;- 两个资源都必须放在
metallb-system命名空间(即 MetalLB 安装时创建的命名空间)。
部署示例应用并验证 LoadBalancer
1. 部署带 LoadBalancer 的示例应用
创建一个包含 Namespace、Deployment 与 Service 的清单文件:
apiVersion: v1 kind: Namespace metadata: name: web --- apiVersion: apps/v1 kind: Deployment metadata: name: web-server namespace: web spec: selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: httpd image: httpd:2.4.53-alpine ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: web-server-service namespace: web spec: selector: app: web ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer应用该清单:
kubectl apply -f web-server.yaml2. 查看 LoadBalancer 状态
运行以下命令查看 Service 是否已获得外部 IP:
kubectl get service -n web如果 MetalLB 安装与配置正确,EXTERNAL-IP列会显示一个来自first-pool地址池的真实 IP;如果负载均衡器不可用,该列会显示<pending>,此时应回头检查 MetalLB 的安装与 IP 池配置。
3. 访问示例应用
由于我们在步骤 2 中配置的是私网 IP 池,应从本地网络内的机器发起访问,使用上一步拿到的EXTERNAL-IP:
curl <EXTERNAL-IP>如果一切正常,你会看到 Apache HTTP Server 的默认响应内容:
<html><body><h1>It works!</h1></body></html>更多选择:云厂商负载均衡器
如果不想使用纯软件方案,也可以通过云厂商提供的负载均衡器获取LoadBalancer支持。k0s 支持所有 Kubernetes 云控制器,但需要作为独立插件安装,且 kubelet 需以--enable-cloud-provider=true启动(使用 k0sctl 部署时可通过 worker 的installFlags注入,详见 docs/cloud-providers.md)。
小结
在 k0s 上启用LoadBalancer服务类型的最小路径可以概括为四步:确认节点间 7946 端口连通、通过 k0s Helm 扩展安装 MetalLB、创建IPAddressPool+L2Advertisement声明专用 IP 池、部署type: LoadBalancer的应用并验证EXTERNAL-IP。由于 k0s 默认使用 Kube-Router CNI,配合 MetalLB 的 L2 模式开箱即用;只有改用 kube-proxy IPVS 模式时才需要显式开启strictARP(其配置链路已在本指南中给出源码级印证)。部署完成后,MetalLB 提供的负载均衡入口还可以进一步与 Ingress 控制器(如 NGINX Ingress、Traefik)组合,把多个应用的路由规则收敛到单一入口,相关示例可参考 docs/examples/nginx-ingress.md 与 docs/examples/traefik-ingress.md。
- 云原生
- 容器编排
- 边缘计算
【免费下载链接】k0s
k0s - The Zero Friction Kubernetes
相关推荐
Bitnami Helm Chart 部署 MetalLB:为裸金属 Kubernetes 集群提供标准路由协议负载均衡
Bitnami Helm Chart 部署 MetalLB:为裸金属 Kubernetes 集群提供标准路由协议负载均衡 MetalLB 是专为裸金属 Kube
云原生容器编排MetalLB:在裸金属Kubernetes集群中实现负载均衡的终极指南
MetalLB:在裸金属Kubernetes集群中实现负载均衡的终极指南 MetalLB是一个专为裸金属Kubernetes环境设计的网络负载均衡器实现,它使用
云原生网络终极指南:MetalLB - 裸金属Kubernetes集群的完美负载均衡解决方案
终极指南:MetalLB 裸金属Kubernetes集群的完美负载均衡解决方案 🚀 MetalLB 是一个专为裸金属Kubernetes集群设计的负载均衡器实
云原生网络
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考