使用 Cilium 增强 Kubernetes 网络安全

bd5bebdfe04cadb03540cf65e1218fad.gif

作者 | Addo Zhang

来源 | 云原生指北

TL;DR

在本篇,我们分别使用了 Kubernetes 原生的网络策略和 Cilium 的网络策略实现了 Pod 网络层面的隔离。不同的是,前者只提供了基于 L3/4 的网络策略;后者支持 L3/4、L7 的网络策略。

通过网络策略来提升网络安全,可以极大降低了实现和维护的成本,同时对系统几乎没有影响。

尤其是基于 eBPF 技术的 Cilium,解决了内核扩展性不足的问题,从内核层面为工作负载提供安全可靠、可观测的网络连接。

背景

为什么说 Kubernetes 网络存在安全隐患?集群中的 Pod 默认是未隔离的,也就是 Pod 之间的网络是互通的,可以互相通信的。

这里就会有问题,比如由于数据敏感服务 B 只允许特定的服务 A 才能访问,而服务 C 无法访问 B。要禁止服务 C 对服务 B 的访问,可以有几种方案:

  • 在 SDK 中提供通用的解决方案,实现白名单的功能。首先请求要带有来源的标识,然后服务端可以接收规则设置放行特定标识的请求,拒绝其他的请求。

  • 云原生的解决方案,使用服务网格的 RBAC、mTLS 功能。RBAC 实现原理与应用层的 SDK 方案类似,但是属于基础设施层的抽象通用方案;mTLS 则会更加复杂一些,在连接握手阶段进行身份验证,涉及证书的签发、验证等操作。

以上两种方案各有利弊:

  • SDK 的方案实现简单,但是规模较大的系统会面临升级推广困难、多语言支持成本高等问题。

  • 服务网格的方案是基础设施层的通用方案,天生支持多语言。但是对于未落地网格的用户来说,架构变化大,成本高。如果单纯为了解决安全问题,使用网格方案性价比又很低,且不说现有网格实现等落地难度大及后期的使用维护成本高。

继续向基础设施下层找方案,从网络层入手。Kubernetes 提供了的网络策略 *NetworkPolicy*[1],则可以实现“网络层面的隔离”。

示例应用

在进一步演示 NetworkPolicy 的方案之前,先介绍用于演示的示例应用。我们使用 Cilium 在互动教程 Cilium getting started[2] 中使用的“星球大战”场景。

这里有三个应用,星战迷估计不会陌生:

  • 死星 deathstar:在 80 端口提供 web 服务,有 2 个 副本,通过 Kubernetes Service 的负载均衡为帝国战机对外提供”登陆“服务。

  • 钛战机 tiefighter:执行登陆请求。

  • X翼战机 xwing:执行登陆请求。

6fbc4bb4485dd56502b5a3cf7f957247.png

如图所示,我们使用了 Label 对三个应用进行了标识:org 和 class。在执行网络策略时,我们会使用这两个标签识别负载。

# app.yaml
---
apiVersion: v1
kind: Service
metadata:name: deathstarlabels:app.kubernetes.io/name: deathstar
spec:type: ClusterIPports:- port: 80selector:org: empireclass: deathstar
---
apiVersion: apps/v1
kind: Deployment
metadata:name: deathstarlabels:app.kubernetes.io/name: deathstar
spec:replicas: 2selector:matchLabels:org: empireclass: deathstartemplate:metadata:labels:org: empireclass: deathstarapp.kubernetes.io/name: deathstarspec:containers:- name: deathstarimage: docker.io/cilium/starwars
---
apiVersion: v1
kind: Pod
metadata:name: tiefighterlabels:org: empireclass: tiefighterapp.kubernetes.io/name: tiefighter
spec:containers:- name: spaceshipimage: docker.io/tgraf/netperf
---
apiVersion: v1
kind: Pod
metadata:name: xwinglabels:app.kubernetes.io/name: xwingorg: allianceclass: xwing
spec:containers:- name: spaceshipimage: docker.io/tgraf/netperf

Kubernetes 网络策略

可以通过官方文档[3]获取更多详细信息,这里我们直接放出配置:

# native/networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: policynamespace: default
spec:podSelector:matchLabels:org: empireclass: deathstarpolicyTypes:- Ingressingress:- from:- podSelector:matchLabels:org: empireports:- protocol: TCPport: 80
  • podSelector :表示要应用网络策略的工作负载均衡,通过 label 选择到了 deathstar 的 2 个 Pod。

  • policyTypes :表示流量的类型,可以是 Ingress 或 Egress 或两者兼具。这里使用 Ingress,表示对选择的 deathstar Pod 的入站流量执行规则。

  • ingress.from:表示流量的来源工作负载,也是使用 podSelector 和 Label 进行选择,这里选中了 org=empire 也就是所有“帝国的战机”。

  • ingress.ports:表示流量的进入端口,这里列出了 deathstar 的服务端口。

接下来,我们测试下。

测试

先准备环境,我们使用 K3s[4] 作为 Kubernetes 环境。但由于 K3s 默认的 CNI 插件 Flannel 不支持网络策略,我们需要换个插件,这里选择 Calico[5],即 K3s + Calico 的方案。

先创建一个单节点的集群:

curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" INSTALL_K3S_EXEC="--flannel-backend=none --cluster-cidr=10.42.0.0/16 --disable-network-policy --disable=traefik" sh -

此时,所有的 Pod 都处于 Pending 状态,因为还需要安装 Calico:

kubectl apply -f https://projectcalico.docs.tigera.io/manifests/calico.yaml

待 Calico 成功运行后,所有的 Pod 也会成功运行。

接下来就是部署应用:

kubectl apply -f app.yaml

执行策略前,执行下面的命令看看“战机能否登陆死星”:

kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landedkubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed

从结果来看,两种 ”战机“(Pod 负载)都可以访问 deathstar 服务。

0cc1312560d3ddb2a84fcbb992a86dc7.png

此时执行网络策略:

kubectl apply -f native/networkpolicy.yaml

再次尝试”登陆“,xwing 的登陆请求会停在那(需要使用 ctrl+c 退出,或者请求时加上 --connect-timeout 2)。

0cb1225cac8fcd3854f5d420ff8f16c0.png

思考

使用 Kubernetes 网络策略实现了我们想要的,从网络层面为服务增加了白名单的功能,这种方案没有改造成本,对系统也几乎无影响。

Cilium 还没出场就结束了?我们继续看:

有时我们的服务会对外暴露一些管理端点,由系统调用执行一些管理上的操作,比如热更新、重启等。这些端点是不允许普通服务来调用,否则会造成严重的后果。

比如示例中,tiefighter 访问了 deathstar 的管理端点 /exhaust-port

kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
Panic: deathstar explodedgoroutine 1 [running]:
main.HandleGarbage(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)/code/src/github.com/empire/deathstar/temp/main.go:9 +0x64
main.main()/code/src/github.com/empire/deathstar/temp/main.go:5 +0x85

出现了 Panic 错误,检查 Pod 你会发现 dealthstar 挂了。

Kubernetes 的网络策略仅能工作在 L3/4 层,对 L7 层就无能为力了。

还是要请出 Cilium。

Cilium 网络策略

由于 Cilium 涉及了 Linux 内核、网络等众多知识点,要讲清实现原理篇幅极大。故这里仅摘取了官网的介绍,后期希望有时间再写一篇关于实现的。

Cilium 简介

Cilium[6] 是一个开源软件,用于提供、保护和观察容器工作负载(云原生)之间的网络连接,由革命性的内核技术 eBPF[7] 推动。

eBPF 是什么?

Linux 内核一直是实现监控/可观测性、网络和安全功能的理想地方。不过很多情况下这并非易事,因为这些工作需要修改内核源码或加载内核模块, 最终实现形式是在已有的层层抽象之上叠加新的抽象。eBPF 是一项革命性技术,它能在内核中运行沙箱程序(sandbox programs), 而无需修改内核源码或者加载内核模块。

将 Linux 内核变成可编程之后,就能基于现有的(而非增加新的)抽象层来打造更加智能、 功能更加丰富的基础设施软件,而不会增加系统的复杂度,也不会牺牲执行效率和安全性。

c76b6a2610ccab259b2ff58288833387.png

我们来看下 Cilium 的网络策略:

# cilium/networkpolicy-L4.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:name: "rule1"
spec:description: "L7 policy to restrict access to specific HTTP call"endpointSelector:matchLabels:org: empireclass: deathstaringress:- fromEndpoints:- matchLabels:org: empiretoPorts:- ports:- port: "80"protocol: TCP

与 Kubernetes 的原生网络策略差异不大,参考前面的介绍也都看懂,我们直接进入测试。

测试

由于 Cilium 本身就实现了 CNI,所以之前的集群就不能用了,先卸载集群:

k3s-uninstall.sh
# !!!切记要清理之前的 cni 插件
sudo rm -rf /etc/cni/net.d

还是使用同样的命令创建单节点的集群:

curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" INSTALL_K3S_EXEC="--flannel-backend=none --cluster-cidr=10.42.0.0/16 --disable-network-policy --disable=traefik" sh -# cilium 会使用该变量
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

接下来安装 Cilium CLI:

curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz{,.sha256sum}cilium version
cilium-cli: v0.10.2 compiled with go1.17.6 on linux/amd64
cilium image (default): v1.11.1
cilium image (stable): v1.11.1
cilium image (running): unknown. Unable to obtain cilium version, no cilium pods found in namespace "kube-system"

安装 Cilium 到集群:

cilium install

待 Cilium 成功运行:

cilium status/¯¯\/¯¯\__/¯¯\    Cilium:         OK\__/¯¯\__/    Operator:       OK/¯¯\__/¯¯\    Hubble:         disabled\__/¯¯\__/    ClusterMesh:    disabled\__/Deployment        cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet         cilium             Desired: 1, Ready: 1/1, Available: 1/1
Containers:       cilium             Running: 1cilium-operator    Running: 1
Cluster Pods:     3/3 managed by Cilium
Image versions    cilium-operator    quay.io/cilium/operator-generic:v1.11.1@sha256:977240a4783c7be821e215ead515da3093a10f4a7baea9f803511a2c2b44a235: 1cilium             quay.io/cilium/cilium:v1.11.1@sha256:251ff274acf22fd2067b29a31e9fda94253d2961c061577203621583d7e85bd2: 1

部署应用:

kubectl apply -f app.yaml

待应用启动后测试服务调用:

kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed
kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed

执行 L4 网络策略:

kubectl apply -f cilium/networkpolicy-L4.yaml

再次尝试“登陆”死星,xwing 战机同样无法登陆,说明 L4 层的规则生效。

我们再尝试 L7 层的规则:

# cilium/networkpolicy-L7.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:name: "rule1"
spec:description: "L7 policy to restrict access to specific HTTP call"endpointSelector:matchLabels:org: empireclass: deathstaringress:- fromEndpoints:- matchLabels:org: empiretoPorts:- ports:- port: "80"protocol: TCPrules:http:- method: "POST"path: "/v1/request-landing"

执行规则:

kubectl apply -f cilium/networkpolicy-L7.yaml

这回,使用 tiefighter 调用死星的管理接口:

kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
Access denied
# 登陆接口工作正常
kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
Ship landed

这回返回了 Access denied,说明 L7 层的规则生效了。

1c9ef4ac6cf050132e6cc2af715dd6ed.png

参考资料

[1] 网络策略 NetworkPolicy: https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
[2] Cilium getting started: https://play.instruqt.com/isovalent/tracks/cilium-getting-started
[3] 官方文档: https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
[4] K3s: https://k3s.io
[5] Calico: https://www.tigera.io/project-calico/
[6] Cilium: https://cilium.io
[7] eBPF: https://ebpf.io

f85cbbf724049e1ff69d6697faf6b3dc.gif

da4fecabf524d7dcc28f27666771bce9.png

往期推荐

Android 13 第一个开发者版本来了,网友直呼:Android 12 还没玩透!

CSDN企业数字化之路 ——「低代码」发展研讨会北京站现场实录大放送

使用这个库,让你的服务操作 Redis 速度飞起

将 k8s 制作成 3D 射击游戏,好玩到停不下来

49b4bb842c4c9b439f6e04b5671bbd3f.gif

点分享

c2bf28c7c687a581cec3e77dc37329e9.gif

点收藏

55432b8a8288f575e0fb5427f70bee60.gif

点点赞

333a9f600c1252e1c785550b691dae1f.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内含干货PPT下载|一站式数据管理DMS关键技术解读

简介: 深入解读实时数据流、库仓一体数据处理等核心技术 “数聚云端智驭未来”——阿里云数据库创新上云峰会暨第3届数据库性能挑战赛决赛颁奖典礼已圆满结束,更多干货内容欢迎大家观看峰会直播回放。 峰会直播回放📎数聚云端 智驭未来——…

好饭不怕晚,扒一下 Redis 的配置文件

作者 | 阿Q来源 | 阿Q说代码在往期的文章中我们已经对Redis的概念和基本命令进行了讲解,今天我们来看下它的配置文件,Redis的配置文件在我们的开发和实际应用中起着非常重要的作用。我们可以在安装目录下找到redis.conf配置文件,通过vim命令进…

ICBU可控文本生成技术详解

简介: 文本生成(Text Generation)是自然语言处理(Natural Language Processing,NLP)领域的一项重要且具有挑战的任务。顾名思义,文本生成任务的目的是生成近似于自然语言的文本序列,…

云拨测助力节卡机器人 全面优化海外网站性能

简介: 【案例分享云拨测】借助云拨测,节卡机器人有效挖掘性能瓶颈,经过优化,提升网站打开速度 50% 以上,提高了运营推广活动的 ROI,帮助节卡为全球用户提供更加优质的服务! 作者|白…

分享一个巨好用的 HTTP 命令行宝藏工具

作者 | Eason来源 | 程序员巴士HTTPie是一个命令行 HTTP 客户端。它的目标是使 CLI 与 Web 服务的交互尽可能人性化。HTTPie 设计用于测试、调试以及通常与 API 和 HTTP 服务器交互。http 和 https 的命令允许创建和发送任意 HTTP 请求。HTTPie 整体采用简单自然的语法&#xf…

mysql远程备份工具_innobackupex实现MySQL远程备份

一、了解innobackupex1、mysqldumpmysql逻辑备份工具,作用于服务器本地,不需要额外安装插件可以单表备份,备份为sql文件形式、方便,在多个场景通用可通过shell命令实现定时备份,但备份时如果用户有操作,容易…

技术干货 | Native 页面下如何实现导航栏的定制化开发?

简介: 通过不同实际场景的描述,供大家参考完成 Native 页面的定制化开发。 很多 mPaaS Coder 在接入 H5 容器后都会对容器的导航栏进行深度定制,本文旨在通过不同实际场景的描述,供大家参考完成 Native 页面的定制化开发。 欢迎关…

深入理解云计算OpenAPI体系

简介: 就云计算的API来看,当前并没有类似POSIX这样的API标准,基本上各大厂商各自为政。当然,有一些业界主流标准例如OAS获得多数云厂商的支持,但云厂商本身的API却往往由于历史原因、技术路线原因百花齐放,…

Gartner:2025年有效细分市场中过半企业的 IT 支出将转向云

来源 | CSDN云计算 根据Gartner的最新预测,2025年有效细分市场中的企业在公有云计算领域的IT支出将超过传统IT服务支出。 Gartner的“云迁移”研究只包括可以迁移到云的企业IT市场,即应用软件、基础设施软件、业务流程服务和系统基础设施市场。2025年在这…

阿里云容器服务全面升级为 ACK Anywhere,让云的边界拓展至企业需要的每个场景

简介: 2021 年 9 月 26 日上海阿里云计算峰会上,阿里巴巴研究员、阿里云云原生应用平台负责人丁宇宣布,阿里云容器服务全面升级为 ACK Anywhere,让企业在任何需要云的地方,都能获得一致的容器基础设施能力。 此次升级的…

Redis 突然变慢了如何排查并解决?

作者 | 码哥字节来源 | 码哥字节Redis 通常是我们业务系统中一个重要的组件,比如:缓存、账号登录信息、排行榜等。一旦 Redis 请求延迟增加,可能就会导致业务系统“雪崩”。最近遇到了一个bug,经过查找发现 Redis 报 Could not ge…

成本直降50% | 阿里云发布云原生网关,开启下一代网关新进程

简介: 融合流量网关与微服务网关的下一代网关—云原生网关来啦!优势满满! 流量网关和微服务网关必须分开构建吗? 在容器技术和 K8s 主导的云原生时代,这个命题正浮现出新的答案。 更经济:将流量网关与微…

MongoDB 5.0新特性概览

简介: MongoDB 5.0标志着一个新的发布周期的到来,以更快地交付新特性给到用户。版本化API与在线重新分片相结合,使用户不必担心未来的数据库升级以及业务变化问题;本地原生时间序列数据平台也使MongoDB能支持更广泛的工作负载和业…

深入前端研发效能治理:数据化运营思路及其实践

简介: 数据中台前端研发无不让人厚重真实地感受到“唯一不变的是变化”。拿集团的数据资产服务平台来说,业务上经过两年的发展,已由单一的数据管理和使用平台发展成了集团具有一定规模和影响力的全域数据要素交易所,而从前端技术侧…

啥情况?为什么我的 Service 无法注入进来?

作者 | 敖丙来源 | 敖丙今天同事火急火燎的走了过来,说:快帮我看看这个错误,啥情况啊?我一看报错:Field xxxService in com.xx.xx.service.impl.XxXServiceImpl required a bean of type com.xx.xx.service.XxxService…

oracle sga pga mysql_oracle实例内存(SGA和PGA)调整-xin

一、名词解释(1)SGA:System Global Area是Oracle Instance的基本组成部分,在实例启动时分配;系统全局域SGA主要由三部分构成:共享池、数据缓冲区、日志缓冲区。(2)共享池:Shared Pool用于缓存最近被执行的SQL语句和最近被使用的数…

IoT Studio可视化搭建平台编辑历史功能的思考与探索

简介: 在前端可视化搭建领域中“重做”和“撤销”这两个功能已经是标配中的标配,毕竟只要有用户行为的地方就可能会有出错,这两个功能无疑就是为用户提供了“后悔药”。目前有各种各样的可视化搭建平台,本文介绍IoT Studio可视化搭…

云计算架构设计6大原则,你遵循了吗?| 赠书

作者 | 吕昭波 2006年,第一个云计算(Cloud Computing)产品诞生,云计算的概念也被提出,现在云计算几乎已经渗入所有的行业和应用场景中。我们不一定能直接感受到云计算对日常生活、工作、学习的影响,但作为I…

python写自动化工具_微软最强 Python 自动化工具开源了!不用写一行代码!

1. 前言最近,微软开源了一款非常强大的 Python 自动化依赖库:playwright-python它支持主流的浏览器,包含:Chrome、Firefox、Safari、Microsoft Edge 等,同时支持以无头模式、有头模式运行playwright-python 提供了同步…

复杂推理模型从服务器移植到Web浏览器的理论和实战

简介: 随着机器学习的应用面越来越广,能在浏览器中跑模型推理的Javascript框架引擎也越来越多了。在项目中,前端同学可能会找到一些跑在服务端的python算法模型,很想将其直接集成到自己的代码中,以Javascript语言在浏览…