ASP.NET Core on K8S深入学习(11)K8S网络知多少
Photo :Kubernetes
文?| Edison Zhou
本文已加入《.NET Core on K8S 學習與實踐系列文章索引目錄》,點擊查看容器化相關文章,希望對你有所幫助!
Kubernetes網絡模型
? ? ? ?我們都知道Kubernetes作為容器編排引擎,它有一個強大又復雜的網絡模型,也牽引出了Pod網絡、Service網絡、ClusterIP、NodePort、Ingress等多個概念。這里我們采用楊波老師(架構師楊波)模仿TCP/IP協議棧總結的一個K8S網絡模型圖來看看K8S的四個抽象層次,從而了解一下K8S的網絡。本小節的文字主要引用自楊波老師關于K8S網絡模型的文章及CloudMan的《每天5分鐘玩轉Kubernetes》一書。
K8S網絡層次模型圖 (From 波波老師)
根據上圖模型中展示的四個層次,從0到3,除了第0層,每一層都是構建于前一層之上。
(1)第0層:節點主機互通互聯
主要保證K8S節點(物理或虛擬機)之間能夠正常IP尋址和互通的網絡,這個一般由底層(公有云或數據中心)網絡基礎設施支持,這里我們無需過多關心。
(2)第1層:Pod虛擬機互聯
? 在一個Pod中可以運行一個或多個容器,且Pod中所有容器使用同一個網絡namespace,即相同的IP和端口空間,可以直接用localhost通信,而且還可以共享存儲(本質是通過將Volume掛載到Pod中的每個容器)。
?Pod網絡模型圖 (From 波波老師)
(3)第2層:服務發現和負載均衡
? 在K8S集群中,Pod的IP并不是固定的,可能會頻繁地銷毀和創建實例,為了解決此問題,Service提供了訪問Pod的抽象層。即無論后端Pod如何變化,Service都作為穩定的前端對外提供服務。此外,Service還提供了高可用和負載均衡的功能,它負責將請求轉發給正確的Pod。
??Service網絡模型圖 (From 波波老師)
(4)第3層:外部流量接入
? K8s的Service網絡只是一個集群內部網絡,集群外部是無法直接訪問的。為此,想要將應用暴露出去讓公網能夠訪問,K8S提供了兩種方式:
① NodePort:使Service通過Cluster節點的靜態端口對外提供服務,外部可以通過 NodeIP:NodePort 來訪問Service。
??Node Port方式示意圖 (From 波波老師)
② LoadBalancer:使Service利用Cloud Provider提供的Load Balancer對外提供服務,Cloud Provider負責將Load Balancer的流量導向Service。目前支持的Cloud Provider包括AWS、Azure、阿里云、騰訊云等。
?Load Balancer方式示意圖 (From 波波老師)
More:關于K8S網絡的更多基本原理與講解,強力推薦閱讀波波老師的以下文章:
Kubernetes網絡三部曲-Pod網絡(From 楊波老師)
Kubernetes網絡三部曲-Service網絡(From 楊波老師)
Kubernetes網絡三部曲-外部接入網絡(From 楊波老師)
傳說中的CNI規范
????????為了保證網絡方案的標準化、擴展性和靈活性,K8S采用了CNI(Container Networking Interface)規范。CNI是一個Pod網絡集成標準,簡化了K8S和不同Pod網絡實現技術的集成。CNI最大的優點就是支持多種容器runtime,而不僅僅是Docker。目前已經有多種支持K8S的網絡方案,包括 Flannel、Calico、Canal等,它們都實現了CNI規范,因此無論我們選擇哪種具體方案,它們的網絡模型都是一致的。
?CNI模型圖
More:關于CNI的更多基本原理與講解,推薦閱讀陳Sir的文章《K8S網絡詳解:CNI與CNI網絡模型》
Network Policy
關于Network Policy
Network Policy是K8S的一種資源,它使K8S可以通過Label選擇Pod,并指定其他Pod或外界如何與這些Pod通信。換句話說,當Pod被定義了Network Policy時,只有Policy允許的流量才能訪問Pod(默認情況下,任何來源的流量都可以訪問Pod,是沒有限制的)即幫助K8S實現更為精細的流量控制,實現租戶隔離機制。
But,并不是所有K8S網絡方案都支持Network Policy,比如Flannel就不支持,而Calico是支持的。
????????下面我們就來實踐一下Network Policy,只要三步!
部署Canal
想要部署Canal,需要切換網絡方案,這里我們使用最簡單粗暴的方式:重建當前K8S集群
kubeadm reset # 在每個節點上執行一次然后,重新對Master節點進行初始化:
kubeadm init \ --apiserver-advertise-address=192.168.2.100 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.13.3 \ --service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16在兩個Node節點上執行以下命令重新加入集群:(注意這里的token請填寫你的Master節點初始化后的輸出結果)
kubeadm?join?192.168.2.100:6443?--token?ekqxk2.iiu5wx5bbnbdtxsw?\ --discovery-token-ca-cert-hash?\ sha256:c50bb83d04f64f4a714b745f04682b27768c1298f331e697419451f3550f2d05最后,通過以下命令部署Canal:(參考自K8S官方文檔)
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/canal.yaml此時,再次令驗證的集群結果如下:
(1)集群節點狀態
? (2)Pod狀態
?
部署測試應用
????????這里通過一個httpd應用來演示Network Policy,該應用的yaml定義如下:
apiVersion: apps/v1 kind: Deployment metadata:name: httpd spec:replicas: 3selector:matchLabels:name: networkpolicy-demotemplate:metadata:labels:name: networkpolicy-demospec:containers:- name: httpdimage: httpd:latestports:- containerPort: 80imagePullPolicy: IfNotPresent---kind: Service apiVersion: v1 metadata:name: httpd-svc spec:type: NodePortports:- protocol: TCPnodePort: 31000port: 8080targetPort: 80selector:name: networkpolicy-demo通過kubectl將其部署到K8S集群:
kubectl apply -f httpd-demo.yaml這時候三個httpd Pod已經成功Running:
由于定義的是NodePort方式暴露服務,這里我們在集群外部訪問Service看看:
由于當前并沒有創建任何Network Policy,這里我們可以通過創建一個Pod應用(我們熟悉的busybox)來驗證一下是否可以在K8S集群內部隨意訪問該httpd應用:
kubectl run busybox --rm -it --image=busybox /bin/sh
? 從上圖可以知道,它可以正常訪問到Service,也可以正常ping到Pod節點。
部署Network Policy有效性
現在我們創建一個Network Policy,其配置文件yaml如下:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:name: access-httpd spec:podSelector:matchLabels:name: networkpolicy-demoingress:- from:- podSelector:matchLabels:access: "true"ports:- protocol: TCPport: 80該Network Policy定義了如下規則:
(1)應用于所有 label 為 name : networkpolicy-demo 的Pod,這里即剛剛創建的三個httpd pod。
(2)ingress中定義了只有 label 為 access : "true" 的Pod才能訪問應用。
(3)即使通過Policy也只能訪問80端口
通過kubectl將其應用到K8S集群中:
kubectl apply -f networkpolicy.yaml下面再次在busybox pod中驗證Network Policy的有效性:
從上圖中可以看到,已經無法再成功訪問Service,也無法再ping通三個Pod節點。
這個時候,集群外也無法再通過NodePort訪問到Service:
如果想要讓測試Pod(busybox)能訪問到應用了Network Policy的httpd應用,我們可以對busybox pod加一個label("access=true")就可以:
kubectl run busybox --rm -it --image=busybox \ --labels="access=true" /bin/sh運行后的驗證結果如下,可以訪問到Service,但Ping卻被禁止:
? 但是,此時集群節點(k8s-master與兩個node)與集群仍然無法訪問到應用了Network Policy的httpd應用,如果想要讓它們也訪問到,則需要修改Network Policy做一個類似于開防火墻白名單的操作(注意下面的ipBlock配置):
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:name: access-httpd spec:podSelector:matchLabels:name: networkpolicy-demoingress:- from:- podSelector:matchLabels:access: "true"- ipBlock:cidr: 192.168.2.0/24ports:- protocol: TCPport: 80再次應用到K8S集群后,再來通過集群外部的訪問者瀏覽器試試:
? 可以看到,已經可以正常訪問啦!
小結
???????本文簡單介紹了Kubernetes的4層網絡模型、CNI 容器網絡接口規范 和 Network Policy,并通過改造K8S集群的網絡配置從Flannel到Canal來驗證Network Policy的有效性。對于Kubernetes的網絡模型的原理與介紹,強烈推薦閱讀楊波老師的《Kubernetes網絡三部曲》,它的傳送門位于下方的參考資料列表中。
????????最后,碼字不易,也希望各位看官看完覺得還行就在本文右下方順手點個“在看”,就是對我最大的鼓勵!
參考資料:
(1)CloudMan,《每天5分鐘玩轉Kubernetes》?
(2)李振良,《一天入門Kubernets教程》?
(3)馬哥(馬永亮),《Kubernetes快速入門》?
(4)Liang,《K8S CNI網絡最強對比》?
(5)楊波,《K8S網絡三部曲》?
(6)陳Sir,《K8S網絡詳解:CNI與CNI網絡模型》
往期精彩回顧
.NET Core on K8S學習與實踐系列文章索引目錄
熊逸《唐詩必修50講》學習筆記系列文章索引目錄
【重磅】2019 .NET China Conf 資料下載
2019?.NET?Conf China - 路一直都在,社區會更好
阿里云MVP第十期全球發布—讓天下沒有難做的技術
基于Jenkins的開發測試全流程持續集成實踐
基于Jenkins Pipeline的ASP.NET Core持續集成實踐
恰童鞋騷年,風華也許不再正茂,但卻仍想揮斥方遒。
本公眾號會長期關注和分享.NET Core,Microservice,Cloud Native,DevOps等技術內容文章,還會與你分享個人生活成長的點滴及各類好書的讀書筆記,希望能對你有所幫助,一起成長!
長按訂閱更多精彩▼
點個【在看】和更多人一起分享
總結
以上是生活随笔為你收集整理的ASP.NET Core on K8S深入学习(11)K8S网络知多少的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特意向大家推荐.NET技术圈一些优秀开发
- 下一篇: asp.net ajax控件工具集 Au