【ingress-nginx】重定向设置示例
Ingress 的作用是什么?
-
- クラスター内のServiceに対する外部からのアクセス(主にHTTP)を管理するAPIオブジェクトで、負荷分散、SSL終端、名前ベースの仮想ホスティングの機能を提供する。
-
- 一つのingress上に、複数のドメインの設定を行うことが可能。
ingress-nginxを使った場合は、バーチャルサーバ(バーチャルホスト)の機能を使って実現している。
具体的には、nginx.confに以下のような設定が適用される(以下の例では、foo.example.comとbar.next-example.jpドメインをホストしている)。
http {
:
:
## start server foo.example.com
server {
server_name foo.example.com ;
# Custom code snippet configured for host foo.example.com
location ~* "^/bar/(.*)" {
#
# some config comes here
#
}
}
## end server foo.example.com
## start server bar.next-example.jp
server {
server_name bar.next-example.jp ;
location ~* "^/(.*)" {
}
location ~* "^/" {
}
}
## end server bar.next-example.jp
}
前提 (Chinese) – prerequisite/assumption
-
- Ingressリソースが動作するためには、クラスターでIngressコントローラーが実行されている必要がある。
Ingressコントローラーの一つにIngress NGINX Controllerがある。
今回対象とするのは、このコントローラー上で設定されるIngressリソース。
クラスター内に複数のIngressコントローラーが存在する場合にどのIngressコントローラーを使用するかを示すために、複数のcontrollerをデプロイした時は、適切なspec.ingressClassNameフィールドを指定する必要がある(例:ingressClassName: nginx)。
ドキュメントでは、ingress.classのアノテーションとなっている箇所がある。ingressClassNameフィールドはこのアノテーションを置き換えるものだが、完全に等価ではない。
実運用上は、 ingress.classのアノテーションは使わず、ingressClassNameフィールドを使えば良い認識(ingress.classは、kubernetes v1.22+で非推奨となる)。
単一のIngressコントローラーのみが存在する場合も、ingressClassNameフィールドを指定しておけば間違いない。
以下是参照文档的链接:
https://kubernetes.io/ja/docs/concepts/services-networking/ingress-controllers/
https://kubernetes.io/ja/docs/concepts/services-networking/ingress/
https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/
- Ingressリソースの設定は、nginx.confに反映される。そのため、nginxの設定が理解できていると、イメージしやすい。
设置范例
根据路径执行重定向操作。
如果要将重定向作用于单个域名,可以按照文档所述,使用nginx.ingress.kubernetes.io/permanent-redirect: https://www.google.com注释。
如果要根据路径进行重定向,请使用以下任意一种方法。
nginx.ingress.kubernetes.io/server-snippet
nginx.confのserverディレクティブに設定が追加されます。
server-snippet は1つのホストにつき1回しか設定できない。
nginx.ingress.kubernetes.io/configuration-snippet
nginx.confのlocationディレクティブに設定が追加されます。
既存のlocationディレクティブがあった場合、その全てに、ここで設定したものがネストして追加される(以下、例)
location ~* "^/foo/(.*)" { // 既存の location directive
location ~* "^/foo/(.*)" { // configuration-snippet を使って追加された location directive。本来は、既存の location directive に追加したいが、ネストして追加される。
}
}
location ~* "^/bar/(.*)" { // 既存の location directive
location ~* "^/foo/(.*)" { // configuration-snippet を使って追加された location directive。ここに追加する意味は本来ないが、追加される。
}
}
location ~* "^/" { // 既存の location directive
location ~* "^/foo/(.*)" { // configuration-snippet を使って追加された location directive。ここに追加する意味は本来ないが、追加される。
}
}
以下是使用配置片段(configuration-snippet)的示例。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sample-ingress-nginx
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/$ https://example.com permanent;
rewrite ^/en\/?$ https://example.com/en/foo permanent;
rewrite ^/ja\/?$ https://example.com/ja/foo permanent;
rewrite ^/(.*) https://another-example.com/$1 permanent;
cert-manager.io/issuer: "sample-letsencrypt-issuer"
spec:
ingressClassName: nginx
tls:
- hosts:
- sample.example.com
secretName: sample-letsencrypt-cert
rules:
- host: sample.example.com
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: sample-service
port:
number: 80
以下是使用server-snippet的示例,使用location + return 301,但此配置未生成SSL证书。
在生成SSL证书时,会启动临时的ingress来接受生成请求,但似乎无法正确处理请求,但详细信息不清楚。
annotations:
:
nginx.ingress.kubernetes.io/server-snippet: |
location ~ ^/((foo|bar)\/?)?$ {
return 301 https://redirect1-sample.example.com/$1;
}
location ~ ^/(.*) {
return 301 https://redirect2-sample.example.com/$1;
}
cert-manager.io/v1.0示例配置
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: sample-letsencrypt-issuer
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: foo@example.com
privateKeySecretRef:
name: sample-acme-client-letsencrypt
solvers:
- http01:
ingress:
class: nginx
准备注意事项
在进行ingress-nginx的配置时,理解nginx的配置非常重要。
关于性能方面,以下文章可供参考:
-
- 可能な限り、正規表現ではなく、完全一致を使う。
rewriteではなく、nested locationsを使う。
しかし、上記の例では、location + return では SSL証明書の発行ができなかったため、rewrite を使っている。
请确认nginx.conf的设置。
NAMESPACE=ingress-nginx
kubectl get pods --namespace=$NAMESPACE
// で pod を確認し、以下のコマンドで指定する。
kubectl exec --stdin --tty --namespace=$NAMESPACE ingress-nginx-controller-844c488f4b-85h6j -- cat /etc/nginx/nginx.conf
// or
kubectl exec -it -n $NAMESPACE ingress-nginx-controller-844c488f4b-85h6j -- cat /etc/nginx/nginx.conf
查看 Ingress 的日志
kubectl logs ingress-nginx-controller-5849c9f946-dqczh -n $NAMESPACE -f
登录 ingress 的 pod
kubectl exec -it -n $NAMESPACE ingress-nginx-controller-844c488f4b-85h6j -- /bin/bash
另外,参考网址
-
- ingress-nginx Installation Guide
-
- https://medium.com/ww-engineering/kubernetes-nginx-ingress-traffic-redirect-using-annotations-demystified-b7de846fb43d
-
- https://blog.grasys.io/post/tsunoda/nginx-rewrite/
-
- https://stackoverflow.com/questions/58993607/passing-parameters-down-to-permanent-redirect-in-ingress-nginx
-
- https://docs.nginx.com/nginx/admin-guide/web-server/web-server/
-
- https://blog.cybozu.io/entry/2015/11/20/080000
-
- http://nginx.org/en/docs/http/converting_rewrite_rules.html
- https://heartbeats.jp/hbblog/2012/04/nginx05.html