Reputation: 29
I got a problem with infinite redirects. I've tried looking "everywhere" but I couldnt find anything that would solve my problem.
I've got a K8s deployment with Docker image that's running an Nginx image.
The problem is that when I make a request to http://[company]
I correctly get a 301
and get redirected to https
, but the same happens when I make a request to a https://[company]
- and it causes an infinite redirects.
Also, when I make a request to http://[company]/healthz
I get 200
, which is correct, but when I make the request to https://[company]/healthz
I also get the 200
response - which is incorrect!
From this behaviour I assume that the server on port 80
somehow catches all the traffic, but I cannot figure out why.
Please take a look on my config files - maybe it's a small mistake (please bear in mind, that I'm kind of still new to Nginx and K8s and I want to understand how it works).
Here's my 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;
}
}
Here's my Dockerfile
:
FROM nginx:alpine
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
Here's my deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
...
spec:
...
spec:
containers:
...
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
Here's my ingress.yaml
:
apiVersion: extensions/v1beta1
kind: Ingress
...
spec:
backend:
serviceName: [service-name]
servicePort: 80
At this point I really don't know why it doesn't work, so please, even if it's some dumb mistake, please feel free to point it out! What am I doing wrong here?
Upvotes: 0
Views: 116
Reputation: 83
What you are doing wrong here is that you are not using Ingress resource correctly. K8s Ingress is used to expose services, and also act as DNS records for your application. The nginx setup you have isn't made for running inside docker.
What you should do in order to have everything working is as follows:
1.rewrite your nginx.conf
as follows:
...
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";
}
}
}
2.rewrite your Dockerfile
as follows:
...
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
3.rewrite your deployment.yaml
as follows:
apiVersion: apps/v1
kind: Deployment
...
spec:
...
spec:
containers:
...
ports:
- containerPort: 80
name: http
protocol: TCP
4.rewrite your ingress.yaml
as follows:
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
With this setup you are allowing Ingress to do it's work properly and not bear extra load inside the container as this is not necessary nor functional. After this setup you also need to add the certification files into a k8s secret resource.
EDIT: If you want to include the headers you had the SSL server block, I suggest into looking into way of doing this inside Ingress.
Upvotes: 2
Reputation: 18
Try this :
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://[company]$request_uri;
Upvotes: 0