/home/k8s-ingress-behind-nginx-reserved-proxy

Kubernetes ingress chạy bên dưới nginx reverse proxy

Published on | Updated

Mình có setup 1 Kubernetes cluster nho nhỏ với mục đích thử nghiệm bằng k3s.

Chuyện sẽ chẳng có gì nếu mà expose thẳng Ingress ra internet như bình thường, mình chỉ cần vào DNS controlpanel và trỏ domain về là xong.

Nhưng không, mọi chuyện phức tạp lên nhiều khi mà mình đang chạy n thứ với Nginx trên server đó.

k8s-ingress-behind-nginx-reserved-proxy

Mình không thể bỏ mặc những thứ đang up & running được, vậy nên là tìm cách để đào thoát thôi.

Loay hoay vật vã sau 2 đêm lần mò thử nghiệm, cuối cùng mình cũng đã tìm ra được cách.

1. Deploy ArgoCD với host bất kì. Ở đây mình để tên là homelab.local

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/ssl-passthrough: "false"
spec:
  rules:
  - host: homelab.local
    http:
      paths:
      - path: /argocd
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https

2. Chỉnh sửa file /etc/hosts để trỏ homelab.local về 127.0.0.1

127.0.0.1    homelab.local

3. Test thử truy cập trên server

curl http://homelab.local:32135/argocd/

Sẽ nhận được kết quả như này

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Argo CD</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel='icon' type='image/png' href='assets/favicon/favicon-32x32.png' sizes='32x32'/>
    <link rel='icon' type='image/png' href='assets/favicon/favicon-16x16.png' sizes='16x16'/>
    <link href="assets/fonts.css" rel="stylesheet">
</head>

<body>
    <noscript>
        <p>
        Your browser does not support JavaScript. Please enable JavaScript to view the site.
        Alternatively, Argo CD can be used with the <a href="https://argoproj.github.io/argo-cd/cli_installation/">Argo CD CLI</a>.
        </p>
    </noscript>
    <div id="app"></div>
<script type="text/javascript" src="main.c7ea22e999b3805bc676.js"></script></body>

</html>

Tại sao mình lại dùng port 32135? Vì mình đã expose port 80 của ingress ra port 32135 nên mình có thể truy cập được từ server vào k8s cluster

4. Tạo nginx config proxy_pass về homelab.local

Trick nằm ở đây.
Ví dụ bạn có domain homelab.dungnt.net.
Bạn muốn truy cập homelab.dungnt.net/argocd/ ?

Nhưng nếu chỉ đơn giản setup nginx cài trên server là proxy_pass http://homelab.local:32135; thì chắc chắn bạn sẽ gặp lỗi 404 luôn.

Vì sao?
Vì nginx trong k8s không biết Host homelab.dungnt.net là cái nào cả, nên là nó không ăn.

Việc của mình là lừa nó bằng một số header, giả lập cho nó nhận là Host homelab.local đang truy vấn.

File nginx config sẽ kiểu như này

server {
    listen 80;
    server_name homelab.dungnt.net;
    location / {
	     proxy_set_header Host homelab.local;
	     proxy_set_header X-Forwarded-Host homelab.local;

	      proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto http;
        proxy_redirect off;

        proxy_pass http://homelab.local:32135;
    }
}

Chỉ cần tập trung chính vào header X-Forwarded-HostHost là ok.

5. Test thử thôi

Tạm truy cập được ArgoCD qua đường vòng rồi, giờ thì đi ngủ :cry: