在 Azure CNI 中启用 Calico WireGuard
作者:Peter Kelly
译者:Wendi Wang注:本文已取得作者本人的翻译授权!
去年6月,Tigera 宣布首次在 K8s 上支持用于集群内加密传输的开源 VPN - WireGuard 。我们从来不喜欢坐以待毙,所以我们一直在努力为这项技术开发一些令人兴奋的新功能,其中第一个功能是使用 Azure 容器网络接口(CNI)在 Azure Kubernetes 服务(AKS)上支持WireGuard。
首先,这里简单回顾一下什么是 WireGuard 以及我们是如何在 Calico 中使用它的。
WireGuard 是一种 VPN 技术,从 linux 5.6 内核开始默认包含在内核中,它被定位为 IPsec 和 OpenVPN 的替代品。它的目标是更加快速、安全、易于部署和管理。正如不断涌现的 SSL/TLS 的漏洞显示,密码的敏捷性会极大增加复杂性,这与 WireGuard 的目标不符,为此,WireGuard 故意将密码和算法的配置灵活性降低,以减少该技术的可攻击面和可审计性。它的目标是更加简单快速,所以使用标准的 Linux 网络命令便可以很容易的对它进行配置,并且只有约 4000 行代码,使得它的代码可读性高,容易理解、审查。
WireGuard 是一种 VPN 技术,通常被认为是 C/S 架构。它同样能在对等的网格网络架构中配置使用,这就是 Tigera 设计的可以在 Kubernetes 中使用的 WireGuard 解决方案。使用 Calico,将所有启用 WireGuard 的节点相互对等形成一个加密的网格。它甚至支持在同一集群内同时包含启用 WireGuard 的节点与未启用 WireGuard 的节点,并且可以相互通信。

我们选择 WireGuard 并不是一个折中的方案。我们希望提供最简单、最安全、最快速的方式来加密传输 Kubernetes 集群中的数据,mTLS、IPsec 或复杂的配置不是我们想要的。事实上,您可以把 WireGuard 看成是另一个具有加密功能的 overlay。
用户只需一条命令就可以启用 WireGuard,而 Calico 负责完成剩余的工作,包括:
- 在每个节点创建 WireGuard 的网络接口
- 计算编写最优的 MTU
- 为每个节点创建 WireGuard 公钥私钥对
- 向每个节点添加公钥,以便在集群中共享资源
- 将所有节点编辑为对等节点
- 使用防火墙标记(fwmark)编辑 IP route、IP tables和 Routing tables,以此正确处理各自节点上的路由
您仅需指明意图,其他的事情都由集群完成。
使用 WireGuard 时数据包流量的情况
下图显示了启用 WireGuard 后集群中的各种数据包流量情况。

同一主机上的 Pod:
- 数据包被路由到 WireGuard 表。
- 如果目标 IP 是同一主机上的 Pod,则 Calico 将在 WireGuard 路由表中插入一个 “ throw ” 条目,将数据包引导回主路由表。数据包被定向到目标 Pod 的 veth 接口,并且它将在未加密的情况下流动(在图中以绿色显示)。
不同节点上的 Pod:
- 数据包被路由到 WireGuard 表。
- 路由条目与目标 Pod IP 匹配并发送到 WireGuard 组件: cali.wireguard。
- WireGuard 组件加密并封装数据包(在图中以红色显示)并设置 fwmark 以防止路由环路。
- WireGuard 组件使用它与目标 Pod IP(允许的 IP)匹配的对等方的公钥对数据包进行加密,将其封装在 UDP 中,并使用特殊的 fwmark 对其进行标记以防止路由环路。
- 数据包通过 eth0 发送到目标节点并解密。
- 这也适用于主机流量(例如,节点联网的 Pod)。
在以下动画中,您可以看到 3 种流量:
- 同一主机上 Pod 到 Pod 未被加密的流量。
- 不同主机上的 Pod 到 Pod 被加密的流量。
- 主机到主机的流量也会被加密。
注意:绿色表示未加密流量,红色表示加密流量。
WireGuard 在 AKS 中的应用
在 AKS 上使用 Azure CNI 对 WireGuard 的支持带来了一些非常有趣的挑战。
首先,使用 Azure CNI 意味着不使用 Calico IPAM( IP 地址管理)管理 CIDR(无类域间路由)块分配的 Pod IP 。相反,它们是采用节点IP相同的分配方式从底层 VNet 分配的。这对 WireGuard 路由来说是一个有趣的挑战,以往我们可以在 WireGuard 配置中的 Allowed IPs 列表中添加一个 CIDR 块,相比之下,我们现在必须写出该节点所有 Pod IP。这需要 Calico 将 routeSource 的配置设为 workloadIPs。如果您使用的是 AKS 集群进行部署,便无需额外配置。
使用 wireguard-tools 中优秀的工具 wg,可以查看集群内节点允许通过的 IP 列表,其中包括每个节点的 Pod IP 和主机 IP(注意终端 IP也在允许 IP 列表中)。在 AKS 上提供了业务流量加密和主机到主机的加密。
interface: wireguard.cali
public key: bbcKpAY+Q9VpmIRLT+yPaaOALxqnonxBuk5LRlvKClA=
private key: (hidden)
listening port: 51820
fwmark: 0x100000
peer: /r0PzTX6F0ZrW9ExPQE8zou2rh1vb20IU6SrXMiKImw=
endpoint: 10.240.0.64:51820
allowed ips: 10.240.0.64/32, 10.240.0.65/32, 10.240.0.66/32
latest handshake: 11 seconds ago
transfer: 1.17 MiB received, 3.04 MiB sent
peer: QfUXYghyJWDcy+xLW0o+xJVsQhurVNdqtbstTsdOp20=
endpoint: 10.240.0.4:51820
allowed ips: 10.240.0.4/32, 10.240.0.5/32, 10.240.0.6/32
latest handshake: 46 seconds ago
transfer: 83.48 KiB received, 365.77 KiB sent
第二个挑战是正确处理 MTU(最大传输单元)。Azure 设置的 MTU 是 1500,而 WireGuard 在数据包上设置了一个 DF(Don't Fragment)标记。如果没有正确调整 WireGuard MTU,我们会在启用 WireGuard 时发现有丢包和低带宽。我们可以在 AKS 中通过Calico 自动检测并为 WireGuard 的 MTU 设置正确的开销来优化。
我们还可以将节点 IP 本身添加为对等节点允许通信的 IP ,并通过 AKS 中的 WireGuard 处理主机联网的 Pod 和主机到主机通信。主机到主机通信的方法是,当 RPF(反向路径转发)发生时,通过 WireGuard 接口获得路由返回的响应。通过在发送到目的节点的数据包上设置一个标记,然后配置内核以尊守 sysctl 中的 RPF 标记来解决这个问题。
现在您使用AKS时,节点之间的业务流量和主机到主机通信都会被加密。您仅需指明意图,其他的事情都由集群完成。
本文由博客一文多发平台 OpenWrite 发布!
在 Azure CNI 中启用 Calico WireGuard的更多相关文章
- 【Azure Application Insights】在Azure Function中启用Application Insights后,如何配置不输出某些日志到AI 的Trace中
问题描述 基于.NET Core的Function App如果配置了Application Insights之后,每有一个函数被执行,则在Application Insights中的Logs中的tra ...
- 使用Azure Functions 在web 应用中启用自动更新(一)分析基于轮询的 Web 应用的限制
1,引言 上一篇介绍了使用使用 Visual Studio 开发 "Azure Functions" 函数,此篇介绍 “Azure Functions” 的测试以及直接从 Vist ...
- 运行预构建 Linux 映像的 Windows Azure 虚拟机中的交换空间 – 第 1 部分
本文章由 Azure CAT 团队的 Piyush Ranjan (MSFT) 撰写. 随着基础结构服务(虚拟机和虚拟网络)近期在 Windows Azure 上正式发布,越来越多的企业工作负荷正在向 ...
- 探索 Windows Azure 网站中的自动伸缩功能
去年10月,我们发布了若干针对 WindowsAzure平台的更新,其中一项更新是添加了基于日期的自动伸缩调度支持(在不同的日期设置不同的规则). 在这篇博客文章中,我们将了解自动伸缩的概念,并 ...
- 在 Windows Azure 网站中配置动态 IP 地址限制
我们最近对 Windows Azure 网站进行了升级,并启用了IIS8的动态 IP 限制模块.现在,开发人员可以为其网站启用并配置动态 IP 限制功能(或简称 DIPR). 可以通过以下链接查看此 ...
- 如何将Azure DevOps中的代码发布到Azure App Service中
标题:如何将Azure DevOps中的代码发布到Azure App Service中 作者:Lamond Lu 背景 最近做了几个项目一直在用Azure DevOps和Azure App Servi ...
- Azure 应用服务中的 API 应用、ASP.NET 和 Swagger 入门
学习内容: 如何通过 Visual Studio 2015 中的内置工具在 Azure 应用服务中创建和部署 API 应用. 如何使用 Swashbuckle NuGet 包动态生成 Swagger ...
- 在 Azure 虚拟机中配置 Always On 可用性组(经典)
在开始之前,请先假设现在可以在 Azure Resource Manager 模型中完成此任务. 我们建议使用 Azure Resource Manager 模型来进行新的部署. 请参阅 Azure ...
- 在 ASP.NET Core 中启用跨域请求(CORS)
本文介绍如何在 ASP.NET Core 的应用程序中启用 CORS. 浏览器安全可以防止网页向其他域发送请求,而不是为网页提供服务. 此限制称为相同源策略. 同一源策略可防止恶意站点读取另一个站点中 ...
- 【应用程序见解 Application Insights】使用Azure Monitor Application Insights Agent获取Azure VM中监控数据及IIS请求指标等信息
问题情形 为了使用Application Insights也可以监控Azure VM中的相关性能数据,如CPU, Memory,IIS Reuqest等信息,可以在VM中开始一个一个扩展插件: Azu ...
随机推荐
- MySQL 是如何实现数据的排序的?
1.背景 或许你面试的时候被问到了mysql的排序问题 又或许你在学习排序算法的时候想到了数据库的排序是如何实现的呢 下面重点从面试的角度来回答这个问题 2.面试回答 1.普通面试者回答 普通面试者的 ...
- 如何在通用异常处理时获取到方法名称(获取注解参数JoinPoint)
1.背景 很多时候我们在梳理公共异常时,需要获取到接口的而具体名称,便于很好的提示是那个接口错误了 2.实现逻辑 1.在controller方法上的注解上写方法名称,一般使用了swagger都有方法名 ...
- 2.6倍!WhaleTunnel 客户POC实景对弈DataX
作为阿里早期的开源产品,DataX是一款非常优秀的数据集成工具,普遍被用于多个数据源之间的批量同步,包括类似Apache DolphinScheduler的Task类型也对DataX进行了适配和增强, ...
- 利用标准IO函数接口实现文件拷贝
把本地磁盘的文件A中的数据完整的拷贝到另一个文本B中,如果文本B不存在则创建,要求文本A的名称和文本B的名称通过命令行传递,并进行验证是否正确. /************************** ...
- 阿里云 CLI 使用
安装 macOS: brew install aliyun-cli Linux: wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-a ...
- springboot 大文件切片上传
1. 前端(vue element ui & 原生) 初始变量声明: currentFile: {}, // 当前上传的文件 bigFileSliceCount: 20, // 大文件切片后的 ...
- SQL Server磁盘空间清理 【转】
SQL Server在删除数据后,会重新利用这部分空间,所以如果不是空间紧张的情况下,可以不回收.回收一般先回收日志文件,因为这个回收速度非常快,可以短时间内清理出一部分可用空间.回收步骤: 1.查看 ...
- 注册中心Nacos集群搭建
一提到注册中心,大家往往想到Zookeeper.或者Eureka.今天我们看看阿里的一款配置中心+注册中心的中间件--Nacos.有了它以后,我们的项目中的配置就可以统一从Nacos中获取了,而且Sp ...
- 游戏AI寻路——八叉树+A*寻路
利用八叉树的空中寻路 你有思考过在空中如何进行寻"路"吗?来想象一个的场景:飞机从空中基地出发,要避开许多空中建筑,最终到达目的地.这种情况下的寻路是没有路面的,寻路物体的移动方向 ...
- 全网最适合入门的面向对象编程教程:47 Python函数方法与接口-回调函数Callback
全网最适合入门的面向对象编程教程:47 Python 函数方法与接口-回调函数 Callback 摘要: 回调函数是编程中一种非常常见的模式,用于将函数作为参数传递给其他函数或方法.这种模式在 Pyt ...