我在kubernetes集群中部署了一个nginx pod来提供静态文件。为了在不同的环境中设置特定的标头,我遵循了official nginx docker image docs中的使用envsubst
的说明,在运行nginx之前从模板生成配置文件。
这是我的nginx模板(nginx.conf.template):
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
root /usr/share/nginx/html;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
location / {
add_header x-myapp-env $MYAPP_ENV;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
}
我使用Kubernetes的default command override功能在启动nginx之前初始生成nginx conf文件。这是配置的相关部分:
command: ["/bin/sh"]
args: ["-c", "envsubst < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf && nginx -g 'daemon off;'" ]
Kubernetes成功部署了pod,但是当我发出请求时,我的浏览器出现ERR_TOO_MANY_REDIRECTS
错误。
奇怪的是,当我使用与上面几乎完全相同的nginx.conf(而没有add_header
指令)运行命令覆盖而不运行命令覆盖时,它工作正常。
(所有要提供的SSL证书和文件都很高兴在构建时复制到容器上,所以那里应该没有问题)
任何帮助表示赞赏。
答案 0 :(得分:2)
我非常确定envsubst
将try_files $uri $uri/ /index.html;
变为try_files / /index.html;
而return 301 https://$host$request_uri;
变为return 301 https://;
,从而咬住了你。这会导致重定向循环。
我建议您改为运行envsubst '$MYAPP_ENV' <template >nginx.conf
。那只会取代那个单一的变量而不是非预期的变量。 (注意在示例命令中绕变量转义!)如果以后需要添加变量,可以将它们全部指定为envsubsts '$VAR1$VAR2$VAR3'
。
如果您要替换所有环境变量,可以使用此代码段:
envsubst `declare -x | sed 's/^declare -x \([^=]*\)=.*/$\1/' | tr -d '\n'` <template >nginx.conf
此外,虽然问题中未提及,但使用... && exec nginx -g 'daemon off;'
可以省去一些麻烦。 exec
将使用nginx进程替换正在运行的shell(pid 1),而不是将其分叉。这也意味着信号将由nginx等接收。