系列目錄html
Kubernetes要求集羣中全部pod,不管是節點內仍是跨節點,均可以直接通訊,或者說全部pod工做在同一跨節點網絡,此網絡通常是二層虛擬網絡,稱爲pod網絡。在安裝引導kubernetes時,由選擇並安裝的network plugin實現。默認狀況下,集羣中全部pod之間、pod與節點之間能夠互通。nginx
網絡主要解決兩個問題,一個是連通性,實體之間可以經過網絡互通。另外一個是隔離性,出於安全、限制網絡流量的目的,又要控制實體之間的連通性。Network Policy用來實現隔離性,只有匹配規則的流量才能進入pod,同理只有匹配規則的流量才能夠離開pod。api
但請注意,kubernetes支持的用以實現pod網絡的network plugin有不少種,並非所有都支持Network Policy,爲kubernetes選擇network plugin時須要考慮到這點,是否須要隔離?可用network plugin及是否支持Network Policy請參考這裏。數組
Network Policy是kubernetes中的一種資源類型,它從屬於某個namespace。其內容從邏輯上看包含兩個關鍵部分,一是pod選擇器,基於標籤選擇相同namespace下的pod,將其中定義的規則做用於選中的pod。另外一個就是規則了,就是網絡流量進出pod的規則,其採用的是白名單模式,符合規則的經過,不符合規則的拒絕。安全
首先給出示例Spec,結合示例說明Spec中的關鍵字段與邏輯,關於Spec徹底說明參考這裏。示例以下:bash
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
對象建立方法與其它如ReplicaSet相同。apiVersion、kind、metadata與其它類型對象含義相同,不詳細描述。網絡
顧名思義,它是pod選擇器,基於標籤選擇與Network Policy處於同一namespace下的pod,若是pod被選中,則對其應用Network Policy中定義的規則。此爲可選字段,當沒有此字段時,表示選中全部pod。frontend
Network Policy定義的規則能夠分紅兩種,一種是入pod的Ingress規則,一種是出pod的Egress規則。本字段能夠看做是一個開關,若是其中包含Ingress,則Ingress部分定義的規則生效,若是是Egress則Egress部分定義的規則生效,若是都包含則所有生效。固然此字段也可選,若是沒有指定的話,則默認Ingress生效,若是Egress部分有定義的話,Egress才生效。怎麼理解這句話,下文會提到,沒有明肯定義Ingress、Egress部分,它也是一種規則,默認規則而非沒有規則。ide
前者定義入pod規則,後者定義出pod規則,詳細參考這裏,這裏只講一下重點。上例中ingress與egress都只包含一條規則,二者都是數組,能夠包含多條規則。當包含多條時,條目之間的邏輯關係是「或」,只要匹配其中一條就能夠。.spec.ingress[].from
也是數組,數組成員對訪問pod的外部source進行描述,符合條件的source才能夠訪問pod,有多種方法,如示例中的ip地址塊、名稱空間、pod標籤等,數組中的成員也是邏輯或的關係。spec.ingress[].from.prots表示容許經過的協議及端口號。測試
.spec.egress.to定義的是pod想要訪問的外部destination,其它與ingress相同。
不定義規則並不是沒有規則,此時默認規則生效,如下展現默認規則用法。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Ingress
上例中沒有定義pod選擇器,表示若是namespace下的某個pod沒有被任何Network Policy對象選中,則應用此對象,若是被其它Network Policy先中則不該用此對象。
policyTypes的值爲Ingress,表示本例啓用Ingress規則。可是本例沒有定義具體的Ingress,那就應用默認規則。默認規則禁止全部入pod流量,但例外狀況是若是source就是pod運行的節點,則容許經過。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} ingress: - {}
一樣沒有定義pod選擇器,意義與上例同。注意ingress的定義,這個是有規則的,只是規則中的條目爲空,與默認規則不一樣,表示所有容許經過。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Egress
與默認禁止全部入pod流量(Default deny all ingress traffic)同,只是流量由入變成出
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} egress: - {} policyTypes: - Egress
與默認容許全部入pod流量(Default allow all ingress traffic)同,只是流量由入變成出。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Ingress - Egress
無需詳解,但請注意,pod與所運行節點之間流量不受Network Policy限制。
下面經過一個真實示例展現Network Policy普通用法
$ kubectl run nginx --image=nginx --replicas=2 deployment "nginx" created $ kubectl expose deployment nginx --port=80 service "nginx" exposed
$ kubectl get svc,pod NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/kubernetes 10.100.0.1 <none> 443/TCP 46m svc/nginx 10.100.0.16 <none> 80/TCP 33s NAME READY STATUS RESTARTS AGE po/nginx-701339712-e0qfq 1/1 Running 0 35s po/nginx-701339712-o00ef 1/1 Running 0 35s
$ kubectl run busybox --rm -ti --image=busybox /bin/sh Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt / # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) / #
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: access: "true"
只容許包含access: "true"標籤的pod訪問nginx服務。
$ kubectl create -f nginx-policy.yaml networkpolicy "access-nginx" created
$ kubectl run busybox --rm -ti --image=busybox /bin/sh Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt / # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) wget: download timed out / #
$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt / # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) / #