Bootstrap

如何在 K3s 中使用网络策略

本文将介绍如何在示例项目中使用网络策略,并解释它在 K3s 中的工作原理,从而帮助用户提高部署的安全性。

关于 K3s 对网络策略的支持存在一个普遍的误解,因为 K3s 默认使用 Flannel CNI,而 Flannel CNI 不支持网络策略。其实,K3s 使用 Kube-router 网络策略控制器为网络策略提供支持,所以网络策略也可以在 K3s 中使用,就像在其他 Kubernetes 发行版中一样。

正常的 Pod 相互通信

默认情况下,在 K3s 中,一个特定命名空间中的所有 services/Pod 都可以被任何其他命名空间中的所有其他 Pod 访问。

为了举例说明 Pod 如何相互通信,让我们在两个不同的命名空间(sample1 和 sample2)中使用简单的 nginx deployment 和 service 来测试,如下所示:

nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: ngnix-service
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

创建测试命名空间并将 nginx 部署到对应命名空间中:

# 在 sample1 中创建第一个示例应用
kubectl create ns sample1
kubectl apply -f nginx.yaml -n sample1

# 在 sample2 中创建第二个示例应用
kubectl create ns sample2
kubectl apply -f nginx.yaml -n sample2

接下来可以尝试在 Pod 中使用 curl 来检查 Pod 间的通信。

sample1 中的 pod -> sample2 命名空间中的 service:

# 从 sample1 访问 sample2
kubectl exec -n sample1 $(kubectl get po -n sample1 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample2.svc.cluster.local

# 从 sample1 访问 sample1
kubectl exec -n sample1 $(kubectl get po -n sample1 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample1.svc.cluster.local:80

sample2 中的 pod -> sample1 命名空间中的 service:

# 从 sample2 访问 sample1
kubectl exec -n sample2 $(kubectl get po -n sample2 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample1.svc.cluster.local:80

# 从 sample2 访问 sample2
kubectl exec -n sample2 $(kubectl get po -n sample2 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample2.svc.cluster.local:80

可以看到,以上命令均可以访问到对应目的地址,也就代表相互都可以通信。

使用 NetworkPolicy 限制 Pod 相互通信

NetworkPolicy Editor(https://editor.cilium.io/)是一个很好的 UI 工具,可以用于生成 Networkploicy,下面是一个示例。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network
;