k8s集群网络策略(Network Policy)

梁浩
2023-12-01

默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。
网络策略(Network Policy):是一个K8s资源,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。
网络策略的应用场景:
• 应用程序间的访问控制,例如项目A不能访问项目B的Pod
• 开发环境命名空间不能访问测试环境命名空间Pod
• 当Pod暴露到外部时,需要做Pod白名单
• 多租户网络环境隔离
官方文档说明:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
NetworkPolicy 的示例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

说明:

podSelector:目标Pod,根据标签选择。
policyTypes:策略类型,指定策略用于入站、出站流量。
Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、入流量
Pod标签等,ports是可以访问的端口。
Egress:这个Pod组可以访问外部的IP段和端口,出流量

案例一、拒绝namespace下所有的pod出入站流量

[root@master1 np]# kubectl create ns test		#创建测试ns
namespace/test created
[root@master1 np]# kubectl run web --image=nginx -n test		#创建测试pod web
pod/web created
[root@master1 np]# kubectl run busybox --image=busybox -n test -- sleep 12h  #创建测试pod
pod/busybox created
#验证pod可正常访问
[root@master1 np]# kubectl exec busybox -n test -- ping baidu.com
PING baidu.com (39.156.69.79): 56 data bytes
64 bytes from 39.156.69.79: seq=0 ttl=127 time=44.998 ms
64 bytes from 39.156.69.79: seq=1 ttl=127 time=91.008 ms
64 bytes from 39.156.69.79: seq=2 ttl=127 time=76.516 ms
^C

创建应用拒绝访问test ns的规则

[root@master1 np]# kubectl apply -f test.yaml
networkpolicy.networking.k8s.io/deny-all-test created
[root@master1 np]# cat test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-test
  namespace: test    #匹配的ns
spec:
  podSelector: {}    #匹配所有的pod
  policyTypes:
  - Ingress
  - Egress
## ingress和egress没有指定规则,则不允许任何流量进出pod
[root@master1 np]# kubectl get networkpolicy -n test
NAME            POD-SELECTOR   AGE
deny-all-test   <none>         4m13s
#测试是否拒绝
[root@master1 np]# kubectl exec busybox -n test -- ping baidu.com
ping: bad address 'baidu.com'
command terminated with exit code 1

#测试无法访问规则生效

案例二:拒绝其他命名空间Pod访问
需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。

[root@master1 np]# cat test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-test
  namespace: test
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

案例三:允许其他命名空间Pod访问指定应用

[root@master1 np]# cat test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-test
  namespace: test
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

案例四、同一个命名空间下应用之间限制访问
需求:将标签为run=web的pod隔离,只允许标签为run=client1的pod访问80端口

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-test
  namespace: test
spec:
  podSelector:
    matchLabels:
      run: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          run: client1
    ports:
    - protocol: TCP
      port: 80

注:原生使用k8s网络策略 flannel不支持,需要切换成calico.这个在k8s官方有说明
云上环境使用网络策略Network Policy 参考:https://help.aliyun.com/document_detail/97621.html?spm=a2c4g.11186623.6.763.6f575ffeTaThH4

 类似资料: