Kubernetes Ingress Nginx Rewrite non-www to www

Background

由于近期项目都开始面向全球用户,开始将前端部署配置起 CDN,踩了很多坑,这里记录一下关于 @ 域名 CNAME 解析与 MX 邮箱冲突的问题。

一般做法是直接将 @ 使用 A 解析到 IP,但这样就没法使用 CDN 了。

这是一个普遍存在的问题,参考 阿里云文档

按照RFC标准协议CNAME优先级最高,所以在解析请求过程中,会优先返回CNAME解析记录结果,这样设置的结果导致用户无法请求到MX记录,直接对客户的邮箱业务造成使用影响。所以对于这类情况,云解析DNS会通过记录冲突的提示方式,来帮助用户避免这种配置风险。

阿里云的推荐做法是使用 URL转发 解决问题,比如强制跳转 $DOMAIN.com 到 www.$DOMAIN.com,测试通过,但不支持 https,即如果直接访问 https://domain.com 不会进行跳转。

为此有两个解决思路:

  • 部一个前端项目,配置好证书和 @ 的解析,通过页面进行跳转
  • 使用反向代理直接进行跳转

这里使用反向代理进行处理,目前运行很完美。

使用 Nginx 反向代理

反向代理使用 Nginx,由于这个项目是跑在 Kubernetes 集群上的,使用了 ingress-nginx,同时附上普通 nginx 的配置供参考。

假设域名为 $DOMAIN,请自行替换。

Kubernetes Ingress Nginx

  • 配置 YAML 文件

rewrite.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rewrite
namespace: prod
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/(.*)$ https://www.$DOMAIN.com/$1 permanent;
spec:
tls:
- hosts:
- $DOMAIN.com
secretName: rewrite
rules:
- host: $DOMAIN.com

注:这里同时使用了 letsencrypt 作为 cert-manager 进行 SSl 证书的自动化管理,namespace 也请按各人需求配置

  • 执行命令
1
$ kubectl apply -f rewrite.yaml

普通 Nginx 配置参考

1
2
3
4
5
6
7
8
9
10
11
12
# @ 跳转到 www
server {
listen 80;
server_name $DOMAIN.com
rewrite ^/(.*)$ http://www.$DOMAIN.com/$1 permanent;
}

server {
listen 80;
server_name www.$DOMAIN.com;
# 省略通用配置内容
}