Docker

Kubernetes,http訪問集群中的應用程序

  • July 7, 2020

我對 Kubernetes 很陌生。我需要一些建議如何訪問部署在集群中的應用程序。

我有一個帶有 Django 應用程序和 Gunicorn 的 docker 映像來執行 .wsgi。我正在使用此映像在具有 3 個節點的集群中部署容器(學習 k8s 的環境,1 個 master 2 個 worker)。如果我使用 nodePort 公開服務並使用 curl <node’sIP>:

$$ port $$,從未包含的伺服器到集群,我可以訪問該應用程序。 但是現在我想要一個單一的入口點,它可以與任何副本連接。

我想過再創建一台機器,不包含在安裝了 Nginx 或 HAproxy 的集群中,但我找不到任何解決方案如何將外部反向代理與 kubernetes 服務連接。

你能給我更好的解決方案,或者建議我如何繼續我的想法嗎?

TL;博士

在託管的 Kubernetes 集群中GKEEKS或者AKS您可以向雲提供商請求服務的 IP 地址。

例如,Virtualbox使用任何一種方式創建的 Kubernetes 集群kubespraykubeadm 需要額外的工具才能獲得External-IP服務。

您可以使用在不受雲提供商管理的集群中metallb進行分配。External-IP請看官網:

在這種情況下,公開應用程序的步驟是:

  • 部署應用程序 pod

  • 創建一個service附加到 pod

  • 部署metallb和配置它

  • 通過以下任一方式公開應用程序:

    • 創建服務類型LoadBalancer
    • 創建Ingress資源

免責聲明!

創建Ingress資源需要Ingress控制器。我在下面附上了其中一個的連結。

我在下面提供了一個範例和更多說明,說明如何在 Virtualbox 創建的集群中使用metallb和公開您的應用程序nginx-ingress-controller


這是一個範例,展示瞭如何在 Virtualbox 中創建的 Kubernetes 集群上公開應用程序:

  • metallb
  • nginx-ingress-controller

我將這個答案分為兩部分:

  • 虛擬盒子
  • Kubernetes

虛擬盒子

當您VM's在 Virtualbox 中創建時,您有多種方式來配置網路。他們之中有一些是:

  • Bridged networking- 將您的 Kubernetes 集群連接到物理網路
  • Host-only- 允許單個適配器連接到節點和允許網路連接的主機。Host-only此解決方案需要另一個可以訪問 Internet 的適配器或連接相同網路適配器的網關(例如 PfSense) 。

此範例使用帶有Bridged適配器的客戶端和 3 個節點:

  • client帶IP地址:192.168.0.2
  • master帶IP地址:192.168.0.117
  • worker1帶IP地址:192.168.0.118
  • worker2帶IP地址:192.168.0.119

為確保此範例在主機之外工作,我使用了同一網路中的另一台設備。

請確保節點之間具有完全連接,並且您的主機可以完全訪問它們。

Kubernetes

讓我們假設:

  • 集群配置正確並且可以訪問 Internet
  • 您擁有此集群的完全訪問權限
  • 您可以從任何其他主機“ping”每個節點
  • 您的 pod 響應您選擇的埠上的請求(例如8000

腳步:

  • 創建一個 podgunicorn
  • gunicorn為pod創建服務定義
  • 部署Metallb
  • 使用服務類型公開應用程序LoadBalancer
  • Ingress使用資源公開應用程序

創建一個 podgunicorn

我使用下面的部署定義來創建一個響應請求的 pod:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: gunicorn
spec:
 selector:
   matchLabels:
     app: gunicorn
 replicas: 1
 template:
   metadata:
     labels:
       app: gunicorn
   spec:
     containers:
     - name: gunicorn
       image: ubuntu
       command:
       - sleep
       - "infinity"

我使用ubuntu了我exec進入並執行以下命令的圖像:

  • $ apt update && apt install -y python3 python3-pip
  • $ pip3 install gunicorn

我使用的範常式式碼myapp.py

def app(environ, start_response):
   data = b"Hello, World!\n"
   start_response("200 OK", [
       ("Content-Type", "text/plain"),
       ("Content-Length", str(len(data)))
   ])
   return iter([data])
  • $ gunicorn -w 1 -b 0.0.0.0 myapp:app &

以上範例基於:

在此步驟之後,您的 pod 應該在埠8000上響應Hello, World!.

gunicorn為pod創建服務定義

gunicornpod的服務定義:

apiVersion: v1
kind: Service
metadata:
 name: gunicorn-service
spec:
 selector:
   app: gunicorn
 ports:
   - name: gunicorn-port
     port: 8000
     targetPort: 8000
 type: NodePort

部署Metallb

以下官方Metallb文件:Metallb.universe.tf:安裝

  • 編輯kube-proxy以將strictARP模式從更改falsetrue

    • $ kubectl edit configmap -n kube-system kube-proxy
  • $ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml

  • $ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml

  • $ kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)

您還需要添加一個configMap告訴metallb他可以為服務分配哪些 IP 地址:

apiVersion: v1
kind: ConfigMap
metadata:
 namespace: metallb-system
 name: config
data:
 config: |
   address-pools:
   - name: default
     protocol: layer2
     addresses:
     - 192.168.0.240-192.168.0.250

請具體看一下:

     addresses:
     - 192.168.0.240-192.168.0.250

請確保此地址範圍不與您網路中使用的任何地址重疊,並且它與節點和客戶端位於同一網路中。

之後,您應該能夠創建LoadBalancer將獲得 IP 地址的類型的服務。

使用服務類型公開應用程序LoadBalancer

您應該能夠執行:

  • $ kubectl expose deployment gunicorn --type=LoadBalancer --port=8000

的輸出$ kubectl get services應該顯示:

NAME               TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
gunicorn           LoadBalancer   10.233.43.104   192.168.0.240   8000:32591/TCP   3s
gunicorn-service   NodePort       10.233.34.96    &lt;none&gt;          8000:30862/TCP   73s
kubernetes         ClusterIP      10.233.0.1      &lt;none&gt;          443/TCP          23h

如您所見,gunicorn服務的EXTERNAL-IPIP192.168.0.240池位於metallb.

本例中使用的物理網路是192.168.0.0/24

您可以執行:curl 192.168.0.240:8000並獲得:Hello, World!

Ingress使用資源公開應用程序

Ingress在公開您的應用程序之前,您需要部署控制器。nginx-ingress-controller您可以通過執行進行部署:

  • $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml

Ingress控制器將LoadBalancer附加一個服務類型,這將是請求的入口點。****

您可以通過呼叫來獲取它的 IP 地址$ kubectl get svc -n ingress-nginx

NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.233.52.8     192.168.0.241   80:31380/TCP,443:30066/TCP   29m
ingress-nginx-controller-admission   ClusterIP      10.233.37.255   &lt;none&gt;          443/TCP                      29m

以下是將Ingress流量從控制器路由到您的 pod 的定義:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: gunicorn-ingress
 annotations:
   kubernetes.io/ingress.class: "nginx"
spec:
 rules:
 - host: 
   http:
     paths:
     - path: /
       backend:
         serviceName: gunicorn-service
         servicePort: gunicorn-port

應用後,您應該能夠:

  • curl 192.168.0.241並得到回應gunicorn

引用自:https://serverfault.com/questions/1023980