k8s学习笔记-网络策略

​网络策略(Network Policy )

1.概述

网络策略是允许群组与其他网络终端进行通信的规范。

NetworkPolicy资源使用标签选择pods并定义规则,以指定允许所选pods的流量。

2.使用网络策略的前提 
网络策略由网络插件实现,因此您必须使用支持NetworkPolicy的网络解决方案

​Kubernetes的网络策略功能也是由第三方的网络插件实现的,因此,只有支持网络策略功能的网络插件才能进行配置网络策略,比如Calico、Canal、kube-router等等。

3.隔离和非隔离pods
默认pods与pods之间是非隔离的,通过网络插件可以是实现允许哪些pod的流量或者不允许哪些pod的流量

 网络策略也是Kubernetes 的一种资源。Network Policy 通过 Label 选择 Pod,并指定其他 Pod 或外界如何与这些 Pod 通信。

​ Pod的网络流量包含流入(Ingress)和流出(Egress)两种方向。默认情况下,所有 Pod 是非隔离的,即任何来源的网络流量都能够访问 Pod,没有任何限制。

当为 Pod 定义了 Network Policy,只有 Policy 允许的流量才能访问 Pod。

注意:Kubernetes自1.8版本才支持Egress网络策略,在该版本之前仅支持Ingress网络策略。

总结:

网络策略说明一组 Pod 之间是如何被允许互相通信,以及如何与其它网络 Endpoint 进行通信。

网络策略通过网络插件来实现,所以必须使用一种支持 NetworkPolicy 的网络方案 —— 非 Controller 创建的资源,是不起作用的。

前面我们学习到的Flannel自身并不具备为Pod网络实现网络策略和网络通信隔离的功能,为此只能借助于Calico联合统一的项目Calnal项目进行构建网络策略的功能

4.部署Canal提供网络策略功能

calico官网

https://docs.projectcalico.org/v3.7/getting-started/kubernetes/

Calico可以独立地为Kubernetes提供网络解决方案和网络策略,也可以和flannel相结合,由flannel提供网络解决方案,Calico仅用于提供网络策略,此时将Calico称为Canal。

结合flannel工作时,Calico提供的默认配置清单式以flannel默认使用的10.244.0.0/16为Pod网络,因此在集群中kube-controller-manager启动时就需要通过--cluster-cidr选项进行设置使用该网络地址,

并且---allocate-node-cidrs的值应设置为true。我们前面通过flannel实现了网络,现在是需要提供一种网络策略,按下面文档安装即可

https://docs.projectcalico.org/v3.7/getting-started/kubernetes/installation/flannel

总结安装的方法:

必须开启--allocate-node-cidrs=true.默认是开启的

如果我们自己设置了--pod-network-cidr=<your-pod-cidr>需要替换配置文件

sed -i -e "s?10.244.0.0/16?$POD_CIDR?g"  canal.yaml

我默认使用kubeadm 安装的时候指定了10.244.0.0/16 所以不需要修改

curl https://docs.projectcalico.org/v3.7/manifests/canal.yaml -O
kubectl apply -f canal.yaml
[root@k8s-master k8s]# kubectl get pods -n kube-system -o wide |egrep canal |awk '{print $1,$6,$7}'
canal-4fnfs 10.211.55.12 k8s-node1
canal-68spc 10.211.55.13 k8s-node2
canal-ztk94 10.211.55.11 k8s-master

可以看到Canal作为DaemonSet部署到每个节点,属于kube-system这个名称空间。

需要注意的是,Canal只是直接使用了Calicoflannel项目,代码本身没有修改,Canal只是一种部署的模式,用于安装和配置项目

5.配置网络策略

在Kubernetes系统中,报文的流入和流出的核心组件是Pod资源,它们也是网络策略功能的主要应用对象。

NetworkPolicy对象通过podSelector选择 一组Pod资源作为控制对象。

NetworkPolicy是定义在一组Pod资源之上用于管理入站流量(Ingress),或出站流量(Egress)的一组规则,也可以出入站规则一起生效,规则的生效模式通常由spec.policyTypes进行 定义

kubectl explain networkpolicy
kubectl explain networkpolicy.spec.egress
kubectl explain networkpolicy.spec.ingress
kubectl explain networkpolicy.spec.policytypes

如图:

 

默认情况下,Pod对象的流量控制是为空的,报文可以自由出入。

在附加网络策略之后,Pod对象会因为NetworkPolicy而被隔离,

一旦名称空间中有任何NetworkPolicy对象匹配了某特定的Pod对象,则该Pod将拒绝NetworkPolicy规则中不允许的所有连接请求,但是那些未被匹配到的Pod对象依旧可以接受所有流量。

就特定的Pod集合来说,入站和出站流量默认是放行状态,除非有规则可以进行匹配。

还有一点需要注意的是,在spec.policyTypes中指定了生效的规则类型,但是在networkpolicy.spec字段中嵌套定义了没有任何规则的Ingress或Egress时,则表示拒绝入站或出站的一切流量。

定义网络策略的基本格式如下:

1.入站规则演示:

定义默认策略为拒绝所有:
vim ingress-def.yaml
apiVersion:  networking.k8s.io/v1 #这里注意一下
kind:  NetworkPolicy
metadata:
   name:  deny-all-ingress
spec:
   podSelector:  {}                # 默认选择器为空,表示选整个名称空间的所有Pod
   policyTypes:                     #policyTypes ["Ingress"]  可以是Ingress,Egress,或者两者共存
   -  Ingress                          #指明了Ingress生效规则,但不定义任何Ingress字段,因此不能匹配任何源端点,从而拒绝所有的入站流量

下面验证一下

kubectl create namespace dev
kubectl create namespace prod
vim pod-a.yaml
apiVersion:  v1
kind:  Pod
metadata:
   name:  pod1
spec:
  containers:
  -  name:  myapp
     image: ikubernetes/myapp:v1

kubectl apply -f pod-a.yaml -n dev
kubectl apply -f pod-a.yaml -n prod
kubectl apply -f ingress-def.yaml -n dev
[root@k8s-master networkpolicy]# kubectl get netpol -n dev
NAME                      POD-SELECTOR          AGE
deny-all-ingress            <none>                     11m
[root@k8s-master networkpolicy]# kubectl get pods -n dev -o wide |awk '{print $1,$6}'
NAME IP
pod1 10.244.2.2
[root@k8s-master networkpolicy]# kubectl get pods -n prod -o wide |awk '{print $1,$6}'
NAME IP
pod1 10.244.2.3
[root@k8s-master networkpolicy]# curl 10.244.2.2 
[root@k8s-master networkpolicy]# curl 10.244.2.3
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
通过上面的规则,2.3 可以访问,2.2 访问不了

这样就验证了上面的规则,默认拒绝整个dev名称空间的所有入站规则,出站规则是允许的,没有定义
下面修改规则允许访问:

如果要将默认策略设置为允许所有入站流量,只需要定义Ingress字段,并将这个字段设置为空,以匹配所有源端点,但本身不设定网络策略,就已经是默认允许所有入站流量访问的
spec:
   podSelector: {}
   ingress:
   -  {}  #表示允许所有
   policyTypes:
   -  Ingress

kubectl apply -f ingress-def.yaml -n dev
[root@k8s-master networkpolicy]# curl 10.244.2.2
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
下面演示一个只允许访问带特定标签的POD 的80 端口,其他端口都拒绝
修改默认规则为拒绝所有
这样 curl 10.244.2.2 实效
kubectl apply -f ingress-def.yaml -n dev
vim ingress-allow.yaml
apiVersion:  networking.k8s.io/v1
kind:  NetworkPolicy
metadata:
   name:  allow-myapp-ingress
spec:
   podSelector:
   matchLabels:
      app:  myapp
   ingress:
   -  from:
      -  ipBlock:
         cidr:  10.244.0.0/16 #允许这个网段访问
         except:
         -  10.244.1.2/32 #排除这个地址,记得加子网掩码
       ports:
       -  protocol: TCP
          port: 80 #允许访问的端口
kubectl label pods pod1 app=myapp -n dev
kubectl apply -f ingress-all.yaml -n dev
[root@k8s-master networkpolicy]# curl 10.244.2.2
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master networkpolicy]# curl 10.244.2.2:443 这个访问就拒绝了

2.出站规则:

定义默认规则为拒绝本名称空间下所有pod 
vim egress-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
   spec:
    podSelector: {}
    policyTypes:
    -   Egress

kubectl apply -f egress-deny.yaml -n prod
kubectl exec -it pod1 -n prod -- ping 10.244.1.12(这个是集群下面的pod地址)

上面规则影响,不能ping通
修改默认规则为允许所有
spec:
   podSelector:  {}
   egress:
   -  {}
   policyTypes:
   -  Egress
[root@k8s-master networkpolicy]# kubectl exec -it pod1 -n prod -- ping 10.244.1.12
PING 10.244.1.12 (10.244.1.12): 56 data bytes
64 bytes from 10.244.1.12: seq=0 ttl=62 time=0.481 ms
64 bytes from 10.244.1.12: seq=1 ttl=62 time=0.621 ms
64 bytes from 10.244.1.12: seq=2 ttl=62 time=0.594 ms

总结:

定义规则的标准规范,类似防火墙

默认先拒绝所有出站,入站

放行需要的入站和出站

为了安全,我们可以设置每个名称空间拒绝所有入站、拒绝所有出站,然后单独放行;

但是这样也会有一个问题,就是同一名称空间的pod也不能通信;

所以还要加条策略就是允许本名称空间的pod之间可以互相通信(放行所有出站目标本名称空间内的所有pod),但是不允许和外部名称空间之间进行通信;

这里用我现在的K8S 环境来实施:

​通常需要彼此隔离所有的名称空间,但是又需要允许它们可以和kube-system名称空间中的Pod资源进行流量交换,以实现监控和名称解析等各种管理功能。

下面的配置清单示例在default名称空间定义相关规则,在出站和入站都默认均为拒绝的情况下,它用于放行名称空间内部的各Pod对象之间的通信,以及和kube-system名称空间内各Pod间的通信。

需要注意的是,有一些额外的系统附件可能会单独部署到独有的名称空间中,比如将prometheus监控系统部署到prom名称空间等,这类具有管理功能的附件所在的名称空间和每一个特定的名称空间的出入流量也是需要被放行的

所以网络策略的使用还是根据实际情况来制定,规则定义简单,但是结合实际可能要踩许多坑了,这个需要自行测试了。

 

转载于:https://www.cnblogs.com/centos-python/articles/10876083.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值