Nginx Ingress Controller là gì

Đảm bảo rằng bạn hiểu Dịch vụ Kubernetes từ Phần 1:

  • Phần 1: Dịch vụ Kubernetes giải thích trực quan đơn giản
  • Phần 2: (bài này)
  • Phần 3: Kubernetes Istio đơn giản giải thích trực quan
  • Phần 4: Kubernetes Serverless đơn giản giải thích trực quan

Kubernetes Ingress không phải là một Dịch vụ Kubernetes. Rất đơn giản, nó chỉ là một Nginx Pod chuyển hướng các yêu cầu đến các dịch vụ nội bộ (ClusterIP) khác. Bản thân Pod này được tạo có thể truy cập thông qua Dịch vụ Kubernetes, phổ biến nhất là LoadBalancer.

Bạn có nên đọc nó không?

Trước tiên, tôi hy vọng tôi có thể cung cấp cho bạn một cái nhìn tổng quan rõ ràng và đơn giản về những gì đằng sau Kubernetes Ingress bí ẩn này, sau đó giúp bạn dễ dàng hiểu những gì bạn đang thực sự triển khai hoặc thậm chí nếu bạn nên làm như vậy.

Sau đó, tôi hiển thị một số cấu hình ví dụ dựa trên ví dụ mà chúng tôi sử dụng trong suốt bài viết này.

Tại sao sử dụng Ingress?

Bạn sử dụng nó để làm cho các dịch vụ nội bộ có thể truy cập được từ bên ngoài cụm của bạn. Nó giúp bạn tiết kiệm các IP tĩnh quý giá, vì bạn sẽ không cần phải khai báo nhiều dịch vụ LoadBalancer. Ngoài ra, nó cho phép cấu hình nhiều hơn và thiết lập dễ dàng hơn như chúng ta sẽ thấy.

Chúng ta sẽ làm gì ở đây?

  • Đầu tiên chúng tôi làm thực sự chuyến tham quan ngắn vào cách http server, đặc biệt là Nginx, làm việc và những gì họ có thể làm.
  • Sau đó, chúng tôi sẽ chỉ ra cách một Ingress có thể được thiết lập theo cách thủ công, vì vậy hoàn toàn không sử dụng tài nguyên Kubernetes Ingress ưa thích.
  • Tiếp theo, chúng ta sẽ thấy rằng Kubernetes Ingress không hơn gì một máy chủ Nginx được định cấu hình trước.

Ở đây chúng ta quay trở lại thời gian trước khi có container, Kubernetes và thế giới Cloud hiện đại. Ở lại với tôi, nó sẽ ngắn.

Máy chủ HTTP (Nginx) có thể làm gì?

Nó có thể nhận được yêu cầu qua giao thức HTTP cho một đường dẫn tệp cụ thể, hãy kiểm tra đường dẫn tệp đó trên hệ thống tệp đính kèm và trả lại nếu tệp đó tồn tại:

Trong Nginx, ví dụ, điều này có thể được thực hiện với một cái gì đó như:

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

Nó có thể nhận yêu cầu cho một đường dẫn tệp cụ thể, chuyển hướng yêu cầu đó đến một máy chủ khác (có nghĩa là nó hoạt động như một proxy) và sau đó chuyển hướng phản hồi của máy chủ đó trở lại máy khách. Đối với máy khách không có gì thay đổi, kết quả nhận được vẫn là tệp được yêu cầu (nếu tồn tại).

Chúng tôi sẽ không đi sâu vào vấn đề này nhưng trong Nginx, ví dụ: chuyển hướng proxy có thể được định cấu hình như:

location /folder { proxy_pass http://second-nginx-server:8000; }

Một ví dụ đơn giản của Kubernetes:

Một lần nữa, từ thời điểm này bạn nên hiểu Dịch vụ Kubernetes . Chúng tôi có hai nút công nhân, chúng tôi bỏ qua các nút chính ở đây. Chúng tôi có hai dịch vụ service-nginxservice-python trỏ đến các nhóm khác nhau.

Các dịch vụ không được lên lịch trên bất kỳ Node cụ thể nào, chỉ cần nói rằng chúng “có sẵn ở mọi nơi trong cụm”.

Bạn nên hiểu chuyện gì đang xảy ra ở đây. Trong nội bộ cụm của chúng tôi, chúng tôi có thể tiếp cận nhóm Nginx và nhóm Python thông qua các dịch vụ của họ. Tiếp theo, chúng tôi cũng muốn cung cấp những thứ đó từ bên ngoài cụm. Vì vậy, chúng tôi chuyển đổi chúng thành các dịch vụ LoadBalancer:

Sử dụng dịch vụ LoadBalancer

Bạn có thể thấy rằng chúng tôi đã chuyển đổi các dịch vụ ClusterIP thành các dịch vụ LoadBalancer. Vì chúng tôi có Cụm Kubernetes của mình được lưu trữ với Nhà cung cấp đám mây có thể xử lý điều này (Gcloud, AWS, DigitalOcean…), nên nó tạo ra hai bộ cân bằng tải bên ngoài chuyển hướng yêu cầu đến các IP Node bên ngoài của chúng tôi, sau đó chuyển hướng đến các dịch vụ ClusterIP nội bộ.

Chúng ta thấy hai LoadBalancers, mỗi bên có IP riêng. Nếu chúng tôi gửi một yêu cầu đến LoadBalancer 22.33.44.55, nó sẽ được chuyển hướng đến dịch vụ nội bộ của chúng tôi -nginx . Nếu chúng tôi gửi yêu cầu đến 77.66.55.44, nó sẽ được chuyển hướng đến service-python nội bộ của chúng tôi .

Điều này hoạt động tuyệt vời! Nhưng địa chỉ IP rất hiếm và giá của LoadBalancer phụ thuộc vào các nhà cung cấp dịch vụ đám mây. Bây giờ hãy tưởng tượng chúng ta không chỉ có hai mà còn nhiều dịch vụ nội bộ khác mà chúng ta muốn tạo LoadBalancers, chi phí sẽ tăng lên.

Có thể có một giải pháp khác cho phép chúng tôi chỉ sử dụng một LoadBalancer (với một IP) nhưng vẫn tiếp cận trực tiếp cả hai dịch vụ nội bộ của chúng tôi không? Trước tiên, hãy khám phá điều này bằng cách triển khai phương pháp thủ công (không phải Kubernetes).

Định cấu hình thủ công Dịch vụ Nginx làm proxy

Như đã mô tả trước đó, Nginx có thể hoạt động như một proxy. Trong hình ảnh sau, chúng ta thấy một dịch vụ mới có tên là service-nginx-proxy , đây thực sự là dịch vụ LoadBalancer duy nhất của chúng tôi. Các -nginx-proxy dịch vụ vẫn sẽ trỏ đến một hoặc nhiều Nginx-pod-điểm cuối, nhưng vì đơn giản tôi không bao gồm này trong đồ họa. Hai dịch vụ khác từ trước được chuyển đổi trở lại thành những dịch vụ ClusterIP đơn giản:

Chúng ta có thể thấy rằng chúng ta chỉ nhấn một LoadBalancer (11.22.33.44) nhưng với các url http khác nhau, các yêu cầu được hiển thị bằng màu vàng giống như cùng một mục tiêu và chỉ chứa nội dung khác nhau (url yêu cầu).

Dịch vụ service-nginx-proxy quyết định (bằng cách sử dụng địa chỉ và vị trí proxy Nginx), tùy thuộc vào các url được chuyển, dịch vụ mà anh ta sẽ chuyển hướng yêu cầu.

Trong trường hợp này, chúng tôi có hai sự lựa chọn, màu đỏ và màu xanh. Red chuyển hướng đến service-nginx trong đó màu xanh chuyển hướng đến service-python .

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

Và bởi vì đây là một giải pháp phổ biến, Kubernetes Ingress đã được tạo ra để giúp cấu hình dễ dàng hơn và dễ quản lý hơn.

Từ điểm này bạn sẽ hiểu lợi thế của ví dụ trên được hiển thị trong hình ảnh. Nếu không, đừng ngại thêm comment bên dưới để cùng thảo luận.

Sử dụng Kubernetes Ingress trong ví dụ của chúng tôi

So sánh hình ảnh sau với hình ảnh trước đó. Thực sự không có nhiều thay đổi. Chúng tôi vừa sử dụng một Nginx được định cấu hình trước (Kubernetes Ingress) đã thực hiện tất cả chuyển hướng proxy cho chúng tôi, điều này giúp chúng tôi tiết kiệm rất nhiều công việc cấu hình thủ công:

Đó là tất cả những gì cần hiểu Kubernetes Ingress. Bây giờ chúng ta hãy chuyển sang một số cấu hình ví dụ.

Cài đặt Kubernetes Ingress Controller

Kubernetes Ingress là một Tài nguyên Kubernetes bổ sung có thể được cài đặt bằng:

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 kubectl get svc,pod --namespace=ingress-nginx

Bên trong, nginx.confbạn sẽ thấy các cài đặt chuyển hướng proxy khác nhau và cấu hình liên quan khác.

Ví dụ Kubernetes Ingress Config

Một ví dụ Ingress yaml cho ví dụ mà chúng tôi đang sử dụng có thể trông như thế này:

# 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

Ví dụ Kubernetes Ingress / Các không gian tên khác nhau

Bây giờ điều gì sẽ xảy ra nếu một trong các dịch vụ nội bộ của bạn, mà Ingress sẽ chuyển hướng đến, nằm trong một không gian tên khác? Vì Tài nguyên Ingress bạn xác định có không gian tên. Bên trong cấu hình Ingress của mình, bạn chỉ có thể chuyển hướng đến các dịch vụ trong cùng một không gian tên.

Nếu bạn xác định nhiều cấu hình Ingress yaml, thì các cấu hình đó sẽ được hợp nhất với nhau thành một cấu hình Nginx bởi một Bộ điều khiển Ingress duy nhất. Có nghĩa là: tất cả đều đang sử dụng cùng một IP LoadBalancer.

Vì vậy, hãy coi service-nginx là mặc định của không gian tên:

# 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 # 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

Làm cách nào để tinh chỉnh cấu hình Ingress Nginx?

Bạn có thể thực hiện việc này bằng các chú thích trên Tài nguyên Inhgress Kubernetes. Ví dụ: bạn có thể định cấu hình các tùy chọn khác nhau mà bạn thường có thể định cấu hình trực tiếp trong Nginx:

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

Các chú thích này sau đó sẽ được dịch sang cấu hình Nginx. Bạn luôn có thể kiểm tra những điều này bằng cách kết nối thủ công ( kubectl exec) vào pod Nginx đi vào và xem cấu hình.

Có nhiều ví dụ cấu hình khác nhau:

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

Kiểm tra Nhật ký Ingress / Nginx

Tìm ra các vấn đề hoặc lỗi cũng hữu ích khi xem nhật ký Ingress:

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

Nếu bạn muốn kiểm tra các quy tắc chuyển hướng Ingress / Nginx của mình, bạn nên sử dụng curl -v yourhost.comthay cho trình duyệt của mình để tránh lưu vào bộ nhớ đệm, v.v.

Các cách chuyển hướng / Quy tắc xâm nhập

Trong các ví dụ trong bài viết này, chúng tôi đã sử dụng các đường dẫn như /folderhoặc /other/directoryđể chuyển hướng đến các dịch vụ khác nhau. Đây được gọi là "Danh sách các đường dẫn".

Cũng có thể phân biệt các yêu cầu theo tên máy chủ của chúng, ví dụ như chuyển hướng api.myurl.comvà website.myurl.comcác dịch vụ ClusterIP nội bộ khác nhau. Điều này có thể trông như thế này:

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

SSL / HTTPS

SSL . Bạn đã nghe nói về nó? :) Bạn có thể muốn truy cập trang web của mình thông qua https an toàn. Kubernetes Ingress cung cấp “Chấm dứt TLS” khá dễ dàng, có nghĩa là nó xử lý tất cả các giao tiếp SSL, giải mã / chấm dứt yêu cầu SSL và sau đó gửi các dịch vụ đã được giải mã đó đến các dịch vụ nội bộ của bạn.

Điều này thật tuyệt nếu nhiều dịch vụ nội bộ của bạn đang sử dụng cùng một chứng chỉ SSL (thậm chí có thể là ký tự đại diện), vì sau đó bạn chỉ phải định cấu hình nó một lần trên Ingress của mình chứ không phải trên tất cả các dịch vụ nội bộ khác của bạn. Ingress có thể sử dụng chứng chỉ SSL từ Bí mật TLS Kubernetes đã định cấu hình.

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

Tóm tắt

Tôi chỉ muốn cung cấp cho bạn một cái nhìn tổng quan về những gì đằng sau Kubernetes Ingress bí ẩn. Đơn giản hóa: nó không hơn gì một cách để dễ dàng cấu hình máy chủ Nginx chuyển hướng yêu cầu đến các dịch vụ nội bộ khác.

Điều này giúp bạn tiết kiệm IP tĩnh và LoadBalancers quý giá. Nhưng Kubernetes Ingress không nên được coi là một trong những Dịch vụ của Kubernetes. Bản thân Ingress không phải là Dịch vụ Kubernetes, nhưng nó thường sử dụng một, chủ yếu là LoadBalancer.

Lưu ý rằng cũng có các loại Kubernetes Ingress khác không thiết lập nội bộ dịch vụ Nginx nhưng có thể sử dụng các công nghệ proxy khác.

Trở thành Kubernetes Certified