前言
上篇提到使用 Kubernetes 的一些基本元件。這次本篇主要在紀錄 Kubernetes 常用有關網路元件的介紹和如何使用:
- Service
- Ingress
Service
Service Discovery
Pod 重啟或重新部署都會產生新的 IP ,透過 Service 當作媒介,管理與監控這些 Pods 並對外暴露自己的 IP 供別人訪問存取。
Serivce 物件
1 | apiVersion: v1 |
- 在 cluster 中若需要
pod-to-pod
請求中,請使用 Service 的 name 作為 hostname 而非 Pod ip 。- 因為你非但不能在 Pod 被建立以前知道他的 IP ,即使可以 Pod 隨時都有可能重啟或重新部署而改變 IP。
http://kubia.<namespace>
sessionAffinity
只有 ClientIP 和 None 兩種模式,並沒有 cookie-based 。因為 K8s Service 是在 L4 而非 L7 所以只有 TCP 和 UDP
多埠 Service 物件
1 | apiVersion: v1 |
使用命名埠
好處是萬一不是一個常見的 port 號,可以透過命名的方式讓結構更清晰
可以隨時更改底層 (Pod) 的 port 號而不會影響到上層的服務 (Service)
首先,先為 Pod 建立好 port 的名字
1 | apiVersion: v1 |
再來是為 Pod 建立好 Service
1 | apiVersion: v1 |
為什麼 ping 不到 Service 的 IP ?
kube-proxy
負責監控 Endpoints 的改變kube-proxy
如有服務訪問這組 IP 就會被 iptables 修改並且 forward 掉
讓外部的用戶連線到 cluster 的 Service
讓外部來連線 Service 有以下幾種方式
將 Service 的類型設為
NodePort
- 每一個在 cluster 裡面的 Node 都會開一個 Port ,然後把流量轉送到底層的 Service
- 該 Service 不僅可以透過 ClusterIP 和 Port 來訪問,也可以透過每個 Node 上的 Port
將 Service 的類型設為
LoadBalancer
- 是 NodePort 的擴充版
- 是根據不同 cloud infrastructure 而定
- 用戶通過 load balancer 的 IP 來訪問 service
建立
Ingress
資源,一種根本不同的機制,用於通過唯一 IP 公開多個服務- 它是在 Layer 7 上運作的
NodePort
1 | apiVersion: v1 |
可以使用以下指令來檢查 NodePort Service
kubectl get svc kubia-nodeport
可以看到 EXTERNAL-IP
是 <nodes>
,也就是說該 Service 可以在每一個 node 上透過 30123 port 被存取。
LoadBalancer
- 用在公有雲上, cloud providers 通常會支援該模式。
- 與 NodePort 不同,它是透過唯一的 Public IP 來做存取。
1 | #... |
Ingress
單純定義一個 Service 並讓 Ingress 指向它
1 | #... |
連接 cluster 外部的 Service
Service 與 Endpoints 的關係
- Service 和 Pod 並不是直接有所連結的,而是有一個叫做 Endpoints 的資源在中間。
- Endpoints 資源(複數)是一組一組可供 Service 做 loadbalance 的 Pod socket 清單
kubectl describe svc kubia
kubectl get endpoints kubia
- 如果 Service 有設定 Pod 的 label selector 就會自動產生 Endpoints 物件,並且幫你自動維護。
- 反之,必須自己建立 Endpoints 物件,並且必須與 Service 同名。
自己設定 Service Endpoints 的時機:連線到外部網路的服務
創建一個沒有 selector 的 Service
1
2
3
4
5
6
7apiVersion: v1
kind: Service
metadata:
name: google-map # Service 的名字必須和 Endpoints 一樣
spec: # 無需定義 selector
ports:
- port: 80為沒有 selector 的 Service 創建 Endpoints
1
2
3
4
5
6
7
8
9
10apiVersion: v1
kind: Endpoints
metadata:
name: google-map # Endpoints 的名字必須和 Service 的一樣
subsets:
- addresses:
- ip: 11.11.11.11 # Service 將連接轉發到的端點的 IP
- ip: 22.22.22.22
ports:
- port: 80
Service 和 Endpoints 建立起來後,就可以讓 Pods 透過 Service 存取具有兩個外部端點。
連線到外部網路服務的另一種方式:ExternalName Service
1 | apiVersion: v1 |
- Pod 呼叫外部的 API 就使用
http://google-map
- 不影響 Pod 的情況下,在 ExternalName Service 上改變存取的外部服務的網址
Ingress
為什麼一定需要 Ingress ?
每一個 LoadBalancer Service 都需要有自己的 IP,而 Ingress 只需要一個 IP。
Ingress 是在 Layer 7 上面運作,所以可以提供比 Service 更多的功能。
Ingress Controller
必須記得 K8s cluster 中必須要有 Ingress controller 才可以讓 Ingress 正常運作。不同的 K8s 環境在 controller 實作上也不同。
創建 Ingress
1 | apiVersion: extensions/v1beta1 |
一個 client 向 K8s cluster 請求的基本流程