WireGuard 系列文章(八):基于 WireGuard 的 K8S CNI Kilo 简介

简介: WireGuard 系列文章(八):基于 WireGuard 的 K8S CNI Kilo 简介

接下来介绍 WireGuard 和 Kubernetes 的整合 – 一个基于 WireGuard 的 K8S 网络插件 – Kilo。

Kilo 是一个建立在 WireGuard 上的 多云 overlay 网络,专为 Kubernetes 设计。

Kilo 概述

Kilo 通过提供一个加密的 三层网络 来连接集群中的节点,该 网络可以跨越数据中心和公共云。由 Kilo 创建的 Pod 网络总是完全连接的,即使节点在不同的网络中或在 NAT 后。通过允许不同位置的节点池安全地通信,Kilo 可以实现多云集群的操作。Kilo 的设计允许客户端通过 VPN 连接到集群,以便安全地访问集群上运行的服务。除了创建多云集群(即一个集群跨越多朵公有云),Kilo 还支持创建多集群服务,即跨不同 Kubernetes 集群的服务。

Kilo 工作原理

Kilo 使用 WireGuard 在集群中的不同节点之间创建一个网格(mesh)。

Kilo agent(kg) 运行在集群中的每个节点上,为 VPN 设置公钥和私钥,以及在位置之间路由数据包所需的规则。

Kilo 既可以作为一个完整的、独立的 K8S 网络插件,也可以作为目前安装在集群上的集群网络解决方案的补充。这意味着,如果集群使用 Flannel 进行网络连接,那么可以将 Kilo 安装在集群顶部,以使位于不同位置(location,如不同的云)的节点池能够连接;Kilo 负责各 location 之间的网络,Flannel 负责各 location 内的网络。

Kilo Annotions

Kilo 安装在 K8S 集群后,通过 K8S Node 的 Annotations(注释) 来实现相应的配置。

以下注释可以添加到任何 Kubernetes Node 对象,以配置 Kilo 网络。

Name type examples
kilo.squat.ai/force-endpoint host:port 55.55.55.55:51820, example.com:1337
kilo.squat.ai/force-internal-ip CIDR 55.55.55.55/32, "-",""
kilo.squat.ai/leader string "", true
kilo.squat.ai/location string gcp-east, lab
kilo.squat.ai/persistent-keepalive uint 10
kilo.squat.ai/allowed-location-ips CIDR 66.66.66.66/32

force-endpoint

为了在位置(location)之间创建链接,Kilo 要求每个位置至少有一个节点有一个端点(就是公网地址 + 端口),即 host:port 组合,可以从其他位置路由。如果位置在不同的云提供商或不同的私有网络中,那么端点的主机部分应该是一个公开可访问的 IP 地址,或一个解析为公共 IP 的 DNS 名称,以便其他位置可以将包路由到它。运行在每个节点上的 Kilo 代理将使用启发式来自动检测节点的外部 IP 地址,并正确配置其端点;然而,在某些情况下,可能需要显式地配置端点以使用,例如:

  • 在网卡上没有自动的公共 IP: 在一些云提供商上,通常为节点分配一个公共 IP 地址,但为网卡只自动配置私有网络地址;在这种情况下,应该指定分配的公网 IP 地址;(国内公有云都是这种情况,所以在国内公有云上使用 Kilo,一定要配置 force-endpoint
  • 多个公网 IP 地址: 如果一个节点有多个公网 IP 地址,但有一个是首选 IP 地址,则指定首选 IP 地址;
  • IPv6: 如果一个节点有公共 IPv4 地址和 IPv6 地址,并且 Kilo 网络应该在 IPv6 上运行,那么应该指定 IPv6 地址;
  • 动态 IP 地址: 如果一个节点有一个动态分配的公网 IP 地址,例如一个从网络提供商租用的 IP,那么可以给出一个动态 DNS 名称。
  • 覆盖端口: 如果一个节点应该监听一个特定的端口,这个端口不同于网格默认的 WireGuard 端口(比如:52181),那么这个注释可以用来覆盖端口;这可能很有用,例如,可以确保在同一个端口转发 NAT 网关后运行的两个节点可以分别分配不同的端口。

force-internal-ip

Kilo 使用节点的内部 IP 地址将数据包发送到同一逻辑位置的节点。运行在每个节点上的 Kilo 代理将使用启发式来自动检测该节点的私有 IP 地址;然而,在某些情况下,可能需要显式地配置 IP 地址,例如:

  • 多个私有 IP 地址: 如果一个节点有多个私有 IP 地址,但有一个是首选 IP 地址,则需要指定首选 IP 地址(典型如一个私有 IP 用于业务,一个私有 IP 用于存储;或者是在本地虚拟机环境下,一个私有 IP 是 Host,一个私有 IP 是 NAT);
  • IPv6: 如果一个节点同时拥有私有 IPv4 和 IPv6 地址,且 Kilo 网络运行在 IPv6 上,则应指定 IPv6 地址。
  • 使用“-”或“”禁用私网 IP: 节点有私网地址和公网地址,但忽略该私网地址。

leader

默认情况下,Kilo 在数据中心粒度上创建一个网络网格。这意味着从每个位置选择一个领导节点作为边缘服务器,并作为到其他位置的网关;网络拓扑结构将是 leader 之间的 full mesh。Kilo 以稳定和确定的方式自动为每个位置选择 leader,以避免网络配置中的混乱,同时优先考虑已知拥有公共 IP 地址的节点。在某些情况下,手动选择一个位置的 leader 可能是可取的,例如:

  • 防火墙: Kilo 需要一个开放的 UDP 端口,默认为 51820,以在位置之间进行通信;如果只有一个节点被配置为开放该端口,那么该节点应该被给予 leader 注释;
  • 带宽: 如果集群中的某些节点有更高的带宽或更低的延迟 Internet 连接,那么这些节点应该被给予 leader 注释。

Note:

在一个位置内的多个节点可以被给予 leader 注释;在这种情况下,Kilo 将从一组注释节点中选择一个 leader。

location

Kilo 允许位于不同逻辑或物理位置的节点相互路由数据包。为了知道要创建什么连接,Kilo 需要知道每个位置上有哪些节点。Kilo 会试图从拓扑结构 topology.kubernetes.io/region label 中推断出每个节点的位置。如果节点没该有标签,例如运行裸金属集群或在不受支持的云提供商(或自己搭建的 K8S 集群)上,则应该指定位置注释。

Note:

所有没有定义位置的节点将被认为处于默认位置""

persistent-keepalive

在某些部署中,集群节点可能位于 NAT 或防火墙 后面,例如位于普通路由器后面的边缘节点。在这种情况下,NAT 转换后的节点可以向 NAT 转换后的网络之外的节点发送报文,但是外部的节点只有在 NAT 映射有效的情况下才能向 NAT 转换后的网络发送报文。为了让 NAT 后的节点接收到来自 NAT 后网络之外的节点的报文,它必须通过定期向这些节点发送报文(即发送 keepalive 报文)来维护 NAT 映射关系。这些 keepalive 报文的发送频率可以通过在 NAT 后的节点上设置 persistent-keepalive 注释来控制。被注释的节点将使用指定的值作为其所有对等体的 persistent-keepalive 间隔,请参阅 WireGuard 文档中的 NAT 和防火墙穿越

allowed-location-ips

通过注释位置中的任何节点,可以将 allowed-location-ips 添加到位置。在一个位置添加允许的位置 ip,使得这些 ip 也可以从其他位置路由。

在一个有两个位置 A 和 B 的 Kilo 部署示例中,可以从位置 B 的节点和 pod 访问位置 A 的打印机。此外,Kilo Peers 可以使用位置 A 的打印机。

附加模式

现有集群的管理员如果不希望改变现有的网络解决方案,可以以附加模式运行 Kilo。

在这种模式下,Kilo 将向集群添加高级特性,如 VPN 和多集群服务,同时将 CNI 管理和本地网络委托给集群的当前网络提供商。Kilo 目前支持在 flannel 上运行。

例如,要在运行 Flannel 的 Typhoon 集群上运行 Kilo:

kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/crds.yaml
kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/kilo-typhoon-flannel.yaml
BASH

VPN

Kilo 还允许 Kubernetes 集群外的对等体(peer)连接到该 VPN,允许集群应用程序安全地访问外部服务,并允许开发人员和支持人员安全地调试集群资源。

为了声明一个对等点,首先定义一个 Kilo peer 资源:

cat <<'EOF' | kubectl apply -f -
apiVersion: kilo.squat.ai/v1alpha1
kind: Peer
metadata:
  name: squat
spec:
  allowedIPs:
  - 10.5.0.1/32
  publicKey: GY5aT1N9dTR/nJnT1N2f4ClZWVj0jOAld0r8ysWLyjg=
  persistentKeepalive: 10
EOF
BASH

这个配置可以应用到本地的 WireGuard 接口,例如 wg0,让它在kgctl 工具的帮助下访问集群:

kgctl showconf peer squat > peer.ini
sudo wg setconf wg0 peer.ini
BASH

Kilo 网络分析

可以使用 kgctl命令行工具分析 Kilo 网络的拓扑和配置。

例如,可以使用 graph 命令生成 Graphviz 格式的网络图:

kgctl graph | circo -Tsvg > cluster.svg
BASH

image.png 示例 Kilo 网络拓扑

Kilo 网络拓扑

Kilo 允许定制加密网络的拓扑结构。集群管理员可以指定加密的网络应该是每个节点之间的 full mesh,还是应该是直接相互通信的不同节点池之间的网格。这使得加密网络可以服务于几个目的,例如:

  • 在拥有不安全私有网络的云提供商上,可以在节点之间创建一个完整的网格,以保护所有集群流量;
  • 运行在不同云提供商中的节点可以通过在两个云之间创建一条链接而加入到单个集群中(这也是后面要实战的主要内容);
  • 更普遍的是,不安全的链接可以被加密,而安全的链接可以保持快速且未封装。

Logical Groups 逻辑组

默认情况下,Kilo 在集群中的不同逻辑位置之间创建一个网格,例如数据中心、云提供商等。Kilo 会利用 kubernetes 拓扑 topology.kubernetes.io/region label 推断节点的位置。此外,Kilo 支持通过设置命令行标志 --topology-label=<label> 来使用自定义拓扑标签。如果这个标签没有设置,那么可使用 kilo.squat.ai/location 标注。 例如,为了将谷歌 Cloud 和 AWS 中的节点连接到一个单独的集群中,管理员可以使用下面的代码片段在名称中对所有具有 GCP 的节点进行注释:

for node in $(kubectl get nodes | grep -i gcp | awk '{print $1}'); do 
    kubectl annotate node $node kilo.squat.ai/location="gcp"; 
done
BASH

在这种情况下,Kilo 会这么做:

  • 将所有带有GCP annotion 的节点分组到一个逻辑位置;
  • 分组所有没有标注的节点将被分组到默认位置;和
  • 在每个 location 选出一个 leader,并在他们之间建立联系。

使用 kgctl 分析集群将产生如下结果:

kgctl graph | circo -Tsvg > cluster.svg

image.png Kilo 网络拓扑模型 - Point-to-point

Full Mesh

创建一个 full mesh 是逻辑网格的逻辑简化,其中每个节点都在自己的组中。Kilo 以命令行标志的形式为这个拓扑提供了一个快捷方式:--mesh-granularity=full. 当指定了 full mesh 粒度时,Kilo 将网络配置为所有节点间的流量都使用 WireGuard 加密。

使用 kgctl 分析集群将产生如下结果:

kgctl graph | circo -Tsvg > cluster.svg

image.png Kilo 网络拓扑模型 - FullMesh

混合

kilo.squat.ai/location 标注可以将一些 full mesh 节点和一些按逻辑位置分组的节点混合在一起。例如,如果一个集群包含一组节点在谷歌云计算和没有安全的私有网络的一组节点,例如一些裸露的金属节点,然后在谷歌云节点可以放置在一个逻辑组,而裸金属节点可以形成一个完整的网。 这可以通过运行以下命令来实现:

for node in $(kubectl get nodes | grep -i gcp | awk '{print $1}'); do kubectl annotate node $node kilo.squat.ai/location="gcp"; done
for node in $(kubectl get nodes | tail -n +2 | grep -v gcp | awk '{print $1}'); do kubectl annotate node $node kilo.squat.ai/location="$node"; done
BASH

使用 kgctl 分析集群将产生如下结果:

kgctl graph | circo -Tsvg > cluster.svg

image.png Kilo 网络拓扑模型 - 混合网络 1

如果集群在 AWS 中也有节点,那么可以使用以下代码片段:

for node in $(kubectl get nodes | grep -i aws | awk '{print $1}'); do kubectl annotate node $node kilo.squat.ai/location="aws"; done
for node in $(kubectl get nodes | grep -i gcp | awk '{print $1}'); do kubectl annotate node $node kilo.squat.ai/location="gcp"; done
for node in $(kubectl get nodes | tail -n +2 | grep -v aws | grep -v gcp | awk '{print $1}'); do kubectl annotate node $node kilo.squat.ai/location="$node"; done
BASH

这反过来会生成如下图表:

kgctl graph | circo -Tsvg > cluster.svg

image.png 网络拓扑模型 - 混合网络 2

总结

Kilo 是一个建立在 WireGuard 上的 多云 overlay 网络,专为 Kubernetes 设计。通过它,可以在多云上建立一个快速、现代、安全的 K8S 集群。🎉🎉🎉

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
6月前
|
Kubernetes 应用服务中间件 API
kubernetes系列文章第二篇-kubectl
kubernetes系列文章第二篇-kubectl
|
6月前
|
存储 Kubernetes 微服务
kubernetes简介-这是一篇学习k8s必看的文章
kubernetes简介-这是一篇学习k8s必看的文章
|
2月前
|
JSON Kubernetes 数据格式
Grafana 系列文章(十三):如何用 Loki 收集查看 Kubernetes Events
Grafana 系列文章(十三):如何用 Loki 收集查看 Kubernetes Events
|
2月前
|
Kubernetes 网络协议 网络虚拟化
WireGuard 系列文章(九):基于 K3S+WireGuard+Kilo 搭建跨多云的统一 K8S 集群
WireGuard 系列文章(九):基于 K3S+WireGuard+Kilo 搭建跨多云的统一 K8S 集群
|
6月前
|
存储 Kubernetes 持续交付
kubernetes系列文章第一篇-k8s基本介绍
kubernetes系列文章第一篇-k8s基本介绍
|
9月前
|
消息中间件 Kubernetes Kafka
一篇文章让你学会K8s软件安装神器Helm
下平时OS安装软件时为什么需要yum安装你可以类比到在k8s中安装 软件为什么需要helm。
194 0
|
Kubernetes 前端开发 JavaScript
一篇文章带你入门K8S二次开发
我们经常会在网上看到K8S和周边工具的教程,例如HELM的使用,droneCI的使用,但是很少有文章写,如何基于K8S进行二次开发,本篇文章将使用python和vue进行K8S的二次开发,实现一个简单的查询k8s的pod和node信息的页面
7106 0
一篇文章带你入门K8S二次开发
|
存储 Kubernetes Cloud Native
重磅合集 | 31 篇技术文章,带你从零入门 K8s (留言赠书)
由阿里云与 CNCF 共同开发的《CNCF x Alibaba 云原生技术公开课》(视频课程)第一期已更新完毕。本文整理了全部课程文章 31 篇,期待给正在学习 Kubernetes 的同学提供一些参考。
12810 0
重磅合集 | 31 篇技术文章,带你从零入门 K8s (留言赠书)
|
存储 JSON 运维
系列文章:Kubernetes日志采集最佳实践
在Kubernetes中,日志采集和普通虚拟机的方式有很大不同,相对实现难度和部署代价也略大,但若使用恰当则比传统方式自动化程度更高、运维代价更低。本期将为大家介绍如何正确的进行Kubernetes的日志采集。
6073 0
|
29天前
|
Prometheus 监控 Kubernetes
Kubernetes 集群监控与日志管理实践
【2月更文挑战第29天】 在微服务架构日益普及的当下,Kubernetes 已成为容器编排的事实标准。然而,随着集群规模的扩大和业务复杂度的提升,有效的监控和日志管理变得至关重要。本文将探讨构建高效 Kubernetes 集群监控系统的策略,以及实施日志聚合和分析的最佳实践。通过引入如 Prometheus 和 Fluentd 等开源工具,我们旨在为运维专家提供一套完整的解决方案,以保障系统的稳定性和可靠性。

推荐镜像

更多