k8s暴露叢集內和叢集外服務的方法
叢集內服務
一般 pod 都是根據 service 資源來進行叢集內的暴露,因為 k8s 在 pod 啟動前就已經給排程節點上的 pod 分配好 ip 地址了,因此我們並不能提前知道提供服務的 pod 的 ip 地址。那麼 service 服務提供的功能就是,使用者根本無需關心後端提供服務 pod 的數量,以及各自對應的 ip 地址。
服務資源會被 k8s 分配一個 cluster-ip 叢集 ip,只能在叢集內部可以被訪問。而在叢集內 k8s 如何配置服務網路的,可以參考之前的網路服務,實際上就是利用 iptables 來進行網路的配置。除此之外 k8s 還可以配置會話的親和性,因為有可能需要請求落入容一個pod,設定服務的 sessionAffinity 屬性為 clientIP。
apiVersion: v1 kind: Service spec: sessionAffinity: ClientIP
這種方式會將服務代理將來自同一個 clientip 的所有請求轉發到同一個 pod 上。k8s 僅僅支援兩種形式的會話親和性服務:None和ClientIP。但是不支援 cookie 的會話親和性選項,因為 k8s 服務不是在 HTTP 層面上工作,服務處理 TCP 和 UDP 包,並不關心其中資料包內容,畢竟解包封包都是需要耗費資源的。
而且同一個服務還可以暴露多個埠,比如一個 pod 中監聽兩個埠,HTTP 監聽 8080,HTTPS 監聽 8443,可以使用一個服務從埠 80 和 443 轉發到 pod 埠 8080 和 8443。比如宣告 service 暴露多個埠
apiVersion: v1 kind: Service metadata: name: kubia spec: ports: - name: http port: 80 targetPort: 8080 // pod 的8080埠對映成 80 埠 - name: https port: 443 targetPort: 8443 selector: app: kubia
叢集外暴露的服務
將服務暴露給外部客戶端的方法有以下幾種:
- 將服務型別設定成 NodePort:會在叢集中節點內開啟一個埠,外部可以直接從節點埠訪問內部服務,k8s 將節點接受的流量衝定向到內部服務中。
- 將服務型別設定成 LoadBalance:NortPort 型別的一種擴充套件,這使得服務可以通過一個專用的負載均衡器來訪問,這是由 k8s 提供的雲基礎設施來實現的,負載均衡負責將流量重定向到跨節點的節點埠,這裡勢必有路由策略和交換器相關。外部客戶端直接通過負載均衡器IP來訪問叢集內部服務
- 建立一個 Ingress 資源。這是建立在 HTTP 層,也就是 7 層網路層上來進行分發工作,比原本 k8s 的四層網路的服務提供更多的功能。
建立 NodePort 型別的服務
apiVersion: v1 kind: Service metadata: name: kubia-nodeport spec: type: NodePort ports: - port: 80 targetPort: 8080 nodePort: 30123 // 通過部署的叢集節點中的 30123 埠可以訪問該服務 selector: app: kubia
在叢集內兩個節點暴露了 30123 埠,到達任何一個節點上埠的傳入連線將被重定向到一個隨機選擇的pod。
通過負載均衡器建立服務
k8s 必須在支援 LoadBalance 服務的環境下才能建立此型別的負載均衡器服務。宣告如下
apiVersion: v1 kind: Service metadata: name: kubia-loadbalancer spec: type: LoadBalancer ports: - port: 80 targetPort: 8080 selector: app: kubia
那麼 nodeport 和 LB 型別的有什麼不同呢?
$ kubectl get svc kubia-nodeport NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubia-nodeport NodePort 10.99.194.15 <nodes> 9000:31090/TCP 1m $ kubectl get svc kubia-nodeport NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubia-loadbalance LoadBalancer 10.99.194.15 130.211.53.173 80:32143/TCP 1m
注意的是在
nodeport 型別和 LoadBalance 型別的服務在 external-ip 不一樣的是,LB是有外部ip暴露的。通過訪問 LB 的外部ip就可以訪問到叢集內部服務了。
建立 Igress 服務
為什麼需要LB的服務,其實最重要的是有獨立公有 ip 地址,當客戶端向 Ingress 傳送 HTTP 請求時,Ingress 會根據請求的主機名和路徑決定請求轉發到的服務。
Ingress 通過在網路棧 http 的應用層操作,可以提供一些服務不能實現的功能,比如 cookie 的會話親和性等功能。
建立 Ingress 資源
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: kubia spec: rules: - host: kubia.example.com // ingress 將域名對映到你的服務上 http: path: / backend: serviceName: kubia-nodeport // 將請求傳送到 kubia-nodeport 服務的 80 埠 servicePort: 80
要讓 LB 正常工作,也就是通過 kubia.example.com 訪問到對應的服務,必須確保在 k8s 叢集內域名解析為 Ingress 的控制器,所以這需要基礎設施的支援。
在 k8s 檢視 ingress 資源
NAME HOST ADDRESS PORTS AGE kubia kubia-example.com 192.168.99.100 80 75d
所以在叢集中需要確保這樣的解析,需要路由器支援配置
192.168.99.100 kubia.example.com
如圖,首先客戶端會對 kubia.example.com 執行 DNS 查詢,DNS 伺服器或者本地作業系統返回了 Ingress 控制器的 IP。客戶端然後向 Ingress 控制器傳送 HTTP 請求,並在 host 頭中指定 kubia.example.com。控制器從該頭部確定客戶端應該訪問哪個服務,通過與該服務關聯的 endpoint 物件檢視 podip,並將請求傳送到某個 pod。
最後再說明一下將不同服務對映到相同主機的不同路徑:
- host: kubia.example.com http: paths: - path: /kubia backend: serviceName: kubia servicePort: 80 - path: /foo backend: serviceName: bar servicePort: 80
- 記一次批量更新整型型別的列 → 探究 UPDATE 的使用細節
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 執行緒池底層原理詳解與原始碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裡都有
- Django 之路由層
- 【前端必會】webpack loader 到底是什麼
- day42-反射01
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8原始碼解讀
- 詳解JS中 call 方法的實現
- 列印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 設計模式---享元模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang程式碼
- [ML從入門到入門] 支援向量機:從SVM的推導過程到SMO的收斂性討論
- 從應用訪問Pod元資料-DownwardApi的應用
- Springboot之 Mybatis 多資料來源實現
- Java 泛型程式設計
- CAS核心思想、底層實現