NGINX Ingress控制器返回502,后端应用程序Pod没有日志。

3

我在我的Kubernetes集群(所有的Vagrant虚拟机)上部署了ECK。该集群具有以下配置。

NAME       STATUS   ROLES                       AGE   VERSION 
kmaster1   Ready    control-plane,master        27d     v1.21.1 
kworker1   Ready    <none>                      27d     v1.21.1
kworker2   Ready    <none>                      27d     v1.21.1

我还设置了一个带有HAProxy的负载均衡器。负载均衡器配置如下(使用了自己创建的私人证书):

frontend http_front
  bind *:80
  stats uri /haproxy?stats
  default_backend http_back

frontend https_front
  bind *:443 ssl crt /etc/ssl/private/mydomain.pem
  stats uri /haproxy?stats
  default_backend https_back


backend http_back
  balance roundrobin
  server kworker1 172.16.16.201:31953
  server kworker2 172.16.16.202:31953
 

backend https_back
  balance roundrobin
  server kworker1 172.16.16.201:31503 check-ssl ssl verify none
  server kworker2 172.16.16.202:31503 check-ssl ssl verify none

我还部署了一个nginx ingress控制器,31953是nginx控制器的http端口,31503是nginx控制器的https端口。

nginx-ingress    nginx-ingress-controller-service   NodePort    10.103.189.197   <none>        80:31953/TCP,443:31503/TCP   8d    app=nginx-ingress

我正在尝试使kibana仪表板在https下在集群外可用。它在集群内部运行良好,我可以访问它。但是我无法通过负载平衡器访问它。

Kibana Pod:

default          quickstart-kb-f74c666b9-nnn27              1/1     Running   4          27d   192.168.41.145   kworker1   <none>           <none>

我已将负载均衡器映射到主机。
172.16.16.100   elastic.kubekluster.com

任何对https://elastic.kubekluster.com的请求都会导致以下错误(来自nginx ingress controller pod的日志)

 10.0.2.15 - - [20/Jun/2021:17:38:14 +0000] "GET / HTTP/1.1" 502 157 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0" "-"
2021/06/20 17:38:14 [error] 178#178: *566 upstream prematurely closed connection while reading response header from upstream, client: 10.0.2.15, server: elastic.kubekluster.com, request: "GET / H
TTP/1.1", upstream: "http://192.168.41.145:5601/", host: "elastic.kubekluster.com"

HAproxy日志如下

Jun 20 18:11:45 loadbalancer haproxy[18285]: 172.16.16.1:48662 [20/Jun/2021:18:11:45.782] https_front~ https_back/kworker2 0/0/0/4/4 502 294 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"

入口如下

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubekluster-elastic-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/default-backend: quickstart-kb-http
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600s"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600s"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600s"
    nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
  tls:
    - hosts:
      - elastic.kubekluster.com
  rules:
  - host: elastic.kubekluster.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: quickstart-kb-http
            port: 
              number: 5601

我认为请求没有到达Kibana Pod,因为我在Pod中没有看到任何日志。此外,我不明白为什么Haproxy发送的请求是HTTP而不是HTTPS。请问您能指出我的配置存在的任何问题吗?


proxy-body-size应该像超时一样加引号。这可能不是问题,但如果你想让它生效,应该加引号。 - oz123
它运行良好,我可以在集群内访问它 - 你是如何测试它的?你能通过 kubectl port-forward 访问仪表板吗? - oz123
是的,我添加了注释只是为了增加超时时间。这并没有解决问题。在正文大小周围添加引号没有任何区别,但我已经注意到了。 对于您的第二个问题,我将服务“quickstart-kb-http”公开为节点端口,并通过https://<nodeid>:<nodeport>访问它。我被重定向到kibana登录页面,并在输入凭据后成功登录。 我还转发了端口以通过服务进行访问,如下所示: kubectl port-forward service/quickstart-kb-http 8080:5601并且能够通过https[colon]//127.0.0.1:8080访问仪表板。 - bluelurker
我认为问题在于这里存在协议混淆。如果后端是HTTPS,则HAProxy应该只是通过流量。或者,使用haproxy中的SSL,但删除与nginx ingress中的TLS\SSL相关的所有内容。 - oz123
2个回答

1

我希望这能帮到您...以下是我如何使用nginx设置"LoadBalancer"并将流量转发到HTTPS服务的方法:

 kubectl get nodes -o wide 
NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP      OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
asd-master-1   Ready    master   72d   v1.19.8   192.168.1.163   213.95.154.199   Ubuntu 20.04.2 LTS   5.8.0-45-generic   docker://20.10.6
asd-node-1     Ready    <none>   72d   v1.19.8   192.168.1.101   <none>           Ubuntu 20.04.1 LTS   5.8.0-45-generic   docker://19.3.15
asd-node-2     Ready    <none>   72d   v1.19.8   192.168.0.5     <none>           Ubuntu 20.04.1 LTS   5.8.0-45-generic   docker://19.3.15
asd-node-3     Ready    <none>   15d   v1.19.8   192.168.2.190   <none>           Ubuntu 20.04.1 LTS   5.8.0-45-generic   docker://19.3.15

这是针对nginx的服务:
# kubectl get service -n ingress-nginx
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.101.161.113   <none>        80:30337/TCP,443:31996/TCP   72d

这是负载均衡器的配置:
# cat /etc/nginx/nginx.conf
... trimmed ...
stream {
    upstream nginx_http {
        least_conn;
        server asd-master-1:30337 max_fails=3 fail_timeout=5s;
        server asd-node-1:30337 max_fails=3 fail_timeout=5s;
        server asd-node-2:30337 max_fails=3 fail_timeout=5s;
    }
    server {
        listen 80;
        proxy_pass nginx_http;
        proxy_protocol on;
    }

    upstream nginx_https {
        least_conn;
        server 192.168.1.163:31996 max_fails=3 fail_timeout=5s;
        server 192.168.1.101:31996 max_fails=3 fail_timeout=5s;
        server 192.168.0.5:31996 max_fails=3 fail_timeout=5s;
    }
    server {
        listen     443;
        proxy_pass nginx_https;
        proxy_protocol on;
    }

}

重要的部分是我正在发送代理协议。您需要配置nginx ingress(在配置映射中)来接受它,可能还需要将正确的语法添加到haproxy配置中。

这可能类似于:

backend https_back
  balance roundrobin
  server kworker1 172.16.16.201:31503 check-ssl ssl verify none send-proxy-v2
  server kworker2 172.16.16.202:31503 check-ssl ssl verify none send-proxy-v2

Nginx Ingress 的配置应该是:

Nginx Ingress 配置应为:

# kubectl get configmap -n ingress-nginx  nginx-configuration -o yaml
apiVersion: v1
data:
  use-proxy-protocol: "true"
kind: ConfigMap
metadata:
...

我希望这能让你走上正确的道路。


谢谢。这真的很有帮助。 - bluelurker

0
借鉴@oz123的答案,我进行了更深入的分析,并最终通过以下配置实现了它。 负载均衡器配置(HAProxy) 通过在Vagrantfile中进行配置,使用桥接网络公开了LB。 启用了Haproxy中的TLS透传。
frontend kubernetes-frontend
  bind 192.168.1.23:6443
  mode tcp
  option tcplog
  default_backend kubernetes-backend

backend kubernetes-backend
  mode tcp
  option tcp-check
  balance roundrobin
  server kmaster1 172.16.16.101:6443 check fall 3 rise 2

frontend http_front
  bind *:80
  stats uri /haproxy?stats
  default_backend http_back

frontend https_front
  mode tcp
  bind *:443
  #ssl crt /etc/ssl/private/mydomain.pem
  stats uri /haproxy?stats
  default_backend https_back


backend http_back
  balance roundrobin
  server kworker1 172.16.16.201:32502
  server kworker2 172.16.16.202:32502


backend https_back
  mode tcp
  balance roundrobin
  server kworker1 172.16.16.201:31012
  server kworker2 172.16.16.202:31012
  

Ingress控制器

创建了一个Nodeport Ingress控制器服务,并通过该控制器公开了所有内部服务(例如Kibana)。除Ingress控制器之外,所有其他服务均为ClusterIP。

apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    helm.sh/chart: ingress-nginx-4.0.15
  name: ingress-nginx-controller
  namespace: ingress-nginx
  resourceVersion: "8198"
  uid: 245a554f-56a8-4bc4-a3dd-19ffc9116a08
spec:
  clusterIP: 10.105.43.200
  clusterIPs:
  - 10.105.43.200
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    nodePort: 32502
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    nodePort: 31012
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

Kibana 的 Ingress 资源

kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  generation: 1
  name: ingress-kibana
  namespace: default
spec:
  rules:
  - host: kibana.kubekluster.com
    http:
      paths:
      - backend:
          service:
            name: quickstart-kb-http
            port:
              number: 5601
        path: /
        pathType: Prefix
  tls:
  - secretName: quickstart-kb-http-certs-public

最后,在/etc/hosts中创建一个条目,将LB IP映射到子域名,并像下面这样访问kibana控制台。
https://kibana.kubekluster.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接