容器网络接口插件
Linkerd installs 可以配置去运行一个 CNI plugin, 该插件自动重写每个 pod 的 iptables 规则。通过 pod 的 linkerd-proxy
容器路由网络流量需要重写 iptables。启用 CNI 插件后,单个 Pod 不再需要包含需要 NET_ADMIN
功能来执行重写的 init 容器。这在集群管理员限制该功能的集群中很有用。
安装
使用 Linkerd CNI 插件需要先在集群上成功安装 linkerd-cni
DaemonSet, 然后再安装 Linkerd 控制平面。
使用 CLI
要安装 linkerd-cni
DaemonSet,请运行:
linkerd install-cni | kubectl apply -f -
一旦 DaemonSet 启动并运行,所有包含 linkerd-proxy
容器(包括 Linkerd 控制平面) 的后续安装都不再需要包含 linkerd-init
容器。init 容器的省略由控制平面安装时的 --linkerd-cni-enabled
标志控制。
安装 Linkerd 控制平面,使用:
linkerd install --linkerd-cni-enabled | kubectl apply -f -
这将在 linkerd-config
ConfigMap 中设置 cniEnabled
标志。所有后续代理注入都将读取此字段并省略 init 容器。
使用 Helm
首先确保您的 Helm 本地缓存已更新:
helm repo update helm search linkerd2-cni NAME CHART VERSION APP VERSION DESCRIPTION linkerd-edge/linkerd2-cni 20.1.1 edge-20.1.1 A helm chart containing the resources needed by the Linke... linkerd-stable/linkerd2-cni 2.7.0 stable-2.7.0 A helm chart containing the resources needed by the Linke...
运行以下命令安装 CNI DaemonSet:
# install the CNI plugin first helm install linkerd2-cni linkerd2/linkerd2-cni # ensure the plugin is installed and ready linkerd check --pre --linkerd-cni-enabled
对于低于 v3 的 Helm 版本,必须专门传递 --name
标志。在 Helm v3 中,它已被弃用,并且是上面指定的第一个参数。
此时,您已准备好在启用 CNI 的情况下安装 Linkerd。您可以按照使用 Helm 安装 Linkerd 来执行此操作。
附加配置
linkerd install-cni
命令包括可用于自定义安装的附加标志。有关更多信息,请参阅 linkerd install-cni --help
。请注意,许多标志类似于运行 linkerd 注入时可用于配置代理的标志。如果在运行 linkerd install-cni
时更改了默认值, 则需要确保在运行 linkerd inject
时进行相应的更改。
最重要的标志是:
--dest-cni-net-dir
: 这是 CNI 配置所在节点上的目录。默认为:/etc/cni/net.d
。--dest-cni-bin-dir
: 这是 CNI 插件二进制文件所在的节点上的目录。默认为:/opt/cni/bin
。--cni-log-level
: 将此设置为debug
将允许更详细的日志记录。要查看 CNI 插件日志,您必须能够查看kubelet
日志。一种方法是登录节点并使用journalctl -t kubelet
。字符串linkerd-cni:
可用作查找插件日志输出的搜索。
升级 CNI 插件
由于 CNI 插件基本上是无状态的,因此不需要单独的 upgrade
命令。如果您使用 CLI 升级 CNI 插件,您可以执行以下操作:
linkerd install-cni | kubectl apply --prune -l linkerd.io/cni-resource=true -f -
请记住,如果您是从实验版本(experimental version)升级插件,则需要卸载并重新安装。
仪表板和 Grafana
除了命令行界面, Linkerd 还提供了一个 Web 仪表板和预配置的 Grafana 仪表板。
要访问此功能,您需要安装 Viz 扩展:
linkerd viz install | kubectl apply -f -
Linkerd 仪表板
Linkerd 仪表板提供实时服务发生情况的高级视图。它可用于查看“黄金”指标(成功率、请求/秒和延迟)、 可视化服务依赖关系并了解特定服务路由的健康状况。拉起它的一种方法是从命令行运行 linkerd viz dashboard
。
Grafana
作为控制平面的一个组件,Grafana 为您的服务提供开箱即用的可操作仪表板。可以查看高级指标并深入了解细节,甚至是 pod。
开箱即用的仪表板包括:
Top Line Metrics
Deployment Detail
Pod Detail
Linkerd Health
分布式追踪
跟踪可以成为调试分布式系统性能的宝贵工具, 尤其是用于识别瓶颈和了解系统中每个组件的延迟成本。Linkerd 可以配置为从代理发出跟踪跨度, 允许您准确查看请求和响应在内部花费的时间。
与 Linkerd 的大多数功能不同,分布式跟踪需要更改代码和配置。
此外,Linkerd 提供了许多通常与分布式跟踪相关的功能,无需配置或应用程序更改,包括:
- 实时服务拓扑和依赖关系图
- 聚合服务运行状况、延迟和请求量
- 聚合 path / route 运行状况、延迟和请求量
例如,Linkerd 可以显示服务的所有传入和传出依赖项的实时拓扑, 而无需分布式跟踪或任何其他此类应用程序修改:
Linkerd 仪表板显示自动生成的拓扑图
同样,Linkerd 可以为每个服务和每个 route 提供黄金指标, 同样不需要分布式跟踪或任何其他此类应用程序修改:
Linkerd 仪表板显示自动生成的路由指标
使用分布式跟踪
也就是说,分布式跟踪肯定有其用途,Linkerd 使这尽可能简单。Linkerd 在分布式跟踪中的作用实际上非常简单:当 Linkerd 数据平面代理(data plane proxy)在代理的 HTTP 请求中 看到跟踪头(tracing header)时, Linkerd 将为该请求发出跟踪范围(trace span)。此跨度将包括有关在 Linkerd 代理中花费的确切时间量的信息。当与软件配合使用来收集、存储和分析这些信息时, 这可以提供对 mesh 行为的重要洞察。
要使用此功能,您还需要引入几个额外的系统中的组件, 包括启动特定请求跟踪的入口层(ingress layer)、 应用程序的客户端库(或传播跟踪头的机制)、 收集跨度数据并将其转换为跟踪的跟踪收集器, 以及跟踪后端存储跟踪数据并允许用户查看/查询它。
故障注入
故障注入是混沌工程的一种形式,通过人为地增加服务的错误率来观察对整个系统的影响。传统上,这需要修改服务的代码,以添加一个执行实际工作的错误注入库。Linkeder 可以做到这一点,而不需要任何服务代码更改,只需要一点配置。
高可用性
对于生产工作负载,Linkerd 的控制平面可以在高可用性 (HA) 模式下运行。这种模式:
- 运行关键控制平面组件的三个副本。
- 在控制平面组件上设置生产就绪(production-ready) CPU 和内存资源请求。
- 在数据平面代理上设置生产就绪的 CPU 和内存资源请求
- 要求 proxy auto-injector 可用于任何要调度的 pod。
- 在关键控制平面组件上设置反关联性策略(anti-affinity policies),
以确保在可能的情况下,默认情况下将它们安排在单独的节点和单独的区域中。
启用 HA
您可以在控制平面安装时使用 --ha
标志启用 HA 模式:
linkerd install --ha | kubectl apply -f -
另请注意,可视化扩展还支持具有类似特征的 --ha
标志:
linkerd viz install --ha | kubectl apply -f -
您可以在安装时通过将其他标志传递给 install
命令来覆盖 HA 行为的某些方面。例如,您可以使用 --controller-replicas
标志覆盖关键组件的副本数:
linkerd install --ha --controller-replicas=2 | kubectl apply -f -
请参阅完整的 install
CLI 文档以供参考。
linkerd upgrade
命令可用于在现有控制平面上启用 HA 模式:
linkerd upgrade --ha | kubectl apply -f -
代理注入器故障策略
HA 代理注入器(proxy injector)部署了更严格的故障策略(failure policy), 以强制执行 automatic proxy injection。此设置可确保在没有 Linkerd 代理的情况下, 不会意外安排带注解的工作负载在您的集群上运行。(当代理注入器关闭时可能会发生这种情况。)
如果在准入阶段由于无法识别或超时错误导致代理注入过程失败, 则工作负载准入将被 Kubernetes API 服务器拒绝,部署将失败。
因此,始终至少有一个运行在集群上的代理注入器的健康副本非常重要。
如果您不能保证集群上健康的代理注入器的数量, 您可以通过将其值设置为 Ignore
来放松 webhook 故障策略,如 Linkerd Helm chart所示。
有关准入 webhook 失败策略的更多信息,请参阅 Kubernetes documentation。
排除 kube-system 命名空间
根据 Kubernetes documentation 的建议,应该为 kube-system
命名空间禁用代理注入器。
这可以通过使用以下标签标记 kube-system
命名空间来完成:
kubectl label namespace kube-system config.linkerd.io/admission-webhooks=disabled
在具有此标签的命名空间中工作负载的准入阶段,Kubernetes API 服务器不会调用代理注入器。
Pod 反关联规则
所有关键控制平面组件都部署了 pod 反关联性(anti-affinity)规则以确保冗余。
Linkerd 使用 requiredDuringSchedulingIgnoredDuringExecution
pod anti-affinity 规则 来确保 Kubernetes 调度程序不会将关键组件的副本并置在同一节点上。还添加了一个 preferredDuringSchedulingIgnoredDuringExecution
pod anti-affinity 规则, 以尝试在可能的情况下在不同区域中安排副本。
为了满足这些反关联(anti-affinity)规则,HA 模式假设 Kubernetes 集群中始终至少有三个节点。如果违反此假设(例如,集群缩小到两个或更少的节点),则系统可能会处于非功能(non-functional
)状态。
请注意,这些反关联性规则不适用于 Prometheus 和 Grafana 等附加组件。
缩放 Prometheus
Linkerd Viz 扩展提供了一个预配置的 Prometheus pod,但对于生产工作负载, 我们建议设置您自己的 Prometheus 实例。
在规划存储 Linkerd 时间序列数据的内存容量时,通常的指导是每个网格 pod 5MB。
如果您的 Prometheus 由于来自数据平面的数据量而遇到定期 OOMKilled
事件, 则可以调整的两个关键参数是:
storage.tsdb.retention.time
定义将采样保留多长时间。更高的值意味着需要更多的内存来将数据保存更长时间。降低此值将减少OOMKilled
事件的数量,因为数据保留的时间较短storage.tsdb.retention.size
定义可以为块存储的最大字节数。较低的值也将有助于减少OOMKilled
事件的数量
使用 Cluster AutoScaler
Linkerd 代理将其 mTLS 私钥存储在 tmpfs emptyDir 卷中, 以确保此信息永远不会离开 pod。这会导致 Cluster AutoScaler 的默认设置无法缩小具有注入工作负载副本的节点。
解决方法是使用 cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
annotation 来注入工作负载。如果您可以完全控制 Cluster AutoScaler 配置, 则可以使用 --skip-nodes-with-local-storage=false
选项启动 Cluster AutoScaler。
多集群通信
Linkerd 可以以安全、对应用程序完全透明且独立于网络拓扑的方式 跨集群边界连接 Kubernetes 服务。这种多集群功能旨在提供:
- 统一的信任域。 在集群边界内和跨集群边界的每一步都验证源和目标工作负载的身份。
- 单独的故障域。 一个集群的故障允许剩余的集群运行。
- 支持异构网络。 由于集群可以跨越云、VPC、本地数据中心及其组合, Linkerd 不会引入除网关连接(gateway connectivity)之外的任何 L3/L4 要求。
- 集群通信中的统一模型。 Linkerd 为集群内通信提供的可观测性(observability)、可靠性(reliability) 和安全特性(security)也扩展到了跨集群通信。
就像集群内连接一样,Linkerd 的跨集群连接对应用程序代码是透明的。无论通信发生在集群内、数据中心或 VPC 内的集群之间, 还是通过公共互联网,Linkerd 都会在集群之间建立连接, 该连接在双方都使用 mTLS 进行加密和身份验证。
工作原理
Linkerd 的多集群支持通过在集群之间“镜像(mirroring)”服务信息来工作。由于远程服务被表示为 Kubernetes 服务, Linkerd 的完整可观察性、安全性和路由功能统一 适用于集群内和集群调用,应用程序不需要区分这些情况。
Linkerd 的多集群功能由两个组件实现:服务镜像(service mirror)和网关(gateway)。服务镜像(service mirror)组件监视目标集群中的服务更新,并在源集群上本地镜像这些服务更新。这提供了对目标集群的服务名称的可见性,以便应用程序可以直接寻址它们。多集群网关组件为目标集群提供了一种从源集群接收请求的方式。(这允许 Linkerd 支持分层网络)
安装这些组件后,可以将与标签选择器(label selector)匹配的 Kubernetes Service
资源导出到其他集群。
服务配置文件
服务配置文件是一种自定义 Kubernetes 资源 (CRD), 可以提供有关服务的 Linkerd 附加信息。特别是,它允许您定义服务的路由列表。每个路由都使用一个正则表达式来定义哪些路径应该与该路由匹配。定义服务配置文件使 Linkerd 能够报告每个路由的指标, 还允许您启用每个路由的功能,例如重试和超时。
如果使用无头服务,则无法检索服务配置文件。Linkerd 根据目标 IP 地址读取服务发现信息, 如果这恰好是 pod IP 地址,则它无法判断 pod 属于哪个服务。
流量拆分(金丝雀、蓝/绿部署)
Linkerd 的流量拆分功能允许您将目的地为 Kubernetes 服务的流量的任意部分动态转移到不同的目的地服务。此功能可用于实施复杂的部署策略,例如 金丝雀部署和 蓝/绿部署, 例如,通过缓慢地将流量从旧版本的服务转移到新版本。
如果使用无头服务,则无法检索流量拆分。Linkerd 根据目标 IP 地址读取服务发现信息, 如果这恰好是 pod IP 地址,则它无法判断 pod 属于哪个服务。
Linkerd 通过 Service Mesh Interface (SMI) TrafficSplit API 公开此功能。要使用此功能,您需要按照 TrafficSplit 规范中的描述创建一个 Kubernetes 资源,Linkerd 负责其余的工作。
通过将流量拆分与 Linkerd 的指标相结合,可以实现更强大的部署技术, 自动考虑新旧版本的成功率和延迟。有关此示例的一个示例,请参阅 Flagger 项目。