天天看點

k8s使用kube-router網絡元件并實作網絡隔離

簡介

本文章主要介紹k8s如何使用

kube-router

實作pod通信,服務 代理,網絡政策隔離等功能

kube-router

是一個新的k8s的網絡插件,使用

lvs

做服務的代理及負載均衡,使用

iptables

來做網絡的隔離政策。部署簡單,隻需要在每個節點部署一個daemonset即可,高性能,易維護。支援pod間通信,以及服務的代理。

環境說明

本實驗在已經安裝配置好k8s叢集基礎之上進行實驗,k8s安裝參考部落格其他文章。

實驗架構

lab1: master 11.11.11.111
lab2: node 11.11.11.112
lab3: node 11.11.11.113
複制代碼           

安裝

# 本次實驗重新建立了叢集,使用之前測試其他網絡插件的叢集環境沒有成功
# 可能是由于環境幹擾,實驗時需要注意

# 建立kube-router目錄下載下傳相關檔案
mkdir kube-router && cd kube-router
rm -f generic-kuberouter-all-features.yaml
wget https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/generic-kuberouter-all-features.yaml

# 啟用pod網絡通信,網絡隔離政策,服務代理所有功能
# CLUSTERCIDR kube-controller-manager 啟動參數 --cluster-cidr 的值
# APISERVER kube-apiserver 啟動參數 --advertise-address 值
CLUSTERCIDR='10.244.0.0/16'
APISERVER='https://11.11.11.111:6443'
sed -i "s;%APISERVER%;$APISERVER;g" generic-kuberouter-all-features.yaml
sed -i "s;%CLUSTERCIDR%;$CLUSTERCIDR;g" generic-kuberouter-all-features.yaml
kubectl apply -f generic-kuberouter-all-features.yaml

# 删除kube-proxy
kubectl -n kube-system delete ds kube-proxy

# 在每個節點上執行
# 如果是二進制安裝使用如下指令
systemctl stop kube-proxy

# 在每個節點上執行
# 清理kube-proxy留下的規則
docker run --privileged --net=host registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64:v1.10.2 kube-proxy --cleanup

# 檢視
kubectl get pods -n kube-system
kubectl get svc -n kube-system
複制代碼           

測試

# 測試之前請先安裝配置好kube-dns或者coredns

# 啟動用于測試的deployment
kubectl run nginx --replicas=2 --image=nginx:alpine --port=80
kubectl expose deployment nginx --type=NodePort --name=example-service-nodeport
kubectl expose deployment nginx --name=example-service

# 檢視
kubectl get pods -o wide
kubectl get svc -o wide

# dns及通路測試
kubectl run curl --image=radial/busyboxplus:curl -i --tty
nslookup kubernetes
nslookup example-service
curl example-service

# 清理
kubectl delete svc example-service example-service-nodeport
kubectl delete deploy nginx curl
複制代碼           

網絡隔離政策

部署應用

# 建立 production staging 命名空間
kubectl create namespace production
kubectl create namespace staging

# 在每個命名空間各部署一套服務
cd kube-router
wget https://raw.githubusercontent.com/mgxian/istio-test/master/service/node/v1/node-v1.yml
wget https://raw.githubusercontent.com/mgxian/istio-test/master/service/go/v1/go-v1.yml
kubectl apply -f node-v1.yml -n production
kubectl apply -f go-v1.yml -n production
kubectl apply -f node-v1.yml -n staging
kubectl apply -f go-v1.yml -n staging

# 檢視狀态
kubectl get pods --all-namespaces -o wide
複制代碼           

測試pod通信

# 擷取相關POD資訊
PRODUCTION_NODE_NAME=$(kubectl get pods -n production | grep Running | grep service-node | awk '{print $1}')
STAGING_NODE_NAME=$(kubectl get pods -n staging | grep Running | grep service-node | awk '{print $1}')
PRODUCTION_GO_IP=$(kubectl get pods -n production -o wide | grep Running | grep service-go | awk '{print $6}')
STAGING_GO_IP=$(kubectl get pods -n staging -o wide | grep Running | grep service-go | awk '{print $6}')
echo $PRODUCTION_NODE_NAME $PRODUCTION_GO_IP
echo $STAGING_NODE_NAME $STAGING_GO_IP


# 同namespace的pod通信
kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $PRODUCTION_GO_IP 
kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $STAGING_GO_IP 

# 不同namespace的pod通信
kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $STAGING_GO_IP
kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $PRODUCTION_GO_IP

# 結論:任何namespace的任何pod間都可以直接通信
複制代碼           

設定預設政策測試

# 設定預設政策為拒絕所有流量
cat >default-deny.yml<<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
EOF
kubectl apply -f default-deny.yml -n production
kubectl apply -f default-deny.yml -n staging

# 測試通信
# 同namespace的pod通信
kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $PRODUCTION_GO_IP 
kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $STAGING_GO_IP 

# 不同namespace的pod通信
kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $STAGING_GO_IP
kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $PRODUCTION_GO_IP

# 結論:所有pod間都不能通信
複制代碼           

設定允許規則

# 設定 service-go 允許從 service-node 通路
cat >service-go-allow-service-node.yml<<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: service-go-allow-service-node
spec:
  podSelector:
    matchLabels:
      app: service-go
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: service-node
EOF
kubectl apply -f service-go-allow-service-node.yml -n production
kubectl apply -f service-go-allow-service-node.yml -n staging

# 設定 service-node 允許 通路 tcp 80 端口
cat >service-node-allow-tcp-80.yml<<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: service-node-allow-tcp-80
spec:
  podSelector:
    matchLabels:
      app: service-node
  ingress:
  - from:
    ports:
    - protocol: TCP
      port: 80
EOF
kubectl apply -f service-node-allow-tcp-80.yml -n production
kubectl apply -f service-node-allow-tcp-80.yml -n staging

# 測試通信
# 同namespace的pod通信
kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $PRODUCTION_GO_IP 
kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $STAGING_GO_IP 

# 不同namespace的pod通信
kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $STAGING_GO_IP
kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $PRODUCTION_GO_IP

# 通過service測試
PRODUCTION_GO_SVC=$(kubectl get svc -n production | grep service-go | awk '{print $3}')
STAGING_GO_SVC=$(kubectl get svc -n staging | grep service-go | awk '{print $3}')
echo $PRODUCTION_GO_SVC $STAGING_GO_SVC
curl $PRODUCTION_GO_SVC
curl $STAGING_GO_SVC

# 結論:同一namespace的pod間可以通信,不同namespace的pod間不可以通信,隻允許配置了網絡規則的pod間通信
# 通過 service 也無法繞過網絡隔離政策
複制代碼           

清理

# 删除 namespace 自動删除相關資源
kubectl delete ns production
kubectl delete ns staging           

本文轉自掘金-

k8s使用kube-router網絡元件并實作網絡隔離

繼續閱讀