好的,各位观众老爷们,大家好!👋 今天咱们来聊聊云原生世界的“防火墙”——Kubernetes Network Policy(K8s网络策略)以及它的小伙伴 CNI 插件。没错,就是那个能让你的 Pod “各扫门前雪”,确保安全又清净的神器!
开场白:云原生世界里的“邻里关系”
想象一下,你的云原生应用就像一个热闹的小区,各种微服务、数据库、缓存都在里面安家落户。一开始大家其乐融融,互相协作,共享资源,简直是乌托邦!但是,随着小区规模越来越大,住户越来越多,问题也来了:
- 熊孩子微服务: 有些微服务调皮捣蛋,未经允许就想访问别人的数据库,搞得数据鸡飞狗跳。
- 八卦大妈微服务: 有些微服务喜欢打探隐私,偷偷窥探其他微服务的配置信息,简直是防不胜防。
- 恶意访客: 有些黑客伪装成普通住户,混入小区,试图入侵你的应用。
这时候,我们不禁要问:小区物业在哪儿?保安在哪里?怎么没人管管这些乱象?
别急!Kubernetes Network Policy 就是你的小区物业,CNI 插件就是你的尽职尽责的保安。它们联手打造一个安全、有序的云原生环境,让你的应用免受各种威胁。
第一幕:Network Policy 闪亮登场!
Network Policy,顾名思义,就是用来定义网络访问规则的策略。它就像一份“邻里公约”,规定了哪些 Pod 可以访问哪些 Pod,哪些流量可以进出你的应用。
1. Network Policy 长啥样?
Network Policy 本质上就是一个 YAML 文件,定义了一些规则,告诉 Kubernetes 如何控制 Pod 之间的网络流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-network-policy # 策略的名字
namespace: my-namespace # 策略应用的命名空间
spec:
podSelector: # 策略应用的目标 Pod
matchLabels:
app: my-app # 匹配标签为 app=my-app 的 Pod
ingress: # 入站规则
- from: # 允许哪些 Pod 访问目标 Pod
- podSelector:
matchLabels:
app: allowed-app # 允许标签为 app=allowed-app 的 Pod 访问
ports: # 允许的端口
- protocol: TCP
port: 8080
egress: # 出站规则
- to: # 允许目标 Pod 访问哪些 Pod
- ipBlock:
cidr: 10.0.0.0/16 # 允许访问 10.0.0.0/16 网段的 IP 地址
ports:
- protocol: TCP
port: 443
别被这些 YAML 代码吓到!咱们来逐行解释:
apiVersion
和kind
:定义了 API 版本和资源类型,告诉 Kubernetes 这是个 Network Policy。metadata
:包含 Network Policy 的名字和命名空间,方便我们管理和查找。spec
:这是 Network Policy 的核心部分,定义了具体的规则。podSelector
:指定 Network Policy 应用的目标 Pod,只有匹配这个选择器的 Pod 才会受到策略的约束。ingress
:定义入站规则,控制哪些流量可以进入目标 Pod。from
:指定允许访问目标 Pod 的来源,可以是其他 Pod、命名空间或者 IP 地址段。ports
:指定允许访问的端口和协议。
egress
:定义出站规则,控制目标 Pod 可以访问哪些目标。to
:指定目标 Pod 可以访问的目标,可以是其他 Pod、命名空间或者 IP 地址段。ports
:指定允许访问的端口和协议。
2. Network Policy 的工作原理
Network Policy 的工作原理其实很简单:它会拦截 Pod 之间的网络流量,然后根据你定义的规则进行判断,决定是否允许流量通过。如果流量符合规则,就放行;如果不符合规则,就直接丢弃。
就像小区保安一样,Network Policy 会检查每一个进出你家门的访客,看看他们有没有通行证,有没有不良记录,然后决定是否放行。
3. Network Policy 的“默认规则”
在 Kubernetes 中,Network Policy 有一个非常重要的默认规则:默认允许所有流量。也就是说,如果你没有定义任何 Network Policy,那么所有的 Pod 都可以互相访问,没有任何限制。
这就像一个没有保安的小区,任何人都可以自由进出,安全隐患非常大。所以,为了确保安全,你必须主动定义 Network Policy,明确指定哪些流量可以进出你的应用。
第二幕:CNI 插件登场!
Network Policy 虽然很强大,但它本身并不能直接控制网络流量。它需要借助 CNI 插件来实现具体的网络策略执行。
1. 什么是 CNI 插件?
CNI(Container Network Interface)是 Kubernetes 定义的一个标准接口,用于配置容器的网络。CNI 插件就是实现了这个接口的程序,它可以负责创建和管理容器的网络,包括分配 IP 地址、配置路由、设置防火墙等等。
简单来说,CNI 插件就像 Kubernetes 的“网络管理员”,负责管理 Pod 的网络连接。
2. CNI 插件的种类
市面上有很多 CNI 插件可供选择,例如:
- Calico: 一个非常流行的 CNI 插件,提供了强大的网络策略和安全功能。
- Cilium: 基于 eBPF 技术,提供了高性能的网络策略和可观察性。
- Weave Net: 一个简单易用的 CNI 插件,适合小型集群。
- Flannel: 一个经典的 CNI 插件,使用 VXLAN 技术构建 overlay 网络。
选择哪个 CNI 插件取决于你的具体需求。如果你需要强大的网络策略和安全功能,可以选择 Calico 或 Cilium;如果你需要一个简单易用的 CNI 插件,可以选择 Weave Net 或 Flannel。
3. CNI 插件如何与 Network Policy 配合?
CNI 插件会监听 Kubernetes API 服务器,当有新的 Network Policy 创建或更新时,CNI 插件会读取这些策略,然后将它们转换成具体的网络规则,配置到 Pod 的网络接口上。
就像小区保安接到物业的通知,得知哪些住户可以自由进出小区,哪些住户需要特殊检查,然后根据通知执行相应的操作。
第三幕:Network Policy 的高级安全实践
有了 Network Policy 和 CNI 插件,我们就可以构建各种高级安全策略,保护我们的云原生应用。
1. Namespace 隔离
Namespace 是 Kubernetes 中用于隔离资源的一种机制。我们可以使用 Network Policy 来实现 Namespace 级别的网络隔离,防止不同 Namespace 中的 Pod 互相访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-namespace
namespace: my-namespace
spec:
podSelector: {} # 匹配所有 Pod
ingress:
- from:
- podSelector: {}
namespaceSelector:
matchLabels:
name: my-namespace # 只允许来自相同 Namespace 的 Pod 访问
这个 Network Policy 会阻止来自其他 Namespace 的所有流量进入 my-namespace
Namespace 中的 Pod。
2. 基于标签的访问控制
我们可以使用标签来定义更细粒度的访问控制规则。例如,我们可以给数据库 Pod 打上 role=database
的标签,然后只允许应用 Pod 访问数据库 Pod。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app-to-db
namespace: my-namespace
spec:
podSelector:
matchLabels:
role: database # 匹配标签为 role=database 的 Pod
ingress:
- from:
- podSelector:
matchLabels:
app: my-app # 允许标签为 app=my-app 的 Pod 访问
ports:
- protocol: TCP
port: 5432 # 允许访问 5432 端口(PostgreSQL 默认端口)
这个 Network Policy 只允许标签为 app=my-app
的 Pod 访问标签为 role=database
的 Pod 的 5432 端口。
3. 限制外部访问
我们可以使用 Network Policy 来限制外部流量进入我们的应用。例如,我们可以只允许来自特定 IP 地址段的流量访问我们的应用。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-access
namespace: my-namespace
spec:
podSelector:
matchLabels:
app: my-app
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/16 # 只允许来自 10.0.0.0/16 网段的 IP 地址访问
ports:
- protocol: TCP
port: 80
- from:
- ipBlock:
cidr: 20.0.0.0/16 # 只允许来自 20.0.0.0/16 网段的 IP 地址访问
ports:
- protocol: TCP
port: 443
这个 Network Policy 只允许来自 10.0.0.0/16
和 20.0.0.0/16
网段的 IP 地址访问标签为 app=my-app
的 Pod 的 80 和 443 端口。
4. 使用 Global Network Policy
有些 CNI 插件(例如 Calico)支持 Global Network Policy,它可以应用于整个集群,而不仅仅是单个 Namespace。这对于实现一些全局性的安全策略非常有用,例如:
- 默认拒绝所有流量: 可以创建一个 Global Network Policy,默认拒绝所有流量,然后只允许特定的流量通过。
- 强制执行安全策略: 可以创建一个 Global Network Policy,强制所有 Namespace 都必须遵守特定的安全策略。
第四幕:实战演练:保护你的 WordPress 应用
为了让大家更好地理解 Network Policy 的用法,我们来一个实战演练:保护一个简单的 WordPress 应用。
1. 应用架构
我们的 WordPress 应用包含两个 Pod:
- wordpress: 运行 WordPress 程序的 Pod。
- mysql: 运行 MySQL 数据库的 Pod。
2. 安全需求
- 只允许
wordpress
Pod 访问mysql
Pod 的 3306 端口(MySQL 默认端口)。 - 只允许外部流量访问
wordpress
Pod 的 80 和 443 端口。 - 阻止所有其他流量。
3. 实现步骤
- 给 Pod 打标签:
# wordpress Pod 的 YAML 文件
apiVersion: v1
kind: Pod
metadata:
name: wordpress
labels:
app: wordpress
role: web
spec:
containers:
- name: wordpress
image: wordpress:latest
ports:
- containerPort: 80
# mysql Pod 的 YAML 文件
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
app: mysql
role: db
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
- 创建 Network Policy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: wordpress-network-policy
namespace: default
spec:
podSelector: {} # 匹配所有 Pod
ingress:
- from:
- podSelector:
matchLabels:
app: wordpress # 允许 wordpress Pod 访问
ports:
- protocol: TCP
port: 3306 # 允许访问 3306 端口
- from:
- ipBlock:
cidr: 0.0.0.0/0 # 允许来自任何 IP 地址的流量
ports:
- protocol: TCP
port: 80 # 允许访问 80 端口
- protocol: TCP
port: 443 # 允许访问 443 端口
egress:
- to: {} # 允许所有出站流量
这个 Network Policy 做了以下事情:
- 允许
wordpress
Pod 访问mysql
Pod 的 3306 端口。 - 允许来自任何 IP 地址的流量访问
wordpress
Pod 的 80 和 443 端口。 - 允许所有出站流量,因为 WordPress 需要访问外部资源。
4. 验证结果
部署 Network Policy 后,你可以尝试从其他 Pod 或外部网络访问 mysql
Pod 的 3306 端口,你会发现访问被拒绝。但是,你可以正常访问 wordpress
Pod 的 80 和 443 端口。
第五幕:常见问题解答
-
Q:我应该选择哪个 CNI 插件?
A:选择哪个 CNI 插件取决于你的具体需求。如果你需要强大的网络策略和安全功能,可以选择 Calico 或 Cilium;如果你需要一个简单易用的 CNI 插件,可以选择 Weave Net 或 Flannel。
-
Q:Network Policy 会影响性能吗?
A:Network Policy 会增加一些额外的网络开销,但通常来说影响不大。如果你对性能非常敏感,可以选择一些高性能的 CNI 插件,例如 Cilium。
-
Q:我可以使用 Network Policy 来阻止 DNS 查询吗?
A:是的,你可以使用 Network Policy 来阻止 DNS 查询。你需要创建一个 Network Policy,阻止 Pod 访问 DNS 服务器的 53 端口。
-
Q:我可以使用 Network Policy 来限制 Pod 的 CPU 和内存使用吗?
A:不可以。Network Policy 只能控制网络流量,不能控制 Pod 的 CPU 和内存使用。你需要使用 Resource Quotas 和 Limit Ranges 来限制 Pod 的 CPU 和内存使用。
总结:打造坚不可摧的云原生安全防线
Kubernetes Network Policy 和 CNI 插件是云原生安全的重要组成部分。它们可以帮助你构建一个安全、可靠、可控的云原生环境,保护你的应用免受各种威胁。
希望今天的分享能帮助大家更好地理解 Network Policy 和 CNI 插件,并在实际项目中灵活运用。记住,安全无小事,一定要重视云原生安全,打造坚不可摧的安全防线!🛡️
感谢大家的观看!我们下期再见!👋