1,NetworkPolicy
简介
为了实现细粒度的容器间往来访问隔离策略,Kubernetes 从 1.3 版本开始,由 SIG-Network 小组主导研发了 Network Policy 机制,目前已升级为 networking.k8s.io/v1 稳定版本。Network Policy 的主导功能是对 Pod 间的网络通信进行限制和准入控制,设置方式为将 Pod 的 Label 作为查询条件,设置允许访问或禁止访问的客户端 Pod 列表。目前查询条件可以作用于 Pod 和 Namespace 级别。
为了使用 Network Policy,Kubernetes 引入了一个新的资源对象 NetworkPolicy,供用户设置 Pod 间网络访问的策略。但仅定义一个网络策略是无法完成实际的网络隔离的,还需要一个策略控制器(Policy Controller)进行策略的实现。策略控制器由第三方网络组建提供,目前 Calico、Cilium、Kube-router、Romana、Weave Net 等开源项目均支持网络策略的实现。
Policy Controller 需要实现一个 API Listener,监听用户设置的 NetworkPolicy 定义,并将网络访问规则通过各 Node 的 Agent 进行实际设置(Agent 则需要通过 CNI 网络插件实现)。
隔离和非隔离的 Pod
默认情况下,Pod 是非隔离的,它们接受任何来源的流量。
Pod 在被某 NetworkPolicy 选中时进入被隔离状态。 一旦名称空间中有 NetworkPolicy 选择了特定的 Pod,该 Pod 会拒绝该 NetworkPolicy 所不允许的连接。 (名称空间下其他未被 NetworkPolicy 所选择的 Pod 会继续接受所有的流量)
网络策略不会冲突,它们是累积的。 如果任何一个或多个策略选择了一个 Pod, 则该 Pod 受限于这些策略的 入站(Ingress)/出站(Egress)规则的并集。因此评估的顺序并不会影响策略的结果。
为了允许两个 Pods 之间的网络数据流,源端 Pod 上的出站(Egress)规则和 目标端 Pod 上的入站(Ingress)规则都需要允许该流量。 如果源端的出站(Egress)规则或目标端的入站(Ingress)规则拒绝该流量, 则流量将被拒绝。
部署calic网络
wget https://docs.projectcalico.org/v3.9/manifests/calico.yaml
kubectl apply -f calico.yaml
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5fbfc9dfb6-jhddm 1/1 Running 0 16m
calico-node-2d28h 1/1 Running 0 16m
calico-node-77rx5 1/1 Running 0 16m
calico-node-xzrdh 1/1 Running 0 16m
coredns-7ff77c879f-p4smr 1/1 Running 0 18m
coredns-7ff77c879f-tn7w9 1/1 Running 0 18m
etcd-master 1/1 Running 0 18m
kube-apiserver-master 1/1 Running 0 18m
kube-controller-manager-master 1/1 Running 0 18m
kube-proxy-8h5gh 1/1 Running 0 18m
kube-proxy-97dzz 1/1 Running 0 18m
kube-proxy-986fs 1/1 Running 0 18m
kube-scheduler-master 1/1 Running 0 18m
NetworkPolicy示例
参数说明:
podSelector:用于定义该网络策略作用的 Pod 方位,本例的选择条件为包含 "role=db" 标签的 Pod。
policyTypes:网络策略的类型,包括 ingress 和 egress 两种,用于设置目标 Pod 的入站和出站的网络限制。
ingress:定义允许访问目标 Pod 的入站白名单规则,满足 from 条件的客户端才能访问 ports 定义的目标 Pod 端口号。
- from:对符合条件的客户端 Pod 进行网络放行,规则包括基于客户端 Pod 的 Label、基于客户端 Pod 所在的 Namespace 的 Label 或者客户端的 IP 范围。
- ports:允许访问的目标 Pod 监听的端口号。
egress:定义目标 Pod 允许访问的 "出站" 白名单规则,目标 Pod 仅允许访问满足 to 条件的服务端 IP 范围和 ports 定义的端口号。
- to: 允许访问的服务端信息,可以基于服务端 Pod 的Label、基于服务端 Pod 所在的 Namespace 的 Label 或者服务端 IP 范围。
- ports:允许访问的服务端的端口号。
创建两个名称空间
[root@master ~]# kubectl create namespace dev
namespace/dev created
[root@master ~]# kubectl create namespace prod
namespace/prod created
[root@master ~]# cat pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
[root@master ~]# kubectl apply -f pods.yaml -n dev
[root@master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 57s 192.168.196.131 node01 <none> <none>
[root@master ~]# cat ingres-def.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ingres
namespace: dev
spec:
podSelector: {}
policyTypes:
- Ingress
测试:
image.png
将pod创建在prod中
[root@master ~]# kubectl apply -f pods.yaml -n prod
pod/pod1 created
[root@master ~]# kubectl get pods -n prod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 14s 192.168.140.69 node02 <none>
<none>
测试:
[root@master ~]# curl 192.168.140.69
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
上面的networkpolicy中定义了ingress要生效但是ingress没有定义规则就表示默认不允许任何人访问,egress没有定义默认所有的都可以访问
定义所有访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ingres
namespace: dev
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
[root@master ~]# kubectl apply -f ingres-def.yaml
networkpolicy.networking.k8s.io/ingres configured
测试:
[root@master ~]# curl 192.168.196.131
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
允许别人来放着这组pod
给pod打个标签
[root@master ~]# kubectl label pods pod1 app=myapp -n dev
pod/pod1 labeled
vim allow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress
spec:
podSelector:
matchLabels:
app: myapp
ingress:
- from:
- ipBlock:
cidr: 192.168.0.0/16
except:
- 192.168.1.12/32
ports:
- protocol: TCP
port: 80
[root@master ~]# kubectl apply -f allow-ingress.yaml -n dev
[root@master ~]# kubectl get netpol -n dev
NAME POD-SELECTOR AGE
allow-ingress app=myapp 65s
ingres <none> 45m
官方文档:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
网友评论