- 建立服務
apiVersion: v1 kind: Service metadata: name: host-http spec: ports: - name: http port: 9090 targetPort: 9080 selector: app: host說明一下,這個 yaml 做了些什麼:
- 第 4 行定義了服務的名稱為 host-http
- 第 8 行指出服務開放給外界訪問的 port 是 9090
- 第 9 行指出 pod 的 port 是 9080
- 第 10~11 行指出 pod 上有 label "app=host" 的綁定到這個服務
kubectl describe svc host-http
kubectl exec host-2vxjs -- curl -s http://10.108.180.52:9090/host/info注意看到,每次執行不一定會使用到同一個 pod。
- 發現服務 Kubernetes 配發給服務的 IP 在服務整個生命週期不會變,但是,pod 要如何知道服務的 cluster IP ? 我們先刪除所有的 pod,rs 會自動再產生 3 個新的 pod。
kubectl exec host-kxdtn env如上,跳入一個 pod 查看環境變數,內容如下,為什麼上面要故意刪除 pod 讓 rs 重新產生? 因為 pod 被新創立時,會根據 Kubernetes 最新狀況生成環境變數,記錄在 pod 裡面。
PATH=/usr/local/jdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=host-kxdtn HOST_HTTP_PORT_9090_TCP=tcp://10.108.180.52:9090 HOST_HTTP_PORT_9090_TCP_PROTO=tcp HOST_HTTP_PORT_9090_TCP_PORT=9090 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 HOST_HTTP_SERVICE_HOST=10.108.180.52 HOST_HTTP_SERVICE_PORT=9090 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 HOST_HTTP_SERVICE_PORT_HTTP=9090 HOST_HTTP_PORT=tcp://10.108.180.52:9090 HOST_HTTP_PORT_9090_TCP_ADDR=10.108.180.52 KUBERNETES_SERVICE_HOST=10.96.0.1 KUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT_443_TCP_PROTO=tcp JAVA_HOME=/usr/local/jdk-11 HOME=/root注意看到第 7~8 行,顯示了服務的 cluster IP (10.108.180.52) 及開放出來的 port (9090),新創建的 pod 透過環境變數即可得知。除了這個辦法還有沒有其它辦法? 通常在網路上發現各項服務是透過 DNS,Kubernetes 是否有相同的方式? 答案是有! Kubernetes 提供了 DNS 服務,每個服務的名稱會對映到它的 IP,同時透過 FQDN,這記錄在每個 pod 的 /etc/resolv.conf 檔裡,當服務名稱找不到 IP 時,會根據這個檔的設定加上後綴,再尋找看看,現在再跳入一個 pod 來試看看。 如上,跳入 pod host-kxdtn,並執行 bash,這樣就可以在裡面下指令,在 pod 裡面要對服務 request,最簡單的就是以服務的名稱當成網址,上面有 ping 看看,真的可以得到服務的 IP,下了 curl http://host-http:9090/host/info 也得到正確的回應,當然啦~ 服務的 port 仍需從環境變數才能得到。
- 開放服務給客戶端 上面的做法雖然讓 Kubernetes 內的 pod 可以透過服務互相訪問,但是,上面建立服務的方式,沒有將服務暴露出來給外部,K8s 外的客戶端訪問不到,現在修改 yaml 如下:
apiVersion: v1 kind: Service metadata: name: host-http spec: type: LoadBalancer ports: - name: http port: 9090 targetPort: 9080 selector: app: host加入第 6 行的設定,設定 K8s cluster 的架構為 LoadBalancer,刪除服務 host-http 並用這個 yaml 重新建立,接著查詢服務,可以得到如下結果,如果 Kubernetes 有支援負載平衡,在 EXTERNAL-IP 欄位會顯示出開放給外部的 IP,我的環境是自建的私有雲沒有支援,type 被降為 NodePort,該欄位會一直顯示 <pending>,這時候就只能使用 master node 的 IP 為 EXTERNAL-IP,port 如下面顯示的是 32015。 【番外篇】
Kubernetes 本身沒有提供負載平衡的支援,如果是使用 GCP、AWS、Azure … 就會由這些平台提供,為了解決這個問題,出現了 MetalLB 這個解決方案,依該網站提供的安裝程序安裝後,重新建立 service,EXTERNAL-IP 就會有對外 IP 了。
沒有留言:
張貼留言