圖解Kubernetes之Ingress


圖解Kubernetes之Ingress

TL; DR

Kubernetes Ingress不是Kubernetes服務。 非常簡化的只是一個Nginx Pod,它將請求重定向到其他內部(ClusterIP)服務。 該Pod本身可以通過Kubernetes服務(通常是LoadBalancer)來訪問。

你甚至應該讀這個嗎?

首先,我希望我能為您提供這個神秘的Kubernetes Ingress背後的內容的簡單明瞭的概述,然後使您更容易理解您實際上正在實施的內容,或為什麼應該這樣做。

稍後,我將基於本文中使用的示例展示一些示例配置。

為什麼要使用Ingress?

您可以使用它來從群集外部訪問內部服務。 它省去了寶貴的靜態IP,因為您無需聲明多個LoadBalancer服務。 而且,如我們所見,它還允許進行更多的配置和更容易的設置。

我們在這裡做什麼?

  • 首先,我們對HTTP服務器(尤其是Nginx)如何工作以及它們可以做什麼進行了非常簡短的考察。
  • 然後,我們將說明如何手動設置Ingress,從而完全不用花哨的Kubernetes Ingress資源。
  • 接下來,我們將看到Kubernetes Ingress只是預配置的Nginx服務器。

聽起來令人困惑? 只要在這裡跟隨我。

簡要了解簡單HTTP服務器的世界

在這裡,我們回到容器,Kubernetes和現代雲世界之前的時代。 和我在一起,時間會很短。

(Nginx)HTTP服務器可以做什麼?

它可以通過HTTP協議接收針對特定文件路徑的請求,檢查附加文件系統上的文件路徑,如果該文件存在,則將其返回:

圖解Kubernetes之Ingress

在Nginx中,例如可以通過以下方式完成此操作:

<code>location /folder {    root /var/www/;    index index.html;}/<code>


(Nginx)HTTP服務器還能做什麼?

它可以接收對特定文件路徑的請求,將該請求重定向到另一臺服務器(這意味著它充當代理),然後將該服務器的響應重定向回客戶端。 對於客戶端,沒有任何變化,接收到的結果仍然是請求的文件(如果存在)。

圖解Kubernetes之Ingress

我們不會深入探討這一點,但是在Nginx中,例如可以將代理重定向配置為:

<code>location /folder {    proxy_pass http://second-nginx-server:8000;}location /folder {    root /var/www/;    index index.html;}/<code>


這意味著Nginx可以充當代理,來從文件系統提供文件,或將響應重定向到其他服務器並返回其響應。

一個簡單的Kubernetes示例:

使用ClusterIP服務

同樣,從這一點開始,您應該瞭解Kubernetes Services。 我們有兩個工作節點,這裡我們忽略主節點。 我們有兩個服務service-nginx和service-python指向不同的容器。

服務不是在任何特定的節點上調度的,只能說它們"在群集中的任何地方都可用"。

圖解Kubernetes之Ingress

您應該瞭解這裡發生了什麼。 在我們集群的內部,我們可以通過它們的服務訪問Nginx pod和Python pod。 接下來,我們還要從集群外部提供這些資源。 因此,我們將它們轉換為LoadBalancer服務:

使用LoadBalancer服務

您可以看到我們將ClusterIP服務轉換為LoadBalancer服務。 因為我們的Kubernetes集群託管有可以處理此問題的雲提供商(Gcloud,AWS,DigitalOcean…),所以它創建了兩個外部負載均衡器,可將請求重定向到我們的外部節點IP,再將其重定向到內部ClusterIP服務。

圖解Kubernetes之Ingress

我們看到兩個LoadBalancers,每個都有自己的IP。 如果我們向LoadBalancer 22.33.44.55發送請求,它將被重定向到我們的內部服務nginx。 如果我們將請求發送到77.66.55.44,它將被重定向到內部服務python。

這很棒! 但是IP地址很少,LoadBalancer的定價取決於雲提供商。 現在想象一下,我們要創建LoadBalancers的不僅僅是內部服務,而是更多的內部服務,成本將會增加。

可能會有另一種解決方案,使我們僅使用一個LoadBalancer(具有一個IP),但仍可以直接訪問我們的兩個內部服務嗎? 首先,我們通過實施手動(非Kubernetes)方法來對此進行探討。

手動將Nginx服務配置為代理

如前所述,Nginx可以充當代理。 在下圖中,我們看到一個名為service-nginx-proxy的新服務,它實際上是我們唯一的LoadBalancer服務。 service-nginx-proxy仍將指向一個或多個Nginx-pod端點,但是為簡單起見,我未在圖形中包括該端點。 之前的其他兩項服務將轉換回簡單的ClusterIP服務:

圖解Kubernetes之Ingress

我們可以看到,我們只打了一個LoadBalancer(11.22.33.44),但是使用了不同的http URL,這些請求以黃色顯示為相同的目標,並且只包含不同的內容(請求url)。

服務service-nginx-proxy根據所傳遞的URL決定(通過使用Nginx代理傳遞和位置),他應將請求重定向到哪個服務。

在這種情況下,我們有兩個選擇,紅色和藍色。 紅色重定向到service-nginx,藍色重定向到service-python。

<code># very simplified Nginx config examplelocation /folder {    proxy_pass http://service-nginx:3001;}location /other {    proxy_pass http://service-python:3002;}/<code>


當前,我們需要手動配置service-nginx-proxy。 就像創建指向我們的ClusterIP服務的正確的Nginx配置文件一樣。 這是一個可能的,可行的且通用的解決方案。

並且由於這是/是常見的解決方案,因此創建了Kubernetes Ingress以使配置更容易且更易於管理。

從這一點開始,您應該瞭解圖像中顯示的上述示例的優勢。 如果您不願意,請隨時在下面添加評論以進行討論。

在我們的示例中使用Kubernetes Ingress

將以下圖像與上一張圖像進行比較。 真的沒多大變化。 我們只使用了預先配置的Nginx(Kubernetes Ingress),它已經為我們完成了所有代理重定向,從而節省了很多手動配置工作:

圖解Kubernetes之Ingress

這就是了解Kubernetes Ingress是什麼的全部。 現在,讓我們轉到一些示例配置。

安裝Kubernetes入口控制器

Kubernetes Ingress是額外的Kubernetes資源,可以通過以下方式安裝:

<code>kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yamlkubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml/<code>

使用以下命令,您將看到k8s資源已安裝在名稱空間ingress-nginx中:

<code>kubectl get svc,pod --namespace=ingress-nginx/<code>


圖解Kubernetes之Ingress

您會看到帶有外部IP和附屬Pod的常規LoadBalancer服務。 您甚至可以將kubectl exec放入該pod中,以查看其中包含預先配置的Nginx服務器:

圖解Kubernetes之Ingress

在nginx.conf中,您會看到各種代理重定向設置和其他相關配置。

示例Kubernetes入口配置

我們一直在使用的示例Ingress yaml可能如下所示:

<code># just example, not testedapiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx  namespace: default  name: test-ingressspec:  rules:  - http:      paths:      - path: /folder        backend:          serviceName: service-nginx          servicePort: 3001  - http:      paths:      - path: /other        backend:          serviceName: service-python          servicePort: 3002/<code>


我們需要像通過kubectl create -f ingress.yaml來創建其他任何資源一樣的yaml。 然後,該Yaml將由先前安裝的Ingress Controller轉換為Nginx配置。

示例Kubernetes入口/不同的命名空間

現在,如果Ingress應該重定向到的內部服務之一在另一個名稱空間中,該怎麼辦? 因為您定義的入口資源是命名空間。 在Ingress配置中,您只能重定向到相同名稱空間中的服務。

如果定義了多個Ingress yaml配置,則這些配置將由一個Ingress Controller合併到一個Nginx配置中。 含義:所有人也都使用相同的LoadBalancer IP。

因此,我們考慮將service-nginx設置為默認名稱空間:

<code># just example, not testedapiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx  namespace: default  name: ingress1spec:  rules:  - http:      paths:      - path: /folder        backend:          serviceName: service-nginx          servicePort: 3001/<code>

然後service-python在命名空間namespace2中:

<code># just example, not testedapiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx  namespace: namespace2  name: ingress2spec:  rules:  - http:      paths:      - path: /other        backend:          serviceName: service-python          servicePort: 3002/<code>


因此,我們創建了兩個Ingress yaml資源。

如何微調Ingress Nginx配置?

您可以通過Inhgress Kubernetes資源上的註釋來做到這一點。 例如,您可以配置通常可以直接在Nginx中配置的各種選項:

<code>kind: Ingressmetadata:  name: ingress  annotations:      kubernetes.io/ingress.class: nginx      nginx.ingress.kubernetes.io/proxy-connect-timeout: '30'      nginx.ingress.kubernetes.io/proxy-send-timeout: '500'      nginx.ingress.kubernetes.io/proxy-read-timeout: '500'      nginx.ingress.kubernetes.io/send-timeout: "500"      nginx.ingress.kubernetes.io/enable-cors: "true"      nginx.ingress.kubernetes.io/cors-allow-methods: "*"      nginx.ingress.kubernetes.io/cors-allow-origin: "*".../<code>

您甚至可以執行非常具體的規則,例如:

<code>nginx.ingress.kubernetes.io/configuration-snippet: |  if ($host = 'www.wuestkamp.com' ) {    rewrite ^ https://wuestkamp.com$request_uri permanent;  }/<code>


使用www。 是"2008"年的怪獸!

然後,這些註釋將轉換為Nginx配置。 您始終可以通過手動將(kubectl exec)連接到Ingress Nginx pod並查看配置來進行檢查。

有各種配置示例:

  • https://github.com/kubernetes/ingress-nginx/tree/master/docs/user-guide/nginx-configuration
  • https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#lua-resty-waf

檢查入口/ Nginx日誌

找出問題或錯誤,查看Ingress日誌也很有幫助:

<code>kubectl logs -n ingress-nginx ingress-nginx-controller-6cfd5b6544-k2r4n/<code>


圖解Kubernetes之Ingress

使用Curl測試設置

如果要測試您的Ingress / Nginx重定向規則,則最好使用curl -v yourhost.com而不是瀏覽器,以避免緩存等。

重定向方式/入口規則

在本文的示例中,我們使用了/ folder或/ other / directory之類的路徑來重定向到其他服務。 這稱為"路徑列表"。

還可以通過請求的主機名來區分請求,例如將api.myurl.com和website.myurl.com重定向到其他內部ClusterIP服務。 可能看起來像這樣:

<code>apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:  name: simple-fanout-examplespec:  rules:  - host: api.myurl.com    http:      paths:      - path: /foo        backend:          serviceName: service1          servicePort: 4200      - path: /bar        backend:          serviceName: service2          servicePort: 8080  - host: website.myurl.com    http:      paths:      - path: /        backend:          serviceName: service3          servicePort: 3333/<code>

在此示例中,我們看到對於特定的主機名,我們將不同的http路徑重定向到不同的內部服務。

SSL / HTTPS

SSL。 你聽說過嗎? :)您可能希望通過安全的https訪問您的網站。 Kubernetes Ingress提供了非常簡單的" TLS Termination",這意味著它可以處理所有SSL通信,解密/終止SSL請求,然後將解密後的請求發送到您的內部服務。

如果您的多個內部服務使用的是相同(甚至是通配符)SSL證書,那就非常好,因為這樣一來,您只需在Ingress上配置一次即可,而不必在所有其他內部服務上進行配置。 入口可以使用已配置的TLS Kubernetes Secret中的SSL證書。

<code>apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:  name: tls-example-ingressspec:  tls:  - hosts:    - sslexample.foo.com    secretName: testsecret-tls  rules:    - host: sslexample.foo.com      http:        paths:        - path: /          backend:            serviceName: service1            servicePort: 80/<code>

您只需要確保如果在不同的名稱空間中有多個Ingress資源,則TLS秘密也必須在使用它定義了Ingress資源的所有名稱空間中都可用。

概括

我只是想為您提供有關神秘的Kubernetes Ingress背後的內容的廣泛概述。 簡化:無非是一種輕鬆配置Nginx服務器的方法,該服務器會將請求重定向到其他內部服務。

這為您節省了寶貴的靜態IP和LoadBalancers。 但是,不應將Kubernetes Ingress視為Kubernetes服務之一。 Ingress本身不是Kubernetes服務,但通常使用一個,主要是LoadBalancer。

請注意,還有其他Kubernetes Ingress類型不在內部設置Nginx服務,但可能使用其他代理技術。

(本文翻譯自Kim Wuestkamp的文章《Kubernetes Ingress simply visually explained》,參考:https://codeburst.io/kubernetes-ingress-simply-visually-explained-d9cad44e4419)


分享到:


相關文章: