Network Policy及應用
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.Network Policy概述
network policy規范包含在給定命名空間中定義特定網絡策略所需的所有信息。
podSeletcor:
每個NetworkPolicy都包含一個podSelector,它選擇應用該策略的pod分組。空的podSeletcor選擇命名空間中的所有pod。
policyTypes:
每個NetworkPolicy都包含一個podTypes列表,其中可能包括入口、出口或兩者。policyTypes字段指示給定策略是否應用於所選pod的入口流量、所選pod的出口流量或兩者。如果在網絡策略上未指定策略類型,則默認情況下,將始終設置入口,如果網絡策略具有任何出口規則,則將設置出口。

[root@master200.yinzhengjie.org.cn ~]# kubectl explain netpol KIND: NetworkPolicy VERSION: networking.k8s.io/v1 DESCRIPTION: NetworkPolicy describes what network traffic is allowed for a set of Pods FIELDS: apiVersion <string> APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind <string> Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata spec <Object> Specification of the desired behavior for this NetworkPolicy. [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl explain netpol.spec KIND: NetworkPolicy VERSION: networking.k8s.io/v1 RESOURCE: spec <Object> DESCRIPTION: Specification of the desired behavior for this NetworkPolicy. NetworkPolicySpec provides the specification of a NetworkPolicy FIELDS: egress <[]Object> List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8 ingress <[]Object> List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default) podSelector <Object> -required- Selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace. policyTypes <[]string> List of rule types that the NetworkPolicy relates to. Valid options are "Ingress", "Egress", or "Ingress,Egress". If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include "Egress" (since such a policy would not include an Egress section and would otherwise default to just [ "Ingress" ]). This field is beta-level in 1.8 [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl explain netpol.spec.egress KIND: NetworkPolicy VERSION: networking.k8s.io/v1 RESOURCE: egress <[]Object> DESCRIPTION: List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8 NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. This type is beta-level in 1.8 FIELDS: ports <[]Object> List of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list. to <[]Object> List of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list. [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl explain netpol.spec.ingress KIND: NetworkPolicy VERSION: networking.k8s.io/v1 RESOURCE: ingress <[]Object> DESCRIPTION: List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default) NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. FIELDS: from <[]Object> List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list. ports <[]Object> List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list. [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl explain netpol.spec.podSelector KIND: NetworkPolicy VERSION: networking.k8s.io/v1 RESOURCE: podSelector <Object> DESCRIPTION: Selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace. A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects. FIELDS: matchExpressions <[]Object> matchExpressions is a list of label selector requirements. The requirements are ANDed. matchLabels <map[string]string> matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. [root@master200.yinzhengjie.org.cn ~]#
二.部署Calico網絡模型實現網絡策略(因為集群基於flannel網絡模型用來作於網絡功能,但其不支持網絡策略,我們使用Calico網絡模型來支持網絡策略)
1>.參考官方文檔
博主推薦閱讀: https://docs.projectcalico.org/getting-started/kubernetes/installation/flannel
2>.直接應用canal.yaml配置文件(由於我們使用kubeadm部署k8s時指定的網段默認就是10.244.0.0/16,因此如上圖所示的sed步驟可直接跳過)
[root@master200.yinzhengjie.org.cn ~]# kubectl apply -f https://docs.projectcalico.org/manifests/canal.yaml
3>.部署canal時可以使用"-w"選項實時觀察Pods的信息
[root@master200.yinzhengjie.org.cn ~]# kubectl get pods -n kube-system -w
三.配置網絡策略,使得相同和不同名稱空間的Pod之間無法相互訪問
1>.創建名稱空間
[root@master200.yinzhengjie.org.cn ~]# kubectl create ns yinzhengjie-dev namespace/yinzhengjie-dev created [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl create ns yinzhengjie-prod namespace/yinzhengjie-prod created [root@master200.yinzhengjie.org.cn ~]#
2>.在yinzhengjie-dev名稱空間中創建一個Pod作為服務端
[root@master200.yinzhengjie.org.cn ~]# kubectl create deployment mynginx --image=nginx:1.14-alpine -n yinzhengjie-dev
3>.在yinzhengjie-prod名稱空間創建另外一個pod作為客戶端
[root@master200.yinzhengjie.org.cn ~]# cat client-pod.yaml apiVersion: v1 kind: Pod metadata: name: client-pod spec: containers: - name: client image: busybox imagePullPolicy: IfNotPresent command: ["/bin/sh","-c","sleep 86400"] [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl apply -f client-pod.yaml -n yinzhengjie-prod pod/client-pod created [root@master200.yinzhengjie.org.cn ~]#
4>.連接客戶端Pod去訪問服務端Pod默認是可以正常訪問的
[root@master200.yinzhengjie.org.cn ~]# kubectl exec -it client-pod -n yinzhengjie-prod -- /bin/sh / # / # wget -O - -q 10.244.2.4
5>.使用canal定義網絡策略
[root@master200.yinzhengjie.org.cn ~]# cat Kubernetes_Advanced_Practical/chapter11/deny-all-ingress.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-ingress namespace: yinzhengjie-dev spec: podSelector: {} policyTypes: - Ingress [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl apply -f Kubernetes_Advanced_Practical/chapter11/deny-all-ingress.yaml networkpolicy.networking.k8s.io/deny-all-ingress created [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl describe netpol -n yinzhengjie-dev Name: deny-all-ingress Namespace: yinzhengjie-dev Created on: 2020-02-20 20:17:59 +0800 CST Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"name":"deny-all-ingress","namespace":"yinzhengji... Spec: PodSelector: <none> (Allowing the specific traffic to all pods in this namespace) Allowing ingress traffic: <none> (Selected pods are isolated for ingress connectivity) Not affecting egress traffic Policy Types: Ingress [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]#
6>.連接客戶端Pod去訪問服務端Pod默認是不可以訪問的
7>.相同名稱空間的Pod也不可以相互訪問
四.配置網絡策略,使得指定標簽的名稱空間下的所有Pods可以訪問某一個名稱空間下的所有Pods
1>.為yinzhengjie-prod打標簽
[root@master200.yinzhengjie.org.cn ~]# kubectl label ns yinzhengjie-prod name=prod
2>.創建網絡策略
[root@master200.yinzhengjie.org.cn ~]# cat Kubernetes_Advanced_Practical/chapter11/allow-all-ingress.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-ingress namespace: yinzhengjie-dev spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: prod [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl apply -f Kubernetes_Advanced_Practical/chapter11/allow-all-ingress.yaml networkpolicy.networking.k8s.io/allow-all-ingress created [root@master200.yinzhengjie.org.cn ~]#
3>.我們發現策略會立即生效
五.網絡安全策略其它配置參考案例
1>.指定允許訪問的端口配置案例
[root@master200.yinzhengjie.org.cn ~]# cat Kubernetes_Advanced_Practical/chapter11/allow-all-ingress.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-ingress namespace: yinzhengjie-dev spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: prod ports: - port: 80 [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl apply -f Kubernetes_Advanced_Practical/chapter11/allow-all-ingress.yaml networkpolicy.networking.k8s.io/allow-all-ingress configured [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl describe netpol -n yinzhengjie-dev allow-all-ingress Name: allow-all-ingress Namespace: yinzhengjie-dev Created on: 2020-02-20 20:38:26 +0800 CST Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"name":"allow-all-ingress","namespace":"yinzhengj... Spec: PodSelector: <none> (Allowing the specific traffic to all pods in this namespace) Allowing ingress traffic: To Port: 80/TCP From: NamespaceSelector: name=prod Not affecting egress traffic Policy Types: Ingress [root@master200.yinzhengjie.org.cn ~]#
2>.指定允許多個名稱空間訪問配置案例
[root@master200.yinzhengjie.org.cn ~]# kubectl label ns yinzhengjie-dev name=dev namespace/yinzhengjie-dev labeled [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# cat Kubernetes_Advanced_Practical/chapter11/allow-internnal-ingress.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-internnal-ingress namespace: yinzhengjie-dev spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchExpressions: - key: name operator: In values: ["dev","prod"] ports: - port: 80 [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl apply -f Kubernetes_Advanced_Practical/chapter11/allow-internnal-ingress.yaml networkpolicy.networking.k8s.io/allow-internnal-ingress created [root@master200.yinzhengjie.org.cn ~]#

[root@master200.yinzhengjie.org.cn ~]# kubectl get netpol -n yinzhengjie-dev NAME POD-SELECTOR AGE allow-all-ingress <none> 34m allow-internnal-ingress <none> 18s deny-all-ingress <none> 54m [root@master200.yinzhengjie.org.cn ~]# [root@master200.yinzhengjie.org.cn ~]# kubectl describe netpol -n yinzhengjie-dev allow-internnal-ingress Name: allow-internnal-ingress Namespace: yinzhengjie-dev Created on: 2020-02-20 21:12:10 +0800 CST Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"name":"allow-internnal-ing ress","namespace":"yin...Spec: PodSelector: <none> (Allowing the specific traffic to all pods in this namespace) Allowing ingress traffic: To Port: 80/TCP From: NamespaceSelector: name in (dev,prod) Not affecting egress traffic Policy Types: Ingress [root@master200.yinzhengjie.org.cn ~]#