/ api /へのリクエストに応答するポッドがあります
/ auth/api /へのリクエストが/ api /に移動する場所を書き換えたいです。
Ingress(nginx)を使用して、ingress.kubernetes.io/rewrite-target:アノテーションを使用すると、次のようなことができると思いました。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapi-ing
annotations:
ingress.kubernetes.io/rewrite-target: /api
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- Host: api.myapp.com
http:
paths:
- path: /auth/api
backend:
serviceName: myapi
servicePort: myapi-port
しかし、何が起こっているのかというと、/ auth /がservice/podに渡され、404が正しくスローされています。書き換えアノテーションを誤解しているに違いありません。
K8とイングレスでこれを行う方法はありますか?
動作する次の例を作成しました。これについて説明します。この最小限の例を実行するには、次のコマンドを実行します。
$ minikube start
$ minikube addons enable ingress # might take a while for ingress pod to bootstrap
$ kubectl apply -f kubernetes.yaml
$ curl https://$(minikube ip)/auth/api/ --insecure
success - path: /api/
$ curl https://$(minikube ip)/auth/api --insecure
failure - path: /auth/api
$ curl https://$(minikube ip)/auth/api/blah/whatever --insecure
success - path: /api/blah/whatever
お気づきのように、イングレス書き換えアノテーションは、末尾のスラッシュに非常に特化しています。末尾のスラッシュが存在しない場合、リクエストは書き換えられません。ただし、末尾のスラッシュが指定されている場合、リクエストURIは書き換えられ、プロキシは期待どおりに機能します。
生成されたnginx.conf
イングレスコントローラー内部のファイル。この動作を担当するコード行は次のとおりです。
rewrite /auth/api/(.*) api/$1 break;
この行は、最初の引数に一致するリクエストのみが、2番目の引数で指定されたパスで書き換えられることを示しています。
これはバグに値すると信じています。
kubernetes.yaml
---
apiVersion: v1
kind: Service
metadata:
name: ingress-rewite-example
spec:
selector:
app: ingress-rewite-example
ports:
- name: nginx
port: 80
protocol: TCP
targetPort: 80
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ingress-rewite-example
spec:
template:
metadata:
labels:
app: ingress-rewite-example
spec:
containers:
- name: ingress-rewite-example
image: fbgrecojr/office-hours:so-47837087
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-rewite-example
annotations:
ingress.kubernetes.io/rewrite-target: /api
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /auth/api
backend:
serviceName: ingress-rewite-example
servicePort: 80
main.go
package main
import (
"fmt"
"strings"
"net/http"
)
func httpHandler(w http.ResponseWriter, r *http.Request) {
var response string
if strings.HasPrefix(r.URL.Path, "/api") {
response = "success"
} else {
response = "failure"
}
fmt.Fprintf(w, response + " - path: " + r.URL.Path + "\n")
}
func main() {
http.HandleFunc("/", httpHandler)
panic(http.ListenAndServe(":80", nil))
}
これがまだ問題かどうかはわかりませんが、バージョン0.22以降、キャプチャグループを使用して値をrewrite-target値に渡す必要があるようですnginxの例から入手可能 here
バージョン0.22.0以降、アノテーションnginx.ingress.kubernetes.io/rewrite-targetを使用したイングレス定義は、以前のバージョンとの後方互換性がありません。バージョン0.22.0以降では、リクエストURI内の書き換えられたパスに渡す必要があるサブストリングは、キャプチャグループで明示的に定義する必要があります。
あなたの特定のニーズのために、このような何かがトリックを行う必要があります
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapi-ing
annotations:
ingress.kubernetes.io/rewrite-target: /api/$2
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- Host: api.myapp.com
http:
paths:
- path: /auth/api(/|$)(.*)
backend:
serviceName: myapi
servicePort: myapi-port