如何在 Kubernetes 中设置自定义 HTTP 错误

Rag*_*ock 10 kubernetes kubernetes-ingress

我想创建一个自定义的 403 错误页面。目前我已经创建了一个 Ingress 并且在注释中我有这样的东西:

"nginx.ingress.kubernetes.io/whitelist-source-range": "100.01.128.0/20,88.100.01.01"
Run Code Online (Sandbox Code Playgroud)

因此,在该 IP 范围之外访问我的 Web 应用程序的任何尝试都会收到 403 错误。

为了创建自定义页面,我尝试添加以下注释:

"nginx.ingress.kubernetes.io/custom-http-errors": "403",
"nginx.ingress.kubernetes.io/default-backend": "default-http-backend"
Run Code Online (Sandbox Code Playgroud)

其中 default-http-backend 是已部署的应用程序的名称。 豆荚详情

入口有这个:

{
  "kind": "Ingress",
  "apiVersion": "extensions/v1beta1",
  "metadata": {
    "name": "my-app-ingress",
    "namespace": "my-app-test",
    "selfLink": "/apis/extensions/v1beta1/namespaces/my-app-test/ingresses/my-app-ingress",
    "uid": "8f31f2b4-428d-11ea-b15a-ee0dcf00d5a8",
    "resourceVersion": "129105581",
    "generation": 3,
    "creationTimestamp": "2020-01-29T11:50:34Z",
    "annotations": {
      "kubernetes.io/ingress.class": "nginx",
      "nginx.ingress.kubernetes.io/custom-http-errors": "403",
      "nginx.ingress.kubernetes.io/default-backend": "default-http-backend",
      "nginx.ingress.kubernetes.io/rewrite-target": "/",
      "nginx.ingress.kubernetes.io/whitelist-source-range": "100.01.128.0/20,90.108.01.012"
    }
  },
  "spec": {
    "tls": [
      {
        "hosts": [
          "my-app-test.retail-azure.js-devops.co.uk"
        ],
        "secretName": "ssl-secret"
      }
    ],
    "rules": [
      {
        "host": "my-app-test.retail-azure.js-devops.co.uk",
        "http": {
          "paths": [
            {
              "path": "/api",
              "backend": {
                "serviceName": "my-app-backend",
                "servicePort": 80
              }
            },
            {
              "path": "/",
              "backend": {
                "serviceName": "my-app-frontend",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  },
  "status": {
    "loadBalancer": {
      "ingress": [
        {}
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然而我总是得到默认的 403。我错过了什么?

Mr.*_*ler 10

我已经重现了你的场景,这对我有用。我将尝试按照我遵循的步骤指导您。

云提供商:GKE Kubernetes 版本:v1.15.3 命名空间default

我正在使用 2 个图像的 2 个部署,每个图像都有一个服务。

服务 1 : default-http-backend- 使用 nginx 镜像,它将是我们的默认后端。

服务 2 : custom-http-backend- 使用无生命/回声服务器图像,如果请求来自列入白名单的 ip,则将显示此服务。

入口:带有注释的 Nginx 入口。

预期行为:入口将被配置为使用default-backendcustom-http-errorswhitelist-source-range注释。如果请求是从列入白名单的 ip 发出的,入口将重定向到custom-http-backend,否则将重定向到default-http-backend

部署 1:default-http-backend

创建一个default-http-backend.yaml包含以下内容的文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: default-http-backend
spec:
  selector:
    matchLabels:
      app: default-http-backend
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      containers:
      - name: default-http-backend
        image: nginx
        ports:
        - name: http
          containerPort: 80
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
spec:
  selector:
    app: default-http-backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
Run Code Online (Sandbox Code Playgroud)

应用 yaml 文件: k apply -f default-http-backend.yaml

部署 2:custom-http-backend

创建一个custom-http-backend.yaml包含以下内容的文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-http-backend
spec:
  selector:
    matchLabels:
      app: custom-http-backend
  template:
    metadata:
      labels:
        app: custom-http-backend
    spec:
      containers:
      - name: custom-http-backend
        image: inanimate/echo-server
        ports:
        - name: http
          containerPort: 8080
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: custom-http-backend
spec:
  selector:
    app: custom-http-backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
Run Code Online (Sandbox Code Playgroud)

应用 yaml 文件: k apply -f custom-http-backend.yaml

检查服务是否已启动并正在运行

我使用的是别名kkubectl

?  ~ k get svc                                 
NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
custom-http-backend    ClusterIP   10.125.5.227   <none>        80/TCP    73s
default-http-backend   ClusterIP   10.125.9.218   <none>        80/TCP    5m41s
...
Run Code Online (Sandbox Code Playgroud)
?  ~ k get pods
NAME                                    READY   STATUS    RESTARTS   AGE
custom-http-backend-67844fb65d-k2mwl    1/1     Running   0          2m10s
default-http-backend-5485f569bd-fkd6f   1/1     Running   0          6m39s
...
Run Code Online (Sandbox Code Playgroud)

您可以使用port-forward测试服务:

default-http-backend k port-forward svc/default-http-backend 8080:80 尝试在浏览器中访问http://localhost:8080以查看 nginx 默认页面。

custom-http-backend k port-forward svc/custom-http-backend 8080:80 尝试在浏览器中访问http://localhost:8080以查看 echo-server 图像提供的自定义页面。

入口配置

此时我们已经启动并运行了两个服务,我们需要安装和配置 nginx 入口。可以参考官方文档,这里不做介绍。

安装后,让我们部署入口,根据您发布的代码,我做了一些修改:删除了 tls,添加了其他域并删除了/api仅用于测试目的的路径,并将我的家庭 ip 添加到白名单。

创建一个my-app-ingress.yaml包含内容的文件:

?  ~ k get svc                                 
NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
custom-http-backend    ClusterIP   10.125.5.227   <none>        80/TCP    73s
default-http-backend   ClusterIP   10.125.9.218   <none>        80/TCP    5m41s
...
Run Code Online (Sandbox Code Playgroud)

应用规范: k apply -f my-app-ingress.yaml

使用以下命令检查入口:

?  ~ k get ing
NAME             HOSTS              ADDRESS          PORTS   AGE
my-app-ingress   myapp.rabello.me   146.148.xx.xxx   80      36m
Run Code Online (Sandbox Code Playgroud)

就这样!

如果我在家中使用列入白名单的 ip 进行测试,则会显示自定义页面,但如果我尝试在 4G 网络中使用手机访问,则会显示 nginx 默认页面。

注意我在同一个命名空间中使用入口和服务,如果您需要使用不同的命名空间,则需要使用ExternalName

我希望这有帮助!

参考资料: kubernetes 部署

Kubernetes 服务

nginx入口

nginx 注释


Arg*_*dhu 0

您需要创建并部署自定义默认后端,它将返回自定义错误页面。按照文档部署自定义默认后端,并通过修改部署 yaml 以使用此自定义默认后端来配置 nginx 入口控制器。

自定义默认后端的部署 yaml 位于此处,源代码位于此处