039.Kubernetes集群網絡-Pod和SVC網絡實踐


一 Pod和SVC網絡

1.1 實踐准備及原理

Docker實現了不同的網絡模式,Kubernetes也以一種不同的方式來解決這些網絡模式的挑戰。本完整實驗深入剖析Kubernetes在網絡層是如何實現及工作的。
實驗節點架構:
clipboard
如上圖所示,Kubernetes的網絡模型要求每個Node上的容器都可以相互訪問。默認的Docker網絡模型提供了一個IP地址段是172.17.0.0/16的docker0網橋。每個容器都會在這個子網內獲得IP地址,並且將docker0網橋的IP地址(172.17.42.1)作為其默認網關。需要注意的是,Docker宿主機外面的網絡不需要知道任何關於這個172.17.0.0/16的信息或者知道如何連接到其內部,因為Docker的宿主機針對容器發出的數據,在物理網卡地址后面都做了IP偽裝MASQUERADE(隱含NAT)。也就是說,在網絡上看到的任何容器數據流都來源於那台Docker節點的物理IP地址。這里所說的網絡都指連接這些主機的物理網絡。
默認的Docker網絡模型簡單便捷,但需要依賴端口映射的機制。在Kubernetes的網絡模型中,每台主機上的docker0網橋都是可以被路由到的。也就是說,在部署了一個Pod時,在同一個集群內,各主機都可以訪問其他主機上的Pod IP,並不需要在主機上做端口映射。
因此,可以在網絡層將Kubernetes的節點看作一個路由器,其網絡架構如下:
clipboard

二 Pod和SVC實驗

2.1 檢查環境

[root@k8smaster02 ~]# ifconfig #node1上檢查網絡地址
clipboard
由上可知,有一個docker0網橋和一個本地eth0地址的網絡端口。

2.2 創建RC

[root@k8smaster01 study]# vi frontend-controller.yaml
  1 apiVersion: v1
  2 kind: ReplicationController
  3 metadata:
  4   name: frontend
  5   labels:
  6     name: frontend
  7 spec:
  8   replicas: 1
  9   selector:
 10     name: frontend
 11   template:
 12     metadata:
 13       labels:
 14         name: frontend
 15     spec:
 16       containers:
 17       - name: php-redis
 18         image: kubeguide/guestbook-php-frontend
 19         env:
 20         - name: GET_HOSTS_FROM
 21           value: env
 22         ports:
 23         - containerPort: 80
 24           hostPort: 80
[root@k8smaster01 study]# kubectl create -f frontend-controller.yaml

2.3 再次檢查網絡

[root@k8smaster01 study]# kubectl get pods -o wide
clipboard
Kubernetes為這個Pod找了一個主機172.24.8.71(k8smaster01) 來運行它。另外,這個Pod獲得了一個在k8smaster01的docker0網橋上的IP地址。
[root@k8smaster01 study]# docker ps #k8smaster01上查看正在運行的容器
clipboard
第2個運行的是一個google_containers/pause:latest的鏡像,而且這個容器已經做了端口映射。
[root@k8smaster01 study]# docker inspect c6578085541b | grep NetworkMode #查看容器的網絡模型
"NetworkMode": "default",
[root@k8smaster01 study]# docker inspect da8251102c93 | grep NetworkMode
"NetworkMode": "container:c6578085541b6f47ab624134d0ed0be352b30b42379493a71a8fc913d829989c",
解釋:第1個容器是運行了“google_containers/pause:latest”鏡像的容器,它使用了Docker默認的網絡模型bridge(默認網絡模型即為橋接);
第2個容器,也就是在RC/Pod中定義運行的php-redis容器,使用了非默認的網絡配置和映射容器的模型,指定了映射目標容器為“google_containers/pause:latest”。

2.4 網絡模型釋義

首先,一個Pod內的所有容器都需要共用同一個IP地址,這就意味着一定要使用網絡的容器映射模式。然而,為什么不能只啟動第1個Pod中的容器,而將第2個Pod中的容器關聯到第1個容器呢?
Kubernetes主要基於如下兩個覺得考慮:
首先,如果在Pod內有多個容器的話,則可能很難連接這些容器;
其次,后面的容器還要依賴第1個被關聯的容器,如果第2個容器關聯到第1個容器,且第1個容器異常的話,第2個容器也將異常。
啟動一個基礎容器,然后將Pod內的所有容器都連接到基礎容器相對容易。因為只需要為基礎的這個Google_containers/pause容器執行端口映射規則,這也簡化了端口映射的過程。所以啟動Pod后的網絡模型類似下圖:
clipboard
實際上,應用容器直接監聽了這些端口,和google_containers/pause容器共享了同一個網絡堆棧。這就是為什么在Pod內部實際容器的端口映射都顯示到google_containers/pause容器上了。
[root@k8smaster01 study]# docker port c6578085541b #通過dockerport命令來檢驗端口轉發
80/tcp -> 0.0.0.0:80
綜上所述,google_containers/pause容器實際上只是負責接管這個Pod的Endpoint。

2.5 發布SVC

Service允許我們在多個Pod之間抽象一些服務,而且服務可以通過提供在同一個Service的多個Pod之間的負載均衡機制來支持水平擴展。
[root@k8smaster01 study]# vi frontend-service.yaml
  1 apiVersion: v1
  2 kind: Service
  3 metadata:
  4   name: frontend
  5   labels:
  6     name: frontend
  7 spec:
  8   ports:
  9   - port: 80
 10   selector:
 11     name: frontend
[root@k8smaster01 study]# kubectl create -f frontend-service.yaml
[root@k8smaster01 study]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend ClusterIP 10.254.176.53 <none> 80/TCP 45s
釋義:如上可知Kubernetes集群已經為這個服務分配了一個虛擬IP地址10.254.176.53,這個IP地址是在Kubernetes的Portal Network中分配的。 而這個Portal Network的地址范圍是我們在Kubmaster上啟動API服務進程時,使用--service-cluster-ip-range=xx命令行參數指定:
[root@k8smaster01 study]# cat /etc/systemd/system/kube-apiserver.service | grep 10.254
--service-cluster-ip-range=10.254.0.0/16 \
注意:這個IP段可以是任何段,只要不和docker0或者物理網絡的子網沖突即可。選擇任意其他網段的原因是這個網段將不會在物理網絡和docker0網絡上進行路由。這個Portal Network針對每一個Node都有局部的特殊性,實際上它存在的意義是讓容器的流量都指向默認網關(也就是docker0網橋)。

2.6 確認驗證

當所有的Pod都運行起來,Service將會把客戶端請求負載分發到包含“name=frontend”標簽的所有Pod上。
clipboard
注意:本實驗更詳細的步驟參考:https://blog.csdn.net/qq_31136839/article/details/99778434


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM