Kubernetes 服務的網路設定與對外暴露至關重要。本文將探討如何使用 Ingress 實作服務對外暴露,並解析相關設定步驟與技術細節。首先,Kubernetes 預設服務型別 ClusterIP 僅限叢集內部存取,可透過 kubectl execcurl 驗證。要對外暴露服務,需啟用 Ingress 功能,microk8s 可使用 microk8s enable ingress 啟用。接著,建立 Ingress 資源 YAML 檔案,定義後端服務和連線埠,並使用 kubectl apply 佈署。佈署後,可透過 curl localhost 測試 Ingress 存取,並使用 ip 命令查詢主機 IP,供其他機器透過該 IP 存取服務。文章也涵蓋了在 AWS EKS 上設定 Ingress 的步驟,包含服務驗證、NodePort 使用、Ingress 資源建立和佈署,以及透過 kubectl describecurl 進行除錯。最後,文章也指出 Ingress 控制器最佳化、安全增強和多叢集管理等未來發展方向。

Kubernetes 網路與 Ingress 設定

在 Kubernetes 中,服務的網路設定與對外暴露是至關重要的。本篇文章將探討如何使用 Ingress 控制器來實作服務的對外暴露,並詳細解析相關的設定步驟與技術細節。

ClusterIP 與服務對記憶體取

在 Kubernetes 中,預設的服務型別是 ClusterIP,這種服務型別只能在叢集內部進行存取。我們可以透過 kubectl 命令來驗證這一點:

shiva@wks01:~$ microk8s kubectl exec -it mydeployment-8566b984cc-c7b79 -- curl 10.152.183.153:80
<html>
<title>
new title
</title>
<body>
new content
</body>
</html>
shiva@wks01:~$

內容解密:

  • 這段指令是在 Kubernetes 的 Pod 中執行 curl 命令來存取 ClusterIP 服務。
  • microk8s kubectl exec -it mydeployment-8566b984cc-c7b79 -- curl 10.152.183.153:80:這條命令進入指定的 Pod 並執行 curl 命令來存取 http://10.152.183.153:80
  • ClusterIP 是 Kubernetes 內部預設的服務型別,只能在叢集內部進行存取。

啟用 Ingress 功能

在 microk8s 中,Ingress 功能預設是未啟用的。我們需要手動啟用 Ingress 附加元件:

shiva@mk8s-01:~$ microk8s status
microk8s is running
high-availability: no
datastore master nodes: 127.0.0.1:19001
datastore standby nodes: none
addons:
enabled:
  ha-cluster # (core) Configure high availability on the current node
  helm # (core) Helm - the package manager for Kubernetes
  helm3 # (core) Helm3 - the package manager for Kubernetes
disabled:
  ingress # (core) Ingress controller for external access
  kube-ovn # (core) An advanced network fabric for Kubernetes
  mayastor # (core) OpenEBS MayaStor

內容解密:

  • microk8s status:用來檢查目前 microk8s 的執行狀態和已啟用的附加元件。
  • Ingress 控制器目前是停用的狀態。

啟用 Ingress 附加元件

執行以下命令來啟用 Ingress:

shiva@wks01:~$ microk8s enable ingress
Infer repository core for addon ingress
Enabling Ingress
ingressclass.networking.k8s.io/public created
ingressclass.networking.k8s.io/nginx created
namespace/ingress created
serviceaccount/nginx-ingress-microk8s-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-microk8s-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-microk8s-role created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-microk8s created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-microk8s created
configmap/nginx-load-balancer-microk8s-conf created
configmap/nginx-ingress-tcp-microk8s-conf created
configmap/nginx-ingress-udp-microk8s-conf created
daemonset.apps/nginx-ingress-microk8s-controller created
Ingress is enabled
shiva@wks01:~$

內容解密:

  • microk8s enable ingress:啟用 Ingress 附加元件。
  • 啟用後,Kubernetes 會建立 Ingress 相關的資源,包括 Ingress 類別、名稱空間、服務帳戶、角色和設定檔等。
  • 啟用 Ingress 後,Ingress 控制器會被佈署並開始運作。

建立 Ingress 資源

建立一個名為 myingress01.yaml 的檔案,內容如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myingress01
spec:
  defaultBackend:
    service:
      name: myservice
      port:
        number: 80

內容解密:

  • apiVersion: networking.k8s.io/v1:指定使用的 Kubernetes API 版本。
  • kind: Ingress:定義資源型別為 Ingress。
  • metadata.name:指定 Ingress 資源的名稱為 myingress01
  • spec.defaultBackend:定義預設的後端服務,這裡指定了 myservice 服務和對應的連線埠 80

佈署 Ingress 資源

執行以下命令來佈署 Ingress 資源:

shiva@wks01:~$ microk8s kubectl apply -f myingress01.yaml
ingress.networking.k8s.io/myingress01 created
shiva@wks01:~$ microk8s kubectl get ingress
NAME        CLASS    HOSTS   ADDRESS   PORTS   AGE
myingress01   public   *       80      17s
shiva@wks01:~$

內容解密:

  • microk8s kubectl apply -f myingress01.yaml:套用 myingress01.yaml 檔案中的設定來建立 Ingress 資源。
  • microk8s kubectl get ingress:查詢目前 Ingress 資源的狀態。
  • 可以看到 myingress01 Ingress 資源已經成功建立,並監聽在 80 連線埠上。

測試 Ingress 存取

執行以下命令來測試透過 Ingress 存取服務:

shiva@wks01:~$ curl localhost:80
<html>
<title>
new title
</title>
<body>
new content
</body>
</html>
shiva@wks01:~$

內容解密:

  • curl localhost:80:透過 curl 命令存取本地端的 80 連線埠。
  • 由於 Ingress 控制器已經將外部的 80 連線埠流量導向後端的 myservice 服務,因此可以正確取得網頁內容。

從其他機器存取 Ingress

首先,查詢工作站的 IP 位址:

shiva@wks01:~$ ip -br -p -4 address
lo               UNKNOWN        127.0.0.1/8
ens160           UP             192.168.0.81/24 metric 100
docker0          DOWN           172.17.0.1/16
vxlan.calico     UNKNOWN        10.1.166.0/32
shiva@wks01:~$

內容解密:

  • ip -br -p -4 address:查詢目前主機的 IPv4 位址資訊。
  • 可以看到 ens160 網路介面的 IP 位址是 192.168.0.81

在同一網路中的其他機器上測試存取 Ingress:

# 在其他機器上執行
curl http://192.168.0.81:80

內容解密:

  • 在同一網路中的其他機器上,可以透過 curl 命令存取 http://192.168.0.81:80 來測試 Ingress 是否可以正常運作。

參考資料

透過上述步驟和技術細節的解析,我們可以更深入地理解 Kubernetes 中的 Ingress 設定和管理,從而更好地應用於實際的生產環境中。未來,我們將繼續探討更多關於 Kubernetes 網路和 Ingress 的相關主題,以提供更全面的技術和最佳實踐。

網路組態與Ingress服務實作詳解

在現代的容器化應用程式佈署中,Kubernetes已成為業界標準。Ingress是Kubernetes中的一個重要資源,用於管理叢集內部服務的外部存取。本文將探討Kubernetes中的Ingress資源組態及其在AWS EKS上的實作。

網路基礎組態驗證

首先,我們需要確認目標機器是否位於相同的網路中。透過執行ip -br -p -4 address命令,可以檢視目前的網路介面組態。

清單16-21:確認其他機器位於相同網路

shiva@wks07:~$ ip -br -p -4 address
lo               UNKNOWN        127.0.0.1/8
ens160           UP             192.168.0.209/24 metric 100
docker0          DOWN           172.17.0.1/16
vxlan.calico     UNKNOWN        10.1.166.0/32
shiva@wks07:~$

從輸出結果可以看出,目前的機器具有IP位址192.168.0.209/24,表明它位於192.168.0.0/24網路中。

存取Nginx Web伺服器

接下來,我們嘗試從另一台機器存取Nginx Web伺服器。

清單16-22:從其他機器存取Web伺服器

shiva@wks07:~$ curl 192.168.0.81
<html>
<title>
new title
</title>
<body>
new content
</body>
</html>
shiva@wks07:~$

成功存取Web伺服器後,我們確認了Ingress功能正常運作。

在AWS EKS上組態Ingress

切換到AWS EKS環境後,我們首先列出目前的服務。

清單16-23:取得AWS EKS叢集中的服務列表

shiva@wks01:~$ kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   10.100.0.1      <none>        443/TCP          47d
label-nginx     NodePort    10.100.5.40     <none>        80:30969/TCP     27m
primeornot      NodePort    10.100.171.157  <none>        80:31747/TCP     26m
shiva@wks01:~$

目前有兩個服務:label-nginxprimeornot,皆透過NodePort暴露。

驗證服務可存取性

在切換到Ingress之前,我們需要確認這兩個服務可以透過NodePort存取。

清單16-24:描述mydeployment佈署

shiva@wks01:~$ kubectl describe deployment mydeployment
Name:                   mydeployment
Namespace:              default
CreationTimestamp:      Sat, 31 Dec 2022 17:16:46 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=label-nginx
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=label-nginx
  Containers:
    name:  nginx
      Image:          public.ecr.aws/nginx/nginx:stable
      Port:           80/TCP
      Host Port:      0/TCP
      Environment:    <none>
      Mounts:
        /usr/share/nginx/html from persistent-storage (rw)
  Volumes:
    persistent-storage:
      Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
      ClaimName:  efs-claim
      ReadOnly:   false
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:    mydeployment-64845ffdff (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  36m   deployment-controller  Scaled up replica set mydeployment-64845ffdff to 1
shiva@wks01:~$

清單16-25:取得節點的外部IP

shiva@wks01:~$ kubectl describe nodes | grep -i ExternalIP
ExternalIP:   18.218.183.7
shiva@wks01:~$

使用節點的外部IP和NodePort,我們可以存取服務。

清單16-26:透過CURL存取Web伺服器

shiva@wks01:~$ curl 18.218.183.7:30969
<html><title>Hello from EFS! </title><body>This content is served to you by the EFS that is mounted on this pod that is running this nginx! <br> we just inserted brs in this file <br>How cool, eh!<br></body></html>
shiva@wks01:~$

同樣地,我們也可以透過瀏覽器存取該服務。

建立Ingress資源

現在,我們將為Nginx服務建立Ingress資源。

清單16-28:eks-myingress01.yaml檔案內容

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myingress01
spec:
  defaultBackend:
    service:
      name: label-nginx
      port:
        number: 80

清單16-29:佈署Ingress資源

shiva@wks01:~$ kubectl apply -f eks-myingress01.yaml
ingress.networking.k8s.io/myingress01 created
shiva@wks01:~$

清單16-30:取得Ingress資源詳情

shiva@wks01:~$ kubectl get ingress
NAME          CLASS    HOSTS   ADDRESS   PORTS   AGE
myingress01   <none>   *                 80      24s
shiva@wks01:~$

然而,當我們嘗試存取Web伺服器時,連線失敗。

清單16-31:嘗試連線至Web伺服器

shiva@wks01:~$ curl localhost
curl: (7) Failed to connect to localhost port 80 after 0 ms: Connection refused
shiva@wks01:~$

內容解密:

  1. Ingress資源建立:我們定義了一個名為myingress01的Ingress資源,將所有到達的流量路由到label-nginx服務的80埠。

  2. Ingress功能驗證:嘗試透過curl localhost存取本地主機的80埠,但連線被拒絕,表明Ingress尚未正確組態或生效。

  3. 下一步驟:需要進一步檢查Ingress控制器的狀態、相關日誌以及網路組態,以確定問題所在。

  4. Ingress控制器最佳化:研究並最佳化Ingress控制器的組態,以提升效能和可靠性。

  5. 安全增強:實作TLS加密和認證機制,增強Ingress服務的安全性。

  6. 多叢集管理:探索在多叢集環境中管理Ingress資源的最佳實踐。

透過持續最佳化和改進,我們可以建立更強壯和高效的Kubernetes網路架構。