圖解 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;
}/<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,它將被重定向到我們的內部service-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 example
location /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.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml/<code>

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

kubectl get svc,pod --namespace=ingress-nginx

圖解 Kubernetes Ingress

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

圖解 Kubernetes Ingress

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

示例Kubernetes入口配置

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

<code># just example, not tested
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: default
name: test-ingress
spec:
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 tested
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: default
name: ingress1
spec:
rules:
- http:
paths:
- path: /folder
backend:
serviceName: service-nginx
servicePort: 3001/<code>

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

<code># just example, not tested
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: namespace2
name: ingress2
spec:
rules:
- http:
paths:
- path: /other
backend:
serviceName: service-python
servicePort: 3002/<code>

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

如何微調Ingress Nginx配置?

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

<code>kind: Ingress
metadata:
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)連接到入口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日誌也很有幫助:

kubectl logs -n ingress-nginx ingress-nginx-controller-6cfd5b6544-k2r4n

圖解 Kubernetes Ingress

使用Curl測試設置

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

重定向方式/入口規則

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

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

<code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
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終止”,這意味著它可以處理所有SSL通信,解密/終止SSL請求,然後將解密後的請求發送到您的內部服務。

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

<code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
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)


分享到:


相關文章: