手把手教你配置 Kubernetes 网络策略,提升集群安全性
Kubernetes 网络策略:集群安全的最后一道防线
最近在啃 Kubernetes,发现网络策略这玩意儿是真的重要。它就像集群里的防火墙,能帮你控制 Pod 之间的流量,防止一些不必要的访问,提高整体的安全性。今天就来聊聊怎么配置 Kubernetes 网络策略,让你的集群更安全。
为什么需要网络策略?
想象一下,如果你的 Kubernetes 集群里,所有的 Pod 都可以互相访问,那会怎么样?一旦某个 Pod 被攻破,攻击者就能轻松地访问集群里的其他服务,后果不堪设想。网络策略就是为了解决这个问题而生的。它可以让你定义哪些 Pod 可以互相访问,哪些不能,从而缩小攻击面,提高安全性。
网络策略的核心概念
在开始配置网络策略之前,我们需要了解几个核心概念:
- Pod Selector: 用于选择一组 Pod,例如
app=nginx可以选择所有带有app=nginx标签的 Pod。 - Namespace Selector: 用于选择一个 Namespace,例如
namespace=default可以选择defaultNamespace。 - Policy Types: 网络策略有两种类型:
- Ingress: 控制进入 Pod 的流量。
- Egress: 控制 Pod 发出的流量。
- Ports: 指定允许的端口。
- IPBlock: 指定允许的 IP 地址范围。
实战演练:配置网络策略
接下来,我们通过一个例子来演示如何配置 Kubernetes 网络策略。假设我们有两个 Namespace:dev 和 prod。dev Namespace 用于开发环境,prod Namespace 用于生产环境。我们希望实现以下目标:
prodNamespace 中的 Pod 只能被ingress-nginxNamespace 中的 Pod 访问。devNamespace 中的 Pod 可以访问任何 Pod。- 所有 Pod 都可以访问集群内部的 DNS 服务(通常是
kube-systemNamespace 中的kube-dnsPod)。
步骤 1:创建 Namespace
首先,我们需要创建 dev 和 prod Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Namespace
metadata:
name: prod
执行以下命令创建 Namespace:
kubectl apply -f namespace.yaml
步骤 2:部署 Pod
为了方便演示,我们在 dev 和 prod Namespace 中分别部署一个 Nginx Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dev
namespace: dev
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-prod
namespace: prod
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
执行以下命令部署 Pod:
kubectl apply -f deployment.yaml
步骤 3:配置网络策略
接下来,我们创建网络策略来限制 prod Namespace 中的 Pod 的访问:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: prod-allow-ingress
namespace: prod
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system # 允许 kube-system namespace 访问,通常用于 DNS
ports:
- protocol: UDP
port: 53
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system # 允许 kube-system namespace 访问,通常用于 DNS
ports:
- protocol: UDP
port: 53
这个网络策略做了以下几件事:
podSelector选择了prodNamespace 中所有带有app=nginx标签的 Pod。policyTypes指定了这是一个 Ingress 类型的网络策略,用于控制进入 Pod 的流量。ingress定义了允许哪些流量进入 Pod:namespaceSelector选择了ingress-nginxNamespace,允许该 Namespace 中的 Pod 访问prodNamespace 中的 Pod。namespaceSelector选择了kube-systemNamespace,允许该 Namespace 中的 Pod 访问prodNamespace 中的 Pod,主要用于 DNS 解析。ports允许 UDP 协议的 53 端口,用于 DNS 解析。
egress定义了允许 Pod 发出哪些流量:namespaceSelector选择了kube-systemNamespace,允许 Pod 访问该 Namespace 中的 Pod,主要用于 DNS 解析。ports允许 UDP 协议的 53 端口,用于 DNS 解析。
执行以下命令创建网络策略:
kubectl apply -f networkpolicy.yaml
步骤 4:验证网络策略
为了验证网络策略是否生效,我们可以创建一个测试 Pod,分别在 dev 和 prod Namespace 中尝试访问 prod Namespace 中的 Nginx Pod。如果网络策略配置正确,dev Namespace 中的 Pod 应该可以访问 prod Namespace 中的 Nginx Pod,而 prod Namespace 中的 Pod 无法访问。
首先,创建测试 Pod:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: <namespace>
spec:
containers:
- name: test
image: busybox:latest
command: ['sh', '-c', 'while true; do sleep 3600; done']
将 <namespace> 替换为 dev 或 prod,然后执行以下命令创建 Pod:
kubectl apply -f test-pod.yaml
进入 Pod:
kubectl exec -it test-pod -n <namespace> -- sh
尝试访问 prod Namespace 中的 Nginx Pod:
wget -O- <nginx-prod-service-ip>
将 <nginx-prod-service-ip> 替换为 prod Namespace 中 Nginx Service 的 IP 地址。如果网络策略配置正确,dev Namespace 中的 Pod 应该可以成功访问,而 prod Namespace 中的 Pod 无法访问。
总结
Kubernetes 网络策略是提高集群安全性的重要手段。通过合理配置网络策略,我们可以限制 Pod 之间的网络流量,缩小攻击面,防止恶意攻击。希望这篇文章能帮助你更好地理解和使用 Kubernetes 网络策略,让你的集群更安全。
额外提示
- 选择合适的 CNI 插件: 不同的 CNI 插件对网络策略的支持程度不同,选择一个支持网络策略的 CNI 插件非常重要。常见的 CNI 插件包括 Calico、Cilium、Flannel 等。
- 使用 NetworkPolicy Controller: 可以使用 NetworkPolicy Controller 来自动化管理网络策略,例如自动创建默认的网络策略,监控网络策略的执行情况等。
- 持续监控和审计: 定期检查和更新网络策略,确保其符合安全要求。同时,对网络策略的执行情况进行监控和审计,及时发现和解决安全问题。
希望这些信息能帮到你,祝你学习顺利!