Docker Nginx-Http到Https配置导致无限重定向

Docker Nginx-Http到Https配置导致无限重定向,docker,nginx,kubernetes,webserver,Docker,Nginx,Kubernetes,Webserver,我遇到了无限重定向的问题。我试着到处找,但找不到任何能解决我问题的东西 我有一个带有Docker映像的K8s部署,它运行一个Nginx映像 问题是,当我向http://[company]发出请求时,我正确地得到了301,并被重定向到https,但当我向https://[company]发出请求时,也会发生同样的情况,这会导致无限的重定向 另外,当我向http://[company]/healthz发出请求时,我得到了200,这是正确的,但当我向https://[company]/healthz发

我遇到了无限重定向的问题。我试着到处找,但找不到任何能解决我问题的东西

我有一个带有Docker映像的K8s部署,它运行一个Nginx映像

问题是,当我向
http://[company]
发出请求时,我正确地得到了
301
,并被重定向到
https
,但当我向
https://[company]
发出请求时,也会发生同样的情况,这会导致无限的重定向

另外,当我向
http://[company]/healthz
发出请求时,我得到了
200
,这是正确的,但当我向
https://[company]/healthz
发出请求时,我也得到了
200
的响应,这是不正确的

根据这种行为,我假设端口
80
上的服务器以某种方式捕获了所有通信量,但我无法找出原因

请看一下我的配置文件——也许这是一个小错误(请记住,我对Nginx和K8s还是一个新手,我想了解它是如何工作的)

这是我的
nginx.conf

worker_processes auto;

events {
  worker_connections 1024;
  multi_accept on;
}

http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      return 301 https://[company]$request_uri;
    }
    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }

  server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name [company];
    root /var/www;

    error_log /var/www/logs/ssl_error.log error;

    location / {
      index index.html;
      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 $scheme;
      proxy_set_header Host $host;
      proxy_set_header X-Url-Scheme $scheme;
      proxy_redirect off;
      proxy_max_temp_file_size 0;
    }

    ssl_certificate /etc/cert/[company].crt;
    ssl_certificate_key /etc/cert/[company].key;
  }
}
这是我的
Dockerfile

FROM nginx:alpine
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
这是我的
部署。yaml

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
            - containerPort: 443
              name: https
              protocol: TCP
apiVersion: extensions/v1beta1
kind: Ingress
...
spec:
  backend:
    serviceName: [service-name]
    servicePort: 80
这是我的
入口。yaml

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
            - containerPort: 443
              name: https
              protocol: TCP
apiVersion: extensions/v1beta1
kind: Ingress
...
spec:
  backend:
    serviceName: [service-name]
    servicePort: 80
在这一点上,我真的不知道为什么它不工作,所以请,即使它是一些愚蠢的错误,请随时指出它! 我做错了什么?

试试这个:

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name _;
  return 301 https://[company]$request_uri;
试试这个:

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name _;
  return 301 https://[company]$request_uri;

这里的错误是您没有正确使用入口资源。K8s入口用于公开服务,并充当应用程序的DNS记录。您的nginx设置不是为在docker内部运行而设计的

为了让一切正常工作,您应该做以下几点:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
1.将您的
nginx.conf
重写如下:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
2.将您的
Dockerfile
重写如下:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
3.按如下方式重写部署.yaml:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
4.重写您的
ingres.yaml
,如下所示:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
通过此设置,您可以允许入口正常工作,并且不会在容器内承受额外负载,因为这既不必要也不起作用。完成此设置后,您还需要将证书文件添加到k8s机密资源中


编辑:如果您想包含SSL服务器块中的头,我建议您研究在入口中执行此操作的方法。

这里的错误是您没有正确使用入口资源。K8s入口用于公开服务,并充当应用程序的DNS记录。您的nginx设置不是为在docker内部运行而设计的

为了让一切正常工作,您应该做以下几点:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
1.将您的
nginx.conf
重写如下:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
2.将您的
Dockerfile
重写如下:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
3.按如下方式重写部署.yaml:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
4.重写您的
ingres.yaml
,如下所示:

...
http {
  include /etc/nginx/mime.types;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    error_log /var/www/logs/http_error.log error;

    location / {
      index index.html;
      ...
    }

    location /healthz {
      access_log off;
      return 200 "healthy";
    }
  }
}
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      containers:
        ...
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
spec:
  tls:
  - hosts:
      - [company]
    secretName: [company]-tls
  rules:
  - host: [company]
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
通过此设置,您可以允许入口正常工作,并且不会在容器内承受额外负载,因为这既不必要也不起作用。完成此设置后,您还需要将证书文件添加到k8s机密资源中


编辑:如果您想包含SSL服务器块的标题,我建议您研究在入口中执行此操作的方法。

您的应用程序是否也在重定向?Nginx容器服务于一个简单的静态网站,因此没有后端,这将导致重定向-这只是一个HTML文件。您是否可以尝试使用
$schema
对设置标题的行进行注释,如果不起作用,您是否可以在debug And Verbose中发布
curl
输出?您的应用程序是否也重定向?Nginx容器提供一个简单的静态网站,因此没有后端,这将导致重定向-这只是一个HTML文件。您是否可以尝试使用
$schema
对设置标题的行进行注释,如果它不起作用,您是否可以在调试和详细操作中发布
curl
输出非常感谢您的回答并为我指出正确的方向-它解决了我遇到的问题!非常感谢您的回答,并为我指出了正确的方向-它解决了我的问题!谢谢你的回答,但遗憾的是,这并没有解决我的问题。问题在于我用Nginx设置我的K8s入口的方式(在Gabriel的回答的帮助下解决了)。谢谢你的回答,但遗憾的是它没有解决我的问题。问题在于我用Nginx设置我的K8s入口的方式(在Gabriel的回答的帮助下解决了这个问题)。