1. 程式人生 > >K8S Calico

K8S Calico

NetworkPolicy是kubernetes對pod的隔離手段,是宿主機上的一系列iptables規則。

Egress 表示出站流量,就是pod作為客戶端訪問外部服務,pod地址作為源地址。策略可以定義目標地址或者目的埠
Ingress 表示入站流量,pod地址和服務作為服務端,提供外部訪問。pod地址作為目標地址。策略可以定義源地址和自己埠

官網
https://docs.projectcalico.org/v3.1/getting-started/kubernetes/

我們這裡使用的是 flannel 構建 K8S 網路,使用 Calico 構建網路規則

mkdir ~/networkpolicy ; cd ~/networkpolicy

kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml
kubectl get pods -n kube-system

# 建立兩個名稱空間 dev 和 prod 進行測試
kubectl create namespace dev
kubectl create namespace prod

vi pod-a.yaml
# 內容如下
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1

# 在名稱空間 dev 建立 pod1
kubectl apply -f pod-a.yaml -n dev
kubectl get pods -n dev -o wide
# 執行結果:
NAME   READY   STATUS    RESTARTS   AGE   IP           NODE
pod1   1/1     Running   0          14m   10.244.2.2   node2

# 在名稱空間 prod 建立 pod1
kubectl apply -f pod-a.yaml -n prod
kubectl get pods -n prod -o wide
# 執行結果:
NAME   READY   STATUS    RESTARTS   AGE   IP           NODE
pod1   1/1     Running   0          14m   10.244.1.2   node1

# 測試網路
curl 10.244.1.2    # 正常訪問
curl 10.244.2.2    # 正常訪問

kubectl exec pod1 -it -n prod -- /bin/sh
ping 10.244.2.2   # 鏈路正常

Ingress

# Ingress 預設禁止所有的入站流量
vi ngress-def.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

kubectl apply -f ingress-def.yaml -n dev

# 檢視 networkpolicy 規則
kubectl get netpol -n dev

curl 10.244.2.2    # 名稱空間 dev  pod1 無法訪問

curl 10.244.1.2    # 名稱空間 prod pod1 正常訪問

# 開放所有的入站流量
vi ingress-def.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress

kubectl apply -f ingress-def.yaml -n dev


curl 10.244.1.2   # 名稱空間 prod pod1 正常訪問

curl 10.244.2.2   # 名稱空間 dev pod1 正常訪問

通過規則限制入站流量

kubectl delete netpol deny-all-ingress -n dev

kubectl label pods pod1 app=myapp -n dev

# 新增網路規則
vi allow-netpol-demo.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-myapp-ingress
spec:
  podSelector:
    matchLabels:
      app: myapp           # 選擇app=myapp 的標籤放行
  ingress:
  - from:
    - ipBlock:              # 地址段
        cidr: 10.244.0.0/16 # 允許這個地址段訪問
        except:             # 排除一下地址不可以訪問
        - 10.244.1.2/32
    ports:
    - protocol: TCP
      port: 80              # 允許訪問80埠
    - protocol: TCP
      port: 443

kubectl apply -f allow-netpol-demo.yaml -n dev

kubectl get netpol -n dev

curl 10.244.2.2:80    # 名稱空間 dev pod1 正常訪問

curl 10.244.2.2:443   # NetworkPolicy 放行,沒有開放 443 埠,伺服器拒絕
curl: (7) Failed connect to 10.244.2.2:443; Connection refused

curl 10.244.2.2:6443  # 卡住,被 NetworkPolicy 拒絕

Egress

# 預設限制所有的出站流量
vi egrees-def.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

kubectl apply -f egrees-def.yaml -n prod

kubectl get pods -n kube-system -o wide
# 選取一個 coredns 的 pod ip

kubectl exec pod1 -it -n prod -- /bin/sh
ping 10.244.0.4    # 無法正常 ping 通


# 放行所有的出站流量
vi egrees-def.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

kubectl apply -f egrees-def.yaml -n prod

kubectl exec pod1 -it -n prod -- /bin/sh
ping 10.244.0.4    # 正常 ping 通