Hero Image
cilium中的datapth简解

cilium收发包是极其复杂的过程,本节将介绍数据包是如何穿过 network datapath(网络数据路径)的:包括从硬件到内核,再到用户空间 本文中只讨论收包的过程,涉及到的知识点比较多,望君耐心看完,多读几遍,定会颇有收获 网卡驱动 驱动:网卡需要有驱动才能工作,驱动是加载到内核中的模块,负责衔接网卡和内核的网络模块,驱动在加载的时候将自己注册进网络模块,当相应的网卡收到数据包时,网络模块会调用相应的驱动程序处理数据 模块:是在内核空间运行的程序,实际上是一种目标对象文件,没有链接,不能独立运行,但可以装载到系统中作为内核一部分运行,从而动态扩充内核的功能 Linux下对于一个硬件的驱动,可以有两种方式: 1:直接加载到内核代码中,启动内核时就会驱动此硬件设备 2:以模块方式,编译生成一个.o文件,当应用程序需要时再加载进内核空间运行,比如执行命令:insmod SHT21.ko 网卡(NIC): 硬件,内核通过网卡驱动与网卡交互,网卡本身是有内存的,每个网卡一般都有4k以上的内存(fifo队列),用来发送、接受数据。 数据发送:数据从主内存搬到网卡之后,要先在网卡自身的内存中排队,再按先后顺序发送 数据接受:数据从以太网传递到网卡时,网卡也是先把数据存储到自身的内存中,每收到一帧数据,就经过中断,以DMA方式从网卡内存拷贝至内核内存 tap/tun设备 TUN与TAP是操作系统内核中的虚拟网络设备,操作系统通过TUN/TAP设备向绑定该设备的用户空间的程序发送数据,反之,用户空间的程序使用标准网络接口socket API操作tun/tap设备发送数据,它们都是从/dev/net/tun字符设备进行读取数据(2.6+) 1:Tun 是三层网络设备,从/dev/net/tun字符设备上读取的是IP数据包,写入的也只能是IP数据包,因此不能进行二层操作,如发送ARP请求和以太网广播 2:Tap 是二层网络设备,处理的是二层数据帧,从 /dev/net/tun 字符设备上读取的是数据帧,写入的也只能是数据帧 示例: # 创建 tap ip tuntap add dev tap0 mode tap # 创建 tun ip tuntap add dev tun0 mode tun # 删除 tap ip tuntap del dev tap0 mode tap # 删除 tun ip tuntap del dev tun0 mode tun 数据发送流程:

Hero Image
grpc-stream go版简解

基础知识介绍 gRPC (gRPCRemote Procedure Calls) 是Google发起的一个开源的远程过程调用 (Remote procedure call) 系统。该系统基于 HTTP/2 协议传输,使用Protocol Buffers 工具来序列化结构化数据。 protobuf protobuf 全称 Google Protocol Buffers,是 google 开发的的一套用于数据存储,网络通信时用于协议编解码的工具库,proto 文件是以 xxx.proto 命名。 stream Stream 顾名思义就是一种流,可以源源不断的推送数据,很适合大数据传输,或者服务端和客户端长时间数据交互的场景。 使用场景 1:股票app:客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端 2:数据上传:几百万的数据上传处理,若普通rpc则需要全部传输成功后才进行处理,而stream则会再接受第一条数据后就开始处理 3:数据交换:比如LOL,王者荣耀等竞技游戏,client和server之间需要非常频繁地交换数据 ServiceAPI类型 gRPC 中的 Service API 有如下4种类型: SimpleAPI:普通rpc ServerStreaming:服务器流式响应 ClientStreaming:客户端流式发送 BidirectionalStreaming:双向流 操作实战 代码说明:通过传入名字查询对应的结果 下载protoc wget https://github.com/protocolbuffers/protobuf/releases/download/v21.2/protoc-21.2-linux-x86_64.zip unzip protoc-21.2-linux-x86_64.zip mv protoc-21.2-linux-x86_64 /usr/local/protoc 写入环境变量 将protoc命令写入path中,编辑 /etc/profile文件 export PROTOC_HOME=/usr/local/protoc export PATH=$PROTOC_HOME/bin:$PATH 目录说明

Hero Image
使用kubebuilder开发operator详解

基础概念 命令式和声明式 命令式编程(Imperative):详细的命令机器怎么(How)去处理一件事情以达到你想要的结果(What),比如代码详细实现过程。 声明式编程( Declarative):只告诉你想要的结果(What),机器自己摸索过程(How),比如sql查询结果。 简而言之:越接近现实的表达就越“声明式”,越接近于机器的执行过程就越“命令式”。 例如在kubernetes中使用此两种方式来创建服务: 命令式 创建:kubectl create deployment nginx --image nginx 或者 kubectl create -f nginx.yaml 修改:kubectl replace -f nginx.yaml 声明式 创建:kubectl apply -f configs/ 或者 kubectl apply -f nginx.yaml 修改:kubectl apply -f nginx.yaml 从以上两种方式可以看出:声明式对象配置更好地支持对目录进行操作并自动检测每个文件的操作类型(创建,修补,删除),但声明式对象配置难于调试并且出现异常时结果难以理解。 Kubernetes API 在kubernetes集群中,所有需要数据存取的组件都需要和kube-apiserver组件通信,而集群数据都是保存在etcd中。同时,kubernetes也大量使用了声明式api来提高用户开发和使用效率,而其api分别由Group(API 组)、Version(API 版本)和 Resource(API 资源类型)组成。如下图所示: 我们也可以使用以下命令查看有哪些api及其组成方式: kubectl get --raw / { "paths": [ "/api", "/api/v1", "/apis/apps", "/apis/apps/v1", "/apis/batch", "/apis/batch/v1", "/apis/batch/v1beta1", "/apis/apps.

Hero Image
基于Ubuntu20.04版本的cilium1.10.1安装使用

基础概念 linux的内核空间和系统空间 linux系统分为内核空间和用户空间并且相互隔离,内核空间运行内核相关的指令,可以执行任意指令(比如cpu的特权指令的使用,或者驱动程序运行等),用户空间运行非内核的进程(比如自己平常写的java代码等),若用户空间的程序需要调用底层相关的指令(比如说读取文件,分配回收内存等),此时需要调用内核提供的接口来完成对应的有限的操作,这个过程叫做系统调用。如果我们用户空间的程序要直接操作内核并没有提供接口的指令时,通常是需要修改内核代码来满足需求,但后来内核提供了一个内核模块(LKM)来满足此种需求,lkm直接将指令加载至内核执行,不需要再通过系统调用的方式来完成,运行时加载,不需要编译内核也不需要重启系统,但此方法若操作不当,也会直接让内核崩溃,进而增加了安全维护成本. ​ BPF 伯克利包过滤器(Berkeley Packet Filter,缩写 BPF): 是类Unix系统上数据链路层的一种原始接口,提供原始链路层封包的收发 最初是在1992年构思的,目的是提供一种过滤数据包的方法,并避免从内核到用户空间的无用数据包复制,从而极大地提高性能。它最初包含一个简单的字节码,该字节码从用户空间注入到内核中,并由验证程序进行检查(以防止内核崩溃或安全问题)并附加到套接字,然后在每个接收到的数据包上运行 tcpdump就是基于BPF技术实现的,FreeBSD和WinPcap在内的一些平台,使用即时编译(JIT)编译器来把BPF指令转换为原始字节码,以进一步提高性能。Linux有一个BPF JIT编译器,但被默认禁用。 ​ EBPF 随着现代硬件及指令的发展,BPF对于一些硬件上的指令支持有限,因此,Alexei Starovoitov引入了扩展的BPF设计,从3.18版本开始,Linux 内核提供了一种扩展的BPF虚拟机,被称为“extended BPF”,简称为eBPF。利用现代硬件的优势,允许将eBPF指令更紧密地映射到ISA,以提高性能,它也能够被用于非网络相关的功能,比如附在不同的tracepoints上,从而获取当前内核运行的许多信息 架构图如下 工作原理 eBPF程序“附加”到内核中的指定代码路径,遍历代码路径时,将执行所有附加的eBPF程序,为了解决LKM这种安全性的问题,eBPF 程序需要满足一系列的需求,才能被加载到内核。Verifier 会遍历对 eBPF 程序在内核中可能的执行路径进行遍历, 确保程序能够在不出现导致内核锁定的循环的情况下运行完成。除此之外还有其它必须满足的检查,例如有效的寄存器状态、程序大小以及越界等,如果所有的检查都通过了,eBPF 程序被加载并编译到内核中,并监听特定的信号。该信号以事件 的形式出现,会被传递给被加载的 eBPF 程序。一旦被触发,字节码就会根据其中的指令执行并收集信息。 简单说下eBPF 的工作流程: 1:把 eBPF 程序编译成字节码。 2:在载入到 Hook 之前,在虚拟机中对程序进行校验。 3:把程序附加到内核之中,被特定事件触发。 4:JIT 编译。 5:在程序被触发时,调用辅助函数处理数据。 6:在用户空间和内核空间之间使用键值对共享数据。 ​ cilium 如果要实现对流量的监控和规则处理,则我们需要去编写对应的EBPF程序来实现,cilium是基于EBPF来实现的容器管理平台部署的应用程序之间的网络和api连接管理工具,由于eBPF在Linux内核中运行,因此可以在不更改应用程序代码或容器配置的情况下应用和更新Cilium安全策略 ​ Hubble Hubble是一个完全分布式的网络和安全性可观察性平台。它建立在Cilium和eBPF之上,以完全透明的方式深入了解服务以及网络基础结构的通信和行为。 ​ Hubble可以查看以下功能的信息: 服务依赖关系和相互通信的展示: 1:哪些服务正在相互通信?多久一次?服务依赖关系图是什么样的? 2:正在进行哪些HTTP调用?服务从哪些卡夫卡主题中消费或产生什么? 网络监控和警报:

Hero Image
Litmuschaos1.3.0部署及使用

基础概念 litmuschaos是一个云原生的混沌测试工具,专注于kubernetes集群进行模拟故障测试,发现集群及程序脆弱点从而提高集群及程序健壮性 组件 ChaosExperiment:简单来说就是定义一个该测试支持哪些操作,能传入什么参数,可对哪些类型的对象进行实现等CRD资源的清单 通常分为三种类别:通用的测试(比如内存,磁盘,删除等操作),程序的测试(比如针对于kafka来进行测试),平台测试(针对于某个云平台的测试: AWS,Azure,GCP) ChaosEngine: 具有命名空间范围的自定资源,简单来说就是将ChaosExperiment实现的功能具体实现到哪个命名空间的哪些程序 Chaos Operator: 管理Litmus相关的CRD,监视管理ChaosEngine Chaos Portal: 一个展示及管理页面(目前还是bete状态) litmuschaos可以实现Pod及node内存,cpu,网络,磁盘IO等,以及k8s组件(coredns,kubelet,docker)等服务,以及对于不同的程序(比如openebs,kafka,prometheus等)专门的进行测试 安装 使用helm进行部署 添加LitmusChaos Helm存储库 helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/ 安装LitmusChos kubectl create ns litmus helm install chaos litmuschaos/litmus --namespace=litmus 查看是否安装了CRD资源 kubectl get crds | grep chaos chaosengines.litmuschaos.io 2021-03-16T09:43:45Z chaosexperiments.litmuschaos.io 2021-03-16T09:43:45Z chaosresults.litmuschaos.io 2021-03-16T09:43:45Z kubectl api-resources | grep chaos chaosengines litmuschaos.io true ChaosEngine chaosexperiments litmuschaos.io true ChaosExperiment chaosresults litmuschaos.io true ChaosResult 安装需要的Chaos Experiments

Hero Image
Wazuh 4.1部署及使用

基础概念 wazuh是一个开源免费的HIDS(主机入侵检测),用于漏洞扫描,完整性校验,异常流量捕获,shellshock、rootkit检测等 组件 Wazuh server: 通过agent端传过来的数据使用解码器和规则对其进行处理,管理agent配置等 Wazuh agent:安装在节点上的代理,用于检测,采集等 Elastic Stack: 索引数据及展示 集群架构图如下: 代理架构图如下: 架构图说明: 1: Wazuh代理具有模块化架构,其中不同组件负责各自的任务:监视文件系统,读取日志消息,收集清单数据,扫描系统配置,查找恶意软件等,用户可以通过配置启用或禁用代理模块设置 2: agent和server间通过密钥进行数据加密和通信 Log collector: 收集系统和应用程序日志及windows事件等日志 Command execution: 代理周期性运行命令并将输出结果发送到server端进行分析(比如监控磁盘等指标使用率等) File integrity monitoring (FIM): 文件信息监控,在文件修改时将相关信息发送给server端进行分析(比如谁何时做了什么,包括文件自身信息等) Security configuration assessment (SCA): 根据CIS标准来检查现有的安全策略,也可以自定义SCA System inventory: 定期扫描系统信息(比如系统版本,网卡,运行的进场,已安装的程序,打开的端口等信息) Malware detection: 恶意软件扫描,基于non-signature检测异常的程序或rootkit的存在,通过监视系统调用,它将查找隐藏的进程,隐藏的文件和隐藏的端口等 Active response: 检测到威胁时,此模块将自动执行相关操作,比如阻止网络连接,停止正在运行的进程或删除恶意文件,用户也可以在必要时创建自定义响应 Containers security monitoring: 此代理模块与Docker Engine API集成在一起以监视容器化环境中的更改,例如它检测到容器镜像,网络配置或数据量的更改,它还会警告以特权模式运行的容器以及正在运行的容器中执行命令的用户 Cloud security monitoring: 云提供商安全检测,它能够检测到云基础架构的更改(例如,创建新用户,修改安全组,停止云实例等),并收集云服务日志数据(AWS Cloudtrail,AWS Macie,AWS GuardDuty,Azure Active Directory等) server架构图如下: Wazuh server组件负责分析从代理接收的数据,并在检测到威胁或异常时触发警报,它还用于远程管理代理配置并监视其状态 组件说明: Agents registration service: 给每个代理分配一个唯一的预共享身份验证密钥来注册新代理,并支持通过TLS/SSL证书或提供固定密码进行身份验证 Agents connection service: 该组件用于接受agent发送来的数据,利用预共享密钥来验证代理身份和加密代理与Wazuh服务器之间的通信及此将配置推送给远程的agent Analysis engine: 进行数据分析,将agent传送过来的数据进行分析,利用解码器来识别正在处理的信息的类型,通过使用规则,它可以识别解码事件中的特定模式,从而触发警报,甚至可能要求采取自动对策(比如防火墙禁止ip等) Wazuh RESTful API: 管理代理和服务器配置设置,监视基础结构状态和整体运行状况,管理和编辑Wazuh解码器和规则等 Wazuh cluster daemon: 此服务用于水平扩展Wazuh server,将它们部署为群集,这种配置与网络负载平衡器相结合,可提供高可用性和负载平衡(Wazuh server用来相互通信并保持同步的工具) Filebeat: 用于将事件和警报发送到es,它读取Wazuh分析引擎的输出并实时发送事件,当连接到多节点Elasticsearch集群时,它还提供负载平衡 部署 服务器说明 192.

Hero Image
helm 部署Prometheus-Operator

监控基本知识 常用监控方法:(在文章中会持续穿插以下方法的使用) (1) USE方法: 即使用率(Utilization),饱和度(Staturation),错误(Error),针对于每个资源,检查使用率饱和度和错误,侧重于主机层面监控 资源: 系统的组件,例如CPU,内存,IO等 使用率: 资源处理工作的平均时间,通常为百分比表示 饱和度: 资源排队工作的指标, 通常为队列长度表示 错误: 资源错误事件的计数 将以上结合起来创建一份资源清单,并采用一种方法来监控每个要素,例如系统性能出现瓶颈时,我们可以参考以下要素: 1:CPU的清单 CPU使用率随时间的百分比 CPU饱和度,等待CPU的进程数 CPU错误(比较少) 2:内存的清单 内存使用率随时间的百分比 内存饱和度,通过监控swap测量 内存错误(比较少) 其他Linux系统资源的示例可以参考BrenDan Gregg所提供的清单 (2) Google的四个黄金指标: 延迟, 流量, 错误, 饱和度, 更多是针对于应用程序或面向用户部分, 依次选择对应的指标设置报警 延迟: 服务请求所花费的时间, 而成功请求和失败请求有所区别, 例如失败请求会以很低的延迟返回错误的结果 流量: 针对系统,例如每秒HTTP请求数或数据库系统的事务 错误: 请求失败的速率, 例如HTTP 500错误等显示失败, 返回错误内容或无效内容的隐式失败或者强制要求相应时间超过30s的请求视为错误的基于策略原因的失败 饱和度: 应用程序处理极限或系统资源极限,例如到达程序最大处理请求数量或内存cpu等资源饱和 通常监控应用程序主要有两种方法: 黑盒监控:查询程序外部特征,例如端口是否正常,数据或状态码返回是否正常,或者执行ICMP检查服务器是否正常 例如ping服务器,telnet端口号,curl状态码等 白盒监控:主要查看程序内部特征, 例如应用程序检查后所返回其状态,内部组件或事务和事件性能的度量,将事件,日志和指标发送到监控工具 例如redis的info中显示redis slave down, mysql使用show variables暴露内部指标信息,httpd使用mod_status来暴露内部信息等 报警和通知 告警和通知是监控工具的主要输出方式,一个出色的通知系统需包含以下基础信息:

Hero Image
Kafka 2.3 集群部署

基础概念 Broker(节点) 一个kafka节点就是一个broker,一个集群包含多个broker Topic(主题) 信息类别,kafka根据topic对消息进行归类 Producer(生产者) 信息生产者,采用push模式向broker发送消息的一端,Producer可以发布到一个或更多Topic,并且可以选择用于存储数据的Partition Partition(分区) 一个Topic包含一个或者多个Partition(类似于es的分片),Producer能决定将消息推送到Topic的哪些Partition,并且producer能直接发送消息到对应partition的Leader处 某个topic中的某个partition同时只能有一个Consumer消费 Consumer(消费者) 信息消费者,采用pull模式从broker中读取消息的一端,Consumer可以使用一个或多个Topic或Partition Consumer Group(消费组) 每个Consumer属于一个特定的Consumer Group,topic会复制到各Consumer Group,但该Consumer Group中只能有一个Consumer能够消费该消息 replication(副本) Topic的备份,消息以partition为单位分配到多个server,并以partition为单位进行备份,replication有leader和follower两种类型,leader提供服务,follower复制数据 leader 负责跟踪所有的 follower 状态,若Topic下的某个分区的flower比leader落后了太多或超过特定时间未发起数据的Pull求,则leader将其重ISR中移除 每个Topic下的每个分区的leader维护着与其基本保持同步的Replica列表,该列表称为ISR 复制类型: 同步复制: 只有所有的follower把数据拿过去后才commit,一致性好,可用性不高 异步复制: 只要leader拿到数据立即commit,等follower慢慢复制,可用性高,立即返回,一致性差 Commit: 是指leader告诉客户端这条数据写成功了(kafka尽量保证commit后若leader立即挂掉,其他flower都有该条数据) 在Producer端可以设置究竟使用那种同步方式: request.required.asks= 0 相当于异步,不需要leader给予回复,producer立即返回,发送就是成功 1 当leader接收到消息之后发送ack,丢会重发,丢的概率很小 -1 当所有的follower都同步消息成功后发送ack. 丢失消息可能性比较低 segment partition物理上由多个segment组成,同一个topic下有多个不同partition,每一个partition为一个文件夹,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1 offset offset用于在partition内部唯一标识一条消息 Rebalance(重平衡) Consumer Group内某个Consumer 故障后,其他Consumer自动重新订阅topic的过程 API(接口) Kafka 有四个核心API,它们分别是: Producer API: 它允许应用程序向一个或多个 topics 上发送消息记录 Consumer API: 允许应用程序订阅一个或多个 topics 并处理为其生成的记录流 Streams API: 它允许应用程序作为流处理器,从一个或多个Topic中消费输入流并为其生成输出流,有效的将输入流转换为输出流 Connector API: 它允许构建和运行将 Kafka 主题连接到现有应用程序或数据系统的可用生产者和消费者(关系数据库的连接器可能会捕获对表的所有更改) 集群部署 集群规划 节点ip