一 Pod和SVC網路
1.1 實踐準備及原理
Docker實作了不同的網路模式,Kubernetes也以一種不同的方式來解決這些網路模式的挑戰,本完整實驗深入剖析Kubernetes在網路層是如何實作及作業的, 實驗節點架構:
如上圖所示,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的節點看作一個路由器,其網路架構如下:
二 Pod和SVC實驗
2.1 檢查環境
[root@k8smaster02 ~]# ifconfig #node1上檢查網路地址
由上可知,有一個docker0網橋和一個本地eth0地址的網路埠,
2.2 創建RC
[root@k8smaster01 study]# vi frontend-controller.yaml1 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
Kubernetes為這個Pod找了一個主機172.24.8.71(k8smaster01) 來運行它,另外,這個Pod獲得了一個在k8smaster01的docker0網橋上的IP地址,
[root@k8smaster01 study]# docker ps #k8smaster01上查看正在運行的容器
第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后的網路模型類似下圖:
實際上,應用容器直接監聽了這些埠,和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.yaml1 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上,
注意:本實驗更詳細的步驟參考:https://blog.csdn.net/qq_31136839/article/details/99778434,
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/122593.html
標籤:Linux
