Retina——微软开源的eBPFK8S网络测控工具

安全运维得看我 2024-04-03 03:21:56

随着eBPF技术的发展,基于该技术的网络测控工具越来越多,也越来越成熟。作为下一代网络测控技术,eBPF直接内嵌Linux内核,具有高性能、高扩展、安全性等优势,在网络、安全、可观察方面均堪大用。

在容器云为基础的现代系统架构中,eBPF技术尤其具有重要意义,同时也已经出现了Cilium(CNCF云原生项目,用于解决大集群规模下iptables性能问题)、Pixie等优秀的开源项目。

今天我们介绍一个同类的项目Retina(视网膜),这是由微软开源,使用Golang语言开发的K8S网络测控系统

概述

Retina是一个与云无关的开源K8S网络可观察性平台,可以用来解决容器云平台中DevSecOps下网络流量的安全管控和合规性等问题。Retina提供了一个用于监控应用程序和网络健康与安全的集中中心,满足集群网络管理员、集群安全管理员和DevOps工程师的需求。

Retina收集可自定义的遥测数据,并且支持将其存储到无服务器架构中自建Prometheus中心,以及公有云存储中(例如Azure Monitor和其他SaaS产品),并以Grafana等多种界面展示和可视化,比如Azure Log Analytics和其他SaaS产品)。

特征

网络流量洞察;

基于先进的eBPF技术;

按需且可配置,支持自定义指标和流日志;

支持分布式数据包捕获;

云原生支持,可以适用于任何CNI和任何K8S平台。

支持多种操作系统(如 Linux、Windows、Azure Linux)。

典型用例

Retina可以实时高效的测控和捕获平台网络情况,可以最大限度地减少网络相关故障排查痛点和调查时间,典型的应用场景有:

调试网络连接

为什么Pod无法相互连接?传统的排查方法耗时耗力,涉及执行数据包捕获,其中必须识别所涉及的节点,获得对每个节点的访问权限,运行tcpdump命令,并导出每个节点的结果,然后人为分析。

借助Retina,可以用单个CLI命令或CRD/YAM自动执行该过程,实现:

捕获集群中特定Pod的所有节点上网络流量。

将每个节点的结果上传到存储blob。

监控网健康状况

Retina通过Prometheus告警、Grafana仪表板等,可实现:

监视命名空间中丢弃的流量。

针对生产DNS错误激增发出警报。

在测试应用程序的规模时观察API服务器延迟的变化。

针对Pod发送超阈值(低于)的流量,给值守团队发出告警。

基本架构

Retina使用两种类型的遥测:指标和捕获。

指标

Retina提供了丰富的持续可观察性指标:

上行/下行网络流量;

丢包;

TCP/UDP;

域名系统;

API服务器延迟;

节点/接口统计;

同时提供还支持对这些指标:

基本指标(默认,节点级指标)求和。

高级/Pod级指标 (详见文档)。

捕获

Retina捕获记录指定Nodes/Pod的网络流量和元数据。捕获是按需的,并且可以输出到多个目的地。

安装配置安装make helm-install

基本模式(支持捕获)

make helm-install-with-operator

具有远程上下文的高级模式(支持捕获)

make helm-install-advanced-remote-context

具有本地上下文的高级模式(支持捕获)

配置

自建Prometheus/Grafana

创建 K8S 集群并安装Retina DaemonSet,安装需要通过Helm Chart 安装Prometheus。

helm repo add prometheus-community prometheus-community.github.io/helm-chartshelm repo update

安装Prometheus图表

helm install prometheus -n kube-system -f deploy/prometheus/values.yaml prometheus-community/kube-prometheus-stack

或者,如已经安装,请升级认为合适的方式,提供新的作业名称作为附加的抓取配置,例如:

helm upgrade prometheus -n kube-system -f deploy/prometheus/values.yaml prometheus-community/kube-prometheus-stack

节点Grafana和 ube-state指标可能会在Windows节点上调度,当前图表与这些组件没有节点关联性。可能需要一些手动干预。

验证Retina Pod是否正在通过端口转发Prometheus服务器进行抓取:

kubectl port-forward --namespace kube-system svc/prometheus-operated 9090

浏览器访问localhost:9090/targets查看Retina Pod是否被发现并被抓取

配置Grafana

创建一个Grafana实例,然后按照配置Grafana进行操作,或者上面步骤安装的实例。获取Grafana密码:

kubectl get secret -n kube-system prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

导入新的仪表板18814-kubernetes-networking-clusters。如果导入成功,则指标应该可见:

对于自建Prometheus/Grafana或确保可将服务器端口转发到localhost:9090,或者为其他 HTTP 端点配置服务器。端口转发 svc/prometheus-grafana以从本地浏览器访问。

检查Grafana 以确保托管Prometheus数据源存在:

进入仪表板页面并选择“导入”:

导18814-kubernetes-networking-clusters仪表板

Grafana仪表板现在应该可见。

仪表板的版本将预安装在以下位置:

仪表板 > 托管Prometheus > K8S/网络/集群

仪表板 > 托管Prometheus > K8S / 网络 / DNS

基本用法

Retina捕获允许用户按需捕获指定节点/Pod的网络流量/元数据,结果可以输出到主机文件系统、存储blob等。有两种触发 Capture 的方法:CLI命令或CRD/YAML配置。

CLI命令

安装Retina CLI后可用,目前仅支持Linux操作系统。典型的一个实例是:

捕获所有Linux节点的网络流量,将输出存储在每个节点上的/mnt/capture文件夹中。

kubectl-retina capture create --host-path /mnt/capture --node-selectors "K8S.io/os=linux"

对于每个Capture,都会为每个相关节点创建一个K8S作业(可以选择该节点和/或可以托管选定的 Pod)。作业的工作Pod运行指定的持续时间,捕获网络信息并将其包装到tarball中,并将tarball复制到指定的输出位置。作为一种特殊情况,出于安全考虑,将创建一个包含存储blob SAS的K8S密钥,然后将其挂载到Pod。

为每个Retina Capture分配一个随机散列名称以对其进行唯一标记。

捕获CRD

创建Capture并将Capture项目存储到Blob SAS URL指定的存储帐户中。

创建一个Secret来存储blob SAS URL:

apiVersion: v1data:## Data key is required to be "blob-upload-url"blob-upload-url: <based-encode-blob-sas-url>kind: Secretmetadata:name: blob-sas-urlnamespace: defaulttype: Opaque

创建一个Capture,指定创建为blobUpload的密钥,该例还将工件存储在节点主机路径上

apiVersion: retina.sh/v1alpha1kind: Capturemetadata:name: capture-testspec:captureConfiguration:captureOption:duration: 30scaptureTarget:nodeSelector:matchLabels:K8S.io/hostname: aks-nodepool1-11396069-vmss000000outputConfiguration:hostPath: "/tmp/retina"blobUpload: blob-sas-url

与1类似,为每个相关节点创建一个K8S作业。

Retina CLI捕获详解

Retina capture命令允许用户捕获目标的网络流量和元数据,然后将捕获文件发送到输出配置的位置。也可以使用Capture CRD后执行捕获。

创建捕获

retina capture create使用底层K8S作业创建捕获。

非等待(--no-wait)

不要等待长时间运行的捕获作业完成。默认情况下为-no-wait=false,Retina capture CLI将在作业完成之前退出。CLI将等待作业完成并清理创建的K8S 资源。

非等待长时间运行的捕获作业完成:

kubectl retina capture create --host-path /mnt/capture --node-selectors "K8S.io/os=linux" --no-wait=true

命名空间(--namespace)

托管捕获作业的命名空间和用于网络捕获的其他k8s资源。

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux"捕获目标

捕获目标表示将执行网络数据包捕获的目标,用户可以通过节点选择器或节点名称选择节点,也可以通过pod选择器和命名空间选择器对选择Pod。

捕获节点选择器选择的节点上的网络数据包:

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux"

捕获按节点名称选择的节点上的网络数据包:

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-names "aks-nodepool1-41844487-vmss000000,aks-nodepool1-41844487-vmss000001"

捕获pod选择器和命名空间选择器对选择的pod上的网络数据包:

kubectl retina capture create --host-path /mnt/capture --namespace capture --pod-selectors="k8s-app=kube-dns" --namespace-selectors="K8S.io/metadata.name=kube-system"停止捕获

可以通过以下任一方式停止捕获:在给定的时间内,由duration标志,或者当允许的最大捕获文件达到max-size。当两者都指定时,捕获将在任一条件首次满足时停止。根据需要,在满足指定条件之前删除捕获。网络流量将上传到指定的输出位置。

捕捉持续时间(--duration)

抓包时长(默1m),例2分钟后停止捕捉:

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux" --duration=2m

最大捕获尺寸(--max-size)

将捕获文件的大小限制为 MB(默认100MB):当捕获文件大小达到50MB时停止捕获:

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux" --max-size=50

数据包大小(--packet-size)

将每个数据包的大小限制为字节,超过PacketSize的数据包将被截断:将每个数据包大小限制为96字节

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux" --packet-size=96捕获配置

captureconfiguration表示网络抓包的具体配置。

数据包捕获过滤器(--include-filter,--exclude-filter)

数据包捕获过滤器表示捕获中要包含/排除的一系列过滤器:

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux" --exclude-filter="10.224.0.26:80,10.224.0.33:8080" --include-filter="10.224.0.42:80,10.224.0.33:8080"

TCP转储过滤器(--tcpdump-filter)

原始tcpdump标志仅适用于Linux。可以在TCPDUMP手册页中找到可用的 tcpdump过滤器。注意:这仅包括tcpdump标志,对于表达式部分,请使用数据包包含/排除过滤器。例如:过滤 DNS 查询

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux" --tcpdump-filter="udp port 53"

包括元数据(--include-metadata)

如果为true,则将静态网络元数据收集到捕获文件中(默认 true),禁用收集网络元数据:

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux" --include-metadata=false

作业数量限制(--job-num-limit)

每次捕获可以创建最大数量的作业 默认值0表示没有限制。这可以通过每个 CLI 命令的 CLI 标志或 retina-operator 使用的配置映射进行配置。当创建作业需要作业数量超过此限制时,会失败并提示如下 Error: the number of capture jobs 3 exceeds the limit 2。

kubectl retina capture create --job-num-limit=10 --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux"输出配置

OutputConfiguration 指示将存储捕获的位置,并且应至少指定一个位置。 Blob上传需要具有存储帐户容器写入权限的Blob共享访问签名,需要配置对应的密钥和证书等。

将捕获文件存储在节点主机路径中/mnt/capture

kubectl retina capture create --host-path /mnt/capture --namespace capture --node-selectors "K8S.io/os=linux"

将捕获文件存储到PVC mypvc命名空间中的访问模式为ReadWriteMany capture

kubectl retina capture create --pvc mypvc --namespace capture --node-selectors "K8S.io/os=linux"

将捕获文件存储到云存储帐户

kubectl retina capture create --blob-upload <Blob SAS URL with write permission> --node-selectors "K8S.io/os=linux"调试模式

在调试模式下,当--debug指定后,可以覆盖官方默认的抓包作业Pod镜像 GHCR一。

使用ghcr.io默认调试模式下的镜像

kubectl retina capture create --host-path /mnt/test --namespace capture --node-selectors "K8S.io/os=linux" --debug

使用定制的retina代理镜像

RETINA_AGENT_IMAGE=<YOUR RETINA AGENT IMAGE> kubectl retina capture create --host-path /mnt/test --namespace capture --node-selectors "K8S.io/os=linux" --debug删除捕获

retina capture delete删除具有指定Capture名称的K8S作业:

kubectl retina capture delete --name retina-capture-zlx5v捕获列表

retina capture list列出命名空间或所有命名空间中的捕获。

列出命名空间下的捕获

kubectl retina capture list --namespace capture

列出所有命名空间下捕获

kubectl retina capture list --all-namespaces获取输出

从指定位置下载或复制tarball后,通过tarLinux shell或 Windows Powershell 中的命令,例如,

tar -xvf retina-capture-aks-nodepool1-41844487-vmss000000-20230320013600UTC.tar.gz

tarball 采用这样的名称模式,$(capturename)-$(hostname)-$(date +%Y%m%d%H%M%S%Z).tar.gz,例如, retina-capture-aks-nodepool1-41844487-vmss000000-20230313101436UTC.tar.gz。

总结

本文介绍了一个基于下一代网络测控技术eBPF的K8S网络测控系统,可以用于在容器云复杂网络平台下高效、自动的捕获、存储和可视化网络流量等信息。对于复杂平台下排障、安全监控和数据合规管理等都有积极的意义,值得我们大家尝鲜试用。

0 阅读:0

安全运维得看我

简介:感谢大家的关注