基於k8s部署的應用(服務)如何訪問
當我們使用k8s部署了一套應用時(比如一個blog系統),要怎麼訪問它便成了我們最直接的問題,這裡的訪問應該同時包括了對外(tomcat)和對內(mysql)服務。
要弄清楚這個問題,首先我們需要了解kubernetes網路模型設計的基礎原則:
每個pod都擁有一個獨立的ip地址,而且假定所有的pod都在一個直接連通的、扁平的網路空間中。
回到題目的問題,我們這裡分兩步分討論:
1. 叢集內部訪問
1.1 通過pod的ip訪問
通過這種方式訪問是不可靠的,因為當pod重啟後,它的ip會重新分配
1.1.1 因為pod中所有容器共享一個網路堆疊(pod的ip地址是docker0分配的),所以同一個pod中的容器可以通過localhost來互相訪問
1.1.2 不同pod的容器訪問可以使用endpoint方式:pod的ip+容器的埠
1.2 通過服務訪問
通過建立service,可以為一組具有相同功能的容器應用提供一個統一的入口地址,這個地址不會因為pod的重啟而發生改變,所以是可靠的。
訪問方式:服務的clusterIP(這個是系統分配的全域性唯一ip)+containerPort(應用容器的埠)
2. 叢集外部訪問
2.1 直接訪問容器
在啟動pod的rc/deployment中指定容器的hostport,並設定pod級別的hostwork=true,這樣直接通過主機ip+hostport就可以實現訪問
2.2 通過service訪問
2.2.1 NodePort方式
在service.yaml中配置nodeport引數,這一叢集會在每一個node上為需要外部訪問的service開啟一個TCP監聽埠,外部系統只需要用任意一個Node的IP地址+具體的NodePort埠號就可訪問此服務。不過這種方式沒有解決node層負載均衡的問題(pod層kube-proxy會自動實現負載分發到多個pod上,但node層不能負載分發到多個node)
2.2.2 如果使用公有云平臺(如aws、azure、openstack、gce等)部署時,可以用loadbalance方式,配置外部負載均衡器,對service的請求會通過loadbalance轉發到後端pod
2.3 Ingress
Ingress也是k8s中單獨定義的物件,它的作用就是實現對外暴露訪問的負載均衡,它和Service本身LoadBalancer的區別在於:
- Ingress支援L4、L7負載均衡,LoadBalancer設計上只支援L4;
- Ingress基於Pod部署,並將Pod網路設定成external network;
- Ingress controller支援Nginx、Haproxy、GCE-L7,能夠滿足企業內部使用。